updates on the ui changes and table

This commit is contained in:
2026-08-17 15:39:46 +05:30
parent a46212f291
commit 809d046323
38 changed files with 6403 additions and 7019 deletions

View File

@@ -56,6 +56,7 @@ import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
import PageHeader from 'components/nearle_components/PageHeader';
import StatCard from 'components/nearle_components/StatCard';
import TableLoader from 'components/nearle_components/TableLoader';
import { PageShell, KpiGrid, DataCard } from 'components/nearle_components/PageLayout';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { getalltenants } from 'pages/api/api';
import {
@@ -209,7 +210,14 @@ const TenantLocationsDialog = ({ tenant, open, onClose }) => {
{[loc.address, loc.city, loc.state, loc.pincode].filter(Boolean).join(', ')}
</Text>
</VStack>
<IconButton label="Edit location" tooltip="Edit location" size="sm" variant="ghost" icon={<MdEdit size={14} />} onClick={() => openEdit(loc)} />
<IconButton
label="Edit location"
tooltip="Edit location"
size="sm"
variant="ghost"
icon={<MdEdit size={14} />}
onClick={() => openEdit(loc)}
/>
</HStack>
</Card>
))}
@@ -217,7 +225,11 @@ const TenantLocationsDialog = ({ tenant, open, onClose }) => {
)}
{formOpen && (
<Grid columns={{ minWidth: 200 }} gap={2} style={{ marginTop: 16, paddingTop: 16, borderTop: `1px solid ${DT.divider}` }}>
<Grid
columns={{ minWidth: 200, repeat: 'fit' }}
gap={2}
style={{ marginTop: 'var(--spacing-6)', paddingTop: 16, borderTop: `1px solid ${DT.divider}` }}
>
<TextInput label="Location Name" value={form.locationname} onChange={(v) => setForm((f) => ({ ...f, locationname: v }))} />
<TextInput label="Pincode" value={form.pincode} onChange={(v) => setForm((f) => ({ ...f, pincode: v }))} />
<TextInput label="Address" value={form.address} onChange={(v) => setForm((f) => ({ ...f, address: v }))} />
@@ -393,7 +405,14 @@ const TenantCustomersDialog = ({ tenant, open, onClose }) => {
</Text>
</VStack>
<HStack gap={1}>
<IconButton label="Edit customer" tooltip="Edit customer" size="sm" variant="ghost" icon={<MdEdit size={14} />} onClick={() => openEdit(c)} />
<IconButton
label="Edit customer"
tooltip="Edit customer"
size="sm"
variant="ghost"
icon={<MdEdit size={14} />}
onClick={() => openEdit(c)}
/>
<IconButton
label="Delete customer"
tooltip="Delete customer"
@@ -410,7 +429,11 @@ const TenantCustomersDialog = ({ tenant, open, onClose }) => {
)}
{formOpen && (
<Grid columns={{ minWidth: 200 }} gap={2} style={{ marginTop: 16, paddingTop: 16, borderTop: `1px solid ${DT.divider}` }}>
<Grid
columns={{ minWidth: 200, repeat: 'fit' }}
gap={2}
style={{ marginTop: 'var(--spacing-6)', paddingTop: 16, borderTop: `1px solid ${DT.divider}` }}
>
<TextInput label="First Name" value={form.firstname} onChange={(v) => setForm((f) => ({ ...f, firstname: v }))} />
<TextInput label="Last Name" value={form.lastname} onChange={(v) => setForm((f) => ({ ...f, lastname: v }))} />
<TextInput label="Phone" value={form.phone} onChange={(v) => setForm((f) => ({ ...f, phone: v }))} />
@@ -670,9 +693,7 @@ const Clients1 = () => {
if (String(t.status || '').toLowerCase() !== activeStatus) return false;
if (!q) return true;
return (
t.tenantname?.toLowerCase().includes(q) ||
t.primaryemail?.toLowerCase().includes(q) ||
t.primarycontact?.includes(debouncedSearch)
t.tenantname?.toLowerCase().includes(q) || t.primaryemail?.toLowerCase().includes(q) || t.primarycontact?.includes(debouncedSearch)
);
});
}, [tenantList, value0, debouncedSearch]);
@@ -913,12 +934,16 @@ const Clients1 = () => {
>
{value1 == '0' && (
<VStack gap={0} padding={4}>
<Grid columns={{ minWidth: 220 }} gap={3}>
<Grid columns={{ minWidth: 220, repeat: 'fit' }} gap={3}>
<InfoRow icon={FiUser} value={row.tenantname} caption="Tenant" />
<InfoRow icon={FaRegCheckCircle} value={row.status || '—'} caption="Status" />
<InfoRow icon={FiPhoneCall} value={row.primarycontact} caption="Phone" />
<InfoRow icon={LuMail} value={row.primaryemail} caption="E-Mail" />
<InfoRow icon={row.requiredeliveryotp ? MdCheckCircle : MdCancel} value={row.requiredeliveryotp ? 'Yes' : 'No'} caption="Delivery OTP Required" />
<InfoRow
icon={row.requiredeliveryotp ? MdCheckCircle : MdCancel}
value={row.requiredeliveryotp ? 'Yes' : 'No'}
caption="Delivery OTP Required"
/>
</Grid>
</VStack>
)}
@@ -947,20 +972,14 @@ const Clients1 = () => {
{value0 !== 1 && <Tab value="1" label="Edit Pricing" icon={<GiMoneyStack size={16} />} />}
</TabList>
{value2 == '1' && (
<Button
label="Add Pricing"
variant="destructive"
size="sm"
icon={<MdEdit size={14} />}
onClick={() => setDialogopen(true)}
/>
<Button label="Add Pricing" variant="destructive" size="sm" icon={<MdEdit size={14} />} onClick={() => setDialogopen(true)} />
)}
</HStack>
}
>
{value2 == '0' && (
<VStack gap={3} padding={4}>
<Grid columns={{ minWidth: 240 }} gap={3}>
<Grid columns={{ minWidth: 240, repeat: 'fit' }} gap={3}>
<TextInput
label="Tenant Name"
value={editClient.tenantname ?? selectedCustomer.tenantname ?? ''}
@@ -995,7 +1014,7 @@ const Clients1 = () => {
onPlaceSelected={handleAddressPlaceSelected}
/>
<Grid columns={{ minWidth: 200 }} gap={3}>
<Grid columns={{ minWidth: 200, repeat: 'fit' }} gap={3}>
<TextInput
label="City"
value={city == '' ? selectedCustomer.city || '' : city}
@@ -1012,7 +1031,7 @@ const Clients1 = () => {
/>
</Grid>
<Grid columns={{ minWidth: 200 }} gap={3}>
<Grid columns={{ minWidth: 200, repeat: 'fit' }} gap={3}>
<TextInput label="Latitude" value={latlong.lat ?? ''} isDisabled startIcon={TbWorldLatitude} />
<TextInput label="Longitude" value={latlong.lng ?? ''} isDisabled startIcon={TbWorldLongitude} />
</Grid>
@@ -1034,70 +1053,92 @@ const Clients1 = () => {
<>
{(getalltenantsIsLoading || isloader) && <Loader />}
<PageHeader
title="Tenants"
subtitle={`Live · ${locaName || 'All Zones'}`}
live
action={<LocationAutocomplete locaName={locaName} setAppId={setAppId} setLocoName={setLocoName} setPage={setPage} placeholder="Select Zone" />}
/>
<PageShell>
<PageHeader
title="Tenants"
subtitle={`Live · ${locaName || 'All Zones'}`}
live
action={
<LocationAutocomplete
locaName={locaName}
setAppId={setAppId}
setLocoName={setLocoName}
setPage={setPage}
placeholder="Select Zone"
/>
}
/>
<Grid columns={{ minWidth: 200, max: 4, repeat: 'fit' }} gap={3}>
{KPI_META.map((item) => {
const Icon = item.icon;
const value = tenantStatusCounts[item.countKey] ?? 0;
// 'total' has no matching entry in STATUS_TABS (there's no "All"
// tab) — only the three status tiles switch tabs when clicked.
const tabIdx = STATUS_TABS.findIndex((t) => t.countKey === item.countKey);
const clickable = tabIdx !== -1;
return (
<div
key={item.key}
role={clickable ? 'button' : undefined}
tabIndex={clickable ? 0 : undefined}
onClick={clickable ? () => handleChange(tabIdx) : undefined}
onKeyDown={
clickable
? (e) => {
if (e.key === 'Enter' || e.key === ' ') handleChange(tabIdx);
}
: undefined
}
style={{ cursor: clickable ? 'pointer' : 'default', height: '100%' }}
>
<StatCard title={item.label} value={value ?? 0} icon={<Icon size={20} />} color={item.color} loading={getalltenantsIsLoading} />
</div>
);
})}
</Grid>
<KpiGrid>
{KPI_META.map((item) => {
const Icon = item.icon;
const value = tenantStatusCounts[item.countKey] ?? 0;
// 'total' has no matching entry in STATUS_TABS (there's no "All"
// tab) — only the three status tiles switch tabs when clicked.
const tabIdx = STATUS_TABS.findIndex((t) => t.countKey === item.countKey);
const clickable = tabIdx !== -1;
return (
<div
key={item.key}
role={clickable ? 'button' : undefined}
tabIndex={clickable ? 0 : undefined}
onClick={clickable ? () => handleChange(tabIdx) : undefined}
onKeyDown={
clickable
? (e) => {
if (e.key === 'Enter' || e.key === ' ') handleChange(tabIdx);
}
: undefined
}
style={{ cursor: clickable ? 'pointer' : 'default', height: '100%' }}
>
<StatCard
title={item.label}
value={value ?? 0}
icon={<Icon size={20} />}
color={item.color}
loading={getalltenantsIsLoading}
/>
</div>
);
})}
</KpiGrid>
<VStack gap={0} padding={0} style={{ marginTop: 16 }}>
<Card padding={3} elevation="none" style={{ borderBottomLeftRadius: 0, borderBottomRightRadius: 0, borderBottom: 'none' }}>
<HStack justify="between" vAlign="center" gap={2} wrap="wrap-reverse">
<TabList
value={String(value0)}
onChange={(v) => {
const idx = Number(v);
setstatus(STATUS_TABS[idx].status);
handleChange(idx);
}}
size="sm"
hasDivider={false}
>
{STATUS_TABS.map((t, idx) => {
const meta = STATUS_META[t.status];
const Icon = meta.icon;
const count = tenantStatusCounts[t.countKey] ?? 0;
return <Tab key={t.status} value={String(idx)} label={meta.label} icon={<Icon size={15} />} endContent={<Badge variant="neutral" label={count} />} />;
})}
</TabList>
<DataCard
tabs={
<HStack justify="between" vAlign="center" gap={2} wrap="wrap">
<TabList
value={String(value0)}
onChange={(v) => {
const idx = Number(v);
setstatus(STATUS_TABS[idx].status);
handleChange(idx);
}}
size="sm"
hasDivider={false}
>
{STATUS_TABS.map((t, idx) => {
const meta = STATUS_META[t.status];
const Icon = meta.icon;
const count = tenantStatusCounts[t.countKey] ?? 0;
return (
<Tab
key={t.status}
value={String(idx)}
label={meta.label}
icon={<Icon size={15} />}
endContent={<Badge variant="neutral" label={count} />}
/>
);
})}
</TabList>
<div style={{ width: 280, maxWidth: '100%' }}>
<DebounceSearchBar value={searchword} onChange={setSearchword} onDebouncedChange={setDebouncedSearch} />
</div>
</HStack>
</Card>
<Card padding={0} elevation="none" style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0, overflow: 'hidden' }}>
<VStack width={280} padding={0} gap={0}>
<DebounceSearchBar value={searchword} onChange={setSearchword} onDebouncedChange={setDebouncedSearch} />
</VStack>
</HStack>
}
>
{!isMobile && (
<TableScroll minWidth={960}>
<Table density="balanced" dividers="rows" hasHover>
@@ -1272,15 +1313,20 @@ const Clients1 = () => {
</HStack>
</>
)}
</Card>
</VStack>
</DataCard>
</PageShell>
<Dialog isOpen={dialogopen} onOpenChange={(next) => !next && dialogclose()} width={640} purpose="form">
<Layout
header={<DialogHeader title={`Client Pricing - (${selectedCustomer.tenantname || ''})`} onOpenChange={(next) => !next && dialogclose()} />}
header={
<DialogHeader
title={`Client Pricing - (${selectedCustomer.tenantname || ''})`}
onOpenChange={(next) => !next && dialogclose()}
/>
}
content={
<LayoutContent padding={4}>
<Grid columns={{ minWidth: 220 }} gap={3}>
<Grid columns={{ minWidth: 220, repeat: 'fit' }} gap={3}>
<Selector
label="Select Slab"
options={VEHICLE_TYPE_OPTIONS}