);
}
// ============================================
// CART (localStorage)
// ============================================
function useCart() {
const [items, setItems] = useState(() => {
try { return JSON.parse(localStorage.getItem('cristhy-cart') || '[]'); } catch { return []; }
});
useEffect(() => {
localStorage.setItem('cristhy-cart', JSON.stringify(items));
}, [items]);
const add = (product) => setItems(prev => {
const idx = prev.findIndex(i => i.id === product.id);
if (idx >= 0) {
const copy = [...prev];
copy[idx] = { ...copy[idx], qty: copy[idx].qty + 1 };
return copy;
}
return [...prev, { ...product, qty: 1 }];
});
const remove = (id) => setItems(prev => prev.filter(i => i.id !== id));
const clear = () => setItems([]);
const total = items.reduce((s, i) => s + parseFloat(i.price) * i.qty, 0);
return { items, add, remove, clear, total };
}
function CartDrawer({ cart, open, onClose }) {
return (
);
}
function CartButton({ count, onClick }) {
return (
);
}
// ============================================
// POST DETAIL MODAL
// ============================================
function PostDetail({ post, onClose }) {
const [progress, setProgress] = useState(0);
const bodyRef = useRef(null);
useEffect(() => {
const el = bodyRef.current;
if (!el) return;
const onScroll = () => {
const total = el.scrollHeight - el.clientHeight;
setProgress(total > 0 ? (el.scrollTop / total) * 100 : 0);
};
el.addEventListener('scroll', onScroll);
return () => el.removeEventListener('scroll', onScroll);
}, [post]);
useEffect(() => {
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onKey);
document.body.style.overflow = post ? 'hidden' : '';
return () => {
window.removeEventListener('keydown', onKey);
document.body.style.overflow = '';
};
}, [post, onClose]);
if (!post) return null;
const body = `Hace seis meses convertimos una furgoneta vieja en hogar. Pintamos las paredes interiores con cal, pusimos una cocina pequeña, una cama que mira al horizonte y un panel solar que ya nos ha dado más de un disgusto.
La libertad existe, sí. Pero también el panel solar que se rompe un martes a las 7 de la mañana cuando estás en mitad de la nada. La gente pregunta mucho por la parte instagramable: la luz dorada, los desayunos al sol, los lugares con nombre raro.
Yo voy a contar lo otro: el día que se nos coló agua por la claraboya, el día que mi pareja me miró con ojos de "vámonos a casa", el día que descubrimos que en una furgo no caben todas las cosas que crees que necesitas.
Vivir despacio en cuatro ruedas no es huir. Es elegir mejor qué te llevas.`;
return (
);
}
// ============================================
// RECIPE DETAIL MODAL
// ============================================
function RecipeDetail({ recipe, onClose }) {
useEffect(() => {
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onKey);
document.body.style.overflow = recipe ? 'hidden' : '';
return () => {
window.removeEventListener('keydown', onKey);
document.body.style.overflow = '';
};
}, [recipe, onClose]);
if (!recipe) return null;
const ingredients = [
'300g de harina',
'200g de azúcar',
'4 huevos camperos',
'120ml de aceite de oliva virgen extra',
'Ralladura de 2 limones',
'1 yogur natural',
'Levadura química',
'Una pizca de sal',
];
const steps = [
'Precalienta el horno a 180°C con calor arriba y abajo.',
'Mezcla los huevos con el azúcar hasta que blanqueen.',
'Añade el aceite y el yogur. Bate suave.',
'Incorpora la harina con la levadura tamizadas. La ralladura al final.',
'Vuelca en molde engrasado. Hornea 45 minutos.',
'Deja enfriar en el molde 10 minutos antes de desmoldar.',
];
return (
e.stopPropagation()}>
{recipe.cat}
{recipe.title}
{recipe.time}Tiempo
6Raciones
FácilDificultad
Ingredientes
{ingredients.map((i, idx) =>
{i}
)}
Pasos
{steps.map((s, idx) =>
{String(idx + 1).padStart(2, '0')}{s}
)}
);
}
// ============================================
// NOW PLAYING WIDGET
// ============================================
function NowWidget() {
const items = [
{ icon: '🍳', label: 'Cocinando', text: 'Bizcocho de limón' },
{ icon: '📖', label: 'Leyendo', text: 'El cuento de la criada' },
{ icon: '🎧', label: 'Escuchando', text: 'Lana del Rey · Honeymoon' },
{ icon: '🌿', label: 'Plantando', text: 'Tomates cherry' },
];
const [idx, setIdx] = useState(0);
useEffect(() => {
const t = setInterval(() => setIdx(i => (i + 1) % items.length), 4000);
return () => clearInterval(t);
}, []);
return (