feat: enhance Scheme component to handle schedule data and improve venue/date selection
This commit is contained in:
+77
-34
@@ -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
@@ -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 />
|
||||||
|
|||||||
Reference in New Issue
Block a user