// SONARA — Wallet page (artista) const WIcons = window.SonaraIcons; // ============= DATA ============= const TX_DATA = [ { id: "tx-001", date: "Oggi, 14:32", day: "Oggi", kind: "out", icon: "service", label: "Mix Pro · Marco Vega", sub: "Ordine #SV-4821", amount: "-€189,00", badge: "escrow" }, { id: "tx-002", date: "Oggi, 09:15", day: "Oggi", kind: "in", icon: "topup", label: "Ricarica wallet", sub: "Visa •• 4242", amount: "+€100,00", badge: null }, { id: "tx-003", date: "Ieri, 22:04", day: "Ieri", kind: "out", icon: "beat", label: "Beat 'Lunar Drift'", sub: "Producer @luxx · Licenza non-esclusiva", amount: "-€49,00", badge: null }, { id: "tx-004", date: "Ieri, 18:30", day: "Ieri", kind: "refund", icon: "refund", label: "Rimborso ordine #SV-4810", sub: "Annullamento da producer · accreditato in saldo", amount: "+€85,00", badge: "refunded" }, { id: "tx-005", date: "12 mag, 11:20", day: "12 maggio", kind: "out", icon: "beat", label: "Beat 'Tokyo Nights'", sub: "Producer @808king · Licenza non-esclusiva", amount: "-€39,00", badge: null }, { id: "tx-006", date: "10 mag, 16:48", day: "10 maggio", kind: "out", icon: "service", label: "Vocal production · Sara K.", sub: "Ordine #SV-4789 · Completato", amount: "-€220,00", badge: null }, { id: "tx-007", date: "08 mag, 09:00", day: "08 maggio", kind: "in", icon: "topup", label: "Ricarica wallet", sub: "Apple Pay", amount: "+€250,00", badge: null }, { id: "tx-008", date: "05 mag, 12:14", day: "05 maggio", kind: "out", icon: "service", label: "Mastering · Hearfield Studio", sub: "Ordine #SV-4756 · In escrow", amount: "-€95,00", badge: "escrow" }, { id: "tx-009", date: "01 mag, 19:32", day: "01 maggio", kind: "in", icon: "promo", label: "Bonus benvenuto", sub: "Welcome credit · accreditato in saldo", amount: "+€10,00", badge: null }, ]; const METHODS_DATA = [ { id: "m1", brand: "visa", last4: "4242", name: "Luca Marini", exp: "07 / 27", isDefault: true }, { id: "m2", brand: "mc", last4: "8821", name: "Luca Marini", exp: "11 / 25", isDefault: false, expiringSoon: true }, { id: "m3", brand: "applepay", last4: null, name: "Apple Pay · iPhone 15", exp: null, isDefault: false }, ]; const DOCS_DATA = [ { id: "d1", name: "Estratto conto · Maggio 2025", size: "PDF · 124 KB" }, { id: "d2", name: "Estratto conto · Aprile 2025", size: "PDF · 118 KB" }, { id: "d3", name: "Esporta tutto (CSV)", size: "Tutte le transazioni" }, ]; // ============= ICONS ============= const TxKindIcon = ({ kind }) => { if (kind === "topup") return ; if (kind === "promo") return ; if (kind === "refund") return ; if (kind === "service") return ; if (kind === "beat") return ; return ; }; const ChevronRight = ({ size = 16 }) => ( ); const PlusIcon = ({ size = 16 }) => ( ); const DownloadIcon = ({ size = 16 }) => ( ); const FileIcon = ({ size = 16 }) => ( ); const InfoIcon = ({ size = 18 }) => ( ); const DotsIcon = ({ size = 16 }) => ( ); // ============= HERO ============= function WalletHero({ onTopup }) { return (
Saldo wallet
425 ,00
di cui €10 bonus benvenuto €189 in escrow su 1 ordine
Speso 30gg
592
+18% vs mese scorso
Ricaricato 30gg
350
3 ricariche
In escrow
189
su 1 ordine attivo
); } // ============= TX LIST ============= function TxRow({ tx }) { const kindClass = tx.kind === "in" ? "in" : tx.kind === "refund" ? "refund" : tx.kind === "out" && tx.badge === "escrow" ? "escrow" : "out"; const amountClass = tx.kind === "in" ? "in" : tx.kind === "refund" ? "refund" : "out"; return (
{tx.label} {tx.badge === "escrow" && In escrow} {tx.badge === "refunded" && Rimborsato} {tx.badge === "pending" && In sospeso}
{tx.sub} · {tx.date}
{tx.amount}
); } function TxPanel() { const [filter, setFilter] = React.useState("all"); const filtered = React.useMemo(() => { if (filter === "all") return TX_DATA; if (filter === "in") return TX_DATA.filter(t => t.kind === "in"); if (filter === "out") return TX_DATA.filter(t => t.kind === "out"); if (filter === "refund") return TX_DATA.filter(t => t.kind === "refund"); return TX_DATA; }, [filter]); // Group by day const grouped = React.useMemo(() => { const groups = []; let current = null; filtered.forEach(tx => { if (!current || current.day !== tx.day) { current = { day: tx.day, items: [] }; groups.push(current); } current.items.push(tx); }); return groups; }, [filtered]); const counts = React.useMemo(() => ({ all: TX_DATA.length, in: TX_DATA.filter(t => t.kind === "in").length, out: TX_DATA.filter(t => t.kind === "out").length, refund: TX_DATA.filter(t => t.kind === "refund").length, }), []); return (
Transazioni {filtered.length}
{filtered.length === 0 ? (
Nessuna transazione in questa categoria.
) : ( grouped.map(g => (
{g.day}
{g.items.map(tx => )}
)) )}
Mostrate ultime 30 transazioni e.preventDefault()}>Carica altre →
); } // ============= METHODS ============= function MethodRow({ m }) { return (
{m.last4 ? `•••• ${m.last4}` : m.name} {m.isDefault && Default}
{m.exp ? `${m.expiringSoon ? "⚠ Scade " : "Scade "}${m.exp}` : "Wallet del dispositivo"}
); } function MethodsPanel() { return (
Metodi di pagamento {METHODS_DATA.length}
{METHODS_DATA.map(m => )}
); } // ============= DOCS ============= function DocsPanel() { return (
Documenti
{DOCS_DATA.map(d => (
{d.name}
{d.size}
))}
); } // ============= INFO ============= function InfoPanel() { return (
Come funziona il wallet
Il saldo è in € ed è utilizzabile su tutto Sonara. Bonus, refund e ricariche confluiscono in un saldo unico. Quando paghi con il wallet evita le commissioni del circuito carte. e.preventDefault()}>Scopri di più
); } // ============= TOPUP MODAL ============= function TopupModal({ open, onClose }) { const [preset, setPreset] = React.useState(50); const [custom, setCustom] = React.useState(""); const [methodId, setMethodId] = React.useState("m1"); React.useEffect(() => { if (open) { setPreset(50); setCustom(""); setMethodId("m1"); } }, [open]); if (!open) return null; const amount = custom ? parseFloat(custom) || 0 : preset; const canConfirm = amount >= 5 && methodId; return (
e.stopPropagation()}>
Ricarica wallet
Importo preset
{[25, 50, 100, 250].map(v => ( ))}
O importo personalizzato
setCustom(e.target.value)} />
Paga con
{METHODS_DATA.map(m => (
setMethodId(m.id)} >
{m.last4 ? `•••• ${m.last4}` : m.name}
))}
Ricarica totale
€{amount.toFixed(2).replace(".", ",")}
); } // ============= PAGE ============= function WalletPage() { const [topupOpen, setTopupOpen] = React.useState(false); return (

Wallet

Saldo, ricariche, transazioni e metodi di pagamento.
setTopupOpen(true)}/>
setTopupOpen(false)}/>
); } window.WalletPage = WalletPage;