// Interactive flow screens — drawer, dispatch list, call detail, map, login. // Each screen is a self-contained component that takes navigation callbacks. const { useState: useStateS, useEffect: useEffectS } = React; // ─────── Sample data ───────────────────────────────────────── const SAMPLE_CALLS = [ { id: 1, number: '3206', status: 'towing', statusSentence: 'L. Brown is towing', type: 'Tow', vehicleYear: "17'", vehicleMakeModel: 'Chevrolet Corvette', vehicleColor: 'Red', account: 'McDonald Investments', receivedTime: '4:28 PM', timeAgo: '25m ago', eta: '5:45 PM', pickup: '157 Carney Drive, Saint Clair, MI 48079', dropoff: '1655 Yeager St, Port Huron, MI 48060', }, { id: 2, number: '3205', status: 'onscene', statusSentence: 'W. Smith is on scene', type: 'Tow', vehicleYear: "18'", vehicleMakeModel: 'GMC Yukon', vehicleColor: 'Black', account: "Newfie's Chevrolet", receivedTime: '4:27 PM', timeAgo: '26m ago', eta: '6:35 PM', pickup: '1296 Pickwick Pl, Flint, MI 48507', dropoff: '345 Cox Rd, St Clair, MI 48079', }, { id: 3, number: '3204', status: 'enroute', statusSentence: 'E. Brown is en route', type: 'Tow', vehicleYear: "16'", vehicleMakeModel: 'Jaguar XF', vehicleColor: 'Black', account: 'Cash / Private Retail Customer', receivedTime: '4:25 PM', timeAgo: '28m ago', eta: '6:25 PM', pickup: '5402 Lapeer Rd, Burton, MI 48509', dropoff: '880 W Maple Rd, Troy, MI 48084', }, ]; const SAMPLE_WAITING = [ { id: 10, number: '3210', status: 'waiting', statusSentence: 'Unassigned', type: 'Roadside · Lockout', vehicleYear: "21'", vehicleMakeModel: 'Honda Civic', vehicleColor: 'Silver', account: 'AAA', receivedTime: '4:48 PM', timeAgo: '6m ago', pickup: '4400 Court St, Saginaw, MI 48602', dropoff: '—', }, { id: 11, number: '3209', status: 'waiting', statusSentence: 'Unassigned', type: 'Tow · Accident', vehicleYear: "19'", vehicleMakeModel: 'Ford F-150', vehicleColor: 'White', account: 'State Farm', receivedTime: '4:42 PM', timeAgo: '12m ago', pickup: 'I-94 W at Exit 198, Detroit, MI', dropoff: 'Bobby\'s Auto Body, Detroit, MI', }, ]; window.SAMPLE_CALLS = SAMPLE_CALLS; window.SAMPLE_WAITING = SAMPLE_WAITING; // ─────── Driver profile (used in drawer header) ────────────── function DrawerHeader({ name = 'Ellie Brown', role = 'Driver', onClose }) { return (
{name.split(' ').map(s => s[0]).join('')}
{name}
{role}
); } function DrawerLink({ icon, label, badge, active, onClick }) { const [pressed, setPressed] = useStateS(false); return ( ); } function NavDrawerScreen({ active = 'dispatching', onNavigate, onClose, checkedIn, onCheckedInChange }) { return (
Checked in
{checkedIn ? 'Available for calls' : 'Off duty'}
onNavigate?.('dispatching')}/> onNavigate?.('impounds')}/> onNavigate?.('stickering')}/> onNavigate?.('accounts')}/> onNavigate?.('chats')}/> onNavigate?.('inspection')}/>
onNavigate?.('settings')}/> onNavigate?.('logout')}/>
); } // ─────── Dispatch list screen ──────────────────────────────── function DispatchListScreen({ onOpenCall, onOpenDrawer, refreshing, onRefresh, tab, onTabChange }) { const [t, setT] = useStateS(tab || 'active'); const activeTab = tab !== undefined ? tab : t; const setTab = onTabChange || setT; const calls = activeTab === 'active' ? SAMPLE_CALLS : activeTab === 'waiting' ? SAMPLE_WAITING : activeTab === 'completed' ? [{...SAMPLE_CALLS[0], status: 'completed', statusSentence: 'Cleared 2:14 PM'}, {...SAMPLE_CALLS[1], status: 'completed', statusSentence: 'Cleared 11:48 AM'}] : []; return (
{calls.length === 0 ? ( ) : ( calls.map(c => ( onOpenCall?.(c)} onEdit={() => onOpenCall?.(c)} onUpdateStatus={() => onOpenCall?.(c, 'updateStatus')} onCallContact={() => {}} /> )) )}
{}}/>
); } function EmptyState() { return (
No calls yet
Create the first one to get started.
New call
); } // ─────── Call detail screen (#3176) ────────────────────────── function CallDetailScreen({ onBack, onUpdateStatus }) { const [sheetOpen, setSheetOpen] = useStateS(false); const [status, setStatus] = useStateS('onscene'); const accent = (TBT.status[status] || {}).solid || 'var(--green-9)'; return (
{/* status accent strip — follows the current status */}
{/* Vehicle header */}

