feat(settings): add first-run confirmation dialogs for proxy and usage features

Prevent accidental activation of advanced features by showing a one-time
info dialog. Once confirmed, the flag is persisted in settings.json and
the dialog never appears again.

- Proxy: confirmation when toggling proxy server ON for the first time
- Usage: confirmation when enabling usage query inside UsageScriptModal
- Enhanced ConfirmDialog with "info" variant (blue icon + default button)
- Added i18n translations for zh, en, ja
This commit is contained in:
Jason
2026-02-21 21:27:26 +08:00
parent 6b4ba64bbd
commit 5ebc879f09
8 changed files with 119 additions and 10 deletions
@@ -1,3 +1,4 @@
import { useState } from "react";
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { Server, Activity, ChevronDown, Zap, Globe } from "lucide-react";
import { motion } from "framer-motion";
@@ -17,6 +18,7 @@ import { AutoFailoverConfigPanel } from "@/components/proxy/AutoFailoverConfigPa
import { FailoverQueueManager } from "@/components/proxy/FailoverQueueManager";
import { RectifierConfigPanel } from "@/components/settings/RectifierConfigPanel";
import { GlobalProxySettings } from "@/components/settings/GlobalProxySettings";
import { ConfirmDialog } from "@/components/ConfirmDialog";
import { useProxyStatus } from "@/hooks/useProxyStatus";
import type { SettingsFormState } from "@/hooks/useSettings";
@@ -30,6 +32,7 @@ export function ProxyTabContent({
onAutoSave,
}: ProxyTabContentProps) {
const { t } = useTranslation();
const [showProxyConfirm, setShowProxyConfirm] = useState(false);
const {
isRunning,
@@ -42,6 +45,8 @@ export function ProxyTabContent({
try {
if (!checked) {
await stopWithRestore();
} else if (!settings?.proxyConfirmed) {
setShowProxyConfirm(true);
} else {
await startProxyServer();
}
@@ -50,6 +55,16 @@ export function ProxyTabContent({
}
};
const handleProxyConfirm = async () => {
setShowProxyConfirm(false);
try {
await onAutoSave({ proxyConfirmed: true });
await startProxyServer();
} catch (error) {
console.error("Proxy confirm failed:", error);
}
};
return (
<motion.div
initial={{ opacity: 0, y: 10 }}
@@ -269,6 +284,16 @@ export function ProxyTabContent({
</AccordionContent>
</AccordionItem>
</Accordion>
<ConfirmDialog
isOpen={showProxyConfirm}
variant="info"
title={t("confirm.proxy.title")}
message={t("confirm.proxy.message")}
confirmText={t("confirm.proxy.confirm")}
onConfirm={() => void handleProxyConfirm()}
onCancel={() => setShowProxyConfirm(false)}
/>
</motion.div>
);
}