rider partner page
This commit is contained in:
@@ -16,6 +16,7 @@ import { productsApi } from '@/api/products';
|
||||
import { posUsersApi, staffApi } from '@/api/people';
|
||||
import { stockApi, type StockRequestQuery } from '@/api/stock';
|
||||
import { tenantsApi, utilsApi, type TenantListQuery } from '@/api/tenants';
|
||||
import { partnersApi } from '@/api/deliveries';
|
||||
import { customersApi, type CustomerQuery } from '@/api/customers';
|
||||
import { uploadsApi } from '@/api/uploads';
|
||||
import { APP_BROWSE_CATEGORY } from '@/features/catalogue/tenantCategories';
|
||||
@@ -138,6 +139,93 @@ export function useImportedRefs(tenantid: number | undefined) {
|
||||
|
||||
/* ── Products ────────────────────────────────────────────────────────────── */
|
||||
|
||||
/**
|
||||
* Every delivery partner across every region.
|
||||
*
|
||||
* `getpartners` takes one region at a time and refuses 0, so the whole list is
|
||||
* the regions fanned out and flattened. Three regions today — Coimbatore,
|
||||
* Madurai, Nagercoil — so this is three requests, not a page of them.
|
||||
*/
|
||||
export function useAllPartners() {
|
||||
const regions = useAppRegions();
|
||||
const ids = (regions.data ?? []).map((region) => region.applocationid);
|
||||
|
||||
const results = useQueries({
|
||||
queries: ids.map((applocationid) => ({
|
||||
queryKey: queryKeys.partners.inRegion(applocationid),
|
||||
queryFn: () => partnersApi.list(applocationid),
|
||||
...stable,
|
||||
})),
|
||||
});
|
||||
|
||||
return {
|
||||
data: results.flatMap((result) => result.data ?? []),
|
||||
isLoading: regions.isLoading || results.some((result) => result.isLoading),
|
||||
};
|
||||
}
|
||||
|
||||
/** The delivery regions. `0` asks for all of them — see `utilsApi.appLocations`. */
|
||||
export function useAppRegions() {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.regions.all,
|
||||
queryFn: () => utilsApi.appLocations(0),
|
||||
...stable,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* One delivery partner's riders.
|
||||
*
|
||||
* The roster, not `getriders`: the second wants a clock-in stamped today, so a
|
||||
* rider added five minutes ago is absent from it — which reads as a failed
|
||||
* save. The directory shows everybody and reports duty as a state.
|
||||
*/
|
||||
export function usePartnerRiders(partnerid: number | undefined) {
|
||||
return useQuery({
|
||||
queryKey: [...queryKeys.partners.all, 'riders', partnerid ?? 0] as const,
|
||||
queryFn: () => ridersApi.partnerRoster(partnerid as number),
|
||||
enabled: typeof partnerid === 'number' && partnerid > 0,
|
||||
...stable,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* How many riders each partner has, keyed by partnerid.
|
||||
*
|
||||
* Fanned out because `getriderroster` takes one partner at a time. Five
|
||||
* partners today, so five requests — and the count is what makes the Riders
|
||||
* button worth pressing, since "Riders" alone asks you to open a drawer to find
|
||||
* out whether there are any.
|
||||
*/
|
||||
export function usePartnerRiderCounts(partnerids: readonly number[]) {
|
||||
const ids = [...new Set(partnerids)].filter((id) => id > 0);
|
||||
|
||||
const results = useQueries({
|
||||
queries: ids.map((partnerid) => ({
|
||||
queryKey: [...queryKeys.partners.all, 'riders', partnerid] as const,
|
||||
queryFn: () => ridersApi.partnerRoster(partnerid),
|
||||
...stable,
|
||||
})),
|
||||
});
|
||||
|
||||
const counts = new Map<number, number>();
|
||||
results.forEach((result, index) => {
|
||||
const id = ids[index];
|
||||
if (id !== undefined && result.data) counts.set(id, result.data.length);
|
||||
});
|
||||
return counts;
|
||||
}
|
||||
|
||||
/** The regions one partner covers. */
|
||||
export function usePartnerLocations(partnerid: number | undefined) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.partners.locations(partnerid ?? 0),
|
||||
queryFn: () => partnersApi.locations(partnerid as number),
|
||||
enabled: typeof partnerid === 'number' && partnerid > 0,
|
||||
...stable,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The ten aisles the customer app groups products into.
|
||||
*
|
||||
@@ -356,11 +444,21 @@ export function useDeliveries(query: OrderQuery | undefined) {
|
||||
* Scoped by `applocationid`. Passing a tenant instead returns an empty list
|
||||
* with a 200 — see `deliveriesApi.riders`.
|
||||
*/
|
||||
export function useRiders(applocationid: number | undefined) {
|
||||
export function useRiders(scope: {
|
||||
/** The merchant's own riders. */
|
||||
tenantid?: number | undefined;
|
||||
/** A delivery partner's riders. */
|
||||
partnerid?: number | undefined;
|
||||
/** Only used when neither of the above is given. */
|
||||
applocationid?: number | undefined;
|
||||
}) {
|
||||
const { tenantid, partnerid, applocationid } = scope;
|
||||
return useQuery({
|
||||
queryKey: queryKeys.insights.riders(applocationid ?? 0),
|
||||
queryFn: () => deliveriesApi.riders({ applocationid: applocationid as number }),
|
||||
enabled: Boolean(applocationid),
|
||||
// The scope is part of the key, or one fleet's riders would be served to
|
||||
// the other after a toggle.
|
||||
queryKey: [...queryKeys.insights.all, 'riders', tenantid ?? 0, partnerid ?? 0, applocationid ?? 0] as const,
|
||||
queryFn: () => deliveriesApi.riders({ tenantid, partnerid, applocationid }),
|
||||
enabled: Boolean(tenantid || partnerid || applocationid),
|
||||
...live,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user