Replace dashboard with Profile, Support Center & Rules modules
- Remove old dashboard stats/charts content; keep sidebar + header shell which now routes between Profile, Support Center and Rules views. - Profile: hero card + 6 tabs (Personal Info with verify-to-reveal + editable contacts via OTP, KYC two-doc rule + completion %, Security password policy + 2FA, Notifications matrix + contact windows, Privacy consents, Devices + activity timeline). - Support Center: 5 channel cards, support team, Message Center with typing, New Ticket category->department routing + attachment rules, My Tickets + status-timeline modal, Live Chat handshake, Callback/Email modals, Help Center search + accordion. - Rules: the 1-13 business-rules checklist. - Shared design system (Icon, Avatar, PageHead, Pill, Toggle, OtpField, Modal, Toast, Field, Tabs) + full mock data in account-data.ts. - Premium dark visual pass: brand gradients, depth, glow accents, pill tabs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,49 +1,32 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronsUpDown } from "lucide-react";
|
||||
import { FigIcon } from "./figicon";
|
||||
import { Icon } from "./ui";
|
||||
import { user } from "./account-data";
|
||||
|
||||
type Item = { key: string; label: string };
|
||||
type Item = { key: string; label: string; icon: string };
|
||||
|
||||
const GROUPS: { title: string; items: Item[] }[] = [
|
||||
{
|
||||
title: "Workspace",
|
||||
title: "Account",
|
||||
items: [
|
||||
{ key: "dashboard", label: "Dashboard" },
|
||||
{ key: "owners", label: "Owners Box" },
|
||||
{ key: "projects", label: "Projects" },
|
||||
{ key: "leads", label: "Leads" },
|
||||
{ key: "verify", label: "Lead Verification" },
|
||||
{ key: "pipeline", label: "Pipeline" },
|
||||
{ key: "profile", label: "Profile", icon: "user" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Workspace",
|
||||
title: "Help & Support",
|
||||
items: [
|
||||
{ key: "dispatch", label: "LynkDispatch" },
|
||||
{ key: "storm", label: "Storm Intel" },
|
||||
{ key: "territory", label: "Territory Map" },
|
||||
{ key: "procanvas", label: "ProCanvas" },
|
||||
{ key: "estimates", label: "Estimates" },
|
||||
{ key: "support", label: "Support Center", icon: "chat" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Team",
|
||||
title: "Reference",
|
||||
items: [
|
||||
{ key: "schedule", label: "Team Schedule" },
|
||||
{ key: "leaderboard", label: "Leaderboard" },
|
||||
{ key: "subtasks", label: "Subcontractor Tasks" },
|
||||
{ key: "people", label: "People" },
|
||||
{ key: "rules", label: "Rules Checklist", icon: "check-circle" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const EXTRA: Item[] = [
|
||||
{ key: "settings", label: "Org Settings" },
|
||||
{ key: "ai", label: "AI Assistant" },
|
||||
{ key: "home", label: "Home" },
|
||||
];
|
||||
|
||||
export function Sidebar({ active, onSelect }: { active: string; onSelect: (k: string) => void }) {
|
||||
return (
|
||||
<aside className="dash-sidebar">
|
||||
@@ -57,32 +40,26 @@ export function Sidebar({ active, onSelect }: { active: string; onSelect: (k: st
|
||||
{GROUPS.map((g, gi) => (
|
||||
<div key={gi}>
|
||||
<div className="nav-group">{g.title}</div>
|
||||
{g.items.map((it) => <NavBtn key={it.key} it={it} active={active} onSelect={onSelect} />)}
|
||||
{g.items.map((it) => (
|
||||
<button key={it.key} className={`nav-item ${active === it.key ? "active" : ""}`} onClick={() => onSelect(it.key)}>
|
||||
<Icon name={it.icon} size={18} />
|
||||
{it.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
<div style={{ height: 8 }} />
|
||||
{EXTRA.map((it) => <NavBtn key={it.key} it={it} active={active} onSelect={onSelect} />)}
|
||||
</nav>
|
||||
|
||||
<div className="sb-foot">
|
||||
<div className="sb-user">
|
||||
<span className="av" style={{ background: "linear-gradient(135deg,#285ef0,#09b9c6)", display: "grid", placeItems: "center", color: "#fff", fontWeight: 700, fontSize: 12 }}>JJ</span>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div className="nm">Justin Johnson</div>
|
||||
<div className="rl">Owner</div>
|
||||
<button className="sb-user">
|
||||
<span className="av" style={{ background: user.avatarGradient, display: "grid", placeItems: "center", color: "#fff", fontWeight: 700, fontSize: 12 }}>{user.initials}</span>
|
||||
<div style={{ flex: 1, textAlign: "left" }}>
|
||||
<div className="nm">{user.name}</div>
|
||||
<div className="rl">{user.role}</div>
|
||||
</div>
|
||||
<ChevronsUpDown size={15} />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
function NavBtn({ it, active, onSelect }: { it: Item; active: string; onSelect: (k: string) => void }) {
|
||||
return (
|
||||
<button className={`nav-item ${active === it.key ? "active" : ""}`} onClick={() => onSelect(it.key)}>
|
||||
<FigIcon name={it.key} size={18} />
|
||||
{it.label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user