"use client"; import * as React from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { IconBell, IconKey, IconLock, IconShield, IconUpload, IconUser, } from "@tabler/icons-react"; import { toast } from "sonner"; import { updateUserProfile, changePassword, getUserSettings, updateUserSettings, deleteUserAccount, exportUserData, } from "@/lib/actions/settings-actions"; type User = { id: string; name: string; email: string; phone?: string | null; image?: string | null; dateOfBirth?: Date | null; address?: string | null; role?: string; }; type UserSettingsContentProps = { user: User; }; export function UserSettingsContent({ user }: UserSettingsContentProps) { const [isLoading, setIsLoading] = React.useState(false); // Profile State const [name, setName] = React.useState(user.name); const [email, setEmail] = React.useState(user.email); const [phone, setPhone] = React.useState(user.phone || ""); const [address, setAddress] = React.useState(user.address || ""); const [dateOfBirth, setDateOfBirth] = React.useState( user.dateOfBirth ? new Date(user.dateOfBirth).toISOString().split("T")[0] : "" ); // Password State const [currentPassword, setCurrentPassword] = React.useState(""); const [newPassword, setNewPassword] = React.useState(""); const [confirmPassword, setConfirmPassword] = React.useState(""); // Notification Settings const [emailNotifications, setEmailNotifications] = React.useState(true); const [smsNotifications, setSmsNotifications] = React.useState(true); const [appointmentReminders, setAppointmentReminders] = React.useState(true); const [promotionalEmails, setPromotionalEmails] = React.useState(false); const [reminderTiming, setReminderTiming] = React.useState("24"); // Privacy Settings const [profileVisibility, setProfileVisibility] = React.useState("private"); const [shareData, setShareData] = React.useState(false); const [twoFactorAuth, setTwoFactorAuth] = React.useState(false); // Load settings on mount React.useEffect(() => { const loadSettings = async () => { try { const settings = await getUserSettings(user.id); if (settings) { setEmailNotifications(settings.emailNotifications); setSmsNotifications(settings.smsNotifications); setAppointmentReminders(settings.appointmentReminders); setPromotionalEmails(settings.promotionalEmails); setReminderTiming(settings.reminderTiming); setProfileVisibility(settings.profileVisibility); setShareData(settings.shareData); setTwoFactorAuth(settings.twoFactorAuth); } } catch (error) { console.error("Failed to load settings:", error); } }; loadSettings(); }, [user.id]); const handleSaveProfile = async () => { setIsLoading(true); try { const result = await updateUserProfile({ name, email, phone, address, dateOfBirth, }); if (result.success) { toast.success(result.message); } else { toast.error(result.message); } } catch (error) { toast.error("Failed to update profile"); console.error(error); } finally { setIsLoading(false); } }; const handleChangePassword = async () => { if (newPassword !== confirmPassword) { toast.error("Passwords do not match"); return; } if (newPassword.length < 8) { toast.error("Password must be at least 8 characters"); return; } setIsLoading(true); try { const result = await changePassword({ currentPassword, newPassword, }); if (result.success) { toast.success(result.message); setCurrentPassword(""); setNewPassword(""); setConfirmPassword(""); } else { toast.error(result.message); } } catch (error) { toast.error("Failed to change password"); console.error(error); } finally { setIsLoading(false); } }; const handleSaveNotifications = async () => { setIsLoading(true); try { const result = await updateUserSettings({ emailNotifications, smsNotifications, appointmentReminders, promotionalEmails, reminderTiming, }); if (result.success) { toast.success(result.message); } else { toast.error(result.message); } } catch (error) { toast.error("Failed to save notification settings"); console.error(error); } finally { setIsLoading(false); } }; const handleSavePrivacy = async () => { setIsLoading(true); try { const result = await updateUserSettings({ profileVisibility, shareData, twoFactorAuth, }); if (result.success) { toast.success(result.message); } else { toast.error(result.message); } } catch (error) { toast.error("Failed to save privacy settings"); console.error(error); } finally { setIsLoading(false); } }; const handleDeleteAccount = async () => { if ( !confirm( "Are you sure you want to delete your account? This action cannot be undone." ) ) { return; } setIsLoading(true); try { const result = await deleteUserAccount(); if (result.success) { toast.success(result.message); // Redirect to logout or home window.location.href = "/"; } else { toast.error(result.message); } } catch (error) { toast.error("Failed to delete account"); console.error(error); } finally { setIsLoading(false); } }; const handleExportData = async () => { setIsLoading(true); try { const result = await exportUserData(); if (result.success && result.data) { // Create a blob and download const blob = new Blob([result.data], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `user-data-${user.id}-${new Date().toISOString()}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); toast.success(result.message); } else { toast.error(result.message || "Failed to export data"); } } catch (error) { toast.error("Failed to export data"); console.error(error); } finally { setIsLoading(false); } }; const getInitials = (name: string) => { return name .split(" ") .map((n) => n[0]) .join("") .toUpperCase() .slice(0, 2); }; return (
Manage your account settings and preferences
JPG, PNG or GIF. Max size 2MB
Password requirements:
Require a verification code in addition to your password
Setup 2FA
Scan the QR code with your authenticator app or enter the code manually
Receive updates via email
Receive updates via text message
Get reminded before your appointments
Receive news, offers, and updates
Control who can see your profile information
Help us improve our services by sharing anonymous usage data