updates on the astryx desing

This commit is contained in:
2026-08-14 16:09:14 +05:30
parent d3dd687a8d
commit a46212f291
106 changed files with 10244 additions and 24738 deletions

View File

@@ -1,5 +1,5 @@
import React, { useMemo, useState } from 'react';
import { MdOutlineWarehouse, MdEdit, MdDeleteOutline, MdAdd, MdPlace } from 'react-icons/md';
import { MdOutlineWarehouse, MdEdit, MdDeleteOutline, MdAdd, MdPlace, MdOutlineCheckCircle } from 'react-icons/md';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { enqueueSnackbar } from 'notistack';
@@ -11,6 +11,8 @@ import { Text } from '@astryxdesign/core/Text';
import { Button } from '@astryxdesign/core/Button';
import { IconButton } from '@astryxdesign/core/IconButton';
import { Dialog, DialogHeader } from '@astryxdesign/core/Dialog';
import { Layout, LayoutContent, LayoutFooter } from '@astryxdesign/core/Layout';
import { Divider } from '@astryxdesign/core/Divider';
import { TextInput } from '@astryxdesign/core/TextInput';
import { NumberInput } from '@astryxdesign/core/NumberInput';
import { Selector } from '@astryxdesign/core/Selector';
@@ -25,7 +27,7 @@ import StatCard from 'components/nearle_components/StatCard';
import StatusBadge from 'components/nearle_components/StatusBadge';
import { getHubs, createHub, updateHub, deleteHub } from 'pages/api/doormileApi';
import { DT, STATUS } from 'themes/dt/tokens';
import { TableScroll } from 'themes/dt/primitives';
import { TableScroll, AccentAvatar } from 'themes/dt/primitives';
const BRAND = DT.brand;
@@ -76,7 +78,8 @@ const Hubs = () => {
const total = hubs.length;
const sorting = hubs.filter((h) => h.hubtype === 'sorting_center').length;
const delivery = hubs.filter((h) => h.hubtype === 'delivery_hub').length;
return { total, sorting, delivery };
const active = hubs.filter((h) => String(h.status || '').toLowerCase() === 'active').length;
return { total, sorting, delivery, active };
}, [hubs]);
const opentoast = (message, variant = 'error') =>
@@ -155,7 +158,7 @@ const Hubs = () => {
return (
<>
{(isLoading || saveMutation.isPending || deleteMutation.isPending) && <Loader />}
{(isLoading || deleteMutation.isPending) && <Loader />}
<PageHeader
title="Hubs"
@@ -164,10 +167,11 @@ const Hubs = () => {
action={<Button label="New Hub" variant="primary" icon={<MdAdd size={16} />} onClick={openCreate} />}
/>
<Grid columns={{ minWidth: 220 }} gap={3}>
<Grid columns={{ minWidth: 200, max: 4, repeat: 'fit' }} gap={3}>
<StatCard title="Total Hubs" value={stats.total} icon={<MdOutlineWarehouse size={20} />} color={BRAND} />
<StatCard title="Sorting Centers" value={stats.sorting} icon={<MdOutlineWarehouse size={20} />} color={STATUS.info} />
<StatCard title="Delivery Hubs" value={stats.delivery} icon={<MdPlace size={20} />} color={STATUS.delivered} />
<StatCard title="Active Hubs" value={stats.active} icon={<MdOutlineCheckCircle size={20} />} color={STATUS.active} />
</Grid>
<VStack gap={0} padding={0} style={{ marginTop: 16 }}>
@@ -255,49 +259,82 @@ const Hubs = () => {
</Card>
</VStack>
<Dialog isOpen={dialogOpen} onOpenChange={(next) => !next && setDialogOpen(false)} width={640} purpose="form">
<DialogHeader title={form.hubid ? 'Edit Hub' : 'New Hub'} />
<VStack gap={4} padding={4}>
<Grid columns={{ minWidth: 240 }} gap={3}>
<TextInput label="Hub Name" value={form.hubname} onChange={set('hubname')} isRequired />
<Selector label="Type" options={HUB_TYPE_OPTIONS} value={form.hubtype} onChange={set('hubtype')} />
<NumberInput
label="City (applocationid)"
value={form.applocationid === '' ? undefined : Number(form.applocationid)}
onChange={(v) => set('applocationid')(v ?? '')}
description="Read the correct id from GET /admin/hubs rather than guessing"
isRequired
<Dialog isOpen={dialogOpen} onOpenChange={(next) => !next && setDialogOpen(false)} width={680} purpose="form">
<Layout
header={
<DialogHeader
title={form.hubid ? 'Edit Hub' : 'New Hub'}
subtitle={form.hubid ? `Updating "${form.hubname || 'hub'}"` : 'Add a sorting center or delivery hub'}
onOpenChange={(next) => !next && setDialogOpen(false)}
startContent={
<AccentAvatar color={BRAND} selected size={36}>
<MdOutlineWarehouse size={18} />
</AccentAvatar>
}
/>
<TextInput label="Contact No" value={form.contactno} onChange={set('contactno')} isOptional />
</Grid>
}
content={
<LayoutContent padding={4}>
<VStack gap={4} padding={0}>
<VStack gap={3} padding={0}>
<Text type="label" weight="semibold" color="secondary">
Hub Details
</Text>
<TextInput label="Hub Name" value={form.hubname} onChange={set('hubname')} isRequired />
<Grid columns={{ minWidth: 180 }} gap={3}>
<Selector label="Type" options={HUB_TYPE_OPTIONS} value={form.hubtype} onChange={set('hubtype')} />
<Selector label="Status" options={STATUS_OPTIONS} value={form.status} onChange={set('status')} />
<TextInput label="Contact No" value={form.contactno} onChange={set('contactno')} isOptional />
</Grid>
</VStack>
<TextInput label="Address" value={form.address} onChange={set('address')} isOptional />
<Divider />
<Grid columns={{ minWidth: 220 }} gap={3}>
<TextInput label="Pincode" value={form.pincode} onChange={set('pincode')} isOptional />
<NumberInput
label="Latitude"
value={form.latitude === '' ? undefined : Number(form.latitude)}
onChange={(v) => set('latitude')(v ?? '')}
isOptional
/>
<NumberInput
label="Longitude"
value={form.longitude === '' ? undefined : Number(form.longitude)}
onChange={(v) => set('longitude')(v ?? '')}
isOptional
/>
</Grid>
<Grid columns={{ minWidth: 240 }} gap={3}>
<Selector label="Status" options={STATUS_OPTIONS} value={form.status} onChange={set('status')} />
</Grid>
<HStack gap={2} justify="end">
<Button label="Cancel" variant="secondary" onClick={() => setDialogOpen(false)} />
<Button label={form.hubid ? 'Save Changes' : 'Create'} variant="primary" onClick={handleSave} />
</HStack>
</VStack>
<VStack gap={3} padding={0}>
<Text type="label" weight="semibold" color="secondary">
Location
</Text>
<TextInput label="Address" value={form.address} onChange={set('address')} isOptional />
<NumberInput
label="Location ID (applocationid)"
value={form.applocationid === '' ? undefined : Number(form.applocationid)}
onChange={(v) => set('applocationid')(v ?? '')}
description="Read the correct id from GET /admin/hubs rather than guessing"
isRequired
/>
<Grid columns={{ minWidth: 160 }} gap={3}>
<TextInput label="Pincode" value={form.pincode} onChange={set('pincode')} isOptional />
<NumberInput
label="Latitude"
value={form.latitude === '' ? undefined : Number(form.latitude)}
onChange={(v) => set('latitude')(v ?? '')}
isOptional
/>
<NumberInput
label="Longitude"
value={form.longitude === '' ? undefined : Number(form.longitude)}
onChange={(v) => set('longitude')(v ?? '')}
isOptional
/>
</Grid>
</VStack>
</VStack>
</LayoutContent>
}
footer={
<LayoutFooter hasDivider>
<HStack gap={2} justify="end">
<Button label="Cancel" variant="secondary" onClick={() => setDialogOpen(false)} isDisabled={saveMutation.isPending} />
<Button
label={form.hubid ? 'Save Changes' : 'Create Hub'}
variant="primary"
onClick={handleSave}
isLoading={saveMutation.isPending}
/>
</HStack>
</LayoutFooter>
}
/>
</Dialog>
</>
);