feat: complete stage 3 settings refactor

This commit is contained in:
Jason
2025-10-16 11:40:02 +08:00
parent b88eb88608
commit 2b45af118f
17 changed files with 1828 additions and 1121 deletions

View File

@@ -1,7 +1,14 @@
import React from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { AlertTriangle } from "lucide-react";
import { useTranslation } from "react-i18next";
import { AlertTriangle, X } from "lucide-react";
import { isLinux } from "../lib/platform";
interface ConfirmDialogProps {
isOpen: boolean;
@@ -13,7 +20,7 @@ interface ConfirmDialogProps {
onCancel: () => void;
}
export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
export function ConfirmDialog({
isOpen,
title,
message,
@@ -21,63 +28,37 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
cancelText,
onConfirm,
onCancel,
}) => {
}: ConfirmDialogProps) {
const { t } = useTranslation();
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center">
{/* Backdrop */}
<div
className={`absolute inset-0 bg-black/50${isLinux() ? "" : " backdrop-blur-sm"}`}
onClick={onCancel}
/>
{/* Dialog */}
<div className="relative bg-white dark:bg-gray-900 rounded-xl shadow-lg max-w-md w-full mx-4 overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-800">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-red-100 dark:bg-red-500/10 rounded-full flex items-center justify-center">
<AlertTriangle size={20} className="text-red-500" />
</div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">
{title}
</h3>
</div>
<button
onClick={onCancel}
className="p-1 text-gray-500 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-800 rounded-md transition-colors"
>
<X size={18} />
</button>
</div>
{/* Content */}
<div className="p-6">
<p className="text-gray-500 dark:text-gray-400 leading-relaxed">
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) {
onCancel();
}
}}
>
<DialogContent className="max-w-sm">
<DialogHeader className="space-y-3">
<DialogTitle className="flex items-center gap-2 text-lg font-semibold">
<AlertTriangle className="h-5 w-5 text-destructive" />
{title}
</DialogTitle>
<DialogDescription className="whitespace-pre-line text-sm leading-relaxed">
{message}
</p>
</div>
{/* Actions */}
<div className="flex items-center justify-end gap-3 p-6 border-t border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-900">
<button
onClick={onCancel}
className="px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-900 hover:bg-white dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-800 rounded-md transition-colors"
autoFocus
>
</DialogDescription>
</DialogHeader>
<DialogFooter className="flex gap-2 sm:justify-end">
<Button variant="outline" onClick={onCancel}>
{cancelText || t("common.cancel")}
</button>
<button
onClick={onConfirm}
className="px-4 py-2 text-sm font-medium bg-red-500 text-white hover:bg-red-500/90 rounded-md transition-colors"
>
</Button>
<Button variant="destructive" onClick={onConfirm}>
{confirmText || t("common.confirm")}
</button>
</div>
</div>
</div>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
}