updates on the ui changes and changed into doormile

This commit is contained in:
2026-08-24 18:10:47 +05:30
parent dcf9770ada
commit aa42d9ee81
409 changed files with 49950 additions and 66532 deletions

View File

@@ -0,0 +1,191 @@
import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { ArrowLeft, Bike } from 'lucide-react';
import {
Alert, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage,
BreadcrumbSeparator, Button, Field, Input, LoadingState, PageHeader, Select,
SelectContent, SelectItem, SelectTrigger, SelectValue, Stack, Surface,
} from '@/components/ds';
import { useAppLocations, useMiler, useTenants, useUpdateMiler } from '@/lib/doormileHooks';
/**
* Edit a rider.
*
* Reached from the Riders table, which passes the row along in navigation
* state; the record is then re-fetched by `milerprofileid`, because every
* `/admin/milers/:id` route keys on that and 404s on the `userid` the same row
* also carries.
*
* Only identity, contact, client and zone are writable. `PUT /admin/milers/:id`
* documents no fields for bank details, vehicle settings or shift times, so
* those are not offered here rather than shown as inputs that quietly discard
* what is typed into them. A miler has a single `displayname` — there is no
* first/last split anywhere on this resource.
*/
const NO_TENANT = 'none';
export default function EditRider() {
const navigate = useNavigate();
const location = useLocation();
const passed = location.state?.rider;
const milerProfileId = passed?.milerprofileid;
const { data: rider, isLoading } = useMiler(milerProfileId);
const { data: tenants = [] } = useTenants();
const { data: locations = [] } = useAppLocations();
const updateMiler = useUpdateMiler();
const [form, setForm] = useState(null);
/* Seeded from the row that was clicked so the fields are populated on the
first paint, then reconciled with the fetched record when it lands. */
useEffect(() => {
const source = rider || passed;
if (!source) return;
setForm({
displayname: source.displayname || source.authname || '',
phone: source.phone || source.contactno || '',
email: source.email || '',
tenantid: source.tenantid ?? '',
applocationid: source.applocationid ?? '',
});
}, [rider, passed]);
const set = (key) => (value) => setForm((current) => ({ ...current, [key]: value }));
if (!milerProfileId) {
return (
<Stack space="lg">
<PageHeader icon={Bike} title="Edit rider" />
<Alert
tone="warning"
title="No rider selected"
action={<Button onClick={() => navigate('/doormile/riders')}>Go to Riders</Button>}
>
Open a rider from the Riders table — this page needs the record that was clicked.
</Alert>
</Stack>
);
}
const submit = (event) => {
event.preventDefault();
updateMiler.mutate(
{
id: milerProfileId,
data: {
displayname: form.displayname,
contactno: form.phone,
email: form.email,
tenantid: form.tenantid === '' ? undefined : Number(form.tenantid),
applocationid: form.applocationid === '' ? undefined : Number(form.applocationid),
},
},
{ onSuccess: (res) => res?.success !== false && navigate('/doormile/riders') }
);
};
return (
<Stack space="lg">
<PageHeader
icon={Bike}
title={form?.displayname || 'Edit rider'}
subtitle="Identity, contact, client and zone"
breadcrumb={
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/doormile/riders">Riders</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Edit</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
}
actions={
<Button variant="outline" onClick={() => navigate('/doormile/riders')}>
<ArrowLeft className="mr-1.5 h-4 w-4" /> Back
</Button>
}
/>
{isLoading && !form ? (
<LoadingState message="Loading rider…" />
) : (
<form onSubmit={submit}>
<Surface radius="xl" padding="lg">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
<Field label="Display name">
<Input value={form?.displayname || ''} onChange={(e) => set('displayname')(e.target.value)} />
</Field>
<Field label="Mobile number">
<Input
value={form?.phone || ''}
onChange={(e) => set('phone')(e.target.value.replace(/\D/g, '').slice(0, 10))}
inputMode="numeric"
/>
</Field>
<Field label="Email">
<Input type="email" value={form?.email || ''} onChange={(e) => set('email')(e.target.value)} />
</Field>
<Field label="Client">
<Select
value={form?.tenantid === '' ? NO_TENANT : String(form?.tenantid ?? '')}
onValueChange={(value) => set('tenantid')(value === NO_TENANT ? '' : value)}
>
<SelectTrigger>
<SelectValue placeholder="No client" />
</SelectTrigger>
<SelectContent>
<SelectItem value={NO_TENANT}>No client</SelectItem>
{(tenants || []).map((tenant) => (
<SelectItem key={tenant.tenantid} value={String(tenant.tenantid)}>
{tenant.tenantname || `Tenant #${tenant.tenantid}`}
</SelectItem>
))}
</SelectContent>
</Select>
</Field>
<Field label="City">
<Select
value={String(form?.applocationid ?? '')}
onValueChange={set('applocationid')}
>
<SelectTrigger>
<SelectValue placeholder="Choose a city" />
</SelectTrigger>
<SelectContent>
{(locations || [])
.filter((entry) => entry.applocationid)
.map((entry) => (
<SelectItem key={entry.applocationid} value={String(entry.applocationid)}>
{entry.locationname || `Location #${entry.applocationid}`}
</SelectItem>
))}
</SelectContent>
</Select>
</Field>
</div>
<div className="mt-6 flex justify-end gap-2 border-t border-border pt-5">
<Button type="button" variant="ghost" onClick={() => navigate('/doormile/riders')}>
Cancel
</Button>
<Button type="submit" loading={updateMiler.isPending}>
Save changes
</Button>
</div>
</Surface>
</form>
)}
</Stack>
);
}