updates on the astryx desing
This commit is contained in:
@@ -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>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user