// Milfers · Reseñas reales · rotación día / semana / mes // Datos (con traducción ES/VAL/EN) en reviews-data.js → window.MF_REVIEWS // ===================================================================== const REVIEWS = window.MF_REVIEWS || []; // localiza la fecha real al idioma activo (mes + año) function localizeDate(date) { const map = (window.MF_MONTHS && window.MF_MONTHS[window.MF_LANG]) || null; if (!map) return date; return date.replace(/^([a-zñ]+)/i, (m) => map[m.toLowerCase()] || m); } // cuerpo en el idioma activo, con fallback a español function reviewBody(r) { if (r.body && typeof r.body === 'object') return r.body[window.MF_LANG] || r.body.es; return r.body; } // ── ROTACIÓN DETERMINÍSTICA ────────────────────────────────────────────── // hash simple para barajar reproduciblemente según un seed (día/semana/mes) function pickRotating(list, count, seed) { if (list.length <= count) return list; const arr = list.map((r, i) => ({ r, k: hashStr(r.name + seed + i) })); arr.sort((a, b) => a.k - b.k); return arr.slice(0, count).map(x => x.r); } function hashStr(s) { let h = 2166136261; for (let i = 0; i < s.length; i++) { h = (h ^ s.charCodeAt(i)) * 16777619; h |= 0; } return h; } function buildTodayPool() { const today = new Date(); const dayKey = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`; const weekKey = `${today.getFullYear()}-W${Math.ceil((today.getDate() + new Date(today.getFullYear(), today.getMonth(), 1).getDay()) / 7)}-${today.getMonth()}`; const monthKey = `${today.getFullYear()}-${today.getMonth() + 1}`; const daily = REVIEWS.filter(r => r.tier === 'daily'); const weekly = REVIEWS.filter(r => r.tier === 'weekly'); const monthly = REVIEWS.filter(r => r.tier === 'monthly'); const pick = [ ...pickRotating(daily, 2, dayKey), ...pickRotating(weekly, 1, weekKey), ...pickRotating(monthly, 1, monthKey), ]; while (pick.length < 4 && REVIEWS.length > pick.length) { const next = REVIEWS.find(r => !pick.includes(r)); if (next) pick.push(next); else break; } return pick.slice(0, 4); } function ReviewsSection() { const todayReviews = React.useMemo(() => buildTodayPool(), []); return (
{/* EDIT: brand corner bursts + cursive "Milfers" stamp as background texture */}
5. 

{window.t('reviews.link')}
{todayReviews.map((r, i) => (
★★★★★

"{reviewBody(r)}"

{r.name} {localizeDate(r.date)} · {window.t('reviews.source')}
))}
); } window.ReviewsSection = ReviewsSection;