feat: enhance Scheme component to handle schedule data and improve venue/date selection

This commit is contained in:
2025-08-26 22:05:44 +05:00
parent ea065d86a0
commit 5338c94aa0
2 changed files with 126 additions and 37 deletions
+77 -34
View File
@@ -1,7 +1,19 @@
/* eslint-disable @next/next/no-img-element */ /* eslint-disable @next/next/no-img-element */
import { fluxgore, gothampro } from "@/utils/fonts"; import { fluxgore, gothampro } from "@/utils/fonts";
import Button from "./Button"; import Button from "./Button";
import { ReactNode, useState } from "react"; import { ReactNode, useState, useMemo } from "react";
interface ScheduleData {
date: string;
location: string;
start: string;
stop: string;
activity: string;
}
interface SchemeProps {
scheduleData?: ScheduleData[];
}
interface SchemeSelectProps { interface SchemeSelectProps {
children: ReactNode; children: ReactNode;
@@ -16,7 +28,8 @@ function SchemeSelect({
}: SchemeSelectProps) { }: SchemeSelectProps) {
const baseClasses = `${fluxgore.className} leading-none cursor-pointer transition-all duration-300 ease-in-out hover:opacity-80 transform hover:scale-105 uppercase`; const baseClasses = `${fluxgore.className} leading-none cursor-pointer transition-all duration-300 ease-in-out hover:opacity-80 transform hover:scale-105 uppercase`;
const activeClasses = "text-[#1E1E1E] text-2xl md:text-4xl"; const activeClasses = "text-[#1E1E1E] text-2xl md:text-4xl";
const inactiveClasses = "text-[#0D0D0D] text-base md:text-xl opacity-50 self-end"; const inactiveClasses =
"text-[#0D0D0D] text-base md:text-xl opacity-50 self-end";
return ( return (
<p <p
@@ -50,18 +63,51 @@ function SchemeItem({ time, title }: SchemeItemProps) {
); );
} }
function Scheme() { function Scheme({ scheduleData = [] }: SchemeProps) {
const [activeVenue, setActiveVenue] = useState("главная площадка"); // Extract unique dates and venues from schedule data
const { uniqueDates, uniqueVenues } = useMemo(() => {
const dates = [...new Set(scheduleData.map((item) => item.date))];
const venues = [ const venues = [
{ name: "главная площадка" }, ...new Set(scheduleData.map((item) => item.location.toLowerCase())),
{ name: "мотокросс" },
{ name: "картинг" },
{ name: "Детская площадка" },
{ name: "выставка" },
{ name: "мфт" },
]; ];
return {
uniqueDates: dates,
uniqueVenues: venues.length > 0 ? venues : ["главная площадка"],
};
}, [scheduleData]);
const [activeVenue, setActiveVenue] = useState(
uniqueVenues[0] || "главная площадка"
);
const [activeDate, setActiveDate] = useState(uniqueDates[0] || "5 сентября");
// Filter schedule items based on active venue and date
const filteredSchedule = useMemo(() => {
return scheduleData.filter(
(item) =>
item.location.toLowerCase() === activeVenue && item.date === activeDate
);
}, [scheduleData, activeVenue, activeDate]);
// Fallback data if no schedule provided
const fallbackSchedule = [
{ start: "10:00", stop: "10:30", activity: "Открытие фестиваля" },
{ start: "10:30", stop: "11:00", activity: "Приветственная речь" },
{ start: "11:00", stop: "12:00", activity: "Основная программа" },
];
const displaySchedule =
filteredSchedule.length > 0
? filteredSchedule.map((item) => ({
time: `${item.start}-${item.stop}`,
title: item.activity,
}))
: fallbackSchedule.map((item) => ({
time: `${item.start}-${item.stop}`,
title: item.activity,
}));
return ( return (
<div className="bg-[#F4F4F4] relative pt-10 md:pt-20 pb-16 md:pb-32 px-4 md:px-0"> <div className="bg-[#F4F4F4] relative pt-10 md:pt-20 pb-16 md:pb-32 px-4 md:px-0">
<div className="container mx-auto"> <div className="container mx-auto">
@@ -85,41 +131,38 @@ function Scheme() {
className="mt-10 md:mt-20 w-full h-auto" className="mt-10 md:mt-20 w-full h-auto"
/> />
{/* Date Selection */}
<div className="flex flex-col md:flex-row mt-10 md:mt-40 space-y-3 md:space-y-0 md:space-x-5 items-center justify-center"> <div className="flex flex-col md:flex-row mt-10 md:mt-40 space-y-3 md:space-y-0 md:space-x-5 items-center justify-center">
<Button shadowEnabled={false} variant="blue"> {uniqueDates.map((date) => (
5 сентября <Button
</Button> key={date}
<Button shadowEnabled={false} variant="blue_alt"> shadowEnabled={false}
5 сентября variant={date === activeDate ? "blue" : "blue_alt"}
</Button> onClick={() => setActiveDate(date)}
<Button shadowEnabled={false} variant="blue_alt"> >
5 сентября {date}
</Button> </Button>
))}
</div> </div>
{/* Venue Selection */}
<div className="flex flex-wrap md:flex-row mt-8 md:mt-14 gap-3 md:gap-0 md:space-x-12 justify-center min-h-10"> <div className="flex flex-wrap md:flex-row mt-8 md:mt-14 gap-3 md:gap-0 md:space-x-12 justify-center min-h-10">
{venues.map((venue) => ( {uniqueVenues.map((venue) => (
<SchemeSelect <SchemeSelect
key={venue.name} key={venue}
active={venue.name === activeVenue} active={venue === activeVenue}
onClick={() => setActiveVenue(venue.name)} onClick={() => setActiveVenue(venue)}
> >
{venue.name} {venue}
</SchemeSelect> </SchemeSelect>
))} ))}
</div> </div>
{/* Schedule Display */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-10 md:mt-20 max-w-4xl mx-auto"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-10 md:mt-20 max-w-4xl mx-auto">
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" /> {displaySchedule.map((item, index) => (
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" /> <SchemeItem key={index} time={item.time} title={item.title} />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" /> ))}
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
</div> </div>
</div> </div>
</div> </div>
+48 -2
View File
@@ -10,11 +10,57 @@ import Partners from "@/components/Partners";
import Scheme from "@/components/Scheme"; import Scheme from "@/components/Scheme";
import Video from "@/components/Video"; import Video from "@/components/Video";
import Head from "next/head"; import Head from "next/head";
import { act } from "react";
export default function Home() { export default function Home() {
const csvData = [
{
date: "5 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "10:00",
stop: "10:30",
activity: "Репетиция шоу",
},
{
date: "5 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "11:00",
stop: "11:30",
activity: "Открытие фестиваля",
},
{
date: "5 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "12:00",
stop: "13:00",
activity: "Показательные выступления",
},
{
date: "6 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "10:00",
stop: "10:30",
activity: "Репетиция шоу",
},
{
date: "6 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "10:00",
stop: "10:30",
activity: "Репетиция шоу",
},
{
date: "6 сентября",
location: "ГЛАВНАЯ ПЛОЩАДКА",
start: "10:00",
stop: "10:30",
activity: "Репетиция шоу",
},
// ... more data
];
return ( return (
<> <>
<Head> <Head>
<title>Фестиваль технических видов спорта</title> <title>Фестиваль технических видов спорта</title>
</Head> </Head>
@@ -23,7 +69,7 @@ export default function Home() {
<Cover /> <Cover />
<Info /> <Info />
<Video /> <Video />
{/* <Scheme /> */} <Scheme scheduleData={csvData} />
<Events /> <Events />
<Activities /> <Activities />
<Partners /> <Partners />