"use client"; import { useEffect, useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import GlassModal from "@/components/admin/GlassModal"; import StopEditForm from "@/components/admin/StopEditForm"; import StopProductAssignment from "@/components/admin/StopProductAssignment"; import MessageCustomersSection from "@/components/admin/MessageCustomersSection"; import { getStopDetails } from "@/actions/stops/get-stop-details"; import { useToast } from "@/components/admin/design-system"; import type { StopDetail, AssignedProduct } from "@/actions/stops/get-stop-details"; type Tab = "details" | "products" | "message"; type Props = { stopId: string; /** Optional: when the user clicks Duplicate from inside the modal. */ onDuplicate?: (stopId: string) => void; onClose: () => void; }; export default function StopDetailModal({ stopId, onDuplicate, onClose }: Props) { return ( {/* Keying by stopId causes a full remount + fresh data fetch whenever the target stop changes, eliminating the need to reset internal state in an effect. */} ); } function StopDetailContent({ stopId, onDuplicate, onClose: _onClose, }: { stopId: string; onDuplicate?: (stopId: string) => void; onClose: () => void; }) { const router = useRouter(); const { success: showSuccess } = useToast(); const [, startTransition] = useTransition(); const [loading, setLoading] = useState(true); const [loadError, setLoadError] = useState(null); const [stop, setStop] = useState(null); const [allProducts, setAllProducts] = useState<{ id: string; name: string; type: string; price: number }[]>([]); const [assignedProducts, setAssignedProducts] = useState([]); const [brands, setBrands] = useState<{ id: string; name: string; slug: string }[]>([]); const [callerUid, setCallerUid] = useState(""); const [tab, setTab] = useState("details"); useEffect(() => { let cancelled = false; getStopDetails(stopId) .then((res) => { if (cancelled) return; if (!res.success) { setLoadError(res.error); setLoading(false); return; } setStop(res.stop); setAllProducts(res.allProducts); setAssignedProducts(res.assignedProducts); setBrands(res.brands); setCallerUid(res.callerUid); setLoading(false); }) .catch((err) => { if (cancelled) return; setLoadError(err?.message ?? "Failed to load stop"); setLoading(false); }); return () => { cancelled = true; }; }, [stopId]); function refresh() { getStopDetails(stopId).then((res) => { if (!res.success) return; setStop(res.stop); setAllProducts(res.allProducts); setAssignedProducts(res.assignedProducts); setBrands(res.brands); setCallerUid(res.callerUid); }); } function handleEditSaved() { refresh(); showSuccess("Stop updated", "Changes have been saved"); startTransition(() => router.refresh()); } const subtitle = stop?.brands ? (Array.isArray(stop.brands) ? stop.brands[0]?.name : stop.brands.name) ?? undefined : undefined; return ( <> {subtitle} {loading ? ( ) : loadError ? ( {loadError} ) : stop ? ( {/* Tabs */} setTab("details")}> Details setTab("products")}> Products {assignedProducts.length > 0 && ( {assignedProducts.length} )} setTab("message")}> Message {tab === "details" && ( )} {tab === "products" && ( Assigned Products Manage which products are available at this stop. )} {tab === "message" && ( Message Customers Send updates to customers with pending pickups at this stop. )} ) : null} > ); } function TabButton({ active, onClick, children, }: { active: boolean; onClick: () => void; children: React.ReactNode; }) { return ( {children} ); } function DetailsPanel({ stop, brands, onDuplicate, onSaved, }: { stop: StopDetail; brands: { id: string; name: string; slug: string }[]; onDuplicate?: (stopId: string) => void; onSaved: () => void; }) { return ( {stop.city}, {stop.state} {stop.location} {stop.active ? "Active" : "Inactive"} Date {stop.date} Time {stop.time} {stop.address && ( Address {stop.address} {stop.zip ? `, ${stop.zip}` : ""} )} {stop.cutoff_time && ( Cutoff {new Date(stop.cutoff_time).toLocaleString()} )} {onDuplicate ? ( onDuplicate(stop.id)} className="rounded-xl border border-[var(--admin-border)] bg-white px-3 py-1.5 text-xs font-medium text-[var(--admin-text-secondary)] hover:bg-[var(--admin-bg-subtle)]" > Duplicate Stop ) : ( Duplicate Stop )} Edit Stop Update stop details, location, and availability. ); }
Manage which products are available at this stop.
Send updates to customers with pending pickups at this stop.
{stop.location}
Update stop details, location, and availability.