Skip to content

Commit

Permalink
Merge pull request #285 from Studio-Yandex-Practicum/enhancement_280_…
Browse files Browse the repository at this point in the history
…buy_gift_certificate

enhancement_280_buy_gift_certificate
  • Loading branch information
AlexanderMorugin authored Apr 3, 2024
2 parents a0c5e56 + d04e429 commit 166c21f
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/shared/ui/Checkbox/Checkbox.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
display: flex;
align-items: center;
cursor: pointer;

&:first-child {
margin-top: 10px;
}
Expand Down
1 change: 1 addition & 0 deletions src/shared/ui/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const Primary = {
args: {
name: 'Text',
value: 'Text',
type: 'radio',
label: 'Text',
theme: ECheckboxTheme.PRIMARY,
size: ECheckboxSize.M
Expand Down
6 changes: 4 additions & 2 deletions src/shared/ui/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ECheckboxTheme, ECheckboxSize } from '@/shared/model/types/common'
export interface CheckboxProps {
name: string
value?: string
type?: 'radio' | 'checkbox'
label?: string
htmlFor: string
theme?: ECheckboxTheme
Expand All @@ -30,6 +31,7 @@ export interface CheckboxProps {
const Checkbox: FC<CheckboxProps> = props => {
const {
className,
type = 'radio',
value,
htmlFor,
label,
Expand All @@ -40,7 +42,7 @@ const Checkbox: FC<CheckboxProps> = props => {

const additionalClasses = [className, theme && style[theme], style[size]]

const [field] = useField({ name, type: 'radio', value })
const [field] = useField({ name, type, value })

return (
<label className={style.formReturn__checkbox} htmlFor={htmlFor}>
Expand All @@ -50,7 +52,7 @@ const Checkbox: FC<CheckboxProps> = props => {
as={Input}
label={label}
name={name}
type="radio"
type={type}
value={value}
/>
<span>{label}</span>
Expand Down
2 changes: 2 additions & 0 deletions src/widgets/FormBuyGiftCertificate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import FormBuyGiftCertificate from './ui/FormBuyGiftCertificate'
export default FormBuyGiftCertificate
7 changes: 7 additions & 0 deletions src/widgets/FormBuyGiftCertificate/model/types/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface IFormBuyGiftCertificate {
recipientName: string
recipientEmail: string
name: string
email: string
textArea: string
}
26 changes: 26 additions & 0 deletions src/widgets/FormBuyGiftCertificate/model/validation/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as Yup from 'yup'

export const validationSchema = Yup.object().shape({
recipientName: Yup.string()
.required('Введите имя получателя')
.min(2, 'Минимальная длина имени 2 символов')
.max(64, 'Максимальная длина имени 64 символа'),
recipientEmail: Yup.string()
.required('Введите электронную почту получателя')
.email('Укажите корректный адрес электронной почты'),
name: Yup.string()
.required('Введите имя')
.min(6, 'Минимальная длина имени 6 символов')
.max(64, 'Максимальная длина имени 64 символа'),
email: Yup.string()
.required('Введите электронную почту')
.email('Укажите корректный адрес электронной почты'),
textarea: Yup.string()
.min(10, 'Длина текста должна быть от 10 символов')
.max(300, 'Длина текста должна быть до 300 символов'),
sum: Yup.number()
.required('Введите сумму')
.min(1, 'Сумма должна быть не менее 1 руб')
.max(1000, 'Сумма должна быть не более 1000 руб')
.typeError('Сумма указывается только цифрами')
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@use '@/shared/styles/utils/variables' as var;

.form {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
max-width: 700px;
border-radius: 10px;
background-color: var.$white;
margin: 0 0 20px;
padding: 25px 30px 20px;

&__input {
background-color: var.$body-bg;
border: 2px solid var.$border-color;
border-radius: 10px;
margin: 0 0 5px;
padding: 10px 16px;

&_textArea {
min-height: 180px;
}
}

&__input:focus {
border: 2px solid var.$theme-primary-color;
transition: 0.7s;
}

&__label {
position: relative;
font-size: 14px;
margin: 0 0 10px;

&_date[data-no-star]::before {
content: '';
}
}

&__label::before {
content: '*';
color: var.$promo-color;
padding: 0 3px 0 0;

&_date[data-no-star]::before {
content: '';
}
}

&__checkbox {
font-size: 14px;
margin: 0 0 10px;
}

&__error {
position: absolute;
top: 62px;
left: 20px;
font-size: 12px;
font-weight: 100;
color: var.$promo-color;

&_textarea {
top: 203px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from '@storybook/react'

import FormBuyGiftCertificate from './FormBuyGiftCertificate'

const meta = {
title: 'widgets/FormBuyGiftCertificate',
component: FormBuyGiftCertificate,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
} satisfies Meta<typeof FormBuyGiftCertificate>

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {}
144 changes: 144 additions & 0 deletions src/widgets/FormBuyGiftCertificate/ui/FormBuyGiftCertificate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { Field, ErrorMessage, Formik, Form } from 'formik'

import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button/Button'
import Checkbox from '@/shared/ui/Checkbox/Checkbox'
import { Input } from '@/shared/ui/Input/Input'
import Label from '@/shared/ui/Label/Label'
import Paragraph from '@/shared/ui/Paragraph/Paragraph'
import { Textarea } from '@/shared/ui/Textarea/Textarea'

import { IFormBuyGiftCertificate } from '../model/types/types'
import { validationSchema } from '../model/validation/validation'

import styles from './FormBuyGiftCertificate.module.scss'

/**
* Форма покупки подарочного сертификата
*/

const initialValues: IFormBuyGiftCertificate = {
recipientName: '',
recipientEmail: '',
name: '',
email: '',
textArea: ''
}

const FormBuyGiftCertificate = () => {
return (
<Formik
initialValues={initialValues}
onSubmit={(values, { setSubmitting }) => {
setSubmitting(false)
}}
validationSchema={validationSchema}
validateOnBlur={true}>
{({ isSubmitting }) => (
<Form className={styles.form}>
<Paragraph>
Подарочный сертификат будет отправлен получателю после того как Вы оплатите стоимость Подарочного
сертификата.
</Paragraph>
<Label htmlFor="recipientName" className={styles.form__label}>
Имя получателя
<Field
className={styles.form__input}
as={Input}
label="Имя получателя"
name="recipientName"
placeholder="Имя получателя"
required
/>
<ErrorMessage name="recipientName" component="div" className={styles.form__error} />
</Label>
<Label htmlFor="recipientEmail" className={styles.form__label}>
Email получателя
<Field
className={styles.form__input}
as={Input}
label="Email получателя"
name="recipientEmail"
placeholder="Email получателя"
required
/>
<ErrorMessage name="recipientEmail" component="div" className={styles.form__error} />
</Label>
<Label htmlFor="name" className={styles.form__label}>
Ваше имя
<Field
className={styles.form__input}
as={Input}
label="Ваше имя"
name="name"
placeholder="Ваше имя"
required
/>
<ErrorMessage name="name" component="div" className={styles.form__error} />
</Label>
<Label htmlFor="email" className={styles.form__label}>
Ваш Email
<Field
className={styles.form__input}
as={Input}
label="Ваш Email"
name="email"
placeholder="Ваш Email"
required
/>
<ErrorMessage name="email" component="div" className={styles.form__error} />
</Label>
<fieldset className={styles.form__label}>
Тема подарочного сертификата
<Checkbox htmlFor="check" label="День рождения" name="check" value="День рождения" />
<Checkbox htmlFor="check" label="Другое" name="check" value="Другое" />
<Checkbox htmlFor="check" label="Новый год" name="check" value="Новый год" />
</fieldset>
<Label
htmlFor="textarea"
className={`${styles.form__label} ${styles.form__label_date}`}
data-no-star>
Сообщение
<Field
className={`${styles.form__input} ${styles.form__input_textArea}`}
as={Textarea}
label="Сообщение"
name="textarea"
placeholder="Сообщение"
/>
<ErrorMessage
name="textarea"
component="div"
className={`${styles.form__error} ${styles.form__error_textarea}`}
/>
</Label>
<Label htmlFor="sum" className={styles.form__label}>
Сумма (Должна быть больше 1 ₽ и меньше 1000 ₽)
<Field
className={styles.form__input}
as={Input}
label="Сумма"
name="sum"
placeholder="Сумма"
required
/>
<ErrorMessage name="sum" component="div" className={styles.form__error} />
</Label>
<fieldset className={styles.form__checkbox}>
<Checkbox
htmlFor="checkbox"
label="Я уведомлен, что подарочные сертификаты не подлежат возврату."
name="checkbox"
value="Я уведомлен, что подарочные сертификаты не подлежат возврату."
type="checkbox"
/>
</fieldset>
<Button size={ButtonSize.S} theme={ButtonTheme.PRIMARY} type="submit" disabled={isSubmitting}>
Продолжить
</Button>
</Form>
)}
</Formik>
)
}

export default FormBuyGiftCertificate

0 comments on commit 166c21f

Please sign in to comment.