web-next: «Personalizar» abre panel granular de cookies (uw-cookie-details)
El botón Personalizar del banner ahora despliega un panel con checkboxes por
categoría (Necesarias fija+desactivada, Analíticas, Marketing) y «Guardar
preferencias», tal como el markup del usuario. Al guardar, escribe la cookie
uw_cookie_consent con la selección granular y sincroniza con Zaraz. Categorías
alineadas a las del panel (Necesarias/Analíticas/Marketing); ConsentStatus y
acceptAll/rejectAll usan las mismas. Estilos del panel en globals.css.
Verificado: Personalizar abre el panel, marcar Analíticas + Guardar deja la
cookie {necessary,analytics:true,marketing:false} y /cookies lo refleja.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -262,6 +262,52 @@ textarea:focus {
|
||||
border-color: #5c2b2b;
|
||||
color: #d98c8c;
|
||||
}
|
||||
.uw-cookie-btn-save {
|
||||
border-color: #b17c02;
|
||||
color: #f0b93f;
|
||||
}
|
||||
.uw-cookie-btn-save:hover {
|
||||
background: hsla(40, 90%, 45%, 0.15);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Panel «Personalizar» del banner (checkboxes por categoría). */
|
||||
.uw-cookie-details {
|
||||
margin-top: 14px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #352e2b;
|
||||
}
|
||||
.uw-cookie-category {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.uw-cookie-category label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.uw-cookie-category input[type='checkbox'] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
accent-color: #d79602;
|
||||
cursor: pointer;
|
||||
}
|
||||
.uw-cookie-category input[type='checkbox']:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
.uw-cookie-cat-name {
|
||||
color: #ebdec2;
|
||||
font-size: 15px;
|
||||
}
|
||||
.uw-cookie-category p {
|
||||
color: #b1997f;
|
||||
font-size: 13px;
|
||||
margin: 2px 0 0 24px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.uw-cookie-actions-detail {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Panel «Tu estado de consentimiento» en /cookies (datos de la API de Zaraz). */
|
||||
.uw-consent-status {
|
||||
|
||||
@@ -27,12 +27,11 @@ declare global {
|
||||
}
|
||||
|
||||
// Categorías de consentimiento (necesarias siempre activas).
|
||||
type Category = { key: string; label: string; always?: boolean }
|
||||
type Category = { key: string; label: string; always?: boolean; desc?: string }
|
||||
export const CONSENT_CATEGORIES: readonly Category[] = [
|
||||
{ key: 'necessary', label: 'Necesarias', always: true },
|
||||
{ key: 'preferences', label: 'Preferencias' },
|
||||
{ key: 'analytics', label: 'Analíticas' },
|
||||
{ key: 'marketing', label: 'Marketing' },
|
||||
{ key: 'necessary', label: 'Necesarias', always: true, desc: 'Esenciales para el funcionamiento del sitio. No se pueden desactivar.' },
|
||||
{ key: 'analytics', label: 'Analíticas', desc: 'Nos ayudan a entender cómo usas el sitio para mejorarlo.' },
|
||||
{ key: 'marketing', label: 'Marketing', desc: 'Se utilizan para mostrarte anuncios relevantes.' },
|
||||
]
|
||||
|
||||
type Consent = Record<string, boolean>
|
||||
@@ -79,12 +78,6 @@ function acceptAll() {
|
||||
function rejectAll() {
|
||||
writeConsent(allFlags(false))
|
||||
}
|
||||
/** Abre el modal granular de Zaraz; si no está, lleva a la página de cookies. */
|
||||
function customize() {
|
||||
const c = zaraz()
|
||||
if (c) c.modal = true
|
||||
else if (typeof window !== 'undefined') window.location.href = '/cookies'
|
||||
}
|
||||
function showBanner() {
|
||||
window.dispatchEvent(new CustomEvent(SHOW_EVENT))
|
||||
}
|
||||
@@ -101,12 +94,22 @@ function revokeConsent() {
|
||||
// ---------------------------------------------------------------------------
|
||||
export function CookieBanner() {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [details, setDetails] = useState(false)
|
||||
// Estado de los checkboxes granulares (categorías no necesarias).
|
||||
const [prefs, setPrefs] = useState<Consent>({ analytics: false, marketing: false })
|
||||
|
||||
useEffect(() => {
|
||||
window.UWCookies = { showBanner, revokeConsent, acceptAll, rejectAll }
|
||||
// Aparece si aún no hay decisión guardada.
|
||||
if (!readConsent()) setVisible(true)
|
||||
const onShow = () => setVisible(true)
|
||||
// Precarga los checkboxes con lo ya guardado (si lo hay).
|
||||
const saved = readConsent()
|
||||
if (saved) setPrefs({ analytics: !!saved.analytics, marketing: !!saved.marketing })
|
||||
else setVisible(true) // Aparece si aún no hay decisión guardada.
|
||||
const onShow = () => {
|
||||
const cur = readConsent()
|
||||
if (cur) setPrefs({ analytics: !!cur.analytics, marketing: !!cur.marketing })
|
||||
setDetails(false)
|
||||
setVisible(true)
|
||||
}
|
||||
const onChange = () => {
|
||||
if (readConsent()) setVisible(false)
|
||||
}
|
||||
@@ -120,16 +123,50 @@ export function CookieBanner() {
|
||||
|
||||
if (!visible) return null
|
||||
|
||||
function savePrefs() {
|
||||
writeConsent({ necessary: true, analytics: !!prefs.analytics, marketing: !!prefs.marketing })
|
||||
setVisible(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="uw-cookie-content" role="dialog" aria-label="Consentimiento de cookies">
|
||||
<div className="uw-cookie-text">
|
||||
<h3>Utilizamos cookies</h3>
|
||||
<p>Este sitio utiliza cookies propias y de terceros para garantizar el funcionamiento del sitio, analizar el tráfico y ofrecerte publicidad personalizada. Consulta nuestra política de cookies para más información.</p>
|
||||
<Link href="/cookies" className="uw-cookie-link">Política de Cookies</Link>
|
||||
|
||||
{details && (
|
||||
<div className="uw-cookie-details" style={{ display: 'block' }}>
|
||||
<div className="uw-cookie-category">
|
||||
<label>
|
||||
<input type="checkbox" checked disabled readOnly />
|
||||
<span className="uw-cookie-cat-name">Necesarias</span>
|
||||
</label>
|
||||
<p>Esenciales para el funcionamiento del sitio. No se pueden desactivar.</p>
|
||||
</div>
|
||||
<div className="uw-cookie-category">
|
||||
<label>
|
||||
<input type="checkbox" id="uw-cookie-analytics" checked={!!prefs.analytics} onChange={(e) => setPrefs((s) => ({ ...s, analytics: e.target.checked }))} />
|
||||
<span className="uw-cookie-cat-name">Analíticas</span>
|
||||
</label>
|
||||
<p>Nos ayudan a entender cómo usas el sitio para mejorarlo.</p>
|
||||
</div>
|
||||
<div className="uw-cookie-category">
|
||||
<label>
|
||||
<input type="checkbox" id="uw-cookie-marketing" checked={!!prefs.marketing} onChange={(e) => setPrefs((s) => ({ ...s, marketing: e.target.checked }))} />
|
||||
<span className="uw-cookie-cat-name">Marketing</span>
|
||||
</label>
|
||||
<p>Se utilizan para mostrarte anuncios relevantes.</p>
|
||||
</div>
|
||||
<div className="uw-cookie-actions-detail">
|
||||
<button type="button" className="uw-cookie-btn uw-cookie-btn-save" data-action="save" onClick={savePrefs}>Guardar preferencias</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="uw-cookie-actions">
|
||||
<button type="button" className="uw-cookie-btn uw-cookie-btn-reject" data-action="reject" onClick={() => { rejectAll(); setVisible(false) }}>Rechazar</button>
|
||||
<button type="button" className="uw-cookie-btn uw-cookie-btn-customize" data-action="customize" onClick={customize}>Personalizar</button>
|
||||
<button type="button" className="uw-cookie-btn uw-cookie-btn-customize" data-action="customize" onClick={() => setDetails((v) => !v)}>Personalizar</button>
|
||||
<button type="button" className="uw-cookie-btn uw-cookie-btn-accept" data-action="accept" onClick={() => { acceptAll(); setVisible(false) }}>Aceptar todas</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user