From 3d810ee7e0184a9325f0ed222e66843b2e18481c Mon Sep 17 00:00:00 2001 From: default Date: Tue, 2 Jun 2026 04:53:05 +0000 Subject: [PATCH] fix: restore full settings pages with tabbed interface (General, Brand, Workers, Tasks, Users) --- src/app/admin/settings/page.tsx | 25 +- src/components/admin/SettingsClient.tsx | 463 +++++++++++++++++------- 2 files changed, 347 insertions(+), 141 deletions(-) diff --git a/src/app/admin/settings/page.tsx b/src/app/admin/settings/page.tsx index 2a6d79d..0910b8f 100644 --- a/src/app/admin/settings/page.tsx +++ b/src/app/admin/settings/page.tsx @@ -1,5 +1,7 @@ import { redirect } from "next/navigation"; import { getAdminUser } from "@/lib/admin-permissions"; +import { getAdminUsers, getBrands } from "@/actions/admin/users"; +import { getPaymentSettings } from "@/actions/payments"; import SettingsClient from "@/components/admin/SettingsClient"; export const metadata = { @@ -26,5 +28,26 @@ export default async function AdminSettingsPage({ brandId = "64294306-5f42-463d-a5e8-2ad6c81a96de"; } - return ; + const [{ users, error }, { brands }] = await Promise.all([ + getAdminUsers(isPlatformAdmin ? undefined : (adminUser.brand_id ?? undefined)), + getBrands(), + ]); + + // Fetch payment settings for the current brand + const paymentResult = await getPaymentSettings(brandId); + const paymentSettings = paymentResult.success ? paymentResult.settings : null; + + return ( + + ); } \ No newline at end of file diff --git a/src/components/admin/SettingsClient.tsx b/src/components/admin/SettingsClient.tsx index b34bd6a..1d7676c 100644 --- a/src/components/admin/SettingsClient.tsx +++ b/src/components/admin/SettingsClient.tsx @@ -1,154 +1,150 @@ "use client"; import { useState, useEffect } from "react"; -import { PageHeader, AdminFilterTabs } from "@/components/admin/design-system"; +import SettingsSections from "@/components/admin/SettingsSections"; +import UsersPage from "@/components/admin/UsersPage"; +import BrandSettingsForm from "@/components/admin/BrandSettingsForm"; +import PaymentSettingsForm from "@/components/admin/PaymentSettingsForm"; +import { PageHeader, AdminButton } from "@/components/admin/design-system"; +import type { PaymentProvider } from "@/actions/payments"; -type Tab = "general" | "addons" | "billing" | "integrations" | "ai" | "advanced"; +type Tab = "general" | "brand" | "workers" | "tasks" | "users"; -const TABS: { id: Tab; label: string }[] = [ - { id: "general", label: "General" }, - { id: "addons", label: "Add-ons" }, - { id: "billing", label: "Billing" }, - { id: "integrations", label: "Integrations" }, - { id: "ai", label: "AI" }, - { id: "advanced", label: "Advanced" }, +const TABS: { id: Tab; label: string; icon: string; hash: string }[] = [ + { id: "general", label: "General", icon: "settings", hash: "general" }, + { id: "brand", label: "Brand", icon: "brand", hash: "brand" }, + { id: "workers", label: "Workers", icon: "users", hash: "workers" }, + { id: "tasks", label: "Tasks", icon: "list", hash: "tasks" }, + { id: "users", label: "Users", icon: "user-check", hash: "users" }, ]; +// Icon components +const Icons = { + settings: (className: string) => ( + + + + + ), + brand: (className: string) => ( + + + + ), + users: (className: string) => ( + + + + ), + "user-check": (className: string) => ( + + + + + + + ), + plug: (className: string) => ( + + + + ), + list: (className: string) => ( + + + + ), +}; + +type Brand = { id: string; name: string }; + +// Brand Selector Component +function BrandSelector({ + brands, + selectedBrandId, + onSelect, +}: { + brands: Brand[]; + selectedBrandId: string; + onSelect: (id: string) => void; +}) { + return ( +
+

Select which brand's settings to manage:

+
+ {brands.map((brand) => ( + + ))} +
+
+ ); +} + type Props = { brandId: string; + users: import("@/actions/admin/users").AdminUserRow[]; + brands: Brand[]; + paymentSettings?: { + provider?: PaymentProvider | null; + stripe_publishable_key?: string | null; + stripe_secret_key?: string | null; + square_access_token?: string | null; + square_location_id?: string | null; + square_sync_enabled?: boolean; + square_inventory_mode?: "none" | "rc_to_square" | "square_to_rc" | "bidirectional"; + square_last_sync_at?: string | null; + square_last_sync_error?: string | null; + } | null; + currentUser: { + id: string; + role: string; + can_manage_users: boolean; + }; }; -export default function SettingsClient({ brandId }: Props) { +export default function SettingsClient({ + brandId, + users, + brands, + paymentSettings, + currentUser, +}: Props) { const [activeTab, setActiveTab] = useState("general"); - // Handle URL hash for navigation + // Handle URL hash for sidebar navigation useEffect(() => { const hash = window.location.hash.slice(1); - const matchingTab = TABS.find(t => t.id === hash); + const matchingTab = TABS.find(t => t.hash === hash); if (matchingTab) { setActiveTab(matchingTab.id); } }, []); - // Content for each tab - links to full pages - const renderContent = () => { - switch (activeTab) { - case "general": - return ( -
-
-
- - - -
-

Workers, Tasks & Users

-

Manage time tracking workers, tasks, and user permissions

- -
-
- ); - - case "addons": - return ( -
-
-
- - - -
-

Feature Add-ons

-

Enable features to extend your platform capabilities

- - Open Add-ons - -
-
- ); - - case "billing": - return ( -
-
-
- - - -
-

Billing & Plans

-

Manage your subscription, invoices, and usage

- - Open Billing - -
-
- ); - - case "integrations": - return ( -
-
-
- - - -
-

Integrations

-

Configure Stripe, Square, shipping, and other integrations

- - Open Integrations - -
-
- ); - - case "ai": - return ( -
-
-
- - - -
-

AI Settings

-

Configure AI provider settings for intelligent automation

- - Open AI Settings - -
-
- ); - - case "advanced": - return ( -
-
-
- - - - -
-

Advanced Settings

-

Developer settings, APIs, webhooks, and integrations

- - Open Advanced - -
-
- ); - - default: - return null; - } - }; - return (
{/* Page Header */} @@ -162,22 +158,209 @@ export default function SettingsClient({ brandId }: Props) { } + actions={ + window.location.href = "/admin/advanced"} + > + Advanced Settings + + } /> {/* Tab navigation */} -
- setActiveTab(tab as Tab)} - tabs={TABS.map(tab => ({ value: tab.id, label: tab.label }))} - size="md" - /> -
+ {/* Content */}
- {renderContent()} + {activeTab === "general" && ( +
+ +
+ )} + + {activeTab === "brand" && ( +
+ {currentUser.role === "platform_admin" && brands.length > 0 && ( +
+
+
+
+ {Icons.brand("w-4 h-4 text-white")} +
+
+

Select Brand

+

Choose a brand to view and edit its settings

+
+
+
+
+ { + window.location.href = `/admin/settings?brand=${id}#brand`; + }} + /> +
+
+ )} + + {/* Selected Brand Settings */} +
+
+
+
+ {Icons.brand("w-4 h-4 text-white")} +
+
+

Brand Settings

+

Company information, logos, and default signatures

+
+
+
+
+ +
+
+ + {/* Payment Settings */} +
+
+
+
+ + + +
+
+

Payment Settings

+

Configure your payment provider for checkout processing

+
+
+
+
+ +
+
+
+ )} + + {activeTab === "workers" && ( +
+
+
+
+ {Icons.users("w-4 h-4 text-white")} +
+
+

Workers & PINs

+

Manage time tracking workers and PIN codes

+
+
+
+
+ +
+
+ )} + + {activeTab === "tasks" && ( +
+
+
+
+ {Icons.list("w-4 h-4 text-white")} +
+
+

Tasks

+

Define tasks workers can clock into

+
+
+
+
+ +
+
+ )} + + {activeTab === "users" && ( +
+
+
+
+ {Icons["user-check"]("w-4 h-4 text-[var(--admin-bg)]")} +
+
+

Users & Permissions

+

Manage team access and roles

+
+
+
+
+ +
+
+ )} + +
+
+
+
+ + + +
+
+

Advanced Settings

+

AI, integrations, Square sync, shipping, and webhooks

+
+
+ window.location.href = "/admin/advanced"} + > + Open Advanced → + +
+
);