import { useState } from 'react'; import { useMutation, useQuery } from '@tanstack/react-query'; import { MdBadge, MdPerson, MdLocationOn, MdMail, MdShield, MdVerifiedUser, MdLock } from 'react-icons/md'; import { enqueueSnackbar } from 'notistack'; import { Grid } from '@astryxdesign/core/Grid'; import { HStack } from '@astryxdesign/core/HStack'; import { VStack } from '@astryxdesign/core/VStack'; import { Card } from '@astryxdesign/core/Card'; import { Text } from '@astryxdesign/core/Text'; import { Button } from '@astryxdesign/core/Button'; import { TextInput } from '@astryxdesign/core/TextInput'; import { Badge } from '@astryxdesign/core/Badge'; import { Avatar } from '@astryxdesign/core/Avatar'; import { Divider } from '@astryxdesign/core/Divider'; import Loader from 'components/Loader'; import PageHeader from 'components/nearle_components/PageHeader'; import { PageShell } from 'components/nearle_components/PageLayout'; import { getusers } from 'pages/api/api'; import { updateProfilePassword } from 'pages/api/doormileApi'; import { DT } from 'themes/dt/tokens'; import { AccentAvatar } from 'themes/dt/primitives'; const ROLE_LABELS = { 1: 'Admin', 3: 'Manager', 4: 'Executive' }; const BRAND = DT.brand; // A single read-only field rendered as an icon + uppercase label + value. const InfoField = ({ icon: Icon, label, value, accent = BRAND }) => ( {label} {value || '—'} ); // A titled grouping card. const SectionCard = ({ title, icon: Icon, children }) => ( {title} {children} ); const ViewProfile = () => { const { data: userData, isLoading } = useQuery({ queryKey: ['getuser'], queryFn: getusers }); const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const opentoast = (message, variant = 'error') => enqueueSnackbar(message, { variant, anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 2000 }); const changePasswordMutation = useMutation({ mutationFn: () => updateProfilePassword(currentPassword, newPassword), onSuccess: (res) => { if (res.success) { opentoast('Password updated successfully', 'success'); setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); } else { opentoast(res.message || 'Failed to update password'); } }, onError: (err) => opentoast(err.response?.data?.message || err.message || 'Failed to update password') }); const handleChangePassword = () => { if (!currentPassword || !newPassword) { opentoast('Fill current and new password'); return; } if (newPassword !== confirmPassword) { opentoast('New password and confirmation do not match'); return; } changePasswordMutation.mutate(); }; // GET /admin/profile has no documented schema, but the console's own login // response ({ success, token, user: { id, name, email, role, tenantid } }) // is confirmed — /admin/profile almost certainly returns the same "user" // shape. Fields like address/suburb/city/postcode were jupiter-era guesses // with no basis in the new API and have been dropped rather than shown blank. const fullname = userData?.name || userData?.fullname || 'User Profile'; const roleLabel = ROLE_LABELS[userData?.role] || ROLE_LABELS[userData?.roleid] || userData?.role || '—'; const tenantLabel = userData?.tenantid ? `Tenant #${userData.tenantid}` : 'Doormile staff (all tenants)'; return ( <> {isLoading && } {fullname} {roleLabel !== '—' && } label={roleLabel} />} {(userData?.id != null || userData?.userid != null) && ( ID #{userData.id ?? userData.userid} )} {tenantLabel}