// PDP, корзина, оформление const { useState: useStateS, useRef: useRefS, useEffect: useEffectS } = React; const useState = useStateS, useRef = useRefS, useEffect = useEffectS; // собрать медиа-галерею товара: ракурсы (фото) + видео, если оно есть function getGallery(p) { if (p.mediaItems) return getProductMedia(p); const media = []; if (p.video && p.videoFirst) media.push({ type: "video", src: p.video }); // До отбора новых материалов у кепок оставляем только чистую обложку, без старых вспомогательных кадров. const images = p.cat === "hats" && !p.approvedGallery && p.img ? [p.img] : p.images; if (images && images.length) images.forEach((src) => media.push({ type: "image", img: src })); else if (p.img) media.push({ type: "image", img: p.img }); else if (!p.video) { const angles = ["спереди", "сбоку", "деталь"]; angles.forEach((a) => media.push({ type: "image", ph: (p.ph || "фото") + " · " + a })); } if (p.video && !p.videoFirst) media.push({ type: "video", src: p.video }); if (p.videos) p.videos.forEach((src) => media.push({ type: "video", src })); return media; } function ProductView({ p, go, onAdd }) { const [ci, setCi] = useState(0); const [si, setSi] = useState(0); const [mi, setMi] = useState(0); const related = BATONS_PRODUCTS.filter((x) => x.cat === p.cat && x.id !== p.id).slice(0, 4); const gallery = getGallery(p); useEffect(() => { setMi(0); }, [p.id]); const active = gallery[Math.min(mi, gallery.length - 1)] || gallery[0] || { type: "image", ph: "медиа не добавлено" }; return (
{active.type === "video" ?
{gallery.length > 1 && (
{gallery.map((m, i) => ( ))}
)}
{p.brand && BATONS'ON · собственное производство}

{p.name}

{p.sub}

{RUB(p.price)} {p.old && {RUB(p.old)}} {p.old && выгода {RUB(p.old - p.price)}}
или 4 платежа по {RUB(Math.round(p.price / 4))} · Яндекс Сплит
Цвет
{p.sizes.map((s, i) => ( ))}
Доставка 1–3 дняСДЭК · Яндекс · Ozon · до двери или ПВЗ
Оплата как удобноСБП, картой или Яндекс Сплит частями
Примерка и возврат14 дней, бесплатно при заказе от 3 000 ₽

Другие модели

{related.map((r) => go({ name: "product", product: x })} onAdd={onAdd} />)}
); } function CartDrawer({ open, items, onClose, setQty, remove, go }) { const total = items.reduce((s, i) => s + i.price * i.qty, 0); const count = items.reduce((s, i) => s + i.qty, 0); return ( <>
); } function Checkout({ items, go, total, clear }) { const [ship, setShip] = useState("cdek-pvz"); const [pay, setPay] = useState("sbp"); const [done, setDone] = useState(false); const sum = items.reduce((s, i) => s + i.price * i.qty, 0); const shipCost = ship === "courier" ? 390 : ship === "ozon" ? 0 : 190; const SHIP = [ { k: "cdek-pvz", t: "СДЭК — пункт выдачи", d: "1–3 дня · 190 ₽", ico: "СДЭК" }, { k: "courier", t: "Яндекс Доставка — курьер", d: "сегодня–завтра · 390 ₽", ico: "Я.Дост" }, { k: "ozon", t: "Доставка Ozon", d: "2–4 дня · бесплатно", ico: "Ozon" }, ]; const PAY = [ { k: "sbp", t: "СБП", d: "по QR или ссылке, без комиссии" }, { k: "split", t: "Яндекс Сплит", d: "4 платежа по " + RUB(Math.round((sum + shipCost) / 4)) }, { k: "card", t: "Банковская карта", d: "Visa · Mastercard · МИР" }, ]; if (done) return (

Заказ оформлен

Мы отправили детали и трек-номер. Спасибо, что выбрали BATONS'ON.

); return (

Оформление

1 · Контакты

2 · Доставка

{SHIP.map((o) => ( ))}
{ship !== "ozon" && }

3 · Оплата

{PAY.map((o) => ( ))}
); } Object.assign(window, { ProductView, CartDrawer, Checkout });