feat: upgrade schedule with cross-location views, day/time filters, and clickable trainers
- Add "Все студии" tab merging all locations by weekday with location sub-headers - Location tabs show hall name + address subtitle for clarity - Add day multi-select and time-of-day preset filters (Утро/День/Вечер) behind collapsible "Когда" button - Make trainer and type names clickable in day cards for inline filtering - Add group view clustering classes by trainer+type+location - Remove trainer dropdown from filter bar — filter by clicking names in schedule - Add searchable icon picker and lucide-react icon rendering for classes admin/section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { Flame, Sparkles, Wind, Zap, Star, Monitor } from "lucide-react";
|
||||
import { icons } from "lucide-react";
|
||||
import { SectionHeading } from "@/components/ui/SectionHeading";
|
||||
import { Reveal } from "@/components/ui/Reveal";
|
||||
import { ShowcaseLayout } from "@/components/ui/ShowcaseLayout";
|
||||
@@ -9,14 +9,15 @@ import { useShowcaseRotation } from "@/hooks/useShowcaseRotation";
|
||||
import type { ClassItem, SiteContent } from "@/types";
|
||||
import { UI_CONFIG } from "@/lib/config";
|
||||
|
||||
const iconMap: Record<string, React.ReactNode> = {
|
||||
flame: <Flame size={20} />,
|
||||
sparkles: <Sparkles size={20} />,
|
||||
wind: <Wind size={20} />,
|
||||
zap: <Zap size={20} />,
|
||||
star: <Star size={20} />,
|
||||
monitor: <Monitor size={20} />,
|
||||
};
|
||||
// kebab "heart-pulse" → PascalCase "HeartPulse"
|
||||
function toPascal(kebab: string) {
|
||||
return kebab.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
||||
}
|
||||
|
||||
function getIcon(key: string) {
|
||||
const Icon = icons[toPascal(key) as keyof typeof icons];
|
||||
return Icon ? <Icon size={20} /> : null;
|
||||
}
|
||||
|
||||
interface ClassesProps {
|
||||
data: SiteContent["classes"];
|
||||
@@ -60,7 +61,7 @@ export function Classes({ data: classes }: ClassesProps) {
|
||||
{/* Icon + name overlay */}
|
||||
<div className="absolute bottom-0 left-0 right-0 p-6">
|
||||
<div className="mb-2 inline-flex h-9 w-9 items-center justify-center rounded-lg bg-gold/20 text-gold-light backdrop-blur-sm">
|
||||
{iconMap[item.icon]}
|
||||
{getIcon(item.icon)}
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-white">
|
||||
{item.name}
|
||||
@@ -87,7 +88,7 @@ export function Classes({ data: classes }: ClassesProps) {
|
||||
: "bg-neutral-200/50 text-neutral-500 dark:bg-white/[0.06] dark:text-neutral-400"
|
||||
}`}
|
||||
>
|
||||
{iconMap[item.icon]}
|
||||
{getIcon(item.icon)}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<p
|
||||
|
||||
Reference in New Issue
Block a user