Files
doormile_console_expresscopy/src/pages/nearle/viewProfile.js
2026-06-11 18:09:10 +05:30

236 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Avatar, Box, Chip, Grid, Paper, Stack, Typography, useMediaQuery } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { useQuery } from '@tanstack/react-query';
import {
MdBadge,
MdPerson,
MdLocationOn,
MdMail,
MdPhone,
MdPlace,
MdMyLocation,
MdLocationCity,
MdMap,
MdMarkunreadMailbox,
MdVerifiedUser
} from 'react-icons/md';
import CircularLoader from 'components/CircularLoader';
import Loader from 'components/Loader';
import { getusers } from 'pages/api/api';
// ---- shared design tokens (mirrors the DT block used across the console) ----
const DT = {
radiusCard: 16,
radiusInner: 12,
shadowSoft: '0 14px 40px rgba(15, 23, 42, 0.10)',
textPrimary: '#0f172a',
textSecondary: '#64748b',
textMuted: '#94a3b8',
borderSubtle: '#e2e8f0',
divider: '#f1f5f9',
surface: '#ffffff',
surfaceAlt: '#f8fafc'
};
const BRAND = '#662582';
const BRAND_LIGHT = '#9255AB';
const tint = (c) => `${c}08`;
const soft = (c) => `${c}18`;
const initialsOf = (name) =>
(name || '')
.trim()
.split(/\s+/)
.slice(0, 2)
.map((w) => w[0])
.join('')
.toUpperCase() || '';
// A single read-only field rendered as an icon + uppercase label + value.
const InfoField = ({ icon: Icon, label, value, accent = BRAND }) => (
<Stack direction="row" spacing={1.5} alignItems="flex-start" sx={{ minWidth: 0 }}>
<Avatar sx={{ width: 36, height: 36, bgcolor: soft(accent), color: accent, flexShrink: 0 }}>
<Icon size={18} />
</Avatar>
<Box sx={{ minWidth: 0 }}>
<Typography
variant="overline"
sx={{ display: 'block', color: DT.textMuted, lineHeight: 1.6, letterSpacing: '0.06em' }}
>
{label}
</Typography>
<Typography
variant="body1"
sx={{ fontWeight: 600, color: DT.textPrimary, wordBreak: 'break-word' }}
title={value || ''}
>
{value || '—'}
</Typography>
</Box>
</Stack>
);
// A titled grouping card.
const SectionCard = ({ title, icon: Icon, children }) => (
<Paper
elevation={0}
sx={{
borderRadius: DT.radiusCard + 'px',
border: `1px solid ${DT.borderSubtle}`,
boxShadow: DT.shadowSoft,
overflow: 'hidden',
height: '100%'
}}
>
<Stack
direction="row"
alignItems="center"
spacing={1.25}
sx={{ px: 2.5, py: 1.75, borderBottom: `1px solid ${DT.divider}`, bgcolor: DT.surfaceAlt }}
>
<Avatar sx={{ width: 28, height: 28, bgcolor: soft(BRAND), color: BRAND }}>
<Icon size={16} />
</Avatar>
<Typography variant="subtitle1" sx={{ fontWeight: 700, color: DT.textPrimary }}>
{title}
</Typography>
</Stack>
<Box sx={{ p: 2.5 }}>{children}</Box>
</Paper>
);
const ViewProfile = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const { data: userData, isLoading } = useQuery({
queryKey: ['getuser'],
queryFn: getusers
});
const fullname = userData?.fullname || userData?.firstname || 'User Profile';
return (
<>
{isLoading && (
<>
<Loader />
<CircularLoader />
</>
)}
<Box sx={{ p: { xs: 1.5, md: 0 } }}>
{/* ---- Gradient brand header ---- */}
<Paper
elevation={0}
sx={{
borderRadius: DT.radiusCard + 'px',
border: `1px solid ${DT.borderSubtle}`,
background: `linear-gradient(135deg, ${tint(BRAND)} 0%, ${tint(BRAND_LIGHT)} 100%)`,
boxShadow: DT.shadowSoft,
p: { xs: 2.5, md: 3.5 },
mb: { xs: 2.5, md: 3 }
}}
>
<Stack
direction={{ xs: 'column', sm: 'row' }}
spacing={{ xs: 2, sm: 3 }}
alignItems={{ xs: 'flex-start', sm: 'center' }}
>
<Avatar
sx={{
width: { xs: 64, md: 76 },
height: { xs: 64, md: 76 },
bgcolor: BRAND,
color: '#fff',
fontSize: { xs: 24, md: 28 },
fontWeight: 700,
boxShadow: '0 10px 24px rgba(102, 37, 130, 0.35)'
}}
>
{initialsOf(fullname)}
</Avatar>
<Box sx={{ minWidth: 0 }}>
<Typography variant="h3" sx={{ color: DT.textPrimary, fontWeight: 700, mb: 0.5 }}>
{fullname}
</Typography>
<Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap alignItems="center">
{userData?.authname && (
<Chip
size="small"
icon={<MdVerifiedUser size={14} style={{ color: BRAND }} />}
label={userData.authname}
sx={{
bgcolor: soft(BRAND),
color: BRAND,
fontWeight: 700,
border: `1px solid ${BRAND}40`,
'& .MuiChip-icon': { ml: '6px' }
}}
/>
)}
{userData?.userid != null && userData?.userid !== '' && (
<Typography variant="body2" sx={{ color: DT.textSecondary, fontWeight: 600 }}>
ID&nbsp;#{userData.userid}
</Typography>
)}
{userData?.applocation && (
<Stack direction="row" spacing={0.5} alignItems="center" sx={{ color: DT.textSecondary }}>
<MdLocationOn size={15} />
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{userData.applocation}
</Typography>
</Stack>
)}
</Stack>
</Box>
</Stack>
</Paper>
{/* ---- Grouped detail cards ---- */}
<Grid container spacing={{ xs: 2.5, md: 3 }}>
<Grid item xs={12} md={6}>
<SectionCard title="Account" icon={MdBadge}>
<Stack spacing={2.5}>
<InfoField icon={MdPerson} label="User Name" value={userData?.fullname} />
<InfoField icon={MdBadge} label="User ID" value={userData?.userid} />
<InfoField icon={MdVerifiedUser} label="Auth Name" value={userData?.authname} />
<InfoField icon={MdLocationOn} label="App Location" value={userData?.applocation} />
</Stack>
</SectionCard>
</Grid>
<Grid item xs={12} md={6}>
<SectionCard title="Contact" icon={MdMail}>
<Stack spacing={2.5}>
<InfoField icon={MdPhone} label="Contact No" value={userData?.contactno} accent="#0ea5e9" />
<InfoField icon={MdMail} label="E-Mail" value={userData?.email} accent="#0ea5e9" />
<InfoField icon={MdPlace} label="Address" value={userData?.address} accent="#0ea5e9" />
</Stack>
</SectionCard>
</Grid>
<Grid item xs={12}>
<SectionCard title="Location" icon={MdMap}>
<Grid container spacing={isMobile ? 2.5 : 3}>
<Grid item xs={12} sm={6} md={3}>
<InfoField icon={MdMyLocation} label="Suburb" value={userData?.suburb} accent="#14b8a6" />
</Grid>
<Grid item xs={12} sm={6} md={3}>
<InfoField icon={MdLocationCity} label="City" value={userData?.city} accent="#14b8a6" />
</Grid>
<Grid item xs={12} sm={6} md={3}>
<InfoField icon={MdMap} label="State" value={userData?.state} accent="#14b8a6" />
</Grid>
<Grid item xs={12} sm={6} md={3}>
<InfoField icon={MdMarkunreadMailbox} label="Postcode" value={userData?.postcode} accent="#14b8a6" />
</Grid>
</Grid>
</SectionCard>
</Grid>
</Grid>
</Box>
</>
);
};
export default ViewProfile;