76 lines
2.8 KiB
JavaScript
76 lines
2.8 KiB
JavaScript
import { createContext, useContext, useState, useCallback, useMemo } from 'react';
|
|
|
|
// ==============================|| OPS STORE — SESSION PERSISTENCE ||============================== //
|
|
// A lightweight in-memory store so operational actions actually COMMIT during a session (no backend).
|
|
// Holds: dispatch assignments (order → rider), reroutes, and exceptions. Future workflows (status
|
|
// advance, payments) hang off the same provider. State resets on full reload — intentional for a demo.
|
|
|
|
const OpsContext = createContext(null);
|
|
|
|
export function OpsProvider({ children }) {
|
|
// assignments: { [orderId]: { riderId, riderName, vehicle, at } }
|
|
const [assignments, setAssignments] = useState({});
|
|
// reroutes: { [orderId]: at }
|
|
const [reroutes, setReroutes] = useState({});
|
|
// exceptions: { [orderId]: { reason, at } }
|
|
const [exceptions, setExceptions] = useState({});
|
|
|
|
const assignOrder = useCallback((orderId, rider) => {
|
|
setAssignments((prev) => ({
|
|
...prev,
|
|
[orderId]: { riderId: rider.id, riderName: rider.name, vehicle: rider.vehicle, at: Date.now() }
|
|
}));
|
|
}, []);
|
|
|
|
const unassignOrder = useCallback((orderId) => {
|
|
setAssignments((prev) => {
|
|
const next = { ...prev };
|
|
delete next[orderId];
|
|
return next;
|
|
});
|
|
}, []);
|
|
|
|
const rerouteOrder = useCallback((orderId) => {
|
|
setReroutes((prev) => ({ ...prev, [orderId]: Date.now() }));
|
|
}, []);
|
|
|
|
const raiseException = useCallback((orderId, reason) => {
|
|
setExceptions((prev) => ({ ...prev, [orderId]: { reason, at: Date.now() } }));
|
|
}, []);
|
|
|
|
const clearException = useCallback((orderId) => {
|
|
setExceptions((prev) => {
|
|
const next = { ...prev };
|
|
delete next[orderId];
|
|
return next;
|
|
});
|
|
}, []);
|
|
|
|
const assignmentOf = useCallback((orderId) => assignments[orderId] || null, [assignments]);
|
|
const exceptionOf = useCallback((orderId) => exceptions[orderId] || null, [exceptions]);
|
|
const isRerouted = useCallback((orderId) => Boolean(reroutes[orderId]), [reroutes]);
|
|
const riderLoad = useCallback(
|
|
(riderId) => Object.values(assignments).filter((a) => a.riderId === riderId).length,
|
|
[assignments]
|
|
);
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
assignments, reroutes, exceptions,
|
|
assignOrder, unassignOrder, rerouteOrder, raiseException, clearException,
|
|
assignmentOf, exceptionOf, isRerouted, riderLoad,
|
|
assignedCount: Object.keys(assignments).length,
|
|
exceptionCount: Object.keys(exceptions).length
|
|
}),
|
|
[assignments, reroutes, exceptions, assignOrder, unassignOrder, rerouteOrder, raiseException, clearException, assignmentOf, exceptionOf, isRerouted, riderLoad]
|
|
);
|
|
|
|
return <OpsContext.Provider value={value}>{children}</OpsContext.Provider>;
|
|
}
|
|
|
|
export function useOps() {
|
|
const ctx = useContext(OpsContext);
|
|
if (!ctx) throw new Error('useOps must be used within an OpsProvider');
|
|
return ctx;
|
|
}
|