06' Acura TL (Black)

Fuel Delivery
Joes Apt. Complex · 04:06 PM
{/* Address */}
1234 6th St, Marysville, MI 48040, USA
(1234 6th Street) · 7.4 mi
} action={Go} />
{/* Contacts */}
Contacts
John Smith
810-320-5063
} action={} />
{/* Vehicle / details */}
Vehicle Scan}/>
{/* Times */}
Times
{/* Photos */}
Photos Add
{/* Bottom action bar */}
setSheetOpen(true) }, { icon: I.Camera, label: 'Add Photo' }, { icon: I.Map, label: 'Show Map' }, { icon: I.Layers, label: 'More' }, ]}/>
{/* Status update sheet */} setSheetOpen(false)} title="Update status"> {['waiting','enroute','onscene','towing','completed','canceled'].map(s => { const isCurrent = s === status; return ( ); })}
); } function TimeRow({ color, label, value }) { return (
{label} {value}
); } // ─────── Map screen ────────────────────────────────────────── function MapScreen({ onOpenCall }) { const [filter, setFilter] = useStateS('calls'); const [selected, setSelected] = useStateS(null); const dark = typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'dark'; return (
{/* Stylized map (SVG) */} {/* water */} {/* roads */} {/* Filter chips top */}
setFilter('drivers')} icon={I.User}>Drivers setFilter('calls')} icon={I.MapPin}>Calls
{/* Pins */} setSelected('3204')}/> setSelected('3205')}/> setSelected('3206')}/> setSelected('3207')}/> {/* Floating action stack (right) */}
{/* Bottom info card if a pin is selected */} {selected && (
{selected}
17' Chevrolet Corvette (Red)
157 Carney Drive, Saint Clair
Directions onOpenCall?.()}>Open
)}
); } function SegBtn({ active, onClick, icon, children }) { return ( ); } function RoundIconBtn({ icon, onClick }) { return ( ); } function Pin({ top, left, number, status, onClick }) { const dark = typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'dark'; const palette = (dark ? TBT.statusDark : TBT.status)[status]; return ( ); } // ─────── Login screen ──────────────────────────────────────── function LoginScreen() { const [pwd, setPwd] = useStateS(''); const [show, setShow] = useStateS(false); return (
T

Sign in

Use your Towbook driver credentials.

Sign in
Towbook · v8.2.0
); } // ─────── Equipment inspection screen ───────────────────────── function InspectionScreen() { const [data, setData] = useStateS({}); const set = (k, v) => setData(prev => ({...prev, [k]: v})); const items = [ 'Engine oil level', 'Transmission fluid level', 'Brake fluid level', 'Windshield washer fluid', 'Hoses & belts', 'Battery cable connections', 'Tire condition (front)', 'Tire condition (rear)', 'Lights & turn signals', 'Mirrors & glass', 'Wheel lift function', 'Boom & winch operation', ]; return (
Pre-shift inspection
Unit #3 · {Object.keys(data).filter(k => data[k]).length}/{items.length} complete
data[k]).length / items.length}/>
Truck
{items.map((label, i) => ( set(i, v)} photoCount={data[i] === 'fail' ? 1 : 0}/> ))}
Submit inspection
); } Object.assign(window, { NavDrawerScreen, DispatchListScreen, CallDetailScreen, MapScreen, LoginScreen, InspectionScreen, });