Admin AI Tools page: unified design system styling, provider selector with OpenAI turd emoji, free-text model input with exact ID warning

This commit is contained in:
2026-06-02 02:21:11 +00:00
parent 809e0061ca
commit 15e939ad7e
116 changed files with 14991 additions and 5326 deletions
+12 -288
View File
@@ -2,136 +2,10 @@ import Link from "next/link";
import { getAdminUser } from "@/lib/admin-permissions";
import { isFeatureEnabled } from "@/lib/feature-flags";
import { getBrandPlanInfo } from "@/actions/billing/stripe-portal";
import DashboardHeader from "@/components/admin/DashboardHeader";
import DashboardClient from "@/components/admin/DashboardClient";
const TUXEDO_BRAND_ID = "64294306-5f42-463d-a5e8-2ad6c81a96de";
type Section = {
title: string;
href: string;
description: string;
group: "operations" | "fulfillment" | "management" | "tools";
addonKey?: string;
upgradeText?: string;
prominent?: boolean;
};
const sections: Section[] = [
{
title: "Orders",
href: "/admin/orders",
description: "View orders, pickup status, fulfillment, and customer details.",
group: "operations",
prominent: true,
},
{
title: "Products",
href: "/admin/products",
description: "Manage products, pricing, shipping type, and availability.",
group: "operations",
prominent: true,
},
{
title: "Tours & Stops",
href: "/admin/stops",
description: "Manage routes, pickup locations, dates, and cutoff times.",
group: "fulfillment",
},
{
title: "Driver Pickup",
href: "/admin/pickup",
description: "Mobile pickup lookup, QR scanning, and completion tools.",
group: "fulfillment",
},
{
title: "Shipping",
href: "/admin/shipping",
description: "FedEx integration, label creation, and shipment tracking.",
group: "fulfillment",
},
{
title: "Reports",
href: "/admin/reports",
description: "Sales, route, product, pickup, and customer reports.",
group: "management",
},
{
title: "Tax Dashboard",
href: "/admin/taxes",
description: "Sales tax collected, breakdown by state, and exportable reports.",
group: "management",
},
{
title: "Settings",
href: "/admin/settings",
description: "Users, billing, brand, integrations, payments, and shipping.",
group: "management",
},
{
title: "Harvest Reach",
href: "/admin/communications",
description: "Email campaigns, stop blast, templates, and audience segments.",
group: "tools",
addonKey: "harvest_reach",
upgradeText: "Enable to access email & SMS marketing",
},
{
title: "Wholesale Portal",
href: "/admin/wholesale",
description: "Standalone B2B portal with custom pricing, credit limits, and net-30.",
group: "tools",
addonKey: "wholesale_portal",
upgradeText: "Enable to unlock B2B buyer portal",
},
{
title: "Import Center",
href: "/admin/import",
description: "AI-powered import for products, orders, contacts, and stops.",
group: "tools",
addonKey: "ai_tools",
upgradeText: "Enable AI import with smart column mapping",
},
{
title: "AI Intelligence",
href: "/admin/settings/ai",
description: "Campaign writer, pricing advisor, and report explainer.",
group: "tools",
addonKey: "ai_tools",
upgradeText: "Enable AI tools for marketing and pricing",
},
{
title: "Time Tracking",
href: "/admin/time-tracking",
description: "Worker clock-in/out, hours tracking, and overtime management.",
group: "tools",
addonKey: "time_tracking",
upgradeText: "Enable for field worker time tracking",
},
{
title: "Water Log",
href: "/admin/water-log",
description: "Irrigation tracking and water usage reporting.",
group: "tools",
addonKey: "water_log",
upgradeText: "Enable for agricultural water tracking",
},
{
title: "Route Trace",
href: "/admin/route-trace",
description: "Lot tracking, QR stickers, hauling board, and supply chain traceability.",
group: "tools",
addonKey: "route_trace",
upgradeText: "Enable for field-to-delivery traceability",
},
];
const groupMeta = {
operations: { label: "Core Operations", cols: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4" },
fulfillment: { label: "Fulfillment & Logistics", cols: "grid-cols-1 md:grid-cols-3" },
management: { label: "Business Management", cols: "grid-cols-1 md:grid-cols-3" },
tools: { label: "Tools & Add-ons", cols: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4" },
} as const;
export default async function AdminPage() {
const adminUser = await getAdminUser();
const isStoreEmployee = adminUser?.role === "store_employee";
@@ -142,11 +16,12 @@ export default async function AdminPage() {
adminUser?.brand_id === TUXEDO_BRAND_ID &&
adminUser?.can_manage_water_log);
const enabledAddons: Record<string, boolean> = {};
let enabledAddons: Record<string, boolean> = {};
let planTier = "starter";
let usage = { users: 0, stops_this_month: 0, products: 0 };
let limits = { max_users: 1, max_stops_monthly: 10, max_products: 25 };
let brandDisplayName = "Admin";
if (adminUser?.brand_id) {
for (const key of ["harvest_reach", "wholesale_portal", "water_log", "ai_tools", "sms_campaigns", "square_sync", "route_trace"] as const) {
enabledAddons[key] = await isFeatureEnabled(adminUser.brand_id, key);
@@ -211,166 +86,15 @@ export default async function AdminPage() {
);
}
const allGroups = [
{
key: "operations" as const,
label: groupMeta.operations.label,
cols: groupMeta.operations.cols,
sections: sections.filter((s) => s.group === "operations"),
},
{
key: "fulfillment" as const,
label: groupMeta.fulfillment.label,
cols: groupMeta.fulfillment.cols,
sections: sections.filter((s) => s.group === "fulfillment"),
},
{
key: "management" as const,
label: groupMeta.management.label,
cols: groupMeta.management.cols,
sections: sections.filter((s) => s.group === "management"),
},
{
key: "tools" as const,
label: groupMeta.tools.label,
cols: groupMeta.tools.cols,
sections: sections.filter((s) => s.group === "tools"),
},
];
const usagePct = {
users: limits.max_users > 0 ? (usage.users / limits.max_users) * 100 : 0,
stops: limits.max_stops_monthly > 0 ? (usage.stops_this_month / limits.max_stops_monthly) * 100 : 0,
products: limits.max_products > 0 ? (usage.products / limits.max_products) * 100 : 0,
};
return (
<main className="min-h-screen px-6 py-10">
<div className="mx-auto max-w-7xl space-y-10">
{/* Header */}
<DashboardHeader
brandId={adminUser?.brand_id ?? null}
brandName={brandDisplayName}
planTier={planTier}
/>
{/* Usage bar */}
<div className="rounded-2xl border border-stone-200 bg-white p-6 shadow-sm">
<div className="flex items-center gap-5 mb-5">
<span className={`rounded-full px-4 py-1.5 text-xs font-semibold tracking-wide ${
planTier === "enterprise" ? "bg-amber-100 text-amber-700 border border-amber-200" :
planTier === "farm" ? "bg-emerald-100 text-emerald-700 border border-emerald-200" :
"bg-stone-100 text-stone-600 border border-stone-200"
}`}>
{planTier.charAt(0).toUpperCase() + planTier.slice(1)} Plan
</span>
<span className="text-sm text-stone-500">{adminUser?.brand_id ? "Tuxedo Corn" : "All Brands"}</span>
</div>
<div className="grid grid-cols-3 gap-8">
{[
{ label: "Users", value: `${usage.users}/${limits.max_users}`, pct: usagePct.users },
{ label: "Stops / month", value: `${usage.stops_this_month}/${limits.max_stops_monthly}`, pct: usagePct.stops },
{ label: "Products", value: `${usage.products}/${limits.max_products}`, pct: usagePct.products },
].map(({ label, value, pct }) => (
<div key={label}>
<div className="flex items-center justify-between mb-3">
<span className="text-sm font-medium text-stone-600">{label}</span>
<span className="text-sm font-semibold text-stone-900">{value}</span>
</div>
<div className="h-1.5 rounded-full bg-stone-200 overflow-hidden">
<div
className={`h-full rounded-full transition-all duration-500 ${
pct > 85 ? "bg-gradient-to-r from-amber-500 to-amber-400" : "bg-gradient-to-r from-emerald-500 to-emerald-400"
}`}
style={{ width: `${Math.min(pct, 100)}%` }}
/>
</div>
</div>
))}
</div>
</div>
{/* Grouped sections */}
{allGroups.map(({ key, label, cols, sections: groupSections }) => {
if (groupSections.length === 0) return null;
return (
<div key={key}>
<div className="flex items-center gap-4 mb-5">
<p className="text-[11px] font-bold uppercase tracking-widest text-stone-600 flex-shrink-0">{label}</p>
<div className="h-px flex-1 bg-gradient-to-r from-stone-300 to-transparent" />
</div>
<div className={`grid ${cols} gap-4`}>
{groupSections.map((section) => {
if (section.title === "Water Log" && !isWaterLogVisible) return null;
if (section.title === "Route Trace" && !enabledAddons["route_trace"]) return null;
const isAddon = Boolean(section.addonKey);
const isEnabled = section.addonKey ? (enabledAddons[section.addonKey] ?? false) : true;
const isProminent = section.prominent;
return (
<Link
key={section.title}
href={section.href}
className={[
"group relative flex flex-col rounded-2xl border bg-white p-5 transition-all hover:-translate-y-0.5",
isAddon && !isEnabled
? "border-stone-200 shadow-sm opacity-75 hover:opacity-100"
: isProminent
? "border-stone-200 shadow-md shadow-stone-200/50 hover:shadow-lg"
: "border-stone-200 shadow-sm hover:shadow-md",
].join(" ")}
>
<div className="flex items-center justify-between mb-4">
<div className={`flex h-9 w-9 items-center justify-center rounded-xl ${
isAddon && !isEnabled
? "bg-stone-100 text-stone-400"
: isProminent
? "bg-emerald-100 text-emerald-600"
: "bg-violet-100 text-violet-600"
}`}>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
</svg>
</div>
{isAddon && !isEnabled && (
<span className="text-[10px] font-semibold text-amber-800 bg-amber-100 border border-amber-200 rounded-full px-2.5 py-0.5">
Add-on
</span>
)}
{isAddon && isEnabled && (
<span className="text-[10px] font-semibold text-emerald-800 bg-emerald-100 border border-emerald-200 rounded-full px-2.5 py-0.5">
Active
</span>
)}
{isProminent && (
<span className="text-[10px] font-semibold text-emerald-800 bg-emerald-100 border border-emerald-200 rounded-full px-2.5 py-0.5">
Core
</span>
)}
</div>
<h3 className="text-sm font-semibold leading-tight text-stone-950">
{section.title}
</h3>
<p className={`mt-2 text-sm leading-relaxed ${
isAddon && !isEnabled ? "text-stone-500" : "text-stone-600"
}`}>
{section.description}
</p>
{isAddon && !isEnabled && section.upgradeText && (
<p className="mt-3 text-xs text-amber-700 font-medium">{section.upgradeText}</p>
)}
</Link>
);
})}
</div>
</div>
);
})}
</div>
</main>
<DashboardClient
brandId={adminUser?.brand_id ?? null}
brandName={brandDisplayName}
planTier={planTier}
isWaterLogVisible={isWaterLogVisible}
enabledAddons={enabledAddons}
usage={usage}
limits={limits}
/>
);
}