-
Edit Stop
-
- Update stop details, location, and availability.
-
-
-
- {/* Message Customers */}
-
-
Message Customers
-
- Send updates to customers with pending pickups at this stop.
-
+
+
+ Assigned Products
+
+
+ Manage which products are available at this stop.
+
-
+
+
+
Edit Stop
+
+ Update stop details, location, and availability.
+
+
+
+
+
+
+
+ {/* Message Customers */}
+
+
Message Customers
+
+ Send updates to customers with pending pickups at this stop.
+
+
+
+
+
);
-}
\ No newline at end of file
+}
diff --git a/src/app/admin/stops/new/page.tsx b/src/app/admin/stops/new/page.tsx
index 97d9294..428ae13 100644
--- a/src/app/admin/stops/new/page.tsx
+++ b/src/app/admin/stops/new/page.tsx
@@ -3,9 +3,17 @@ import NewStopForm from "@/components/admin/NewStopForm";
import StopProductAssignment from "@/components/admin/StopProductAssignment";
import { getAdminUser } from "@/lib/admin-permissions";
import AdminAccessDenied from "@/components/admin/AdminAccessDenied";
+import { PageHeader } from "@/components/admin/design-system";
import { redirect } from "next/navigation";
import Link from "next/link";
+const StopIcon = () => (
+
+
+
+
+);
+
type Stop = {
city: string;
state: string;
@@ -62,32 +70,39 @@ export default async function NewStopPage({
[brandId]
);
+ const pageTitle = duplicateFrom ? "Duplicate Stop" : "Create Stop";
+ const pageSubtitle = duplicateFrom
+ ? `Pre-filled from ${duplicateFrom.city}, ${duplicateFrom.state}. Edit and save to create.`
+ : "Add a new tour stop for Tuxedo Corn or Indian River Direct.";
+
return (
-
-
-
+
+
+
+
+
- ← Back to Stops
+
+
+
+ Back to Stops
-
-
-
- {duplicateFrom ? "Duplicate Stop" : "Create Stop"}
-
-
-
- {duplicateFrom
- ? `Pre-filled from ${duplicateFrom.city}, ${duplicateFrom.state}. Edit and save to create.`
- : "Add a new tour stop for Tuxedo Corn or Indian River Direct."}
-
-
-
+
+
+
);
-}
\ No newline at end of file
+}
diff --git a/src/app/admin/stops/page.tsx b/src/app/admin/stops/page.tsx
index 23bd03f..bd259ac 100644
--- a/src/app/admin/stops/page.tsx
+++ b/src/app/admin/stops/page.tsx
@@ -3,6 +3,7 @@ import { getAdminUser } from "@/lib/admin-permissions";
import { getActiveBrandId } from "@/lib/brand-scope";
import AdminAccessDenied from "@/components/admin/AdminAccessDenied";
import StopTableClient from "@/components/admin/StopTableClient";
+import { PageHeader } from "@/components/admin/design-system";
import { redirect } from "next/navigation";
const StopIcon = () => (
@@ -75,20 +76,23 @@ export default async function AdminStopsPage({ searchParams }: PageProps) {
-
- Admin
- /
- Stops & Routes
-
-
Error loading stops
-
- {error}
-
-
-
Debug info:
-
adminUser.brand_id: {adminUser.brand_id ?? "null"}
-
adminUser.role: {adminUser.role}
-
adminUser.email: {adminUser.email}
+
Operations
+
}
+ />
+
+
Error loading stops
+
+ {error}
+
+
+
Debug info:
+
adminUser.brand_id: {adminUser.brand_id ?? "null"}
+
adminUser.role: {adminUser.role}
+
adminUser.email: {adminUser.email}
+
@@ -115,7 +119,15 @@ export default async function AdminStopsPage({ searchParams }: PageProps) {
return (
-
diff --git a/src/components/admin/AddStopModal.tsx b/src/components/admin/AddStopModal.tsx
index 194d2b4..8dca66d 100644
--- a/src/components/admin/AddStopModal.tsx
+++ b/src/components/admin/AddStopModal.tsx
@@ -145,7 +145,7 @@ export default function AddStopModal({ isOpen, onClose, brandId, duplicateFrom,
diff --git a/src/components/admin/EditStopModal.tsx b/src/components/admin/EditStopModal.tsx
index f3fd614..3ddbeaa 100644
--- a/src/components/admin/EditStopModal.tsx
+++ b/src/components/admin/EditStopModal.tsx
@@ -185,8 +185,8 @@ export default function EditStopModal({ isOpen, onClose, brandId, stop, onSucces
{error && (
diff --git a/src/components/admin/StopDetailModal.tsx b/src/components/admin/StopDetailModal.tsx
index a44a8fa..91f629d 100644
--- a/src/components/admin/StopDetailModal.tsx
+++ b/src/components/admin/StopDetailModal.tsx
@@ -93,19 +93,25 @@ export default function StopDetailModal({ stopId, onDuplicate, onClose }: Props)
>
{loading ? (
) : loadError ? (
-
+
{loadError}
) : stop ? (
{/* Tabs */}
setTab("details")}>
@@ -223,8 +229,8 @@ function DetailsPanel({
{stop.active ? "Active" : "Inactive"}
@@ -265,14 +271,14 @@ function DetailsPanel({
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-stone-50"
+ 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
diff --git a/src/components/admin/StopMessagingForm.tsx b/src/components/admin/StopMessagingForm.tsx
index dd916c2..ea6d589 100644
--- a/src/components/admin/StopMessagingForm.tsx
+++ b/src/components/admin/StopMessagingForm.tsx
@@ -3,6 +3,7 @@
import { useState } from "react";
import { getStopPendingCustomers, type StopCustomer } from "@/actions/stops/get-stop-customers";
import { sendStopBlast } from "@/actions/communications/stop-blast";
+import { AdminButton } from "@/components/admin/design-system";
const quickMessages = [
{ label: "Truck running late", value: "Heads up — the truck is running about 15 minutes behind schedule. Thanks for your patience!" },
@@ -84,10 +85,10 @@ export default function StopMessagingForm({
return (
-
+
Send Message
-
+
Notify all customers with pending pickups at this stop.
@@ -96,18 +97,21 @@ export default function StopMessagingForm({
{loading ? "Loading customers..." : "Load Pending Customers"}
) : (
<>
{customers.length === 0 ? (
-
+
No pending orders for this stop yet.
) : (
-
+
{customers.length} pending order{customers.length !== 1 ? "s" : ""} found
{recipients.length !== customers.length && (
— {recipients.length} with contact info
@@ -117,21 +121,21 @@ export default function StopMessagingForm({
{/* Channel */}
-
- Send via
+
+ Send via
-
+
{(["sms", "email", "both"] as const).map((ch) => (
setChannel(ch)}
className={`flex-1 rounded-xl px-4 py-3 text-sm font-medium transition-colors ${
channel === ch
- ? "bg-slate-900 text-white"
- : "bg-zinc-950 text-zinc-400 hover:bg-slate-200"
+ ? "bg-[var(--admin-primary)] text-white"
+ : "bg-[var(--admin-bg-subtle)] text-[var(--admin-text-secondary)] hover:bg-[var(--admin-primary-soft)] hover:text-[var(--admin-primary)]"
}`}
>
- {ch === "sms" ? "📱 SMS" : ch === "email" ? "✉️ Email" : "📱+✉️ Both"}
+ {ch === "sms" ? "SMS" : ch === "email" ? "Email" : "Both"}
))}
@@ -139,8 +143,8 @@ export default function StopMessagingForm({
{/* Quick messages */}
-
- Quick messages
+
+ Quick messages
{quickMessages.map((qm) => (
@@ -149,8 +153,8 @@ export default function StopMessagingForm({
onClick={() => applyQuickMessage(qm.value)}
className={`rounded-full px-3 py-1 text-sm font-medium transition-colors ${
message === qm.value
- ? "bg-slate-900 text-white"
- : "bg-zinc-950 text-zinc-400 hover:bg-slate-200"
+ ? "bg-[var(--admin-primary)] text-white"
+ : "bg-[var(--admin-bg-subtle)] text-[var(--admin-text-secondary)] hover:bg-[var(--admin-primary-soft)] hover:text-[var(--admin-primary)]"
}`}
>
{qm.label}
@@ -161,8 +165,8 @@ export default function StopMessagingForm({
{/* Message preview */}
-
- Message
+
+ Message
-
+
{message.length} characters
{error && (
-
+
{error}
)}
{sent > 0 && (
-
+
Message sent to {sent} customer{sent !== 1 ? "s" : ""}!
)}
{/* Recipients */}
{recipients.length > 0 && message && (
-
-
+
+
Recipients ({recipients.length}):
{recipients.map((c) => (
- {c.customer_name}
-
+ {c.customer_name}
+
{c.customer_phone ?? c.customer_email ?? "no contact"}
@@ -210,15 +221,18 @@ export default function StopMessagingForm({
)}
-
{sending
? "Sending..."
: `Send to ${recipients.length} customer${recipients.length !== 1 ? "s" : ""}`}
-
+
>
)}
diff --git a/src/components/admin/StopProductAssignment.tsx b/src/components/admin/StopProductAssignment.tsx
index 0524167..1e50a85 100644
--- a/src/components/admin/StopProductAssignment.tsx
+++ b/src/components/admin/StopProductAssignment.tsx
@@ -203,8 +203,8 @@ export default function StopProductAssignment({
role="alert"
className="flex items-start gap-2 rounded-lg px-3 py-2 text-xs text-[var(--admin-danger)]"
style={{
- background: "rgba(220, 38, 38, 0.06)",
- border: "1px solid rgba(220, 38, 38, 0.15)",
+ background: "var(--admin-danger-soft)",
+ border: "1px solid color-mix(in srgb, var(--admin-danger) 25%, transparent)",
}}
>
diff --git a/src/components/admin/StopsCalendarClient.tsx b/src/components/admin/StopsCalendarClient.tsx
index d7afbfc..4f0d5e0 100644
--- a/src/components/admin/StopsCalendarClient.tsx
+++ b/src/components/admin/StopsCalendarClient.tsx
@@ -403,7 +403,7 @@ export default function StopsCalendarClient({ stops }: Props) {
Active
-
+
Draft
@@ -513,7 +513,7 @@ function EventPopover({
className="inline-block w-1.5 h-1.5 rounded-full"
style={{
background:
- status === "active" ? "var(--admin-accent)" : status === "draft" ? "#f59e0b" : "var(--admin-text-muted)",
+ status === "active" ? "var(--admin-accent)" : status === "draft" ? "var(--admin-warning)" : "var(--admin-text-muted)",
}}
/>
{statusLabel(status)} · {brandName(stop)}
@@ -682,19 +682,19 @@ function DayRouteDrawer({
status === "active"
? "var(--admin-accent-light)"
: status === "draft"
- ? "rgba(245, 158, 11, 0.1)"
+ ? "var(--admin-warning-soft)"
: "var(--admin-bg-subtle)",
color:
status === "active"
? "var(--admin-accent-text)"
: status === "draft"
- ? "#92400e"
+ ? "var(--admin-warning)"
: "var(--admin-text-secondary)",
borderColor:
status === "active"
? "var(--admin-accent)"
: status === "draft"
- ? "rgba(245, 158, 11, 0.3)"
+ ? "var(--admin-warning)"
: "var(--admin-border-light)",
}}
>
diff --git a/src/components/admin/StopsLocationsTabs.tsx b/src/components/admin/StopsLocationsTabs.tsx
index 80974b1..c7c40f9 100644
--- a/src/components/admin/StopsLocationsTabs.tsx
+++ b/src/components/admin/StopsLocationsTabs.tsx
@@ -68,13 +68,13 @@ export default function StopsLocationsTabs({
group relative flex items-center gap-2.5 rounded-xl px-3.5 py-2
text-sm font-semibold transition-all duration-200
${isActive
- ? "bg-white text-emerald-700 border border-emerald-200 shadow-sm"
- : "text-stone-600 border border-transparent hover:text-emerald-700 hover:bg-emerald-50/40"
+ ? "bg-white text-[var(--admin-primary)] border border-[var(--admin-primary)]/30 shadow-sm"
+ : "text-[var(--admin-text-secondary)] border border-transparent hover:text-[var(--admin-primary)] hover:bg-[var(--admin-primary-soft)]/40"
}
`}
>
{t.icon}
@@ -85,8 +85,8 @@ export default function StopsLocationsTabs({
inline-flex h-5 min-w-[1.25rem] items-center justify-center rounded-full px-1.5
text-[11px] font-bold tabular-nums
${isActive
- ? "bg-emerald-600 text-white"
- : "bg-stone-200/70 text-stone-600 group-hover:bg-emerald-100 group-hover:text-emerald-700"
+ ? "bg-[var(--admin-primary)] text-white"
+ : "bg-[var(--admin-bg-subtle)] text-[var(--admin-text-secondary)] group-hover:bg-[var(--admin-primary-soft)] group-hover:text-[var(--admin-primary)]"
}
`}
>
@@ -94,7 +94,7 @@ export default function StopsLocationsTabs({
{t.sublabel && (
· {t.sublabel}