feat: add Events component with EventCard for displaying event details

This commit is contained in:
2025-07-16 23:09:26 +09:00
parent 5e754ab800
commit 0c815c53e2
9 changed files with 192 additions and 9 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

+4 -1
View File
@@ -43,13 +43,16 @@ export default function Button(props: ButtonProps) {
{/* Button */} {/* Button */}
<button <button
className={`${getButtonStyles()} inline-block relative transition-all duration-150 ease-in-out ${ className={`${getButtonStyles()} inline-block relative transition-all duration-150 ease-in-out ${
shadowEnabled ? "active:translate-x-1 active:translate-y-1" : "" shadowEnabled
? "active:translate-x-1 active:translate-y-1"
: "hover:scale-105 active:scale-95"
} ${props.className}`} } ${props.className}`}
onClick={props.onClick} onClick={props.onClick}
style={{ style={{
fontSize: "18px", fontSize: "18px",
lineHeight: "1.2", lineHeight: "1.2",
padding: "20px 40px", padding: "20px 40px",
minWidth: "280px",
clipPath: clipPath:
"polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px)", "polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px)",
border: "none", border: "none",
+3 -3
View File
@@ -73,7 +73,7 @@ function DateBox() {
className="bg-white text-black px-6 py-2 inline-block" className="bg-white text-black px-6 py-2 inline-block"
style={{ style={{
transform: "skewX(-15deg)", transform: "skewX(-15deg)",
fontSize: "2.5vw", // Changed from 40px to 2.5vw fontSize: "2vw", // Changed from 40px to 2.5vw
lineHeight: "1.2", lineHeight: "1.2",
filter: ` filter: `
drop-shadow(8px 8px 0px black) drop-shadow(8px 8px 0px black)
@@ -98,9 +98,9 @@ function Cover() {
className="bg-cover bg-center bg-no-repeat relative justify-center items-center py-36" className="bg-cover bg-center bg-no-repeat relative justify-center items-center py-36"
style={{ backgroundImage: "url('/images/cover.svg')" }} style={{ backgroundImage: "url('/images/cover.svg')" }}
> >
<div className="container mx-auto max-w-5/6 mb-24"> <div className="container mx-auto max-w-5/7 mb-24">
{/* Top row with ФЕСТИВАЛЬ and date box */} {/* Top row with ФЕСТИВАЛЬ and date box */}
<div className="flex items-center" style={{ gap: "40px" }}> <div className="flex flex-row items-center space-x-16">
<CoverHeading>ФЕСТИВАЛЬ</CoverHeading> <CoverHeading>ФЕСТИВАЛЬ</CoverHeading>
<DateBox /> <DateBox />
</div> </div>
+88
View File
@@ -0,0 +1,88 @@
/* eslint-disable @next/next/no-img-element */
import { fluxgore, gothampro } from "@/utils/fonts";
import Button from "./Button";
interface EventCardProps {
image: string;
title: string;
description: string;
link: string;
}
function EventCard(props: EventCardProps) {
return (
<div className="flex flex-row bg-[#272727] py-5 px-2.5">
<div className="w-1/3">
<img
className="w-2/3 h-auto object-cover"
src={props.image}
alt={props.title}
/>
</div>
<div className="w-1/3">
<h2
className={`${fluxgore.className} text-4xl text-white leading-none`}
>
{props.title}
</h2>
<p
className={`${gothampro.className} text-[#E6E6E6] text-base mt-6 leading-none`}
>
{props.description}
</p>
</div>
<div className="flex justify-end w-1/3">
<Button variant="blue" shadowEnabled={false}>
регистрация
</Button>
</div>
</div>
);
}
function Events() {
return (
<div
className="bg-[#161616] relative pt-64 pb-32"
style={{
backgroundImage: `url('/images/noise.svg')`,
backgroundSize: "cover",
backgroundRepeat: "repeat",
backgroundBlendMode: "overlay",
}}
>
<img
className="absolute top-0 object-cover"
src="/images/events/paper_tear.png"
alt="Paper tear"
/>
<div className="container mx-auto">
<div className="flex flex-row justify-between">
<div className={fluxgore.className}>
<h1 className="text-7xl text-white relative">что вас ждет</h1>
</div>
<p
className={`${gothampro.className} text-[#E6E6E6] opacity-90 text-xl max-w-[536px] leading-none self-end`}
>
[Для участия в соревнованиях нажмите кнопку регистрация]
</p>
</div>
<div className="flex flex-col space-y-7 mt-36">
<EventCard
image="/events/yuka.png"
title="YUKA Drive Fest Джимхана"
description="YUKA Drive Fest Джимхана впервые врывается в Москву, и местом его дебюта станет наш Фестиваль технических видов спорта!
Это не просто гонки, это настоящий танец на асфальте, где мастерство водителя и мощь автомобиля сливаются воедино.
Под чутким руководством и вдохновляющим присутствием легендарного Аркадия Цареградцева, амбассадора и супер-босса соревнований, лучшие джимханисты страны покажут невероятные трюки, демонстрируя виртуозное владение машиной. Скорость, точность, дым из-под колес и филигранные маневры в ограниченном пространстве – вот что такое Джимхана."
link="#"
/>
</div>
</div>
</div>
);
}
export default Events;
+7 -1
View File
@@ -64,7 +64,13 @@ function Info() {
<div className="flex-1 basis-1/3"></div> <div className="flex-1 basis-1/3"></div>
<div className="flex-col min-w-2/3 justify-start items-start"> <div className="flex-col min-w-2/3 justify-start items-start">
<Button shadowEnabled={false} variant="blue"> <Button
onClick={() => {
console.log("test");
}}
shadowEnabled={false}
variant="blue"
>
смотреть весь фотоотчёт смотреть весь фотоотчёт
</Button> </Button>
</div> </div>
+86 -2
View File
@@ -1,10 +1,69 @@
/* 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";
interface SchemeSelectProps {
children: ReactNode;
active?: boolean;
onClick?: () => void;
}
function SchemeSelect({
children,
active = false,
onClick,
}: SchemeSelectProps) {
const baseClasses = `${fluxgore.className} leading-none cursor-pointer transition-all duration-300 ease-in-out hover:opacity-80 transform hover:scale-105`;
const activeClasses = "text-[#1E1E1E] text-4xl";
const inactiveClasses = "text-[#0D0D0D] text-xl opacity-50 self-end";
return (
<p
className={`${baseClasses} ${active ? activeClasses : inactiveClasses}`}
onClick={onClick}
>
{children}
</p>
);
}
interface SchemeItemProps {
time: string;
title: string;
}
function SchemeItem({ time, title }: SchemeItemProps) {
return (
<div className="flex flex-row items-center space-x-2.5">
<span
className={`${gothampro.className} text-white bg-[#1068B0] text-xl px-7 py-2.5`}
>
{time}
</span>
<span
className={`${gothampro.className} text-[#0D0D0D] text-xl font-medium`}
>
{title}
</span>
</div>
);
}
function Scheme() { function Scheme() {
const [activeVenue, setActiveVenue] = useState("главная площадка");
const venues = [
{ name: "главная площадка" },
{ name: "мотокросс" },
{ name: "картинг" },
{ name: "Детская площадка" },
{ name: "выставка" },
{ name: "мфт" },
];
return ( return (
<div className="bg-[#F4F4F4] relative pt-20"> <div className="bg-[#F4F4F4] relative pt-20 pb-32">
<div className="container mx-auto"> <div className="container mx-auto">
<div className="flex flex-row justify-between"> <div className="flex flex-row justify-between">
<h1 <h1
@@ -33,10 +92,35 @@ function Scheme() {
<Button shadowEnabled={false} variant="blue_alt"> <Button shadowEnabled={false} variant="blue_alt">
5 сентября 5 сентября
</Button> </Button>
<Button shadowEnabled={false} variant="blue"> <Button shadowEnabled={false} variant="blue_alt">
5 сентября 5 сентября
</Button> </Button>
</div> </div>
<div className="flex flex-row mt-14 space-x-12 justify-center">
{venues.map((venue) => (
<SchemeSelect
key={venue.name}
active={venue.name === activeVenue}
onClick={() => setActiveVenue(venue.name)}
>
{venue.name}
</SchemeSelect>
))}
</div>
<div className="grid grid-cols-2 gap-4 mt-20 max-w-4xl mx-auto">
<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="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
<SchemeItem time="10:00-10:30" title="Открытие фестиваля" />
</div>
</div> </div>
</div> </div>
); );
+2 -2
View File
@@ -35,7 +35,7 @@ function Video() {
}} }}
> >
<img <img
className="absolute top-0 object-cover" className="absolute top-0 right-0 object-cover"
src="/images/video/arrows.svg" src="/images/video/arrows.svg"
alt="Lines" alt="Lines"
/> />
@@ -86,7 +86,7 @@ function Video() {
</div> </div>
<img <img
className="absolute bottom-0" className="absolute bottom-0 object-cover"
src="/images/video/paper_tear.png" src="/images/video/paper_tear.png"
alt="Paper tear" alt="Paper tear"
/> />
+2
View File
@@ -1,4 +1,5 @@
import Cover from "@/components/Cover"; import Cover from "@/components/Cover";
import Events from "@/components/Events";
import Info from "@/components/Info"; import Info from "@/components/Info";
import Navbar from "@/components/Navbar"; import Navbar from "@/components/Navbar";
import Scheme from "@/components/Scheme"; import Scheme from "@/components/Scheme";
@@ -13,6 +14,7 @@ export default function Home() {
<Info /> <Info />
<Video /> <Video />
<Scheme /> <Scheme />
<Events />
</main> </main>
</> </>
); );