/** * DashboardShell — real sidebar + header layout wrapper. * Used for pages that need actual backend connectivity * (My Profile, My Portfolio, Verification) instead of the preview mock. */ import { For, JSX, Show, createMemo } from "solid-js"; import { AiChatWidget } from "./AiChatWidget"; import NotificationBell from "./NotificationBell"; import { User, Briefcase, LayoutDashboard, FolderOpen, MapPin, Star, CreditCard, Globe, ShieldCheck, HelpCircle, Settings, RefreshCw, LogOut, Bell, ChevronRight, Lock, } from "lucide-solid"; const ICON_MAP: Record = { my_dashboard: LayoutDashboard, my_profile: User, my_portfolio: FolderOpen, portfolio: FolderOpen, leads: MapPin, my_responses: Star, responses: Star, credits: CreditCard, explore_nxtgauge: Globe, explore: Globe, verification: ShieldCheck, verification_status: ShieldCheck, help_center: HelpCircle, help: HelpCircle, support: HelpCircle, settings: Settings, switch_services: RefreshCw, switch_service: RefreshCw, logout: LogOut, jobs: Briefcase, job_postings: Briefcase, applications: Briefcase, my_applications: FolderOpen, shortlisted_candidates: User, my_requirements: FolderOpen, requirements: FolderOpen, received_responses: Bell, shortlisted_responses: Star, saved_jobs: Star, }; function normalizeSidebarIconKey(value: string): string { return String(value || "") .trim() .toLowerCase() .replace(/\s+/g, "_") .replace(/-/g, "_"); } function SidebarIcon(props: { label: string }) { const key = normalizeSidebarIconKey(props.label); const Icon = ICON_MAP[key] || ChevronRight; return ; } function titleCase(value: string) { return String(value || "") .toLowerCase() .replace(/_/g, " ") .replace(/\b\w/g, (c) => c.toUpperCase()); } // ── Types ───────────────────────────────────────────────────────────────────── interface Props { sidebarItems: string[]; activeSidebar: string; onSidebarSelect: (item: string) => void; roleKey: string; userName?: string; isAdmin?: boolean; children: JSX.Element; } // ── Brand colours ───────────────────────────────────────────────────────────── export const ORANGE = "#FF5E13"; export const NAVY = "#0D0D2A"; const DARK_INK = "#03004E"; // ── Component ───────────────────────────────────────────────────────────────── export default function DashboardShell(props: Props) { const roleLabel = createMemo(() => { const k = String(props.roleKey || "").replace(/_/g, " "); return k.charAt(0).toUpperCase() + k.slice(1).toLowerCase(); }); return (
{/* ── Sidebar ──────────────────────────────────────────────────────── */} {/* ── Main content ─────────────────────────────────────────────────── */}
{/* Top bar */}

{titleCase(props.activeSidebar)}

{(props.userName || "U").charAt(0).toUpperCase()}
{/* Page content */}
{props.children}
); } // ── Shared UI primitives ────────────────────────────────────────────────────── export const CARD = { background: "#fff", border: "1px solid #E5E7EB", "border-radius": "16px", padding: "14px", "box-shadow": "0 1px 4px rgba(0,0,0,0.06)", } as const; export const BTN_PRIMARY = { height: "34px", "border-radius": "8px", border: "none", background: NAVY, color: "#fff", padding: "0 14px", "font-size": "12px", "font-weight": "700", cursor: "pointer", } as const; export const BTN_ORANGE = { height: "34px", "border-radius": "8px", border: "none", background: ORANGE, color: "#fff", padding: "0 14px", "font-size": "12px", "font-weight": "700", cursor: "pointer", } as const; export const BTN_GHOST = { height: "34px", "border-radius": "8px", border: "1px solid #E5E7EB", background: "#fff", color: "#374151", padding: "0 14px", "font-size": "12px", "font-weight": "700", cursor: "pointer", } as const; export const INPUT = { height: "36px", width: "100%", "border-radius": "8px", border: "1px solid #E5E7EB", padding: "0 10px", "font-size": "12px", color: "#111827", background: "#fff", "box-sizing": "border-box", outline: "none", } as const; export const LABEL = { display: "block", "font-size": "11px", "font-weight": "700", color: "#6B7280", "margin-bottom": "6px", "letter-spacing": "0.01em", "text-transform": "none", } as const; export const PKG_CARD = { WHITE: "#ffffff", COIN_BG: "#FFFBF8", COIN_AVATAR_BG: "linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%)", BEST_VALUE_BG: `linear-gradient(135deg, ${ORANGE} 0%, #FF8A5C 100%)`, BORDER_DEFAULT: "#E5E7EB", TEXT_SECONDARY: "#6B7280", TEXT_PRIMARY: "#111827", TEXT_ACCENT: ORANGE, TEXT_MUTED: "#9CA3AF", TEXT_SUCCESS: "#16A34A", SHADOW_DEFAULT: "0 1px 3px rgba(0, 0, 0, 0.08)", SHADOW_ACCENT: "0 4px 20px rgba(255, 94, 19, 0.15)", } as const;