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 */ |
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ |
||||||
const pool = require("./connect"); |
const pool = require("./connect"); |
||||||
import {QueryError, RowDataPacket} from 'mysql2'; |
import {QueryError} from 'mysql2'; |
||||||
|
|
||||||
interface definitionInterface{ |
interface definitionInterface{ |
||||||
(message:string):void; |
(message:string):void; |
||||||
} |
} |
||||||
export default function Select(sql: string, callback: definitionInterface) { |
export default function Select(sql: string, callback: definitionInterface) { |
||||||
pool.query(sql, (err: QueryError, rows: RowDataPacket[]) => { |
pool.query(sql, (err: QueryError, rows: string) => { |
||||||
callback(rows); |
callback(rows); |
||||||
pool.releaseConnection(pool); |
pool.releaseConnection(pool); |
||||||
}); |
}); |
||||||
|
Loading…
Reference in new issue