updated the ui

This commit is contained in:
2026-06-11 18:09:10 +05:30
parent 251be9afd2
commit f50b4b010c
33 changed files with 1527 additions and 2302 deletions

View File

@@ -30,7 +30,6 @@ import {
useTheme
} from '@mui/material';
import {
MdPeopleAlt,
MdMyLocation,
MdPersonPin,
MdPhone,
@@ -38,7 +37,10 @@ import {
MdEdit,
MdGroups,
MdHowToReg,
MdPlace
MdPlace,
MdOutlineGroups,
MdOutlineHowToReg,
MdOutlinePlace
} from 'react-icons/md';
import Geocode from 'react-geocode';
import LocationOnIcon from '@mui/icons-material/LocationOn';
@@ -48,6 +50,8 @@ import { debounce } from '@mui/material/utils';
import Loader from 'components/Loader';
import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
import LocationAutocomplete from 'components/nearle_components/LocationAutocomplete';
import PageHeader from 'components/nearle_components/PageHeader';
import StatCard from 'components/nearle_components/StatCard';
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
import { getallcustomers, getcustomersummary } from 'pages/api/api';
import { OpenToast } from 'components/third-party/OpenToast';
@@ -61,10 +65,10 @@ import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'compon
// ============================================================================
const DT = {
radiusPill: 999,
radiusCard: 16,
shadowSoft: '0 14px 40px rgba(15, 23, 42, 0.10)',
shadowMd: '0 8px 24px rgba(15, 23, 42, 0.08)',
shadowPop: '0 18px 50px rgba(15, 23, 42, 0.18)',
radiusCard: 14,
shadowSoft: '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px rgba(15, 23, 42, 0.05)',
shadowMd: '0 1px 3px rgba(15, 23, 42, 0.06)',
shadowPop: '0 12px 32px rgba(15, 23, 42, 0.12)',
textPrimary: '#0f172a',
textSecondary: '#64748b',
textMuted: '#94a3b8',
@@ -392,9 +396,9 @@ export default function Customers() {
}
};
const KPI_META = [
{ key: 'total', label: 'Total Customers', color: '#662582', icon: MdGroups, value: pageCount?.Total ?? 0 },
{ key: 'loaded', label: 'Loaded in View', color: '#0ea5e9', icon: MdHowToReg, value: rows.length },
{ key: 'zone', label: 'Active Zone', color: '#10b981', icon: MdPlace, value: locaName || 'All Zones' }
{ key: 'total', label: 'Total Customers', color: '#662582', icon: MdOutlineGroups, value: pageCount?.Total ?? 0 },
{ key: 'loaded', label: 'Loaded in View', color: '#0ea5e9', icon: MdOutlineHowToReg, value: rows.length },
{ key: 'zone', label: 'Active Zone', color: '#10b981', icon: MdOutlinePlace, value: locaName || 'All Zones' }
];
return (
@@ -402,64 +406,11 @@ export default function Customers() {
{(customerSummaryIsLoading || customersIsLoading) && <Loader />}
{/* ============================================= || Header | ============================================= */}
<Paper
elevation={0}
sx={{
mb: { xs: 1.5, md: 2 },
p: { xs: 1.5, sm: 2, md: 2.5 },
borderRadius: DT.radiusCard / 8,
border: '1px solid',
borderColor: DT.borderSubtle,
background: `linear-gradient(135deg, ${tint('#662582')} 0%, ${tint('#9255AB')} 100%)`,
boxShadow: DT.shadowMd
}}
>
<Stack
direction={{ xs: 'column', sm: 'row' }}
alignItems={{ xs: 'flex-start', sm: 'center' }}
justifyContent="space-between"
spacing={{ xs: 1.5, sm: 2 }}
>
<Stack direction="row" alignItems="center" spacing={{ xs: 1.25, sm: 1.75 }}>
<Avatar
sx={{
width: { xs: 40, sm: 48 },
height: { xs: 40, sm: 48 },
bgcolor: '#662582',
color: '#fff',
boxShadow: '0 6px 18px rgba(99,102,241,0.32)'
}}
>
<MdPeopleAlt size={22} />
</Avatar>
<Stack>
<Typography
variant="h3"
sx={{
fontWeight: 800,
color: DT.textPrimary,
lineHeight: 1.1,
fontSize: { xs: '1.25rem', sm: '1.5rem', md: '1.75rem' }
}}
>
Customers
</Typography>
<Stack direction="row" alignItems="center" spacing={0.75} sx={{ mt: 0.5 }}>
<Box
sx={{
width: 8,
height: 8,
borderRadius: '50%',
bgcolor: '#10b981',
boxShadow: '0 0 0 4px rgba(16,185,129,0.18)'
}}
/>
<Typography variant="caption" sx={{ color: DT.textSecondary, fontWeight: 600 }}>
Live · {locaName || 'All Zones'}
</Typography>
</Stack>
</Stack>
</Stack>
<PageHeader
title="Customers"
subtitle={`Live · ${locaName || 'All Zones'}`}
live
action={
<LocationAutocomplete
locaName={locaName}
setAppId={setAppId}
@@ -471,88 +422,22 @@ export default function Customers() {
paperComponent={SoftPaper}
sx={{ width: { xs: '100%', sm: 280 }, zIndex: 100 }}
/>
</Stack>
</Paper>
}
/>
{/* ============================================= || KPI Cards | ============================================= */}
<Grid container spacing={{ xs: 1.25, sm: 1.5, md: 2 }} sx={{ mt: '1px' }}>
<Grid container spacing={{ xs: 2, md: 2.5 }} sx={{ mb: { xs: 1.5, md: 2 } }}>
{KPI_META.map((item) => {
const Icon = item.icon;
return (
<Grid item key={item.key} xs={6} sm={4}>
<Paper
elevation={0}
sx={{
position: 'relative',
overflow: 'hidden',
p: { xs: 1.25, sm: 1.75, md: 2.25 },
borderRadius: DT.radiusCard / 8,
border: '1px solid',
borderColor: DT.borderSubtle,
background: '#fff',
transition: 'transform 0.2s, box-shadow 0.2s, border-color 0.2s',
'&:hover': {
transform: 'translateY(-3px)',
boxShadow: DT.shadowMd,
borderColor: edge(item.color)
}
}}
>
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: 3,
background: `linear-gradient(90deg, ${item.color} 0%, ${soft(item.color)} 100%)`
}}
/>
<Stack direction="row" alignItems="flex-start" justifyContent="space-between" spacing={1}>
<Stack spacing={0.5} sx={{ minWidth: 0, flex: 1 }}>
<Typography
variant="caption"
sx={{
color: DT.textSecondary,
fontWeight: 700,
letterSpacing: 0.4,
textTransform: 'uppercase',
fontSize: { xs: 10, sm: 11 },
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}
>
{item.label}
</Typography>
<Typography
sx={{
fontWeight: 800,
color: DT.textPrimary,
lineHeight: 1.1,
fontSize: { xs: '1.25rem', sm: '1.5rem', md: '1.75rem' },
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}
>
{item.value}
</Typography>
</Stack>
<Avatar
sx={{
width: { xs: 36, sm: 42, md: 48 },
height: { xs: 36, sm: 42, md: 48 },
bgcolor: soft(item.color),
color: item.color,
boxShadow: `inset 0 0 0 1px ${edge(item.color)}`,
flexShrink: 0
}}
>
<Icon size={20} />
</Avatar>
</Stack>
</Paper>
<StatCard
title={item.label}
value={item.value ?? 0}
icon={<Icon size={20} />}
color={item.color}
loading={customerSummaryIsLoading}
/>
</Grid>
);
})}