// ui.jsx — shared components: icons, Reveal, Nav, Footer, Newsletter, Toast, ProductCard const { useState, useEffect, useRef, useCallback } = React; /* ---------------- Icons (inline, stroke-based) ---------------- */ const I = { search: (p) => , user: (p) => , bag: (p) => , heart: (p) => , eye: (p) => , play: (p) => , arrow: (p) => , close: (p) => , menu: (p) => , star: (p) => , check: (p) => , truck: (p) => , refresh:(p) => , shield: (p) => , spark: (p) => , phone: (p) => , mail: (p) => , pin: (p) => , social: (p) => , }; /* ---------------- Aura model image slot ---------------- */ // A persistent drop target for the user's AI model imagery. function AuraSlot({ model, shape = "rect", radius, placeholder, src, ...rest }) { return ( ); } /* ---------------- Scroll reveal ---------------- */ function Reveal({ children, delay = 0, tag = "div", className = "", style = {} }) { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { el.classList.add("in"); io.unobserve(el); } }); }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" }); io.observe(el); return () => io.disconnect(); }, []); const Tag = tag; return {children}; } /* ---------------- Stars ---------------- */ function Stars({ n = 5 }) { return
{Array.from({ length: 5 }).map((_, i) => )}
; } const fmt = (n) => new Intl.NumberFormat("tr-TR").format(n) + " ₺"; /* ---------------- Nav ---------------- */ function Nav({ route, go, cartCount, onSearch }) { const [open, setOpen] = useState(false); const links = [ ["home", "Ana Sayfa"], ["collection", "Koleksiyon"], ["vton", "Sanal Deneme"], ["story", "Hikâye"], ]; return (
{open && ( <>
setOpen(false)}>
BILGEAURA
{links.map(([r, t]) => ( ))}
)}
); } /* ---------------- Product card ---------------- */ function ProductCard({ p, go, onQuick, onFav, onAdd }) { return (
go("product", p.id)}>
{p.badge && {p.badge}}
{p.name}
{p.cat}
{p.old && {fmt(p.old)}} {fmt(p.price)}
); } /* ---------------- Newsletter ---------------- */ function Newsletter({ onToast }) { const [val, setVal] = useState(""); return (

Bülten

Atölyeden ilk haberi siz alın.

Yeni koleksiyonlar, premium atölye ürünleri ve özel kampanyalar — gelen kutunuza, ayda en fazla iki kez.

{ e.preventDefault(); if (val) { onToast("Bültene abone oldunuz ✦"); setVal(""); } }}> setVal(e.target.value)} required aria-label="E-posta" />

Abone olarak KVKK aydınlatma metnini kabul etmiş olursunuz. Dilediğiniz zaman çıkabilirsiniz.

); } /* ---------------- Footer ---------------- */ function Footer({ go }) { return ( ); } /* ---------------- Toast host ---------------- */ function useToasts() { const [toasts, setToasts] = useState([]); const push = useCallback((msg) => { const id = Math.random().toString(36).slice(2); setToasts((t) => [...t, { id, msg }]); setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2600); }, []); const node = (
{toasts.map((t) =>
{t.msg}
)}
); return [push, node]; } Object.assign(window, { I, AuraSlot, Reveal, Stars, fmt, Nav, ProductCard, Newsletter, Footer, useToasts });