chore: apply prettier formatting to component files
This commit is contained in:
@@ -146,7 +146,9 @@ const UsagePlanItem: React.FC<{ data: UsageData }> = ({ data }) => {
|
|||||||
{/* 总额度 */}
|
{/* 总额度 */}
|
||||||
{total !== undefined && (
|
{total !== undefined && (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-500 dark:text-gray-400">{t("usage.total")}</span>
|
<span className="text-gray-500 dark:text-gray-400">
|
||||||
|
{t("usage.total")}
|
||||||
|
</span>
|
||||||
<span className="tabular-nums text-gray-600 dark:text-gray-400">
|
<span className="tabular-nums text-gray-600 dark:text-gray-400">
|
||||||
{total === -1 ? "∞" : total.toFixed(2)}
|
{total === -1 ? "∞" : total.toFixed(2)}
|
||||||
</span>
|
</span>
|
||||||
@@ -157,7 +159,9 @@ const UsagePlanItem: React.FC<{ data: UsageData }> = ({ data }) => {
|
|||||||
{/* 已用额度 */}
|
{/* 已用额度 */}
|
||||||
{used !== undefined && (
|
{used !== undefined && (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-500 dark:text-gray-400">{t("usage.used")}</span>
|
<span className="text-gray-500 dark:text-gray-400">
|
||||||
|
{t("usage.used")}
|
||||||
|
</span>
|
||||||
<span className="tabular-nums text-gray-600 dark:text-gray-400">
|
<span className="tabular-nums text-gray-600 dark:text-gray-400">
|
||||||
{used.toFixed(2)}
|
{used.toFixed(2)}
|
||||||
</span>
|
</span>
|
||||||
@@ -168,7 +172,9 @@ const UsagePlanItem: React.FC<{ data: UsageData }> = ({ data }) => {
|
|||||||
{/* 剩余额度 - 突出显示 */}
|
{/* 剩余额度 - 突出显示 */}
|
||||||
{remaining !== undefined && (
|
{remaining !== undefined && (
|
||||||
<>
|
<>
|
||||||
<span className="text-gray-500 dark:text-gray-400">{t("usage.remaining")}</span>
|
<span className="text-gray-500 dark:text-gray-400">
|
||||||
|
{t("usage.remaining")}
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
className={`font-semibold tabular-nums ${
|
className={`font-semibold tabular-nums ${
|
||||||
isExpired
|
isExpired
|
||||||
|
|||||||
@@ -95,7 +95,11 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
provider.meta?.usage_script || {
|
provider.meta?.usage_script || {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
language: "javascript",
|
language: "javascript",
|
||||||
code: PRESET_TEMPLATES[t("usageScript.presetTemplate") === "预设模板" ? "通用模板" : "General"],
|
code: PRESET_TEMPLATES[
|
||||||
|
t("usageScript.presetTemplate") === "预设模板"
|
||||||
|
? "通用模板"
|
||||||
|
: "General"
|
||||||
|
],
|
||||||
timeout: 10,
|
timeout: 10,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -132,16 +136,24 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
return `${planInfo} ${t("usage.remaining")} ${plan.remaining} ${plan.unit}`;
|
return `${planInfo} ${t("usage.remaining")} ${plan.remaining} ${plan.unit}`;
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
toast.success(`${t("usageScript.testSuccess")}${summary}`, { duration: 3000 });
|
toast.success(`${t("usageScript.testSuccess")}${summary}`, {
|
||||||
} else {
|
duration: 3000,
|
||||||
toast.error(`${t("usageScript.testFailed")}: ${result.error || t("endpointTest.noResult")}`, {
|
|
||||||
duration: 5000,
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
toast.error(
|
||||||
|
`${t("usageScript.testFailed")}: ${result.error || t("endpointTest.noResult")}`,
|
||||||
|
{
|
||||||
|
duration: 5000,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(`${t("usageScript.testFailed")}: ${error?.message || t("common.unknown")}`, {
|
toast.error(
|
||||||
|
`${t("usageScript.testFailed")}: ${error?.message || t("common.unknown")}`,
|
||||||
|
{
|
||||||
duration: 5000,
|
duration: 5000,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setTesting(false);
|
setTesting(false);
|
||||||
}
|
}
|
||||||
@@ -160,9 +172,12 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
setScript({ ...script, code: formatted.trim() });
|
setScript({ ...script, code: formatted.trim() });
|
||||||
toast.success(t("usageScript.formatSuccess"), { duration: 1000 });
|
toast.success(t("usageScript.formatSuccess"), { duration: 1000 });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(`${t("usageScript.formatFailed")}: ${error?.message || t("jsonEditor.invalidJson")}`, {
|
toast.error(
|
||||||
|
`${t("usageScript.formatFailed")}: ${error?.message || t("jsonEditor.invalidJson")}`,
|
||||||
|
{
|
||||||
duration: 3000,
|
duration: 3000,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,7 +192,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||||
<DialogContent className="max-w-3xl max-h-[90vh] flex flex-col">
|
<DialogContent className="max-w-3xl max-h-[90vh] flex flex-col">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{t("usageScript.title")} - {provider.name}</DialogTitle>
|
<DialogTitle>
|
||||||
|
{t("usageScript.title")} - {provider.name}
|
||||||
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
{/* Content - Scrollable */}
|
{/* Content - Scrollable */}
|
||||||
@@ -231,7 +248,7 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
<p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
<p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||||
{t("usageScript.variablesHint", {
|
{t("usageScript.variablesHint", {
|
||||||
apiKey: "{{apiKey}}",
|
apiKey: "{{apiKey}}",
|
||||||
baseUrl: "{{baseUrl}}"
|
baseUrl: "{{baseUrl}}",
|
||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -260,7 +277,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
|
|
||||||
{/* 脚本说明 */}
|
{/* 脚本说明 */}
|
||||||
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg text-sm text-gray-700 dark:text-gray-300">
|
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg text-sm text-gray-700 dark:text-gray-300">
|
||||||
<h4 className="font-medium mb-2">{t("usageScript.scriptHelp")}</h4>
|
<h4 className="font-medium mb-2">
|
||||||
|
{t("usageScript.scriptHelp")}
|
||||||
|
</h4>
|
||||||
<div className="space-y-3 text-xs">
|
<div className="space-y-3 text-xs">
|
||||||
<div>
|
<div>
|
||||||
<strong>{t("usageScript.configFormat")}</strong>
|
<strong>{t("usageScript.configFormat")}</strong>
|
||||||
@@ -304,7 +323,12 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
<div className="text-gray-600 dark:text-gray-400">
|
<div className="text-gray-600 dark:text-gray-400">
|
||||||
<strong>{t("usageScript.tips")}</strong>
|
<strong>{t("usageScript.tips")}</strong>
|
||||||
<ul className="mt-1 space-y-0.5 ml-2">
|
<ul className="mt-1 space-y-0.5 ml-2">
|
||||||
<li>{t("usageScript.tip1", { apiKey: "{{apiKey}}", baseUrl: "{{baseUrl}}" })}</li>
|
<li>
|
||||||
|
{t("usageScript.tip1", {
|
||||||
|
apiKey: "{{apiKey}}",
|
||||||
|
baseUrl: "{{baseUrl}}",
|
||||||
|
})}
|
||||||
|
</li>
|
||||||
<li>{t("usageScript.tip2")}</li>
|
<li>{t("usageScript.tip2")}</li>
|
||||||
<li>{t("usageScript.tip3")}</li>
|
<li>{t("usageScript.tip3")}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ export function ModeToggle() {
|
|||||||
<Button variant="outline" size="icon" onClick={toggleTheme}>
|
<Button variant="outline" size="icon" onClick={toggleTheme}>
|
||||||
<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||||
<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||||
<span className="sr-only">
|
<span className="sr-only">{t("common.toggleTheme")}</span>
|
||||||
{t("common.toggleTheme")}
|
|
||||||
</span>
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,9 +143,7 @@ export function AddProviderDialog({
|
|||||||
<DialogContent className="max-w-3xl max-h-[85vh] min-h-[600px] flex flex-col">
|
<DialogContent className="max-w-3xl max-h-[85vh] min-h-[600px] flex flex-col">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{submitLabel}</DialogTitle>
|
<DialogTitle>{submitLabel}</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>{t("provider.addProviderHint")}</DialogDescription>
|
||||||
{t("provider.addProviderHint")}
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="flex-1 overflow-y-auto px-6 py-4">
|
<div className="flex-1 overflow-y-auto px-6 py-4">
|
||||||
|
|||||||
@@ -67,9 +67,7 @@ export function EditProviderDialog({
|
|||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogContent className="max-w-3xl max-h-[85vh] min-h-[600px] flex flex-col">
|
<DialogContent className="max-w-3xl max-h-[85vh] min-h-[600px] flex flex-col">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>{t("provider.editProvider")}</DialogTitle>
|
||||||
{t("provider.editProvider")}
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
{t("provider.editProviderHint")}
|
{t("provider.editProviderHint")}
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ export function ProviderActions({
|
|||||||
disabled={isCurrent}
|
disabled={isCurrent}
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-20",
|
"w-20",
|
||||||
isCurrent && "bg-gray-200 text-muted-foreground hover:bg-gray-200 hover:text-muted-foreground dark:bg-gray-700 dark:hover:bg-gray-700",
|
isCurrent &&
|
||||||
|
"bg-gray-200 text-muted-foreground hover:bg-gray-200 hover:text-muted-foreground dark:bg-gray-700 dark:hover:bg-gray-700",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isCurrent ? (
|
{isCurrent ? (
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ export function ProviderEmptyState({ onCreate }: ProviderEmptyStateProps) {
|
|||||||
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-muted">
|
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-muted">
|
||||||
<Users className="h-7 w-7 text-muted-foreground" />
|
<Users className="h-7 w-7 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg font-semibold">
|
<h3 className="text-lg font-semibold">{t("provider.noProviders")}</h3>
|
||||||
{t("provider.noProviders")}
|
|
||||||
</h3>
|
|
||||||
<p className="mt-2 max-w-sm text-sm text-muted-foreground">
|
<p className="mt-2 max-w-sm text-sm text-muted-foreground">
|
||||||
{t("provider.noProvidersDescription")}
|
{t("provider.noProvidersDescription")}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -24,14 +24,9 @@ export function BasicFormFields({ form }: BasicFormFieldsProps) {
|
|||||||
name="name"
|
name="name"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>
|
<FormLabel>{t("provider.name")}</FormLabel>
|
||||||
{t("provider.name")}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input {...field} placeholder={t("provider.namePlaceholder")} />
|
||||||
{...field}
|
|
||||||
placeholder={t("provider.namePlaceholder")}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -43,9 +38,7 @@ export function BasicFormFields({ form }: BasicFormFieldsProps) {
|
|||||||
name="websiteUrl"
|
name="websiteUrl"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>
|
<FormLabel>{t("provider.websiteUrl")}</FormLabel>
|
||||||
{t("provider.websiteUrl")}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} placeholder="https://" />
|
<Input {...field} placeholder="https://" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ export function CommonConfigEditor({
|
|||||||
<>
|
<>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="settingsConfig">
|
<Label htmlFor="settingsConfig">{t("provider.configJson")}</Label>
|
||||||
{t("provider.configJson")}
|
|
||||||
</Label>
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<label className="inline-flex items-center gap-2 text-sm text-muted-foreground cursor-pointer">
|
<label className="inline-flex items-center gap-2 text-sm text-muted-foreground cursor-pointer">
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ const EndpointSpeedTest: React.FC<EndpointSpeedTestProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 明确只允许 http: 和 https:
|
// 明确只允许 http: 和 https:
|
||||||
const allowedProtocols = ['http:', 'https:'];
|
const allowedProtocols = ["http:", "https:"];
|
||||||
if (!errorMsg && parsed && !allowedProtocols.includes(parsed.protocol)) {
|
if (!errorMsg && parsed && !allowedProtocols.includes(parsed.protocol)) {
|
||||||
errorMsg = t("endpointTest.onlyHttps");
|
errorMsg = t("endpointTest.onlyHttps");
|
||||||
}
|
}
|
||||||
@@ -333,15 +333,20 @@ const EndpointSpeedTest: React.FC<EndpointSpeedTestProps> = ({
|
|||||||
try {
|
try {
|
||||||
await vscodeApi.removeCustomEndpoint(appType, providerId, entry.url);
|
await vscodeApi.removeCustomEndpoint(appType, providerId, entry.url);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
const errorMsg =
|
||||||
|
error instanceof Error ? error.message : String(error);
|
||||||
|
|
||||||
// 只有"端点不存在"时才允许删除本地条目
|
// 只有"端点不存在"时才允许删除本地条目
|
||||||
if (errorMsg.includes('not found') || errorMsg.includes('does not exist') || errorMsg.includes('不存在')) {
|
if (
|
||||||
console.warn(t('endpointTest.removeEndpointFailed'), errorMsg);
|
errorMsg.includes("not found") ||
|
||||||
|
errorMsg.includes("does not exist") ||
|
||||||
|
errorMsg.includes("不存在")
|
||||||
|
) {
|
||||||
|
console.warn(t("endpointTest.removeEndpointFailed"), errorMsg);
|
||||||
// 继续删除本地条目
|
// 继续删除本地条目
|
||||||
} else {
|
} else {
|
||||||
// 其他错误:显示错误提示,阻止删除
|
// 其他错误:显示错误提示,阻止删除
|
||||||
setLastError(t('endpointTest.removeFailed', { error: errorMsg }));
|
setLastError(t("endpointTest.removeFailed", { error: errorMsg }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -455,7 +455,11 @@ export function ProviderForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form id="provider-form" onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
|
<form
|
||||||
|
id="provider-form"
|
||||||
|
onSubmit={form.handleSubmit(handleSubmit)}
|
||||||
|
className="space-y-6"
|
||||||
|
>
|
||||||
{/* 预设供应商选择(仅新增模式显示) */}
|
{/* 预设供应商选择(仅新增模式显示) */}
|
||||||
{!initialData && (
|
{!initialData && (
|
||||||
<ProviderPresetSelector
|
<ProviderPresetSelector
|
||||||
|
|||||||
@@ -114,9 +114,7 @@ export function ProviderPresetSelector({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<FormLabel>
|
<FormLabel>{t("providerPreset.label")}</FormLabel>
|
||||||
{t("providerPreset.label")}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{/* 自定义按钮 */}
|
{/* 自定义按钮 */}
|
||||||
<button
|
<button
|
||||||
@@ -158,9 +156,7 @@ export function ProviderPresetSelector({
|
|||||||
});
|
});
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">{getCategoryHint()}</p>
|
||||||
{getCategoryHint()}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,10 +122,11 @@ export function useSpeedTestEndpoints({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 编辑模式:初始数据中的 URL
|
// 3. 编辑模式:初始数据中的 URL
|
||||||
const initialCodexConfig =
|
const initialCodexConfig = initialData?.settingsConfig as
|
||||||
initialData?.settingsConfig as {
|
| {
|
||||||
config?: string;
|
config?: string;
|
||||||
} | undefined;
|
}
|
||||||
|
| undefined;
|
||||||
const configStr = initialCodexConfig?.config ?? "";
|
const configStr = initialCodexConfig?.config ?? "";
|
||||||
// 从 TOML 中提取 base_url
|
// 从 TOML 中提取 base_url
|
||||||
const match = /base_url\s*=\s*["']([^"']+)["']/i.exec(configStr);
|
const match = /base_url\s*=\s*["']([^"']+)["']/i.exec(configStr);
|
||||||
|
|||||||
@@ -74,9 +74,7 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
|
|||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[AboutSection] Failed to open release notes", error);
|
console.error("[AboutSection] Failed to open release notes", error);
|
||||||
toast.error(
|
toast.error(t("settings.openReleaseNotesFailed"));
|
||||||
t("settings.openReleaseNotesFailed"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [t, updateInfo?.availableVersion, version]);
|
}, [t, updateInfo?.availableVersion, version]);
|
||||||
|
|
||||||
@@ -98,9 +96,7 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
|
|||||||
await relaunchApp();
|
await relaunchApp();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[AboutSection] Update failed", error);
|
console.error("[AboutSection] Update failed", error);
|
||||||
toast.error(
|
toast.error(t("settings.updateFailed"));
|
||||||
t("settings.updateFailed"),
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
await settingsApi.checkUpdates();
|
await settingsApi.checkUpdates();
|
||||||
} catch (fallbackError) {
|
} catch (fallbackError) {
|
||||||
@@ -122,14 +118,11 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[AboutSection] Check update failed", error);
|
console.error("[AboutSection] Check update failed", error);
|
||||||
toast.error(
|
toast.error(t("settings.checkUpdateFailed"));
|
||||||
t("settings.checkUpdateFailed"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [checkUpdate, hasUpdate, isPortable, resetDismiss, t, updateHandle]);
|
}, [checkUpdate, hasUpdate, isPortable, resetDismiss, t, updateHandle]);
|
||||||
|
|
||||||
const displayVersion =
|
const displayVersion = version ?? t("common.unknown");
|
||||||
version ?? t("common.unknown");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="space-y-4">
|
<section className="space-y-4">
|
||||||
|
|||||||
@@ -142,9 +142,7 @@ function ImportStatusMessage({
|
|||||||
<Loader2 className="mt-0.5 h-4 w-4 animate-spin text-muted-foreground" />
|
<Loader2 className="mt-0.5 h-4 w-4 animate-spin text-muted-foreground" />
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium">{t("settings.importing")}</p>
|
<p className="font-medium">{t("settings.importing")}</p>
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">{t("common.loading")}</p>
|
||||||
{t("common.loading")}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -169,17 +167,13 @@ function ImportStatusMessage({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const message =
|
const message = errorMessage || t("settings.importFailed");
|
||||||
errorMessage ||
|
|
||||||
t("settings.importFailed");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${baseClass} border-red-200 bg-red-100/70 text-red-600`}>
|
<div className={`${baseClass} border-red-200 bg-red-100/70 text-red-600`}>
|
||||||
<AlertCircle className="mt-0.5 h-4 w-4" />
|
<AlertCircle className="mt-0.5 h-4 w-4" />
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<p className="font-medium">
|
<p className="font-medium">{t("settings.importFailed")}</p>
|
||||||
{t("settings.importFailed")}
|
|
||||||
</p>
|
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -142,9 +142,7 @@ export function SettingsDialog({
|
|||||||
const handleRestartNow = useCallback(async () => {
|
const handleRestartNow = useCallback(async () => {
|
||||||
setShowRestartPrompt(false);
|
setShowRestartPrompt(false);
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
toast.success(
|
toast.success(t("settings.devModeRestartHint"));
|
||||||
t("settings.devModeRestartHint"),
|
|
||||||
);
|
|
||||||
closeAfterSave();
|
closeAfterSave();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -153,9 +151,7 @@ export function SettingsDialog({
|
|||||||
await settingsApi.restart();
|
await settingsApi.restart();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[SettingsDialog] Failed to restart app", error);
|
console.error("[SettingsDialog] Failed to restart app", error);
|
||||||
toast.error(
|
toast.error(t("settings.restartFailed"));
|
||||||
t("settings.restartFailed"),
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
closeAfterSave();
|
closeAfterSave();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user