import React, { useState, useEffect } from "react"; import { useAuth } from "../../context/AuthContext"; import { CustomLoader, CustomModal, CustomInput, CustomButton } from "../../components/custom"; import { useTranslation } from "react-i18next"; import { authApi } from "../authentication/AuthApi"; import { Key, Pencil } from "lucide-react"; import type { PasswordForm, FormatDateFunction, FormatNameFunction, RenderStatusBadgeFunction } from "./ProfileTypes"; import { useTheme } from "../../context/ThemeContext"; import { paletteApi } from "../theme/PaletteApi"; import type { ColorPalette } from "../theme/ThemeTypes"; type ProfileForm = { firstName: string; lastName: string; phoneNumber: string; }; const formatDate: FormatDateFunction = (value: string) => { const date = new Date(value); if (Number.isNaN(date.getTime())) return value; return date.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric", }); }; const formatName: FormatNameFunction = (firstName: string, lastName?: string | null) => [firstName, lastName].filter(Boolean).join(" "); const renderStatusBadge: RenderStatusBadgeFunction = (status?: string) => ( {status ? status.charAt(0).toUpperCase() + status.slice(1) : "Unknown"} ); const ProfilePage: React.FC = () => { const { t } = useTranslation(['profile', 'common']); const { user, isLoading, refreshUser } = useAuth(); const [isPasswordModalOpen, setIsPasswordModalOpen] = useState(false); const [passwordForm, setPasswordForm] = useState({ currentPassword: "", newPassword: "", confirmPassword: "", }); const [passwordError, setPasswordError] = useState(""); const [passwordSuccess, setPasswordSuccess] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [profileForm, setProfileForm] = useState({ firstName: "", lastName: "", phoneNumber: "", }); const [profileError, setProfileError] = useState(""); const [profileSuccess, setProfileSuccess] = useState(""); const [isProfileSubmitting, setIsProfileSubmitting] = useState(false); // Theme Logic const { currentPalette, setTheme } = useTheme(); const [palettes, setPalettes] = useState([]); const [isThemesLoading, setIsThemesLoading] = useState(false); useEffect(() => { const fetchPalettes = async () => { setIsThemesLoading(true); try { const data = await paletteApi.getAllPalettes(); setPalettes(data); } catch (error) { console.error("Failed to fetch palettes", error); } finally { setIsThemesLoading(false); } }; fetchPalettes(); }, []); if (isLoading) { return (
); } if (!user) { return (
{t('messages.loadError')}
); } const fullName = formatName(user.first_name, user.last_name); const initials = user.first_name && user.last_name ? `${user.first_name[0]}${user.last_name[0]}` : user.first_name ? user.first_name[0] : "U"; const handlePasswordChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setPasswordForm((prev) => ({ ...prev, [name]: value })); setPasswordError(""); }; const handlePasswordSubmit = async (e: React.FormEvent) => { e.preventDefault(); setPasswordError(""); setPasswordSuccess(""); // Client-side validation if (!passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword) { setPasswordError(t('messages.requiredFields')); return; } if (passwordForm.newPassword.length < 8) { setPasswordError(t('messages.passwordLength')); return; } if (passwordForm.newPassword !== passwordForm.confirmPassword) { setPasswordError(t('messages.passwordMismatch')); return; } setIsSubmitting(true); try { const response = await authApi.resetPassword( passwordForm.currentPassword, passwordForm.newPassword ); setPasswordSuccess(response.message || t('messages.passwordSuccess')); setPasswordForm({ currentPassword: "", newPassword: "", confirmPassword: "", }); // Close modal after 1.5 seconds setTimeout(() => { setIsPasswordModalOpen(false); setPasswordSuccess(""); }, 1500); } catch (err) { const errorMessage = err instanceof Error ? err.message : "Failed to update password"; setPasswordError(errorMessage); } finally { setIsSubmitting(false); } }; const handlePasswordModalClose = () => { setIsPasswordModalOpen(false); setPasswordForm({ currentPassword: "", newPassword: "", confirmPassword: "", }); setPasswordError(""); setPasswordSuccess(""); }; // Edit Profile handlers const handleOpenEditModal = () => { if (user) { setProfileForm({ firstName: user.first_name || "", lastName: user.last_name || "", phoneNumber: user.phone_number || "", }); } setIsEditModalOpen(true); }; const handleProfileChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setProfileForm((prev) => ({ ...prev, [name]: value })); setProfileError(""); }; const handleProfileSubmit = async (e: React.FormEvent) => { e.preventDefault(); setProfileError(""); setProfileSuccess(""); if (!user) return; if (!profileForm.firstName.trim()) { setProfileError(t('messages.firstNameRequired')); return; } setIsProfileSubmitting(true); try { await authApi.updateProfile(user.id, { first_name: profileForm.firstName.trim(), last_name: profileForm.lastName.trim() || undefined, phone_number: profileForm.phoneNumber.trim() || undefined, }); setProfileSuccess(t('messages.profileSuccess')); // Refresh user data if (refreshUser) { await refreshUser(); } // Close modal after 1.5 seconds setTimeout(() => { setIsEditModalOpen(false); setProfileSuccess(""); }, 1500); } catch (err) { const errorMessage = err instanceof Error ? err.message : "Failed to update profile"; setProfileError(errorMessage); } finally { setIsProfileSubmitting(false); } }; const handleEditModalClose = () => { setIsEditModalOpen(false); setProfileError(""); setProfileSuccess(""); }; return (
{/* Header */}

{t('title')}

{t('subTitle')}

{/* Profile Card */}
{/* User Header Section */}
{/* User Info */}
{initials}

{fullName}

{user.email}

{renderStatusBadge(user.status)}
setIsPasswordModalOpen(true)} > {t('buttons.changePassword')} {t('buttons.editProfile')}
{/* User Details Section */}

{t('sections.accountInfo')}

{/* First Name */}

{t('fields.firstName')}

{user.first_name}

{/* Last Name */}

{t('fields.lastName')}

{user.last_name || "--"}

{/* Email */}

{t('fields.email')}

{user.email}

{/* Phone Number */}

{t('fields.phone')}

{user.phone_number || "--"}

{/* Tenant */}

{t('fields.tenant')}

{user.tenant_name || "--"}

{/* Role */}

{t('fields.role')}

{user.role?.role_name || "--"}

{/* Account Created */}

{t('fields.accountCreated')}

{formatDate(user.created_at)}

{/* Last Updated */}

{t('fields.lastUpdated')}

{formatDate(user.updated_at)}

{/* Appearance / Theme Section */}

{t('sections.appearance')}

{t('sections.appearanceDesc')}

{isThemesLoading ? (
) : (
{palettes.map((palette) => ( ))}
)}
{/* Change Password Modal */} {t('common:actions.cancel')} {t('buttons.updatePassword')} } >
{passwordError && (
{passwordError}
)} {passwordSuccess && (
{passwordSuccess}
)}
{/* Edit Profile Modal */} {t('common:actions.cancel')} {t('buttons.saveChanges')} } >
{profileError && (
{profileError}
)} {profileSuccess && (
{profileSuccess}
)}
); }; export default ProfilePage;