// EsploraProducer — Producer directory tab
// Owns: ProducerFilterRail, ProducerGrid, ProducerCard
// Producer card focus: Foto + waveform di un beat signature in autoplay on hover
const ProdIcons = window.SonaraIcons;
const { useState: useStateProd } = React;
function ProdGeoFilter() {
const [mode, setMode] = useStateProd("any");
const [query, setQuery] = useStateProd("");
const [radius, setRadius] = useStateProd(50);
const chips = [
{ id: "any", label: "Ovunque" },
{ id: "near", label: "Vicino a me", icon: true },
{ id: "country", label: "Italia" },
];
return (
{chips.map(c => (
))}
{mode === "near" && (
)}
);
}
const PROD_GENRES = ["Trap", "Drill", "Hip-Hop", "R&B", "Afro", "Pop", "House", "Reggaeton"];
const PROD_CITIES = ["Milano", "Roma", "Napoli", "Torino", "Bologna", "Firenze", "Bari", "Palermo", "Verona", "Catania", "Brescia", "Genova"];
const PROD_NAMES = [
"Yoshi", "Marco V.", "DK Beats", "Riva", "Nemo", "Kyo",
"Astra", "Frey", "Lume", "Tide", "Vento Sud", "Plata",
"Echo Lab", "Notturno", "Sirio", "Onyx", "Mira", "Polvere",
"Nove", "Tessera", "Magma", "Zenith", "Sonar", "Velvet"
];
function prodRand(seed) { let s = seed; return () => (s = (s * 9301 + 49297) % 233280) / 233280; }
function makeProducers() {
const r = prodRand(13);
return PROD_NAMES.map((name, i) => {
const verified = r() > 0.35;
const topRated = r() > 0.65;
const responseHrs = [1, 2, 4, 6, 12, 24][Math.floor(r() * 6)];
const projects = Math.floor(40 + r() * 280);
const rating = Math.round((4.4 + r() * 0.6) * 10) / 10;
const reviews = Math.floor(15 + r() * 220);
const fromPrice = [29, 39, 49, 59, 79][Math.floor(r() * 5)];
const open = r() > 0.18;
const studio = r() > 0.65;
return {
id: i + 1,
name,
art: i % 6,
cover: i % 6,
city: PROD_CITIES[i % PROD_CITIES.length],
genres: [PROD_GENRES[i % PROD_GENRES.length], PROD_GENRES[(i + 3) % PROD_GENRES.length]],
verified, topRated,
responseHrs,
projects,
rating,
reviews,
fromPrice,
open,
studio,
// signature beat
sigTitle: ["Notte Lunga","Skyline","Asfalto","Vetro","Magma","Carbone"][i % 6],
sigBpm: 80 + Math.floor(r() * 80),
peaks: Array.from({ length: 56 }, (_, k) => {
const base = 0.3 + 0.5 * Math.abs(Math.sin(i * 0.9 + k * 0.27));
return Math.min(1, base + (r() - 0.5) * 0.25);
}),
};
});
}
const ALL_PRODUCERS = makeProducers();
// ---------- filter rail (Producer) ----------
function ProducerFilterRail() {
const [genre, setGenre] = useStateProd("Tutti");
const [response, setResponse] = useStateProd("any");
const FS = window.FilterSection;
return (
);
}
// ---------- mini waveform (autoplay on hover) ----------
function ProdMiniWave({ peaks, hovering }) {
return (
{peaks.map((p, i) => (
))}
);
}
// ---------- producer card ----------
function ProducerCard({ p }) {
const [hovering, setHovering] = useStateProd(false);
const arts = ["art-a","art-b","art-c","art-d","art-e","art-f"];
return (
setHovering(true)}
onMouseLeave={() => setHovering(false)}>
{p.topRated &&
★ Top Rated}
{p.studio &&
🎚 Studio}
{!p.open &&
In pausa}
Signature
{p.sigTitle} · {p.sigBpm} BPM
{p.name.charAt(0)}
{p.rating.toFixed(1)}
({p.reviews})
{p.genres.map(g => {g})}
{p.responseHrs}h
risposta
);
}
function ProducerCatalog() {
const producers = ALL_PRODUCERS;
return (
);
}
window.ProducerCatalog = ProducerCatalog;
window.ProducerFilterRail = ProducerFilterRail;
window.ALL_PRODUCERS = ALL_PRODUCERS;
window.PROD_COUNT = ALL_PRODUCERS.length;