"use client";
/* eslint-disable react-hooks/set-state-in-effect */
import { useState, useEffect } from "react";
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" | "brand" | "workers" | "tasks" | "users";
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,
users,
brands,
paymentSettings,
currentUser,
}: Props) {
// Server renders the default tab; client picks up the URL hash after mount
// so the initial server HTML matches the first client render (avoids
// hydration mismatch). Reading window.location.hash in a lazy initializer
// is unsafe because the server has no hash and would render a different
// tab than the client.
const [activeTab, setActiveTab] = useState("general");
useEffect(() => {
const hash = window.location.hash.slice(1);
const tab = TABS.find((t) => t.hash === hash)?.id;
if (tab) setActiveTab(tab);
}, []);
return (
{/* Page Header */}
}
actions={
window.location.href = "/admin/advanced"}
>
Advanced Settings
}
/>
{/* Tab navigation */}
{/* Content */}
{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 →
);
}