feat: Instagram data sync, gold accent, SVG logo, FAQ & Pricing sections
- Sync all content from Instagram: fix addresses, trainer names, add 5 new trainers, remove 2 inactive, update class descriptions - Add FAQ section (11 Q&A items) and Pricing section (tabs: subscriptions, rental, rules) - Redesign with editorial magazine feel: centered headings, generous spacing, section glow effects, glassmorphism cards - Migrate entire accent palette from rose to warm gold (#c9a96e) - Replace low-res PNG logo with vector SVG traced via potrace — crisp at any size, animated gradient (black↔gold), heartbeat pulse animation - Make header brand name gold Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
139
src/components/sections/Pricing.tsx
Normal file
139
src/components/sections/Pricing.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { CreditCard, Building2, ScrollText } from "lucide-react";
|
||||
import { siteContent } from "@/data/content";
|
||||
import { SectionHeading } from "@/components/ui/SectionHeading";
|
||||
import { Reveal } from "@/components/ui/Reveal";
|
||||
|
||||
type Tab = "prices" | "rental" | "rules";
|
||||
|
||||
export function Pricing() {
|
||||
const { pricing } = siteContent;
|
||||
const [activeTab, setActiveTab] = useState<Tab>("prices");
|
||||
|
||||
const tabs: { id: Tab; label: string; icon: React.ReactNode }[] = [
|
||||
{ id: "prices", label: "Абонементы", icon: <CreditCard size={16} /> },
|
||||
{ id: "rental", label: "Аренда зала", icon: <Building2 size={16} /> },
|
||||
{ id: "rules", label: "Правила", icon: <ScrollText size={16} /> },
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="pricing" className="section-glow relative section-padding bg-neutral-50 dark:bg-[#050505]">
|
||||
<div className="section-divider absolute top-0 left-0 right-0" />
|
||||
<div className="section-container">
|
||||
<Reveal>
|
||||
<SectionHeading centered>{pricing.title}</SectionHeading>
|
||||
</Reveal>
|
||||
|
||||
{/* Tabs */}
|
||||
<Reveal>
|
||||
<div className="mt-12 flex flex-wrap justify-center gap-2">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={`inline-flex items-center gap-2 rounded-full px-6 py-2.5 text-sm font-medium transition-all duration-300 ${
|
||||
activeTab === tab.id
|
||||
? "bg-[#c9a96e] text-black shadow-lg shadow-[#c9a96e]/25"
|
||||
: "bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-white/[0.06] dark:text-neutral-300 dark:hover:bg-white/[0.1]"
|
||||
}`}
|
||||
>
|
||||
{tab.icon}
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
{/* Prices tab */}
|
||||
{activeTab === "prices" && (
|
||||
<Reveal>
|
||||
<div className="mx-auto mt-10 max-w-2xl">
|
||||
<p className="mb-8 text-center text-sm text-neutral-500 dark:text-neutral-400">
|
||||
{pricing.subtitle}
|
||||
</p>
|
||||
<div className="overflow-hidden rounded-2xl border border-neutral-200 dark:border-white/[0.06]">
|
||||
{pricing.items.map((item, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`group flex items-center justify-between gap-4 px-6 py-5 transition-colors hover:bg-neutral-50 dark:hover:bg-white/[0.03] ${
|
||||
i > 0 ? "border-t border-neutral-100 dark:border-white/[0.04]" : ""
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<p className="font-medium text-neutral-900 dark:text-white">
|
||||
{item.name}
|
||||
</p>
|
||||
{item.note && (
|
||||
<p className="mt-0.5 text-sm text-neutral-500 dark:text-neutral-400">
|
||||
{item.note}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<span className="shrink-0 font-display text-xl font-bold text-[#a08050] dark:text-[#d4b87a]">
|
||||
{item.price}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
|
||||
{/* Rental tab */}
|
||||
{activeTab === "rental" && (
|
||||
<Reveal>
|
||||
<div className="mx-auto mt-10 max-w-2xl">
|
||||
<div className="overflow-hidden rounded-2xl border border-neutral-200 dark:border-white/[0.06]">
|
||||
{pricing.rentalItems.map((item, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`group flex items-center justify-between gap-4 px-6 py-5 transition-colors hover:bg-neutral-50 dark:hover:bg-white/[0.03] ${
|
||||
i > 0 ? "border-t border-neutral-100 dark:border-white/[0.04]" : ""
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<p className="font-medium text-neutral-900 dark:text-white">
|
||||
{item.name}
|
||||
</p>
|
||||
{item.note && (
|
||||
<p className="mt-0.5 text-sm text-neutral-500 dark:text-neutral-400">
|
||||
{item.note}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<span className="shrink-0 font-display text-xl font-bold text-[#a08050] dark:text-[#d4b87a]">
|
||||
{item.price}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
|
||||
{/* Rules tab */}
|
||||
{activeTab === "rules" && (
|
||||
<Reveal>
|
||||
<div className="mx-auto mt-10 max-w-2xl space-y-4">
|
||||
{pricing.rules.map((rule, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex gap-4"
|
||||
>
|
||||
<span className="mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[#c9a96e]/10 text-xs font-bold text-[#a08050] dark:bg-[#c9a96e]/10 dark:text-[#d4b87a]">
|
||||
{i + 1}
|
||||
</span>
|
||||
<p className="text-sm leading-relaxed text-neutral-700 dark:text-neutral-300 sm:text-base">
|
||||
{rule}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user