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}
}
onClick={handleChangePassword}
isLoading={changePasswordMutation.isPending}
style={{ alignSelf: 'flex-start' }}
/>
>
);
};
export default ViewProfile;