// SONARA — Producer Nav (sidebar + topbar + bottomnav) // Persona: Nico Vega / @nicovega — Milano, trap/hip-hop producer. const PIcons = window.SonaraIcons; function Sidebar({ active = "home" }) { const marketplace = { key: "opportunita", label: "Opportunità", icon: , badge: 8, href: "Opportunita.html" }; const work = [ { key: "home", label: "Home", icon: , href: "Dashboard.html" }, { key: "catalog", label: "Catalog", icon: , href: "Catalog.html" }, { key: "ordini", label: "Ordini", icon: , badge: 4, href: "Ordini.html" }, { key: "messaggi", label: "Messaggi", icon: , badge: 3, href: "Messaggi.html" }, ]; const market = [ { key: "esplora", label: "Esplora marketplace", icon: , href: "Esplora.html" }, ]; const biz = [ { key: "wallet", label: "Wallet & payout", icon: , href: "Wallet.html" }, { key: "profilo", label: "Profilo pubblico", icon: , href: "Profilo.html" }, ]; return ( ); } function Topbar({ available = "1.247", kyc = "verified", // "verified" | "in_review" | "incomplete" theme = "dark", onToggleTheme, }) { const [notifOpen, setNotifOpen] = React.useState(false); const notifRef = React.useRef(null); React.useEffect(() => { const onDown = (e) => { if (notifOpen && notifRef.current && !notifRef.current.contains(e.target)) setNotifOpen(false); }; document.addEventListener("mousedown", onDown); return () => document.removeEventListener("mousedown", onDown); }, [notifOpen]); const SunIcon = ({ size = 16 }) => ( ); const MoonIcon = ({ size = 16 }) => ( ); const kycMeta = kyc === "verified" ? { label: "KYC ok", cls: "ok", ic: } : kyc === "in_review" ? { label: "KYC in review", cls: "warn", ic: } : { label: "Completa KYC", cls: "alert", ic: }; return (
⌘ K
Opportunità 8 nuove Feed 3
{notifOpen && setNotifOpen(false)}/>}
); } function Greet({ name = "Nico", sub = "3 ordini in coda, 2 da consegnare oggi. €1.247 disponibili per payout.", }) { return (

Ciao, {name} 👋

{sub}
); } function BottomNav({ active = "home" }) { const items = [ { key: "home", label: "Home", icon: , href: "Dashboard.html" }, { key: "opportunita", label: "Opp.", icon: , badge: 8, href: "Opportunita.html", primary: true }, { key: "esplora", label: "Esplora", icon: , href: "Esplora.html" }, { key: "ordini", label: "Ordini", icon: , badge: 4, href: "Ordini.html" }, { key: "chat", label: "Chat", icon: , badge: 3, href: "Messaggi.html" }, ]; return ( ); } Object.assign(window, { Sidebar, Topbar, Greet, BottomNav }); /* ─────────────────────────────────────────────────── */ /* Notifications panel (popover) */ /* ─────────────────────────────────────────────────── */ const NOTIFICATIONS = [ { id: "n1", type: "order", unread: true, time: "8m fa", title: "Nuovo ordine ricevuto", body: "RAZZA ha richiesto Mix + Master per l'EP \"Asfalto\" · €180", href: "Ordine.html", icon: "audioFile", accent: "violet", }, { id: "n2", type: "deadline", unread: true, time: "1h fa", urgent: true, title: "Scadenza imminente", body: "ORD-4821 \"EP Asfalto\" scade tra 22h. Carica la v2.", href: "Ordine.html", icon: "clock", accent: "warning", }, { id: "n3", type: "counter", unread: true, time: "3h fa", title: "Counter-offer ricevuto", body: "AlessioRap ti contro-offre €140 invece di €180 su REQ-9214", href: "Ordini.html", icon: "target", accent: "violet", }, { id: "n4", type: "saved_search", unread: false, time: "5h fa", title: "Match dalla tua ricerca salvata", body: "3 nuove richieste matchano \"Trap Milano premium\"", href: "Opportunita.html", icon: "bell", accent: "violet", }, { id: "n5", type: "review", unread: false, time: "Ieri", title: "Nuova recensione 5★", body: "Yoshi K. ti ha lasciato una recensione su \"Co-prod Quartiere\"", href: "Profilo.html", icon: "star", accent: "gold", }, { id: "n6", type: "payout", unread: false, time: "Lun 11 mag", title: "Payout eseguito", body: "€892,00 inviati sul tuo IBAN ***4831. Arrivo previsto in 1-2 gg lavorativi.", href: "Wallet.html", icon: "coins", accent: "success", }, { id: "n7", type: "sale", unread: false, time: "12 mag", title: "Beat venduto", body: "Marco T. ha acquistato \"Notturno\" · +€39,60 in wallet", href: "Catalog.html", icon: "disc", accent: "success", }, { id: "n8", type: "system", unread: false, time: "10 mag", title: "Aggiornamento policy", body: "Abbiamo aggiornato i Termini di Servizio. Leggi le novità.", href: "Profilo.html", icon: "shield", accent: "neutral", }, ]; function NotificationsPanel({ onClose }) { const [filter, setFilter] = React.useState("all"); // all | unread const unreadCount = NOTIFICATIONS.filter(n => n.unread).length; const items = filter === "unread" ? NOTIFICATIONS.filter(n => n.unread) : NOTIFICATIONS; return (
Notifiche {unreadCount > 0 && {unreadCount} nuove}
{items.map(n => { const Ic = PIcons[n.icon] || PIcons.bell; return (
{n.title} {n.time}
{n.body}
{n.unread && }
); })} {items.length === 0 && (
Nessuna notifica non letta
Sei in pari 🎉
)}
); } window.NotificationsPanel = NotificationsPanel;