"use client"; import { useState, useEffect } from "react"; import Image from "next/image"; import { cmsApi, Organization, BrandingPayload, getImageUrl } from "@/lib/api"; import FileUpload from "./FileUpload"; import { useRouter } from "next/navigation"; export default function BrandingSettings() { const router = useRouter(); const [org, setOrg] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [formData, setFormData] = useState({ name: "", primary_color: "#3B82F6", secondary_color: "#8B5CF6", platform_name: "", logo_variant: "standard", }); useEffect(() => { fetchOrg(); }, []); const fetchOrg = async () => { try { const data = await cmsApi.getOrganization(); setOrg(data); setFormData({ name: data.name || "", primary_color: data.primary_color || "#3B82F6", secondary_color: data.secondary_color || "#8B5CF6", platform_name: data.platform_name || "", logo_variant: data.logo_variant || "standard", }); } catch (error) { console.error("Failed to fetch organization:", error); } finally { setLoading(false); } }; const handleSave = async () => { if (!org) return; setSaving(true); try { await cmsApi.updateOrganizationBranding(org.id, formData); fetchOrg(); alert("Branding updated successfully!"); router.refresh(); } catch (error) { console.error("Failed to update branding:", error); alert("Failed to update branding settings."); } finally { setSaving(false); } }; if (loading) return
Loading settings...
; if (!org) return
Failed to load organization settings.
; return (
Brand Identity
{/* Organization Name */}
setFormData({ ...formData, name: e.target.value })} className="w-full bg-slate-50 dark:bg-black/20 border border-slate-200 dark:border-white/10 rounded-lg px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all" placeholder="My Organization" required />

The official name of your organization.

{/* Platform Name */}
setFormData({ ...formData, platform_name: e.target.value })} placeholder={org.name} className="w-full bg-slate-50 dark:bg-black/20 border border-slate-200 dark:border-white/10 rounded-lg px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all" />

Appears in the browser tab and page titles.

{/* Logo Section */}
Logo
{org.logo_url ? ( Logo ) : ( No logo uploaded )}
{ const res = await cmsApi.uploadOrganizationLogo(org.id, file); return { url: res.logo_url || "" }; }} onUploadComplete={(url) => { setOrg({ ...org, logo_url: url }); router.refresh(); }} />

Recommended: SVG or PNG, max 2MB.

{/* Favicon Section */}
Favicon
{org.favicon_url ? (
Favicon
) : ( No favicon )}
{ const res = await cmsApi.uploadOrganizationFavicon(org.id, file); return { url: res.favicon_url || "" }; }} onUploadComplete={(url) => { setOrg({ ...org, favicon_url: url }); router.refresh(); }} />

Recommended: ICO or PNG, 32x32px.

{/* Logo Variant Selection */}
Brand Colors
{/* Primary Color */}
setFormData({ ...formData, primary_color: e.target.value })} aria-label="Primary color picker" className="w-12 h-12 rounded-lg cursor-pointer bg-transparent border-none p-0" />
setFormData({ ...formData, primary_color: e.target.value })} className="w-full bg-slate-50 dark:bg-black/20 border border-slate-200 dark:border-white/10 rounded-lg px-4 py-2 text-slate-900 dark:text-white font-mono uppercase focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all font-bold" aria-describedby="primary-color-desc" />

Used for main buttons, active states, and highlights.

{/* Secondary Color */}
setFormData({ ...formData, secondary_color: e.target.value })} aria-label="Secondary color picker" className="w-12 h-12 rounded-lg cursor-pointer bg-transparent border-none p-0" />
setFormData({ ...formData, secondary_color: e.target.value })} className="w-full bg-slate-50 dark:bg-black/20 border border-slate-200 dark:border-white/10 rounded-lg px-4 py-2 text-slate-900 dark:text-white font-mono uppercase focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all font-bold" aria-describedby="secondary-color-desc" />

Used for accents and gradients.

); }