parent
c96083362a
commit
17cb0a843c
@ -0,0 +1,28 @@ |
||||
# RoboTop сайт робототехнического фестиваля |
||||
|
||||
A Next.js starter for your next blog or personal site. Built with: |
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) |
||||
- Write posts with [MDX](https://mdxjs.com/) |
||||
- Style with [Tailwind CSS](https://tailwindcss.com/) |
||||
- Linting with [ESLint](https://eslint.org/) |
||||
- Formatting with [Prettier](https://prettier.io/) |
||||
- Linting, typechecking and formatting on by default using [`husky`](https://github.com/typicode/husky) for commit hooks |
||||
- Testing with [Jest](https://jestjs.io/) and [`react-testing-library`](https://testing-library.com/docs/react-testing-library/intro) |
||||
|
||||
## Getting Started |
||||
|
||||
```bash |
||||
git clone https://github.com/ChangoMan/nextjs-typescript-mdx-blog.git |
||||
cd nextjs-typescript-mdx-blog |
||||
|
||||
yarn install |
||||
# or |
||||
npm install |
||||
|
||||
yarn dev |
||||
# or |
||||
npm run dev |
||||
``` |
||||
|
||||
Your new site will be up at http://localhost:3000/ |
@ -0,0 +1,248 @@ |
||||
import React,{useRef} from 'react'; |
||||
import { useForm, SubmitHandler } from "react-hook-form"; |
||||
|
||||
interface IFormInputs { |
||||
firstName: string |
||||
lastName: string |
||||
coach_telefon_number: string |
||||
} |
||||
|
||||
const alerError = (props) => { |
||||
return <p className="mt-2 text-sm text-red-600 dark:text-red-500 font-medium">{props}</p> |
||||
} |
||||
|
||||
export const RegistrationForm = (props): JSX.Element => { |
||||
const form = useRef(null); |
||||
const { register, handleSubmit, reset, formState: { errors } } = useForm(); |
||||
|
||||
const onSubmit: SubmitHandler<IFormInputs> = data => { |
||||
fetch('/api/registration', { method: 'POST', body: Object.values(data) }) |
||||
.then(props.updateData(2)) |
||||
reset(); |
||||
} |
||||
return ( |
||||
<> |
||||
<div className="mt-10 sm:mt-0"> |
||||
<div className="md:grid md:grid-cols-3 md:gap-6"> |
||||
<div className="md:col-span-1"> |
||||
<div className="px-4 sm:px-0"> |
||||
<h3 className="text-lg font-medium leading-6">Регистрация команды</h3> |
||||
<p className="mt-1 text-sm">Введите актуальные данные команды</p> |
||||
<p className="mt-1 text-sm">От каждого учебного заведения может быть зарегистрированно неограниченое количеставо команд</p> |
||||
<p className="mt-1 text-sm"> Подписывайтесь на наш<a href="https://t.me/robotop_competition" className="text-blue-600 dark:text-blue-500 hover:underline"> Telegram канал </a>, что-бы быть в курсе новосте про соревнование </p>. |
||||
</div> |
||||
</div> |
||||
<div className="mt-5 md:mt-0 md:col-span-2"> |
||||
<form ref={form} onSubmit={handleSubmit(onSubmit)}> |
||||
<div className="shadow overflow-hidden sm:rounded-md"> |
||||
<div className="px-4 py-5 bg-white sm:p-6"> |
||||
<div className="grid grid-cols-6 gap-6"> |
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="first-name" className="block text-sm font-medium text-gray-700"> |
||||
ФИО тренера команды |
||||
</label> |
||||
<input |
||||
{...register("name_team_coach",{ required: true, maxLength: 80 })} |
||||
name="name_team_coach" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_team_coach && alerError('Введите ФИО тренера команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="last-name" className="block text-sm font-medium text-gray-700"> |
||||
Номер теленона тренера |
||||
</label> |
||||
<input |
||||
{...register("coach_telefon_number",{ required: true, valueAsNumber: true })} |
||||
name="coach_telefon_number" |
||||
placeholder="+79181234567" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.coach_telefon_number && alerError('Введите номер телефона')} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Email тренера |
||||
</label> |
||||
<input |
||||
{...register("trainer_mail",{ required: true, maxLength: 80, pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ })} |
||||
placeholder="you@example.com" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.trainer_mail && alerError('Введите коректный Email адресс') |
||||
} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Город команда |
||||
</label> |
||||
<input |
||||
{...register("city_team",{ required: true, maxLength: 80 })} |
||||
name="city_team" |
||||
placeholder="Краснодар" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{ errors.city_team && alerError('Введите город команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="street-address" className="block text-sm font-medium text-gray-700"> |
||||
Учебное заведение команды |
||||
</label> |
||||
<input |
||||
{...register("training_institution_team",{ required: true, maxLength: 150 })} |
||||
name="training_institution_team" |
||||
placeholder="МАОУ СОШ 103" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.training_institution_team && alerError('Введите название учебного заведения') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="region" className="block text-sm font-medium text-gray-700"> |
||||
Название команды |
||||
</label> |
||||
<input |
||||
{...register("team_name",{ required: true, maxLength: 150 })} |
||||
name="team_name" |
||||
placeholder="Фиксики" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.team_name && alerError('Введите название команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО первого участника |
||||
</label> |
||||
<input |
||||
{...register("name_first_participant",{ required: true, maxLength: 150 })} |
||||
name="name_first_participant" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_first_participant && alerError('Введите ФИО участника') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("first_partial_class")} |
||||
name="first_partial_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО второго участника |
||||
</label> |
||||
<input |
||||
{...register("name_second_participant",{ maxLength: 150 })} |
||||
name="name_second_participant" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Петр Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("second_class")} |
||||
name="second_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО третьего участника |
||||
</label> |
||||
<input |
||||
{...register("name_third_party",{ maxLength: 150 })} |
||||
name="name_third_party" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Дмитрий Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("third_part_class")} |
||||
name="third_part_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
<div className="px-4 py-3 bg-gray-50 text-right sm:px-6"> |
||||
<button |
||||
type="submit" |
||||
className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
||||
> |
||||
Зарегистрировать команду |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default RegistrationForm; |
@ -0,0 +1,248 @@ |
||||
import React,{useRef} from 'react'; |
||||
import { useForm, SubmitHandler } from "react-hook-form"; |
||||
|
||||
interface IFormInputs { |
||||
firstName: string |
||||
lastName: string |
||||
coach_telefon_number: string |
||||
} |
||||
|
||||
const alerError = (props) => { |
||||
return <p className="mt-2 text-sm text-red-600 dark:text-red-500 font-medium">{props}</p> |
||||
} |
||||
|
||||
export const RegistrationForm = (props): JSX.Element => { |
||||
const form = useRef(null); |
||||
const { register, handleSubmit, reset, formState: { errors } } = useForm(); |
||||
|
||||
const onSubmit: SubmitHandler<IFormInputs> = data => { |
||||
fetch('/api/registration', { method: 'POST', body: Object.values(data) }) |
||||
.then(props.updateData(2)) |
||||
reset(); |
||||
} |
||||
return ( |
||||
<> |
||||
<div className="mt-10 sm:mt-0"> |
||||
<div className="md:grid md:grid-cols-3 md:gap-6"> |
||||
<div className="md:col-span-1"> |
||||
<div className="px-4 sm:px-0"> |
||||
<h3 className="text-lg font-medium leading-6">Регистрация команды</h3> |
||||
<p className="mt-1 text-sm">Введите актуальные данные команды</p> |
||||
<p className="mt-1 text-sm">От каждого учебного заведения может быть зарегистрированно неограниченое количеставо команд</p> |
||||
<p className="mt-1 text-sm"> Подписывайтесь на наш<a href="https://t.me/robotop_competition" className="text-blue-600 dark:text-blue-500 hover:underline"> Telegram канал </a>, что-бы быть в курсе новосте про соревнование </p>. |
||||
</div> |
||||
</div> |
||||
<div className="mt-5 md:mt-0 md:col-span-2"> |
||||
<form ref={form} onSubmit={handleSubmit(onSubmit)}> |
||||
<div className="shadow overflow-hidden sm:rounded-md"> |
||||
<div className="px-4 py-5 bg-white sm:p-6"> |
||||
<div className="grid grid-cols-6 gap-6"> |
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="first-name" className="block text-sm font-medium text-gray-700"> |
||||
ФИО тренера команды |
||||
</label> |
||||
<input |
||||
{...register("name_team_coach",{ required: true, maxLength: 80 })} |
||||
name="name_team_coach" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_team_coach && alerError('Введите ФИО тренера команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="last-name" className="block text-sm font-medium text-gray-700"> |
||||
Номер теленона тренера |
||||
</label> |
||||
<input |
||||
{...register("coach_telefon_number",{ required: true, valueAsNumber: true })} |
||||
name="coach_telefon_number" |
||||
placeholder="+79181234567" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.coach_telefon_number && alerError('Введите номер телефона')} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Email тренера |
||||
</label> |
||||
<input |
||||
{...register("trainer_mail",{ required: true, maxLength: 80, pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ })} |
||||
placeholder="you@example.com" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.trainer_mail && alerError('Введите коректный Email адресс') |
||||
} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Город команда |
||||
</label> |
||||
<input |
||||
{...register("city_team",{ required: true, maxLength: 80 })} |
||||
name="city_team" |
||||
placeholder="Краснодар" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{ errors.city_team && alerError('Введите город команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="street-address" className="block text-sm font-medium text-gray-700"> |
||||
Учебное заведение команды |
||||
</label> |
||||
<input |
||||
{...register("training_institution_team",{ required: true, maxLength: 150 })} |
||||
name="training_institution_team" |
||||
placeholder="МАОУ СОШ 103" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.training_institution_team && alerError('Введите название учебного заведения') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="region" className="block text-sm font-medium text-gray-700"> |
||||
Название команды |
||||
</label> |
||||
<input |
||||
{...register("team_name",{ required: true, maxLength: 150 })} |
||||
name="team_name" |
||||
placeholder="Фиксики" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.team_name && alerError('Введите название команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО первого участника |
||||
</label> |
||||
<input |
||||
{...register("name_first_participant",{ required: true, maxLength: 150 })} |
||||
name="name_first_participant" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_first_participant && alerError('Введите ФИО участника') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("first_partial_class")} |
||||
name="first_partial_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО второго участника |
||||
</label> |
||||
<input |
||||
{...register("name_second_participant",{ maxLength: 150 })} |
||||
name="name_second_participant" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Петр Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("second_class")} |
||||
name="second_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО третьего участника |
||||
</label> |
||||
<input |
||||
{...register("name_third_party",{ maxLength: 150 })} |
||||
name="name_third_party" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Дмитрий Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("third_part_class")} |
||||
name="third_part_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
<div className="px-4 py-3 bg-gray-50 text-right sm:px-6"> |
||||
<button |
||||
type="submit" |
||||
className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
||||
> |
||||
Зарегистрировать команду |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default RegistrationForm; |
@ -0,0 +1,249 @@ |
||||
import React,{useRef} from 'react'; |
||||
import { useForm, SubmitHandler } from "react-hook-form"; |
||||
|
||||
interface IFormInputs { |
||||
firstName: string |
||||
lastName: string |
||||
coach_telefon_number: string |
||||
body: string[] |
||||
} |
||||
|
||||
const alerError = (props) => { |
||||
return <p className="mt-2 text-sm text-red-600 dark:text-red-500 font-medium">{props}</p> |
||||
} |
||||
|
||||
export const RegistrationForm = (props): JSX.Element => { |
||||
const form = useRef(null); |
||||
const { register, handleSubmit, reset, formState: { errors } } = useForm(); |
||||
|
||||
const onSubmit: SubmitHandler<IFormInputs> = data => { |
||||
fetch('/api/registration', { method: 'POST', body: Object.values(data) }) |
||||
.then(props.updateData(2)) |
||||
reset(); |
||||
} |
||||
return ( |
||||
<> |
||||
<div className="mt-10 sm:mt-0"> |
||||
<div className="md:grid md:grid-cols-3 md:gap-6"> |
||||
<div className="md:col-span-1"> |
||||
<div className="px-4 sm:px-0"> |
||||
<h3 className="text-lg font-medium leading-6">Регистрация команды</h3> |
||||
<p className="mt-1 text-sm">Введите актуальные данные команды</p> |
||||
<p className="mt-1 text-sm">От каждого учебного заведения может быть зарегистрированно неограниченое количеставо команд</p> |
||||
<p className="mt-1 text-sm"> Подписывайтесь на наш<a href="https://t.me/robotop_competition" className="text-blue-600 dark:text-blue-500 hover:underline"> Telegram канал </a>, что-бы быть в курсе новосте про соревнование </p>. |
||||
</div> |
||||
</div> |
||||
<div className="mt-5 md:mt-0 md:col-span-2"> |
||||
<form ref={form} onSubmit={handleSubmit(onSubmit)}> |
||||
<div className="shadow overflow-hidden sm:rounded-md"> |
||||
<div className="px-4 py-5 bg-white sm:p-6"> |
||||
<div className="grid grid-cols-6 gap-6"> |
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="first-name" className="block text-sm font-medium text-gray-700"> |
||||
ФИО тренера команды |
||||
</label> |
||||
<input |
||||
{...register("name_team_coach",{ required: true, maxLength: 80 })} |
||||
name="name_team_coach" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_team_coach && alerError('Введите ФИО тренера команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="last-name" className="block text-sm font-medium text-gray-700"> |
||||
Номер теленона тренера |
||||
</label> |
||||
<input |
||||
{...register("coach_telefon_number",{ required: true, valueAsNumber: true })} |
||||
name="coach_telefon_number" |
||||
placeholder="+79181234567" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.coach_telefon_number && alerError('Введите номер телефона')} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Email тренера |
||||
</label> |
||||
<input |
||||
{...register("trainer_mail",{ required: true, maxLength: 80, pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ })} |
||||
placeholder="you@example.com" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.trainer_mail && alerError('Введите коректный Email адресс') |
||||
} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Город команда |
||||
</label> |
||||
<input |
||||
{...register("city_team",{ required: true, maxLength: 80 })} |
||||
name="city_team" |
||||
placeholder="Краснодар" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{ errors.city_team && alerError('Введите город команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="street-address" className="block text-sm font-medium text-gray-700"> |
||||
Учебное заведение команды |
||||
</label> |
||||
<input |
||||
{...register("training_institution_team",{ required: true, maxLength: 150 })} |
||||
name="training_institution_team" |
||||
placeholder="МАОУ СОШ 103" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.training_institution_team && alerError('Введите название учебного заведения') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="region" className="block text-sm font-medium text-gray-700"> |
||||
Название команды |
||||
</label> |
||||
<input |
||||
{...register("team_name",{ required: true, maxLength: 150 })} |
||||
name="team_name" |
||||
placeholder="Фиксики" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.team_name && alerError('Введите название команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО первого участника |
||||
</label> |
||||
<input |
||||
{...register("name_first_participant",{ required: true, maxLength: 150 })} |
||||
name="name_first_participant" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_first_participant && alerError('Введите ФИО участника') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("first_partial_class")} |
||||
name="first_partial_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО второго участника |
||||
</label> |
||||
<input |
||||
{...register("name_second_participant",{ maxLength: 150 })} |
||||
name="name_second_participant" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Петр Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("second_class")} |
||||
name="second_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО третьего участника |
||||
</label> |
||||
<input |
||||
{...register("name_third_party",{ maxLength: 150 })} |
||||
name="name_third_party" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Дмитрий Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("third_part_class")} |
||||
name="third_part_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
<div className="px-4 py-3 bg-gray-50 text-right sm:px-6"> |
||||
<button |
||||
type="submit" |
||||
className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
||||
> |
||||
Зарегистрировать команду |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default RegistrationForm; |
@ -0,0 +1,249 @@ |
||||
import React,{useRef} from 'react'; |
||||
import { useForm, SubmitHandler } from "react-hook-form"; |
||||
|
||||
interface IFormInputs { |
||||
firstName: string |
||||
lastName: string |
||||
coach_telefon_number: string |
||||
body: string[] |
||||
} |
||||
|
||||
const alerError = (props) => { |
||||
return <p className="mt-2 text-sm text-red-600 dark:text-red-500 font-medium">{props}</p> |
||||
} |
||||
|
||||
export const RegistrationForm = (props): JSX.Element => { |
||||
const form = useRef(null); |
||||
const { register, handleSubmit, reset, formState: { errors } } = useForm(); |
||||
|
||||
const onSubmit: SubmitHandler<IFormInputs> = data => { |
||||
fetch('/api/registration', { method: 'POST', body: JSON.stringify(Object.values(data)) }) |
||||
.then(props.updateData(2)) |
||||
reset(); |
||||
} |
||||
return ( |
||||
<> |
||||
<div className="mt-10 sm:mt-0"> |
||||
<div className="md:grid md:grid-cols-3 md:gap-6"> |
||||
<div className="md:col-span-1"> |
||||
<div className="px-4 sm:px-0"> |
||||
<h3 className="text-lg font-medium leading-6">Регистрация команды</h3> |
||||
<p className="mt-1 text-sm">Введите актуальные данные команды</p> |
||||
<p className="mt-1 text-sm">От каждого учебного заведения может быть зарегистрированно неограниченое количеставо команд</p> |
||||
<p className="mt-1 text-sm"> Подписывайтесь на наш<a href="https://t.me/robotop_competition" className="text-blue-600 dark:text-blue-500 hover:underline"> Telegram канал </a>, что-бы быть в курсе новосте про соревнование </p>. |
||||
</div> |
||||
</div> |
||||
<div className="mt-5 md:mt-0 md:col-span-2"> |
||||
<form ref={form} onSubmit={handleSubmit(onSubmit)}> |
||||
<div className="shadow overflow-hidden sm:rounded-md"> |
||||
<div className="px-4 py-5 bg-white sm:p-6"> |
||||
<div className="grid grid-cols-6 gap-6"> |
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="first-name" className="block text-sm font-medium text-gray-700"> |
||||
ФИО тренера команды |
||||
</label> |
||||
<input |
||||
{...register("name_team_coach",{ required: true, maxLength: 80 })} |
||||
name="name_team_coach" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_team_coach && alerError('Введите ФИО тренера команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="last-name" className="block text-sm font-medium text-gray-700"> |
||||
Номер теленона тренера |
||||
</label> |
||||
<input |
||||
{...register("coach_telefon_number",{ required: true, valueAsNumber: true })} |
||||
name="coach_telefon_number" |
||||
placeholder="+79181234567" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.coach_telefon_number && alerError('Введите номер телефона')} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Email тренера |
||||
</label> |
||||
<input |
||||
{...register("trainer_mail",{ required: true, maxLength: 80, pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ })} |
||||
placeholder="you@example.com" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.trainer_mail && alerError('Введите коректный Email адресс') |
||||
} |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="email-address" className="block text-sm font-medium text-gray-700"> |
||||
Город команда |
||||
</label> |
||||
<input |
||||
{...register("city_team",{ required: true, maxLength: 80 })} |
||||
name="city_team" |
||||
placeholder="Краснодар" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{ errors.city_team && alerError('Введите город команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="street-address" className="block text-sm font-medium text-gray-700"> |
||||
Учебное заведение команды |
||||
</label> |
||||
<input |
||||
{...register("training_institution_team",{ required: true, maxLength: 150 })} |
||||
name="training_institution_team" |
||||
placeholder="МАОУ СОШ 103" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.training_institution_team && alerError('Введите название учебного заведения') } |
||||
</div> |
||||
|
||||
<div className="col-span-3"> |
||||
<label htmlFor="region" className="block text-sm font-medium text-gray-700"> |
||||
Название команды |
||||
</label> |
||||
<input |
||||
{...register("team_name",{ required: true, maxLength: 150 })} |
||||
name="team_name" |
||||
placeholder="Фиксики" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.team_name && alerError('Введите название команды') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО первого участника |
||||
</label> |
||||
<input |
||||
{...register("name_first_participant",{ required: true, maxLength: 150 })} |
||||
name="name_first_participant" |
||||
placeholder="Иванов Иван Иванович" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
{errors.name_first_participant && alerError('Введите ФИО участника') } |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("first_partial_class")} |
||||
name="first_partial_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО второго участника |
||||
</label> |
||||
<input |
||||
{...register("name_second_participant",{ maxLength: 150 })} |
||||
name="name_second_participant" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Петр Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("second_class")} |
||||
name="second_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="city" className="block text-sm font-medium text-gray-700"> |
||||
ФИО третьего участника |
||||
</label> |
||||
<input |
||||
{...register("name_third_party",{ maxLength: 150 })} |
||||
name="name_third_party" |
||||
defaultValue='нет' |
||||
placeholder="Иванов Дмитрий Иванович / нет" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
/> |
||||
</div> |
||||
|
||||
<div className="col-span-6 sm:col-span-3"> |
||||
<label htmlFor="country" className="block text-sm font-medium text-gray-700"> |
||||
Класс участника |
||||
</label> |
||||
<select |
||||
{...register("third_part_class")} |
||||
name="third_part_class" |
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" |
||||
> |
||||
<option selected>-- Выбрать --</option> |
||||
<option>1</option> |
||||
<option>2</option> |
||||
<option>3</option> |
||||
<option>4</option> |
||||
<option>5</option> |
||||
<option>6</option> |
||||
<option>7</option> |
||||
<option>8</option> |
||||
<option>9</option> |
||||
<option>10</option> |
||||
<option>11</option> |
||||
</select> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
<div className="px-4 py-3 bg-gray-50 text-right sm:px-6"> |
||||
<button |
||||
type="submit" |
||||
className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" |
||||
> |
||||
Зарегистрировать команду |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
}; |
||||
|
||||
export default RegistrationForm; |
@ -0,0 +1,12 @@ |
||||
// .env.local |
||||
|
||||
USER_="crapshr6_robotop" |
||||
HOST="crapshr6.beget.tech" |
||||
DATABASE="crapshr6_robotop" |
||||
PASSWORD="sJ9&alNk" |
||||
|
||||
MAILSERVER="smtp.beget.com" |
||||
MAILNAME="service@vsst.su" |
||||
MAILPASS = "&ekS0NPD" |
||||
|
||||
SITE="http://localhost:3000/api/" |
@ -0,0 +1,20 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
error: string, |
||||
data: string, |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(data){ |
||||
res.status(200).json(data); |
||||
}) |
||||
} |
@ -0,0 +1,20 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
error: string, |
||||
data?: any, |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(data){ |
||||
return res.status(200).json({data}); |
||||
}) |
||||
} |
@ -0,0 +1,20 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
error: string, |
||||
message: string, |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,19 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message: Data[], |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,19 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message: Data[], |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
return res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,19 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message: Data[], |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
return res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,21 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message?: Data[], |
||||
name?: Data[] |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
const name: Data[] = message; |
||||
return res.status(200).json(name); |
||||
}) |
||||
} |
@ -0,0 +1,21 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message?: Data[], |
||||
name?: Data[] |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
//const obj: Data = message;
|
||||
return res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,20 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
type Data = { |
||||
message?: Data[], |
||||
name?: Data[] |
||||
} |
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse<Data> |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,17 @@ |
||||
import type { NextApiRequest, NextApiResponse } from 'next' |
||||
import Insert from "../../server/db/insert"; |
||||
|
||||
const sql = "INSERT INTO members (name_team_coach, coach_telefon_number, trainer_mail, city_team, training_institution_team, team_name, name_first_participant, first_partial_class, name_second_participant, second_class, name_third_party, third_part_class) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
||||
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function handler( |
||||
req: NextApiRequest, |
||||
res: NextApiResponse |
||||
) { |
||||
const re = /\s*,\s*/; |
||||
const parm = req.body; |
||||
Insert(sql, parm.split(re), function(message){ |
||||
res.status(200).json(message); |
||||
}) |
||||
} |
@ -0,0 +1,66 @@ |
||||
import React, {useEffect, useState} from 'react'; |
||||
import Layout from '../components/Layout'; |
||||
import RegistrationForm from '../components/RegistrationForm'; |
||||
import LoadingTeamsForm from '../components/LoadingTeamsForm'; |
||||
import { useSelector } from 'react-redux'; |
||||
import { useAppDispatch } from '../redux/store'; |
||||
import { fetchUser, selectUserData } from '../redux/user'; |
||||
import { ToastContainer, toast } from 'react-toastify'; |
||||
import 'react-toastify/dist/ReactToastify.css'; |
||||
|
||||
export const Registration = (): JSX.Element => { |
||||
const dispatch = useAppDispatch(); |
||||
const [UserAdd, setUserAdd] = useState(0); |
||||
|
||||
const UpdateUser = () => { |
||||
setUserAdd(UserAdd+1); |
||||
toast("Спасибо Ваша команда зарегистрирована"); |
||||
} |
||||
useEffect(() => { |
||||
dispatch( fetchUser() ); |
||||
}, [UserAdd]); |
||||
|
||||
const { user_items } = useSelector(selectUserData); |
||||
const User = user_items.map((obj, index) => <LoadingTeamsForm key={index} {...obj} />); |
||||
return ( |
||||
<Layout |
||||
customMeta={{ |
||||
title: 'Регистрация', |
||||
}} |
||||
> |
||||
<RegistrationForm updateData={UpdateUser}/> |
||||
<ToastContainer /> |
||||
<div className="relative overflow-x-auto shadow-md sm:rounded-lg"> |
||||
<div className="px-4 sm:px-2 m-4 block"> |
||||
<h3 className="text-lg font-medium leading-6">Зарегистрированные команды</h3> |
||||
</div> |
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400"> |
||||
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> |
||||
<tr> |
||||
<th scope="col" className="px-6 py-3"> |
||||
Название команды |
||||
</th> |
||||
<th scope="col" className="px-6 py-3"> |
||||
ФИО тренера |
||||
</th> |
||||
<th scope="col" className="px-6 py-3"> |
||||
Учебное заведение |
||||
</th> |
||||
<th scope="col" className="px-6 py-3"> |
||||
ФИО участников |
||||
</th> |
||||
<th scope="col" className="px-6 py-3"> |
||||
Возрастная группа |
||||
</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{ User } |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</Layout> |
||||
); |
||||
}; |
||||
|
||||
export default Registration; |
@ -0,0 +1,13 @@ |
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ |
||||
const pool = require("./connect"); |
||||
import {QueryError} from 'mysql2'; |
||||
|
||||
interface definitionInterface{ |
||||
(message:string):void; |
||||
} |
||||
export default function Select(sql: string, callback: definitionInterface) { |
||||
pool.query(sql, (err: QueryError, rows: string) => { |
||||
callback(rows); |
||||
pool.releaseConnection(pool); |
||||
}); |
||||
} |
@ -0,0 +1,5 @@ |
||||
{ |
||||
"cSpell.words": [ |
||||
"fdfdf" |
||||
] |
||||
} |
@ -1,3 +1,28 @@ |
||||
# RoboTop - Сайт для робототехнического фестиваля |
||||
# RoboTop сайт робототехнического фестиваля |
||||
|
||||
Next.js |
||||
A Next.js starter for your next blog or personal site. Built with: |
||||
|
||||
- [Typescript](https://www.typescriptlang.org/) |
||||
- Write posts with [MDX](https://mdxjs.com/) |
||||
- Style with [Tailwind CSS](https://tailwindcss.com/) |
||||
- Linting with [ESLint](https://eslint.org/) |
||||
- Formatting with [Prettier](https://prettier.io/) |
||||
- Linting, typechecking and formatting on by default using [`husky`](https://github.com/typicode/husky) for commit hooks |
||||
- Testing with [Jest](https://jestjs.io/) and [`react-testing-library`](https://testing-library.com/docs/react-testing-library/intro) |
||||
|
||||
## Getting Started |
||||
|
||||
```bash |
||||
git clone https://github.com/ChangoMan/nextjs-typescript-mdx-blog.git |
||||
cd nextjs-typescript-mdx-blog |
||||
|
||||
yarn install |
||||
# or |
||||
npm install |
||||
|
||||
yarn dev |
||||
# or |
||||
npm run dev |
||||
``` |
||||
|
||||
Your new site will be up at http://localhost:3000/ |
||||
|
@ -0,0 +1,12 @@ |
||||
// .env.local |
||||
|
||||
USER_="crapshr6_robotop" |
||||
HOST="crapshr6.beget.tech" |
||||
DATABASE="crapshr6_robotop" |
||||
PASSWORD="sJ9&alNk" |
||||
|
||||
MAILSERVER="smtp.beget.com" |
||||
MAILNAME="service@vsst.su" |
||||
MAILPASS = "&ekS0NPD" |
||||
|
||||
SITE="http://localhost:3000/api/" |
@ -1,12 +1,12 @@ |
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ |
||||
const pool = require("./connect"); |
||||
import {QueryError, RowDataPacket} from 'mysql2'; |
||||
import {QueryError} from 'mysql2'; |
||||
|
||||
interface definitionInterface{ |
||||
(message:string):void; |
||||
} |
||||
export default function Select(sql: string, callback: definitionInterface) { |
||||
pool.query(sql, (err: QueryError, rows: RowDataPacket[]) => { |
||||
pool.query(sql, (err: QueryError, rows: string) => { |
||||
callback(rows); |
||||
pool.releaseConnection(pool); |
||||
}); |
||||
|
Loading…
Reference in new issue