Files
doormile_app_web/src/store/OpsStore.jsx
2026-06-11 20:17:18 +05:30

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;
}