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
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}`}
onClick={props.onClick}
style={{
fontSize: "18px",
lineHeight: "1.2",
padding: "20px 40px",
minWidth: "280px",
clipPath:
"polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px)",
border: "none",
+3 -3
View File
@@ -73,7 +73,7 @@ function DateBox() {
className="bg-white text-black px-6 py-2 inline-block"
style={{
transform: "skewX(-15deg)",
fontSize: "2.5vw", // Changed from 40px to 2.5vw
fontSize: "2vw", // Changed from 40px to 2.5vw
lineHeight: "1.2",
filter: `
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"
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 */}
<div className="flex items-center" style={{ gap: "40px" }}>
<div className="flex flex-row items-center space-x-16">
<CoverHeading>ФЕСТИВАЛЬ</CoverHeading>
<DateBox />
</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-col min-w-2/3 justify-start items-start">
<Button shadowEnabled={false} variant="blue">
<Button
onClick={() => {
console.log("test");
}}
shadowEnabled={false}
variant="blue"
>
смотреть весь фотоотчёт
</Button>
</div>
+86 -2
View File
@@ -1,10 +1,69 @@
/* eslint-disable @next/next/no-img-element */
import { fluxgore, gothampro } from "@/utils/fonts";
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() {
const [activeVenue, setActiveVenue] = useState("главная площадка");
const venues = [
{ name: "главная площадка" },
{ name: "мотокросс" },
{ name: "картинг" },
{ name: "Детская площадка" },
{ name: "выставка" },
{ name: "мфт" },
];
return (
<div className="bg-[#F4F4F4] relative pt-20">
<div className="bg-[#F4F4F4] relative pt-20 pb-32">
<div className="container mx-auto">
<div className="flex flex-row justify-between">
<h1
@@ -33,10 +92,35 @@ function Scheme() {
<Button shadowEnabled={false} variant="blue_alt">
5 сентября
</Button>
<Button shadowEnabled={false} variant="blue">
<Button shadowEnabled={false} variant="blue_alt">
5 сентября
</Button>
</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>
);
+2 -2
View File
@@ -35,7 +35,7 @@ function Video() {
}}
>
<img
className="absolute top-0 object-cover"
className="absolute top-0 right-0 object-cover"
src="/images/video/arrows.svg"
alt="Lines"
/>
@@ -86,7 +86,7 @@ function Video() {
</div>
<img
className="absolute bottom-0"
className="absolute bottom-0 object-cover"
src="/images/video/paper_tear.png"
alt="Paper tear"
/>
+2
View File
@@ -1,4 +1,5 @@
import Cover from "@/components/Cover";
import Events from "@/components/Events";
import Info from "@/components/Info";
import Navbar from "@/components/Navbar";
import Scheme from "@/components/Scheme";
@@ -13,6 +14,7 @@ export default function Home() {
<Info />
<Video />
<Scheme />
<Events />
</main>
</>
);