"use client"; import { useEffect, useState, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import Avatar from "@/components/ui/avatar"; import { api } from "@/lib/api"; import { useTranslation } from "@/lib/i18n"; import { useUser } from "@/lib/user-context"; type Me = { username?: string; avatar?: string | null; timezone: string; barkUrl?: string | null; inappEnabled: boolean; barkEnabled: boolean; }; const SettingsPanel = () => { const t = useTranslation(); const { refreshUser } = useUser(); const fileInputRef = useRef(null); const [form, setForm] = useState({ timezone: "Asia/Shanghai", barkUrl: "", avatar: null, inappEnabled: true, barkEnabled: false, }); const [saved, setSaved] = useState(false); const [uploading, setUploading] = useState(false); const [passwordForm, setPasswordForm] = useState({ currentPassword: "", newPassword: "", confirmPassword: "", }); const [passwordError, setPasswordError] = useState(""); const [passwordSuccess, setPasswordSuccess] = useState(false); const [changingPassword, setChangingPassword] = useState(false); useEffect(() => { api .getMe() .then((data) => setForm(data as Me)) .catch(() => null); }, []); const save = async () => { await api.updateSettings({ avatar: form.avatar || null, timezone: form.timezone, barkUrl: form.barkUrl || null, inappEnabled: form.inappEnabled, barkEnabled: form.barkEnabled, }); await refreshUser(); setSaved(true); setTimeout(() => setSaved(false), 1500); }; const handleFileChange = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; // 验证文件类型 const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"]; if (!allowedTypes.includes(file.type)) { alert("不支持的文件格式,请上传 jpg、png、gif 或 webp 格式的图片"); return; } // 验证文件大小 (5MB) if (file.size > 5 * 1024 * 1024) { alert("文件大小不能超过 5MB"); return; } try { setUploading(true); const result = await api.uploadAvatar(file); setForm({ ...form, avatar: result.avatarUrl }); await refreshUser(); } catch (error) { console.error("上传头像失败:", error); alert("上传头像失败,请重试"); } finally { setUploading(false); } }; const handleRemoveAvatar = () => { setForm({ ...form, avatar: null }); if (fileInputRef.current) { fileInputRef.current.value = ""; } }; const handleChangePassword = async () => { setPasswordError(""); setPasswordSuccess(false); if (!passwordForm.currentPassword) { setPasswordError(t("currentPasswordRequired")); return; } if (!passwordForm.newPassword) { setPasswordError(t("newPasswordRequired")); return; } if (passwordForm.newPassword.length < 6) { setPasswordError(t("passwordTooShort")); return; } if (passwordForm.newPassword !== passwordForm.confirmPassword) { setPasswordError(t("passwordMismatch")); return; } try { setChangingPassword(true); await api.changePassword({ currentPassword: passwordForm.currentPassword, newPassword: passwordForm.newPassword, }); setPasswordSuccess(true); setPasswordForm({ currentPassword: "", newPassword: "", confirmPassword: "" }); setTimeout(() => setPasswordSuccess(false), 3000); } catch (error) { setPasswordError(error instanceof Error ? error.message : "Failed to change password"); } finally { setChangingPassword(false); } }; return ( {t("settings")} {t("settingsDesc")}
{/* Avatar Section */}
{form.avatar && ( )}

{t("avatarHint")}

setForm({ ...form, barkUrl: event.target.value })} placeholder="https://your.bark.server" />
setForm({ ...form, timezone: event.target.value })} placeholder="Asia/Shanghai" />
{t("webNotifications")}
{t("webNotificationsDesc")}
setForm({ ...form, inappEnabled: checked === true }) } />
{t("barkAlerts")}
{t("barkAlertsDesc")}
setForm({ ...form, barkEnabled: checked === true }) } />
{saved &&
{t("saved")}
}
{/* Change Password Section */}

{t("changePassword")}

setPasswordForm({ ...passwordForm, currentPassword: e.target.value })} />
setPasswordForm({ ...passwordForm, newPassword: e.target.value })} />
setPasswordForm({ ...passwordForm, confirmPassword: e.target.value })} />
{passwordError && (
{passwordError}
)} {passwordSuccess && (
{t("passwordChanged")}
)}
); }; export default SettingsPanel;