// EsploraServizi — Services catalog tab
// Owns: ServiziFilterRail, ServiziGrid, ServizioCard
// Service card focus: "Cosa include" bullet list visible, with "from €X"
const SvcIcons = window.SonaraIcons;
const { useState: useStateSvc } = React;
function SvcGeoFilter() {
const [mode, setMode] = useStateSvc("any");
const [query, setQuery] = useStateSvc("");
const [radius, setRadius] = useStateSvc(50);
const chips = [
{ id: "any", label: "Ovunque" },
{ id: "near", label: "Vicino a me", icon: true },
{ id: "country", label: "Italia" },
];
return (
{ setQuery(e.target.value); setMode("custom"); }}
/>
{query && (
)}
{chips.map(c => (
))}
{mode === "near" && (
)}
);
}
const SVC_CATEGORIES = [
{ id: "mix", label: "Mix", desc: "Mix stereo di singolo brano" },
{ id: "master", label: "Master", desc: "Mastering di brano già mixato" },
{ id: "mix-master", label: "Mix + Master", desc: "Combo (≈70% degli ordini reali)" },
{ id: "vocal", label: "Vocal production", desc: "Recording + tuning + editing voce" },
{ id: "custom", label: "Custom production", desc: "Beat su brief dell'artista" },
{ id: "topline", label: "Topline / Songwriting", desc: "Melodia + testo" },
{ id: "sound", label: "Sound design", desc: "FX, atmosphere, transitions" },
{ id: "altro", label: "Altro", desc: "Free-form" },
];
const SVC_PRODS = ["Marco V.", "Yoshi", "DK Beats", "Riva", "Nemo", "Kyo", "Astra", "Frey", "Lume", "Tide", "Vento", "Plata"];
const SVC_CITIES = ["Milano", "Roma", "Napoli", "Torino", "Bologna", "Firenze", "Bari", "Catania", "Verona", "Brescia"];
function svcRand(seed) { let s = seed; return () => (s = (s * 9301 + 49297) % 233280) / 233280; }
function makeServizi() {
const r = svcRand(11);
const titles = [
"Mix professionale di singolo trap/drill",
"Mastering radio-ready 24h",
"Mix + Master combo per singolo",
"Vocal production completa con tuning",
"Beat custom su brief con 2 revisioni",
"Topline + testo per singolo pop urban",
"Sound design FX & transitions per album",
"Mix vocal-forward stile R&B",
"Master loudness Spotify/YouTube",
"Mix + Master con 3 revisioni",
"Vocal recording session in studio",
"Custom beat con stems separati inclusi",
"Topline melodica per producer",
"Atmosphere & risers per progetto",
"Stems mixing per remix",
"Master analog warm",
"Pitch correction trasparente",
"Beat brief Trap/Drill con 4 revisioni",
];
const cats = ["mix","master","mix-master","vocal","custom","topline","sound","mix","master","mix-master","vocal","custom","topline","sound","mix","master","vocal","custom"];
const includes = {
mix: ["File WAV stem-ready", "EQ + comp + balance", "1 revisione gratuita", "Consegna in 5 giorni"],
master: ["Master 24-bit + 16-bit", "LUFS calibrato per piattaforma", "1 revisione", "Consegna in 24h"],
"mix-master": ["Mix completo + Master", "WAV + MP3 finali", "2 revisioni gratuite", "Consegna in 7 giorni"],
vocal: ["Tuning trasparente", "Editing breath/pop", "Comping take", "Stems voce ready"],
custom: ["Beat originale su brief", "MP3 + WAV", "2 revisioni incluse", "Stems +€80"],
topline: ["Melodia + testo completo", "Demo vocale", "Pubblishing 50/50", "1 revisione"],
sound: ["Pacchetto FX custom", "Transitions per ogni brano", "Stem WAV", "Royalty-free"],
};
return titles.map((title, i) => {
const cat = cats[i];
const price = [49, 79, 129, 159, 199, 249, 299, 349][Math.floor(r() * 8)];
const delivery = [1, 3, 5, 7, 10][Math.floor(r() * 5)];
const rating = Math.round((4.4 + r() * 0.6) * 10) / 10;
const reviews = Math.floor(8 + r() * 140);
const beforeAfter = r() > 0.45;
return {
id: i + 1,
title,
category: cat,
categoryLabel: SVC_CATEGORIES.find(c => c.id === cat).label,
producer: SVC_PRODS[i % SVC_PRODS.length],
verified: r() > 0.4,
city: SVC_CITIES[i % SVC_CITIES.length],
price,
delivery, // days
rating,
reviews,
beforeAfter,
includes: includes[cat] || ["Servizio personalizzato", "Brief iniziale", "1 revisione", "Consegna concordata"],
art: i % 6,
};
});
}
const ALL_SERVIZI = makeServizi();
// ---------- filter rail (Servizi) ----------
function ServiziFilterRail() {
const [cat, setCat] = useStateSvc("Tutti");
const [delivery, setDelivery] = useStateSvc("any");
const [rating, setRating] = useStateSvc("any");
return (
);
}
// ---------- service card ----------
function ServizioCard({ svc }) {
const arts = ["art-a","art-b","art-c","art-d","art-e","art-f"];
return (
{svc.categoryLabel}
{svc.beforeAfter && (
prima/dopo
)}
{svc.title}
{svc.producer.charAt(0)}
{svc.producer}
{svc.verified && }
{svc.rating.toFixed(1)}
({svc.reviews})
Cosa include
{svc.includes.map(it => (
- {it}
))}
da
€{svc.price}
{svc.delivery === 1 ? "24h" : `${svc.delivery} giorni`}
Vedi
);
}
function ServiziCatalog() {
const servizi = ALL_SERVIZI;
return (
{servizi.map(s => )}
);
}
window.ServiziCatalog = ServiziCatalog;
window.ALL_SERVIZI = ALL_SERVIZI;
window.SVC_COUNT = ALL_SERVIZI.length;