"use client"; import { Suspense, useEffect, useState } from "react"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { Building2, Bell, CreditCard, FileText, Save, CheckCircle2, Users as UsersIcon, } from "lucide-react"; import { api } from "@/lib/api"; import { Package } from "lucide-react"; import UsersPanel from "@/components/UsersPanel"; import BrandsPanel from "@/components/BrandsPanel"; import countryList from "react-select-country-list"; import TimezoneSelect from "react-timezone-select"; import { T, detectLang } from "@/lib/i18n"; import { useLanguage } from "@/contexts/LanguageContext"; import { apiBase } from "@/lib/api"; import { Download } from "lucide-react"; const countries = countryList().getData(); export const LANGS = [ { code: "en", label: "English" }, { code: "hi", label: "हिन्दी" }, { code: "kn", label: "ಕನ್ನಡ" }, { code: "ta", label: "தமிழ்" }, { code: "bn", label: "বাংলা" }, ]; function SettingsInner() { const sp = useSearchParams(); const initial = sp.get("section") ?? "org"; const [active, setActive] = useState(initial); const [org, setOrg] = useState(null); const [form, setForm] = useState({}); const [saved, setSaved] = useState(false); const [sub, setSub] = useState(null); const [logs, setLogs] = useState([]); const [notif, setNotif] = useState({ email: true, system: true, compliance: true, security: true }); const { t, setLang } = useLanguage(); const SECTIONS = [ { id: "org", label: t.organization, icon: Building2 }, { id: "users", label: t.users, icon: UsersIcon }, { id: "brands", label: t.brands, icon: Package }, { id: "notifications", label: t.notifications, icon: Bell }, { id: "subscription", label: t.subscription, icon: CreditCard }, { id: "audit", label: t.audit, icon: FileText }, ]; const [logoPreview, setLogoPreview] = useState(""); const [logoFileName, setLogoFileName] = useState(""); const [filters, setFilters] = useState({ user: "", module: "", from: "", to: "", }); function downloadAuditLogs() { if (!logs.length) return; const rows = logs.map((l) => ({ Time: l.at ? new Date(l.at).toLocaleString(form.language || "en", { timeZone: form.timezone || "Asia/Kolkata", }) : "", User: l.user, Role: l.role, Action: l.action, Module: l.module, Details: l.details, IP: l.ip ?? "", })); const headers = Object.keys(rows[0]); const csv = [ headers.join(","), ...rows.map((r) => headers .map((h) => `"${String((r as any)[h] ?? "").replace(/"/g, '""')}"`) .join(",") ), ].join("\n"); const blob = new Blob([csv], { type: "text/csv;charset=utf-8;", }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = `audit_logs_${new Date() .toISOString() .slice(0, 10)}.csv`; link.click(); URL.revokeObjectURL(url); } async function loadLogs() { const params = new URLSearchParams(); if (filters.user) params.append("user", filters.user); if (filters.module) params.append("module", filters.module); if (filters.from) params.append("from_date", filters.from); if (filters.to) params.append("to_date", filters.to); const data = await api(`/audit-logs?${params.toString()}`); setLogs(data); } useEffect(() => { api("/organization").then((o) => { setOrg(o); setLogoPreview(o.logo_url || ""); localStorage.setItem("timezone", o.timezone); setForm({ name: o.name, gstin: o.gstin ?? "", pan: o.pan ?? "",address: o.address ?? "", phone: o.phone ?? "",logo_url:o.logo_url ?? "", website: o.website ?? "", timezone: o.timezone ?? "Asia/Kolkata", language: o.language ?? "en", contact_email: o.contact_email ?? "",country: o.country ?? "",}); }).catch(() => {}); api("/billing/subscription").then(setSub).catch(() => {}); loadLogs(); }, []); async function uploadLogo(file: File) { const fd = new FormData(); fd.append("file", file); const token = localStorage.getItem("vp_token"); const res = await fetch(`${apiBase}/brands/upload-logo`, { method: "POST", headers: { Authorization: `Bearer ${token}`, }, body: fd, }); const data = await res.json(); setLogoPreview(data.url); setLogoFileName(file.name); setForm({ ...form, logo_url: data.url, }); } async function saveOrg() { await api("/organization", { method: "PUT", body: JSON.stringify(form) }); setLang(form.language); localStorage.setItem("timezone", form.timezone); setSaved(true); setTimeout(() => setSaved(false), 2000); } useEffect(() => { loadLogs(); }, [filters]); return (

{t.settings}

{active === "users" && } {active === "brands" && } {active === "org" && (

{t.organization}

{saved &&
Saved
}
{/* LEFT SIDE */}
{logoPreview ? ( Organization Logo ) : ( No Logo )}
{logoFileName && (

{logoFileName}

)}
{/* RIGHT SIDE */}
setForm({...form,name:v})} /> setForm({...form,website:v})} /> setForm({...form,gstin:v})} /> setForm({...form,pan:v})} /> setForm({...form,phone:v})} /> setForm({...form,contact_email:v})} />
setForm({...form,address:v})} />
)} {active === "notifications" && (

{t.notifications}

{[ ["email", "Email notifications"], ["system", "System alerts"], ["compliance", "Compliance expiry alerts"], ["security", "Security alerts"], ].map(([key, label]) => (
{label}
))}

Preferences are illustrative in this build.

)} {active === "subscription" && (

{t.subscription}

Manage billing
)} {active === "audit" && (

Recent Activity

setFilters({ ...filters, from: e.target.value }) } className="border rounded-lg px-3 py-2" /> setFilters({ ...filters, to: e.target.value }) } className="border rounded-lg px-3 py-2" /> setFilters({ ...filters, user: e.target.value }) } className="border rounded-lg px-3 py-2" />
{logs.map((l, i) => ( ))} {logs.length === 0 && }
Time User Action Details Module
{l.at ? new Date(l.at).toLocaleString(form.language || "en", { timeZone: form.timezone || "Asia/Kolkata", dateStyle: "medium", timeStyle: "short", }) : ""}
{l.user ?? "—"}
{l.role ?? "User"}
{l.action?.replace(".", " ")} {l.details} {l.module}
No activity yet.
)}
); } export default function Settings() { return ( Loading…}> ); } function Field({ label, value, onChange }: any) { return ( ); } function Row({ label, value }: any) { return (
{label} {value}
); }