refactor: centralize gold tokens, extract sub-components, clean up unused code
- Replace hardcoded hex colors with gold/gold-light/gold-dark Tailwind tokens - Extract Schedule into DayCard, ScheduleFilters, MobileSchedule sub-components - Extract Team into TeamCarousel, TeamMemberInfo sub-components - Add UI_CONFIG for centralized magic numbers (timings, thresholds) - Add reusable IconBadge component, simplify Contact section - Convert Pricing clickable divs to semantic buttons for a11y - Remove unused SocialLinks, btn-outline, btn-ghost, nav-link CSS classes - Fix React setState-during-render error in TeamCarousel (deferred update pattern) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
60
src/components/sections/schedule/DayCard.tsx
Normal file
60
src/components/sections/schedule/DayCard.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Clock, User } from "lucide-react";
|
||||
import type { ScheduleDay } from "@/types/content";
|
||||
import { TYPE_DOT } from "./constants";
|
||||
|
||||
export function DayCard({ day }: { day: ScheduleDay }) {
|
||||
return (
|
||||
<div className="rounded-2xl border border-neutral-200 bg-white dark:border-white/[0.06] dark:bg-[#0a0a0a] overflow-hidden">
|
||||
{/* Day header */}
|
||||
<div className="border-b border-neutral-100 bg-neutral-50 px-5 py-4 dark:border-white/[0.04] dark:bg-white/[0.02]">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gold/10 text-sm font-bold text-gold-dark dark:bg-gold/10 dark:text-gold-light">
|
||||
{day.dayShort}
|
||||
</span>
|
||||
<span className="text-base font-semibold text-neutral-900 dark:text-white/90">
|
||||
{day.day}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Classes */}
|
||||
<div className="divide-y divide-neutral-100 dark:divide-white/[0.04]">
|
||||
{day.classes.map((cls, i) => (
|
||||
<div key={i} className={`px-5 py-3.5 ${cls.hasSlots ? "bg-emerald-500/5" : cls.recruiting ? "bg-sky-500/5" : ""}`}>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2 text-sm text-neutral-500 dark:text-white/40">
|
||||
<Clock size={13} />
|
||||
<span className="font-semibold">{cls.time}</span>
|
||||
</div>
|
||||
{cls.hasSlots && (
|
||||
<span className="shrink-0 rounded-full bg-emerald-500/15 border border-emerald-500/25 px-2 py-0.5 text-[10px] font-semibold text-emerald-600 dark:text-emerald-400">
|
||||
есть места
|
||||
</span>
|
||||
)}
|
||||
{cls.recruiting && (
|
||||
<span className="shrink-0 rounded-full bg-sky-500/15 border border-sky-500/25 px-2 py-0.5 text-[10px] font-semibold text-sky-600 dark:text-sky-400">
|
||||
набор
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-1.5 flex items-center gap-2 text-sm font-medium text-neutral-800 dark:text-white/80">
|
||||
<User size={13} className="shrink-0 text-neutral-400 dark:text-white/30" />
|
||||
{cls.trainer}
|
||||
</div>
|
||||
<div className="mt-2 flex items-center gap-2 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`h-2 w-2 shrink-0 rounded-full ${TYPE_DOT[cls.type] ?? "bg-white/30"}`} />
|
||||
<span className="text-xs text-neutral-500 dark:text-white/40">{cls.type}</span>
|
||||
</div>
|
||||
{cls.level && (
|
||||
<span className="rounded-full bg-rose-500/15 border border-rose-500/25 px-2 py-0.5 text-[10px] font-semibold text-rose-600 dark:text-rose-400">
|
||||
{cls.level}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user