import React, { useEffect, useMemo, useRef, useState } from "react";
import { Check, ArrowRight } from "lucide-react";
const cn = (...classes) => classes.filter(Boolean).join(" ");
const Button = ({ children, variant = "primary", className, ...props }) => {
const base =
"inline-flex items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold transition active:scale-[0.99]";
const styles = {
primary:
"bg-zinc-900 text-white hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-zinc-300",
secondary:
"bg-white text-zinc-900 border border-zinc-200 hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-zinc-200",
};
return (
);
};
const Currency = ({ value }) => {
const formatted = useMemo(() => {
const s = String(value);
return s.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}, [value]);
return
{formatted} ₽;
};
const PricingCard = ({ plan, highlight, onSelect }) => (
{plan.name}
{plan.subtitle}
Вы получаете
{plan.items.map((it, idx) => (
- {it}
))}
Съёмка
{plan.shooting}
Продление: {plan.overtime}
);
const FAQItem = ({ q, a }) => (
{q} +
{a}
);
export default function WeddingPricingNotionStyle() {
const [toast, setToast] = useState(null);
const toastTimerRef = useRef(null);
useEffect(() => {
return () => {
if (toastTimerRef.current) window.clearTimeout(toastTimerRef.current);
};
}, []);
const plans = useMemo(
() => [
{
id: "S",
name: "S",
subtitle: "1 оператор (съёмка только необходимых для монтажа кадров) · до 8 часов",
price: 80000,
items: [
"Тизер в вертикальном формате до 1 мин",
"Рилзы 10–15 секунд (до 10 шт)",
"Срок монтажа от 1 до 5 дней",
"Исходные материалы",
],
shooting: "1 оператор · до 8 часов",
overtime: "10 000 ₽/час",
},
{
id: "M",
name: "M",
subtitle: "1 оператор · до 10 часов",
price: 150000,
items: ["Авторский фильм 5–10 минут", "Тизер до 1 минуты", "Исходные материалы"],
shooting: "1 оператор · до 10 часов",
overtime: "15 000 ₽/час",
},
{
id: "L",
name: "L",
subtitle: "2 оператора · до 10 часов",
price: 200000,
items: ["Авторский фильм 7–12 минут", "Тизер до 1 минуты", "Исходные материалы"],
shooting: "2 оператора · до 10 часов",
overtime: "20 000 ₽/час",
},
{
id: "XL",
name: "XL",
subtitle: "3 оператора · работа осветителя (гаффера) · до 10 часов",
price: 250000,
items: [
"Фильм 10–15 минут",
"Тизер до 1 минуты",
"Рилзы 10–15 секунд (до 15 шт)",
"Исходные материалы",
],
shooting: "3 оператора + гаффер · до 10 часов",
overtime: "25 000 ₽/час",
},
],
[]
);
const faqs = useMemo(
() => [
{
q: "Что значит “исходные материалы”?",
a: "Все исходники со съёмки в исходном качестве (без цветокоррекции). Передача через облако или на ваш SSD.",
},
{
q: "Можно ли добавить второй день?",
a: "Да. Добавляем отдельной строкой или считаем продлением по часам — как удобнее по таймингу.",
},
{
q: "Есть ли доп. услуги?",
a: "Архивный фильм — 50 000 ₽, SDE — 45 000 ₽, срочный монтаж (5 дней) — 80 000 ₽.",
},
],
[]
);
const onSelect = (plan) => {
setToast(`Выбрано: ${plan.name}`);
if (toastTimerRef.current) window.clearTimeout(toastTimerRef.current);
toastTimerRef.current = window.setTimeout(() => setToast(null), 2200);
};
return (
Wedding Packages
Свадебные пакеты
S / M / L / XL — структура как в прайсе. Без лишнего.
Дополнительно
Архивный фильм — 50 000 ₽ · SDE — 45 000 ₽ · Срочный монтаж (5 дней) — 80 000 ₽
Безнал +10% (налог), если нужен счёт.
FAQ
Коротко про процесс и материалы.
{faqs.map((f, idx) => (
))}
{toast ? (
) : null}
);
}