implemenation on the bot

This commit is contained in:
2026-08-19 17:08:45 +05:30
parent bdb21766f2
commit 37ca2352e2
52 changed files with 7074 additions and 3568 deletions

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { enqueueSnackbar } from 'notistack';
import { MdPersonAddAlt1 } from 'react-icons/md';
@@ -11,7 +11,6 @@ import { Card } from '@astryxdesign/core/Card';
import { Text } from '@astryxdesign/core/Text';
import { Button } from '@astryxdesign/core/Button';
import { TextInput } from '@astryxdesign/core/TextInput';
import { Selector } from '@astryxdesign/core/Selector';
import { Divider } from '@astryxdesign/core/Divider';
import Loader from 'components/Loader';
@@ -19,34 +18,32 @@ import PageHeader from 'components/nearle_components/PageHeader';
import { PageShell } from 'components/nearle_components/PageLayout';
import AddressAutocomplete from 'components/nearle_components/AddressAutocomplete';
import LocationAutocomplete from 'components/nearle_components/LocationAutocomplete';
import { createTenantCustomer, getAdminTenants } from 'pages/api/doormileApi';
import { createAdminCustomer } from 'pages/api/doormileApi';
import { DT } from 'themes/dt/tokens';
import { AccentAvatar } from 'themes/dt/primitives';
const BRAND = DT.brand;
// Same field set as nearle_console_express's createCustomer.js (Location,
// Choose Client, Name, Phone, Email, Door No, Address, Location/City/State/
// Postcode, Landmark) — but POST /admin/tenantcustomers only persists
// { firstname, lastname, phone, email }. There is no address/coordinate
// storage anywhere on the new API for a customer record (confirmed against
// express-console-api.md — the old jupiter /customers/create body doesn't
// exist here at all). The address section below is collected and shown so
// the form matches the reference 1:1, but it is NOT sent on submit — see the
// note under that section. `tenantid` isn't in the documented POST body
// either; it's included speculatively for staff logins (every other create
// endpoint on this API takes tenantid explicitly) and may be silently
// ignored server-side — unconfirmed, this endpoint isn't in the "confirmed
// end-to-end" list.
// Writes to POST /admin/customers — the same resource the Customers page
// (customers.js) reads via getAdminCustomers(), so a customer created here
// shows up there immediately. This used to call createTenantCustomer
// (POST /admin/tenantcustomers), a different store with its own id
// sequence — a customer created that way never appeared on the Customers
// list. See src/pages/nearle/assistant/CLAUDE.md ("Customer creation writes
// to /admin/customers") for the full history; the Doormile AI assistant's
// executeCreateCustomer was fixed first, this page now matches it.
//
// This resource carries no tenantid (confirmed against a real
// GET /admin/customers response), so there's no tenant picker here — unlike
// Tenants/Riders/etc, a customer isn't scoped to a client at creation time.
// A real GET /admin/customers response does carry address, doorno, landmark,
// suburb, city, state, postcode, latitude and longitude, so the address
// section below is sent (empty fields dropped) rather than discarded.
const Createcustomer = () => {
const navigate = useNavigate();
const loggedInTenantId = localStorage.getItem('tenantid');
const isStaffLogin = !loggedInTenantId || loggedInTenantId === '0';
const [appId, setAppId] = useState(0);
const [locaName, setLocoName] = useState('Select Location');
const [tid, setTid] = useState(isStaffLogin ? '' : loggedInTenantId);
const [firstname, setFirstname] = useState('');
const [lastname, setLastname] = useState('');
@@ -60,13 +57,6 @@ const Createcustomer = () => {
const [appLocaLat, setAppLocaLat] = useState();
const [appLocaLng, setAppLocaLng] = useState();
const { data: tenantList = [] } = useQuery({
queryKey: ['admin-tenants-picker'],
queryFn: getAdminTenants,
enabled: isStaffLogin
});
const tenantOptions = (tenantList || []).map((t) => ({ value: String(t.tenantid), label: t.tenantname || `Tenant #${t.tenantid}` }));
// LocationAutocomplete only reports back applocationid/locationname — it
// caches the full hub list (with lat/lng) in localStorage under a
// tenant-scoped key (applocations_<tenantid>, see LocationAutocomplete.js)
@@ -123,8 +113,13 @@ const Createcustomer = () => {
const opentoast = (message) =>
enqueueSnackbar(message, { variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 2000 });
// Empty fields are dropped rather than sent as noise — mirrors
// buildCustomerPayload in assistant/actions.js, the other caller of this
// same endpoint.
const clean = (obj) => Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined && v !== null && v !== ''));
const createCustomerMutation = useMutation({
mutationFn: (payload) => createTenantCustomer(payload),
mutationFn: (payload) => createAdminCustomer(payload),
onSuccess: (res) => {
if (res.success) {
enqueueSnackbar('Customer created successfully', {
@@ -141,20 +136,28 @@ const Createcustomer = () => {
});
const createprofile = () => {
if (isStaffLogin && !tid) {
opentoast('Select Tenant');
} else if (!firstname) {
if (!firstname) {
opentoast('Enter Name');
} else if (!phone || phone.length !== 10) {
opentoast('Enter a valid 10-digit Mobile Number');
} else {
createCustomerMutation.mutate({
firstname,
lastname,
phone,
email,
...(isStaffLogin && tid ? { tenantid: +tid } : {})
});
createCustomerMutation.mutate(
clean({
firstname,
lastname,
phone,
email,
address: pickCust.address,
doorno,
landmark,
suburb: pickCust.suburb,
city: pickCust.city,
state: pickCust.state,
postcode: pickCust.postcode,
latitude: startPoint.latitude || undefined,
longitude: startPoint.longitude || undefined
})
);
}
};
@@ -182,16 +185,6 @@ const Createcustomer = () => {
</Text>
<LocationAutocomplete locaName={locaName} setAppId={setAppId} setLocoName={setLocoName} />
</VStack>
{isStaffLogin && (
<Selector
label="Choose Client"
options={tenantOptions}
value={tid ? String(tid) : ''}
onChange={(v) => setTid(v || '')}
placeholder="Choose Client"
hasSearch
/>
)}
<TextInput label="Name" placeholder="First Name" value={firstname} onChange={setFirstname} isRequired />
<TextInput label="Last Name" placeholder="Last Name" value={lastname} onChange={setLastname} isOptional />
<TextInput
@@ -210,11 +203,6 @@ const Createcustomer = () => {
<Divider />
<Text type="supporting" color="secondary" style={{ fontStyle: 'italic' }}>
The backend doesn&apos;t store an address against a customer yet — these fields aren&apos;t required and won&apos;t be saved
on submit.
</Text>
<AddressAutocomplete
id="customer-address"
label="Address"