feat: add form components and exhibition registration page
- Implemented Checkbox, Input, Radio, Select, Textarea components for form handling. - Created exhibition registration page with integrated form components. - Added validation and state management for form inputs. - Included styles and accessibility features for better user experience.
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 3.8 MiB |
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 3.8 MiB |
|
After Width: | Height: | Size: 557 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 260 KiB |
@@ -0,0 +1 @@
|
|||||||
|
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import { fluxgore, gothampro } from "@/utils/fonts";
|
import { fluxgore, gothampro } from "@/utils/fonts";
|
||||||
import Button from "./Button";
|
import Button from "./Button";
|
||||||
|
|
||||||
interface EventCardProps {
|
interface EventCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
image: string;
|
image: string;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -11,7 +11,10 @@ interface EventCardProps {
|
|||||||
|
|
||||||
function EventCard(props: EventCardProps) {
|
function EventCard(props: EventCardProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col md:flex-row bg-[#272727] py-5 px-2.5 md:py-5 md:px-2.5 p-4">
|
<div
|
||||||
|
id={props.id}
|
||||||
|
className="flex flex-col md:flex-row bg-[#272727] py-5 px-2.5 md:py-5 md:px-2.5 p-4"
|
||||||
|
>
|
||||||
<div className="w-full md:w-1/3 mb-4 md:mb-0">
|
<div className="w-full md:w-1/3 mb-4 md:mb-0">
|
||||||
<img
|
<img
|
||||||
className="w-full md:w-2/3 h-auto object-cover rounded"
|
className="w-full md:w-2/3 h-auto object-cover rounded"
|
||||||
@@ -74,39 +77,30 @@ function Events() {
|
|||||||
|
|
||||||
<div className="flex flex-col space-y-4 md:space-y-7 mt-16 md:mt-36">
|
<div className="flex flex-col space-y-4 md:space-y-7 mt-16 md:mt-36">
|
||||||
<EventCard
|
<EventCard
|
||||||
|
id="yuka"
|
||||||
image="/events/yuka.png"
|
image="/events/yuka.png"
|
||||||
title="YUKA Drive Fest Джимхана"
|
title="YUKA Drive Fest Джимхана"
|
||||||
description="YUKA Drive Fest Джимхана впервые врывается в Москву, и местом его дебюта станет наш Фестиваль технических видов спорта!
|
description="YUKA Drive Fest Джимхана впервые врывается в Москву, и местом его дебюта станет наш Фестиваль технических видов спорта! Это не просто гонки, это настоящий танец на асфальте, где мастерство водителя и мощь автомобиля сливаются воедино. Под чутким руководством и вдохновляющим присутствием легендарного Аркадия Цареградцева, амбассадора и супер-босса соревнований, лучшие джимханисты страны покажут невероятные трюки, демонстрируя виртуозное владение машиной. Скорость, точность, дым из-под колес и филигранные маневры в ограниченном пространстве – вот что такое Джимхана."
|
||||||
Это не просто гонки, это настоящий танец на асфальте, где мастерство водителя и мощь автомобиля сливаются воедино.
|
|
||||||
Под чутким руководством и вдохновляющим присутствием легендарного Аркадия Цареградцева, амбассадора и супер-босса соревнований, лучшие джимханисты страны покажут невероятные трюки, демонстрируя виртуозное владение машиной. Скорость, точность, дым из-под колес и филигранные маневры в ограниченном пространстве – вот что такое Джимхана."
|
|
||||||
link="#"
|
link="#"
|
||||||
/>
|
/>
|
||||||
<EventCard
|
<EventCard
|
||||||
|
id="moscow_fight"
|
||||||
image="/events/moscow_fight.png"
|
image="/events/moscow_fight.png"
|
||||||
title="Дрифт«Битва за Москву»"
|
title="Дрифт«Битва за Москву»"
|
||||||
description="Любительский турнир по дрифту, который вырос из проекта «Дорога в дрифт», созданного в 2021 году для поиска новых талантов. За три года он превратился в полноценные соревнования с привлекательным призовым фондом.
|
description="Любительский турнир по дрифту, который вырос из проекта «Дорога в дрифт», созданного в 2021 году для поиска новых талантов. За три года он превратился в полноценные соревнования с привлекательным призовым фондом. Во второй день фестиваля, 8 сентября, пройдет дрифт-гонка, где главным призом станет электромобиль «Москвич». Соревнования проводятся по традиционной олимпийской системе. Чтобы принять участие, необходимо подать заявку на сайте и дождаться приглашения от организаторов."
|
||||||
Во второй день фестиваля, 8 сентября, пройдет дрифт-гонка, где главным призом станет электромобиль «Москвич».
|
|
||||||
Соревнования проводятся по традиционной олимпийской системе. Чтобы принять участие, необходимо подать заявку на сайте и дождаться приглашения от организаторов."
|
|
||||||
link="#"
|
link="#"
|
||||||
/>
|
/>
|
||||||
<EventCard
|
<EventCard
|
||||||
|
id="moto"
|
||||||
image="/events/moto.png"
|
image="/events/moto.png"
|
||||||
title="КуБок ШОС по Мотокроссу"
|
title="КуБок ШОС по Мотокроссу"
|
||||||
description="Уникальная возможность увидеть настоящую битву моторов и мастерства на трассе.
|
description="Уникальная возможность увидеть настоящую битву моторов и мастерства на трассе. Лучшие гонщики со всего мира соберутся, чтобы продемонстрировать невероятные прыжки, головокружительные виражи и бескомпромиссную борьбу за победу. Приготовьтесь к взрыву адреналина и незабываемым эмоциям, ведь Кубок ШОС по Мотокроссу обещает стать одним из самых ярких зрелищ фестиваля!"
|
||||||
|
|
||||||
Лучшие гонщики со всего мира соберутся, чтобы продемонстрировать невероятные прыжки, головокружительные виражи и бескомпромиссную борьбу за победу.
|
|
||||||
|
|
||||||
Приготовьтесь к взрыву адреналина и незабываемым эмоциям, ведь Кубок ШОС по Мотокроссу обещает стать одним из самых ярких зрелищ фестиваля!"
|
|
||||||
link="#"
|
link="#"
|
||||||
/>
|
/>
|
||||||
<EventCard
|
<EventCard
|
||||||
image="/events/cart.png"
|
image="/events/cart.png"
|
||||||
title="Кубок по Фиджитал картингу"
|
title="Кубок по Фиджитал картингу"
|
||||||
description="На Фестивале технических видов спорта 2025 впервые состоится Кубок по Фиджитал Картингу!
|
description="На Фестивале технических видов спорта 2025 впервые состоится Кубок по Фиджитал Картингу! Это уникальное состязание, где виртуальная реальность встречается с реальной трассой. Участники будут сражаться на симуляторах, а затем переносить свои навыки на настоящий картинг, демонстрируя невероятную адаптивность и мастерство."
|
||||||
|
|
||||||
Это уникальное состязание, где виртуальная реальность встречается с реальной трассой.
|
|
||||||
|
|
||||||
Участники будут сражаться на симуляторах, а затем переносить свои навыки на настоящий картинг, демонстрируя невероятную адаптивность и мастерство."
|
|
||||||
link="#"
|
link="#"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
import { fluxgore, gothampro } from "@/utils/fonts";
|
import { fluxgore, gothampro } from "@/utils/fonts";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
|
||||||
/* eslint-disable @next/next/no-img-element */
|
/* eslint-disable @next/next/no-img-element */
|
||||||
function Footer() {
|
function Footer() {
|
||||||
|
const scrollToElement = useCallback((elementId: string) => {
|
||||||
|
const element = document.getElementById(elementId);
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "start",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="bg-[#0D0D0D] py-16 md:py-36">
|
<footer className="bg-[#0D0D0D] py-16 md:py-36">
|
||||||
<div className="container mx-auto px-4 flex flex-col space-y-9">
|
<div className="container mx-auto px-4 flex flex-col space-y-9">
|
||||||
@@ -19,7 +30,7 @@ function Footer() {
|
|||||||
<ul className="flex space-x-2 items-center">
|
<ul className="flex space-x-2 items-center">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://t.me/your_channel"
|
href="https://t.me/moscow_drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-500/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-500/30"
|
||||||
@@ -34,7 +45,7 @@ function Footer() {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://vk.com/your_group"
|
href="https://vk.com/mos.drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-600/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-600/30"
|
||||||
@@ -49,7 +60,7 @@ function Footer() {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://youtube.com/@your_channel"
|
href="https://www.youtube.com/@mossportonline9438"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-red-500/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-red-500/30"
|
||||||
@@ -74,30 +85,30 @@ function Footer() {
|
|||||||
СОБЫТИЯ
|
СОБЫТИЯ
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
<Link
|
<button
|
||||||
href="/#cover"
|
onClick={() => scrollToElement("yuka")}
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200 text-left`}
|
||||||
>
|
>
|
||||||
YUKA Drive Fest
|
YUKA Drive Fest
|
||||||
</Link>
|
</button>
|
||||||
<Link
|
<Link
|
||||||
href="/#cover"
|
href="/#cover"
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
||||||
>
|
>
|
||||||
ЭКСПО
|
ЭКСПО
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<button
|
||||||
href="/#cover"
|
onClick={() => scrollToElement("moto")}
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200 text-left`}
|
||||||
>
|
>
|
||||||
Мотокросс
|
Мотокросс
|
||||||
</Link>
|
</button>
|
||||||
<Link
|
<button
|
||||||
href="/#cover"
|
onClick={() => scrollToElement("moscow_fight")}
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200 text-left`}
|
||||||
>
|
>
|
||||||
Дрифт Битва за Москву
|
Дрифт Битва за Москву
|
||||||
</Link>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -108,30 +119,18 @@ function Footer() {
|
|||||||
ИНФОРМАЦИЯ
|
ИНФОРМАЦИЯ
|
||||||
</h3>
|
</h3>
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
<Link
|
<button
|
||||||
href="/#about"
|
onClick={() => scrollToElement("info")}
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200 text-left`}
|
||||||
>
|
>
|
||||||
О фестивале
|
О фестивале
|
||||||
</Link>
|
</button>
|
||||||
<Link
|
<Link
|
||||||
href="/#program"
|
href="/#program"
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
||||||
>
|
>
|
||||||
Программа
|
Программа
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
|
||||||
href="/#tickets"
|
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
|
||||||
>
|
|
||||||
Билеты
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/#contacts"
|
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
|
||||||
>
|
|
||||||
Контакты
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -148,24 +147,18 @@ function Footer() {
|
|||||||
>
|
>
|
||||||
Регистрация
|
Регистрация
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<button
|
||||||
href="/#sponsors"
|
onClick={() => scrollToElement("partners")}
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200 text-left`}
|
||||||
>
|
>
|
||||||
Партнеры
|
Партнеры
|
||||||
</Link>
|
</button>
|
||||||
<Link
|
<Link
|
||||||
href="/#media"
|
href="https://forms.yandex.ru/u/6888b64502848f0274f5e9df"
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
||||||
>
|
>
|
||||||
Пресса
|
Пресса
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
|
||||||
href="/#volunteer"
|
|
||||||
className={`${gothampro.className} text-sm md:text-base text-[#E6E6E6] opacity-60 hover:text-blue-500 transition-colors duration-200`}
|
|
||||||
>
|
|
||||||
Волонтерство
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Button from "./Button";
|
|||||||
|
|
||||||
function Info() {
|
function Info() {
|
||||||
return (
|
return (
|
||||||
<div className={gothampro.className}>
|
<div id="info" className={gothampro.className}>
|
||||||
<div
|
<div
|
||||||
className="bg-[#161616] relative overflow-hidden px-4"
|
className="bg-[#161616] relative overflow-hidden px-4"
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function Navbar() {
|
|||||||
<ul className="hidden md:flex space-x-2 items-center">
|
<ul className="hidden md:flex space-x-2 items-center">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://t.me/your_channel"
|
href="https://t.me/moscow_drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-500/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-500/30"
|
||||||
@@ -62,7 +62,7 @@ function Navbar() {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://vk.com/your_group"
|
href="https://vk.com/mos.drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-600/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-blue-600/30"
|
||||||
@@ -77,7 +77,7 @@ function Navbar() {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="https://youtube.com/@your_channel"
|
href="https://www.youtube.com/@mossportonline9438"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-red-500/30"
|
className="w-8 h-8 bg-white bg-opacity-10 hover:bg-opacity-20 hover:scale-110 active:scale-95 rounded-full flex items-center justify-center transition-all duration-200 transform hover:shadow-lg hover:shadow-red-500/30"
|
||||||
@@ -169,7 +169,7 @@ function Navbar() {
|
|||||||
{/* Mobile Social Links */}
|
{/* Mobile Social Links */}
|
||||||
<div className="flex space-x-4 justify-center md:hidden">
|
<div className="flex space-x-4 justify-center md:hidden">
|
||||||
<Link
|
<Link
|
||||||
href="https://t.me/your_channel"
|
href="https://t.me/moscow_drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
||||||
@@ -179,7 +179,7 @@ function Navbar() {
|
|||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="https://vk.com/your_group"
|
href="https://vk.com/mos.drift"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
||||||
@@ -189,7 +189,7 @@ function Navbar() {
|
|||||||
</svg>
|
</svg>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="https://youtube.com/@your_channel"
|
href="https://www.youtube.com/@mossportonline9438"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
className="w-10 h-10 bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full flex items-center justify-center transition-all duration-200"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { fluxgore } from "@/utils/fonts";
|
|||||||
function Partners() {
|
function Partners() {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
id="partners"
|
||||||
className="bg-[#161616] relative py-16 sm:py-32 lg:py-52"
|
className="bg-[#161616] relative py-16 sm:py-32 lg:py-52"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url('/images/noise.svg')`,
|
backgroundImage: `url('/images/noise.svg')`,
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ function Video() {
|
|||||||
|
|
||||||
<div className="flex mt-8 md:mt-14">
|
<div className="flex mt-8 md:mt-14">
|
||||||
<iframe
|
<iframe
|
||||||
src="https://www.youtube.com/embed/FVzlAMLPFh0?si=E_EaXkQ3tJYtyf_s"
|
src="https://vkvideo.ru/video_ext.php?oid=-23293707&id=456242039&hd=2"
|
||||||
title="YouTube video player"
|
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
referrerPolicy="strict-origin-when-cross-origin"
|
referrerPolicy="strict-origin-when-cross-origin"
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface CheckboxOption {
|
||||||
|
value: string;
|
||||||
|
label: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CheckboxProps {
|
||||||
|
value?: string[];
|
||||||
|
options: CheckboxOption[];
|
||||||
|
onChange?: (values: string[]) => void;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
error?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
className?: string;
|
||||||
|
name: string;
|
||||||
|
direction?: "horizontal" | "vertical";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Checkbox({
|
||||||
|
value = [],
|
||||||
|
options,
|
||||||
|
onChange,
|
||||||
|
onBlur,
|
||||||
|
error,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
className = "",
|
||||||
|
name,
|
||||||
|
direction = "vertical",
|
||||||
|
}: CheckboxProps) {
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (onChange) {
|
||||||
|
const optionValue = e.target.value;
|
||||||
|
const isChecked = e.target.checked;
|
||||||
|
|
||||||
|
let newValues: string[];
|
||||||
|
if (isChecked) {
|
||||||
|
newValues = [...value, optionValue];
|
||||||
|
} else {
|
||||||
|
newValues = value.filter((v) => v !== optionValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(newValues);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-2 w-full max-w-sm ${className}`}>
|
||||||
|
<div
|
||||||
|
className={`flex gap-2 ${
|
||||||
|
direction === "vertical" ? "flex-col" : "flex-row flex-wrap"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{options.map((option) => (
|
||||||
|
<label
|
||||||
|
key={option.value}
|
||||||
|
className={`
|
||||||
|
flex items-center gap-3 cursor-pointer relative
|
||||||
|
${
|
||||||
|
disabled
|
||||||
|
? "cursor-not-allowed opacity-50"
|
||||||
|
: "hover:text-gray-700"
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name={name}
|
||||||
|
value={option.value}
|
||||||
|
checked={value.includes(option.value)}
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
className="sr-only"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
w-8 h-8 border-2 transition-all duration-200
|
||||||
|
${
|
||||||
|
value.includes(option.value)
|
||||||
|
? "border-black bg-white"
|
||||||
|
: "border-gray-400 bg-white hover:border-gray-600"
|
||||||
|
}
|
||||||
|
${disabled ? "opacity-50" : ""}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{value.includes(option.value) && (
|
||||||
|
<svg
|
||||||
|
className="w-6 h-6 text-black absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{option.label}
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{error && <span className="text-sm text-red-500 mt-1">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { gothampro } from "@/utils/fonts";
|
||||||
|
|
||||||
|
interface InputProps {
|
||||||
|
label?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
type?: "text" | "email" | "password" | "number" | "tel";
|
||||||
|
value?: string;
|
||||||
|
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
error?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
className?: string;
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Input({
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
type = "text",
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onBlur,
|
||||||
|
error,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
className = "",
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
}: InputProps) {
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-2 w-full max-w-sm ${className}`}>
|
||||||
|
{label && (
|
||||||
|
<label
|
||||||
|
htmlFor={id || name}
|
||||||
|
className={`${gothampro.className} text-base font-bold text-black`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{required && <span className="text-red-500 ml-1">*</span>}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
<input
|
||||||
|
id={id || name}
|
||||||
|
name={name}
|
||||||
|
type={type}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
placeholder={placeholder}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
className={`
|
||||||
|
w-full px-4 py-3
|
||||||
|
border border-gray-300
|
||||||
|
text-base font-normal
|
||||||
|
bg-white
|
||||||
|
placeholder-gray-400
|
||||||
|
transition-all duration-200 ease-in-out
|
||||||
|
focus:outline-none focus:ring-3 focus:ring-gray-100 focus:border-gray-500
|
||||||
|
hover:border-gray-400
|
||||||
|
disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
{error && <span className="text-sm text-red-500 mt-1">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Input;
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { gothampro } from "@/utils/fonts";
|
||||||
|
|
||||||
|
interface RadioOption {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RadioProps {
|
||||||
|
label?: string;
|
||||||
|
value?: string;
|
||||||
|
options: RadioOption[];
|
||||||
|
onChange?: (value: string) => void;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
error?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
className?: string;
|
||||||
|
name: string;
|
||||||
|
direction?: "horizontal" | "vertical";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Radio({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
options,
|
||||||
|
onChange,
|
||||||
|
onBlur,
|
||||||
|
error,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
className = "",
|
||||||
|
name,
|
||||||
|
direction = "vertical",
|
||||||
|
}: RadioProps) {
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (onChange) {
|
||||||
|
onChange(e.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-2 w-full max-w-sm ${className}`}>
|
||||||
|
{label && (
|
||||||
|
<label
|
||||||
|
className={`${gothampro.className} text-base font-bold text-black`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{required && <span className="text-red-500 ml-1">*</span>}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={`flex gap-2 ${
|
||||||
|
direction === "vertical" ? "flex-col" : "flex-row flex-wrap"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{options.map((option) => (
|
||||||
|
<label
|
||||||
|
key={option.value}
|
||||||
|
className={`
|
||||||
|
flex items-center gap-3 cursor-pointer relative
|
||||||
|
${
|
||||||
|
disabled
|
||||||
|
? "cursor-not-allowed opacity-50"
|
||||||
|
: "hover:text-gray-700"
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name={name}
|
||||||
|
value={option.value}
|
||||||
|
checked={value === option.value}
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
className="sr-only"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
w-8 h-8 rounded-full border-2 transition-all duration-200
|
||||||
|
${
|
||||||
|
value === option.value
|
||||||
|
? "border-black bg-white"
|
||||||
|
: "border-gray-400 bg-white hover:border-gray-600"
|
||||||
|
}
|
||||||
|
${disabled ? "opacity-50" : ""}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{value === option.value && (
|
||||||
|
<div className="w-4 h-4 rounded-full bg-black absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={`${gothampro.className} text-base font-normal text-black select-none`}
|
||||||
|
>
|
||||||
|
{option.label}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{error && <span className="text-sm text-red-500 mt-1">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { gothampro } from "@/utils/fonts";
|
||||||
|
|
||||||
|
interface SelectOption {
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SelectProps {
|
||||||
|
label?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
value?: string;
|
||||||
|
options: SelectOption[];
|
||||||
|
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLSelectElement>) => void;
|
||||||
|
error?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
className?: string;
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Select({
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
value,
|
||||||
|
options,
|
||||||
|
onChange,
|
||||||
|
onBlur,
|
||||||
|
error,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
className = "",
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
}: SelectProps) {
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-2 w-full max-w-sm ${className}`}>
|
||||||
|
{label && (
|
||||||
|
<label
|
||||||
|
htmlFor={id || name}
|
||||||
|
className={`${gothampro.className} text-base font-bold text-black`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{required && <span className="text-red-500 ml-1">*</span>}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
<select
|
||||||
|
id={id || name}
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
className={`
|
||||||
|
w-full px-4 py-3
|
||||||
|
border border-gray-300
|
||||||
|
text-base font-normal
|
||||||
|
bg-white
|
||||||
|
transition-all duration-200 ease-in-out
|
||||||
|
focus:outline-none focus:ring-3 focus:ring-gray-100 focus:border-gray-500
|
||||||
|
hover:border-gray-400
|
||||||
|
disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{placeholder && (
|
||||||
|
<option value="" disabled className="text-gray-400">
|
||||||
|
{placeholder}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
{options.map((option) => (
|
||||||
|
<option key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
{error && <span className="text-sm text-red-500 mt-1">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { gothampro } from "@/utils/fonts";
|
||||||
|
|
||||||
|
interface TextareaProps {
|
||||||
|
label?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
value?: string;
|
||||||
|
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;
|
||||||
|
error?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
className?: string;
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
rows?: number;
|
||||||
|
cols?: number;
|
||||||
|
maxLength?: number;
|
||||||
|
resize?: "none" | "both" | "horizontal" | "vertical";
|
||||||
|
}
|
||||||
|
|
||||||
|
function Textarea({
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onBlur,
|
||||||
|
error,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
className = "",
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
rows = 4,
|
||||||
|
cols,
|
||||||
|
maxLength,
|
||||||
|
resize = "vertical",
|
||||||
|
}: TextareaProps) {
|
||||||
|
const resizeClass = {
|
||||||
|
none: "resize-none",
|
||||||
|
both: "resize",
|
||||||
|
horizontal: "resize-x",
|
||||||
|
vertical: "resize-y",
|
||||||
|
}[resize];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-2 w-full max-w-sm ${className}`}>
|
||||||
|
{label && (
|
||||||
|
<label
|
||||||
|
htmlFor={id || name}
|
||||||
|
className={`${gothampro.className} text-base font-bold text-black`}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{required && <span className="text-red-500 ml-1">*</span>}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
<textarea
|
||||||
|
id={id || name}
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
placeholder={placeholder}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
rows={rows}
|
||||||
|
cols={cols}
|
||||||
|
maxLength={maxLength}
|
||||||
|
className={`
|
||||||
|
w-full px-4 py-3
|
||||||
|
border border-gray-300
|
||||||
|
text-base font-normal
|
||||||
|
bg-white
|
||||||
|
placeholder-gray-400
|
||||||
|
transition-all duration-200 ease-in-out
|
||||||
|
focus:outline-none focus:ring-3 focus:ring-gray-100 focus:border-gray-500
|
||||||
|
hover:border-gray-400
|
||||||
|
disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed
|
||||||
|
${resizeClass}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
{error && <span className="text-sm text-red-500 mt-1">{error}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Textarea
|
||||||
@@ -1,10 +1,49 @@
|
|||||||
|
/* eslint-disable @next/next/no-img-element */
|
||||||
import { Html, Head, Main, NextScript } from "next/document";
|
import { Html, Head, Main, NextScript } from "next/document";
|
||||||
|
|
||||||
export default function Document() {
|
export default function Document() {
|
||||||
return (
|
return (
|
||||||
<Html lang="en">
|
<Html lang="en">
|
||||||
<Head />
|
<Head>
|
||||||
|
<meta name="description" content="Фестиваль технических видов спорта" />
|
||||||
|
<meta
|
||||||
|
property="og:title"
|
||||||
|
content="Фестиваль технических видов спорта"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="Ежегодный Фестиваль технических видов спорта в ЦТВС 'Москва'! Дрифт, джимхана, мотокросс, картинг, море адреналина и хорошего настроения!"
|
||||||
|
/>
|
||||||
|
<meta property="og:url" content="https://tech-fest.sport.mos.ru/" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:image" content="/preview.jpg" />
|
||||||
|
</Head>
|
||||||
<body className="antialiased">
|
<body className="antialiased">
|
||||||
|
<div
|
||||||
|
style={{ display: "none" }}
|
||||||
|
itemScope
|
||||||
|
itemType="https://schema.org/Organization"
|
||||||
|
>
|
||||||
|
<span itemProp="name">Фестиваль технических видов спорта</span>
|
||||||
|
<div
|
||||||
|
itemProp="address"
|
||||||
|
itemScope
|
||||||
|
itemType="https://schema.org/PostalAddress"
|
||||||
|
>
|
||||||
|
Адрес:
|
||||||
|
<span itemProp="streetAddress">
|
||||||
|
Г. МОСКВА, ЦТВС 'МОСКВА'
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span itemProp="email">info@mossport.online</span>
|
||||||
|
<div itemScope itemType="https://schema.org/ImageObject">
|
||||||
|
<img
|
||||||
|
src="/preview.jpg"
|
||||||
|
itemProp="contentUrl"
|
||||||
|
alt="Фестиваль технических видов спорта"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Main />
|
<Main />
|
||||||
<NextScript />
|
<NextScript />
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import Checkbox from "@/components/form/Checkbox";
|
||||||
|
import Input from "@/components/form/Input";
|
||||||
|
import Radio from "@/components/form/Radio";
|
||||||
|
import Select from "@/components/form/Select";
|
||||||
|
import Textarea from "@/components/form/Textarea";
|
||||||
|
import { fluxgore, gothampro } from "@/utils/fonts";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
function ExhibtionFormPage() {
|
||||||
|
const [selectedOption, setSelectedOption] = useState("online");
|
||||||
|
const [checkboxValues, setCheckboxValues] = useState<string[]>([]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-[#ffffff] relative h-full">
|
||||||
|
<h1
|
||||||
|
className={`${fluxgore.className} text-4xl md:text-7xl text-[#060606] relative`}
|
||||||
|
>
|
||||||
|
Регистрация участника
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
label="Имя"
|
||||||
|
placeholder="Введите ваше имя"
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
className="mt-4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Select
|
||||||
|
label="Выберите тип участия"
|
||||||
|
options={[
|
||||||
|
{ value: "speaker", label: "Спикер" },
|
||||||
|
{ value: "attendee", label: "Посетитель" },
|
||||||
|
{ value: "sponsor", label: "Спонсор" },
|
||||||
|
]}
|
||||||
|
required
|
||||||
|
className="mt-4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Radio
|
||||||
|
value={selectedOption}
|
||||||
|
onChange={setSelectedOption}
|
||||||
|
label="Выберите формат участия"
|
||||||
|
options={[
|
||||||
|
{ value: "online", label: "Онлайн" },
|
||||||
|
{ value: "offline", label: "Офлайн" },
|
||||||
|
{ value: "hybrid", label: "Гибридный" },
|
||||||
|
]}
|
||||||
|
required
|
||||||
|
className="mt-4"
|
||||||
|
direction="vertical"
|
||||||
|
name="participationFormat"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Textarea
|
||||||
|
label="Дополнительная информация"
|
||||||
|
placeholder="Введите дополнительную информацию"
|
||||||
|
rows={4}
|
||||||
|
cols={50}
|
||||||
|
className="mt-4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Checkbox
|
||||||
|
value={checkboxValues}
|
||||||
|
onChange={(values) => setCheckboxValues(values)}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
value: "terms",
|
||||||
|
label: (
|
||||||
|
<label className={`${gothampro.className} text-base text-black`}>
|
||||||
|
Согласие на обработку персональных данных
|
||||||
|
</label>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
required
|
||||||
|
className="mt-4"
|
||||||
|
direction="vertical"
|
||||||
|
name="termsAgreement"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExhibtionFormPage;
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
import { CoverSoon } from "@/components/Cover";
|
import { CoverSoon } from "@/components/Cover";
|
||||||
|
import Head from "next/head";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Фестиваль технических видов спорта</title>
|
||||||
|
</Head>
|
||||||
<CoverSoon />
|
<CoverSoon />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,10 +9,15 @@ import Navbar from "@/components/Navbar";
|
|||||||
import Partners from "@/components/Partners";
|
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";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
<Head>
|
||||||
|
<title>Фестиваль технических видов спорта</title>
|
||||||
|
</Head>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main className="flex-col min-h-full">
|
<main className="flex-col min-h-full">
|
||||||
<Cover />
|
<Cover />
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#__next {
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|||||||