diff --git a/locales/en.json b/locales/en.json index fca6625..5c1b66c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -26,6 +26,17 @@ "dry-wash.order-create.form.washing-location-field.label": "Where is the car located?", "dry-wash.order-create.form.washing-location-field.placeholder": "Enter the address or select on the map", "dry-wash.order-create.form.washing-location-field.help": "For example, 55.754364, 48.743295 Universitetskaya Street, 1, Innopolis, Verkhneuslonsky district, Republic of Tatarstan (Tatarstan), 420500", + "dry-wash.order-create.car-color-select.placeholder": "Input color", + "dry-wash.order-create.car-color-select.custom": "Custom", + "dry-wash.order-create.car-color-select.custom-label": "Custom:", + "dry-wash.order-create.car-color-select.colors.white": "White", + "dry-wash.order-create.car-color-select.colors.black": "Black", + "dry-wash.order-create.car-color-select.colors.silver": "Silver", + "dry-wash.order-create.car-color-select.colors.gray": "Gray", + "dry-wash.order-create.car-color-select.colors.beige-brown": "Beige Brown", + "dry-wash.order-create.car-color-select.colors.red": "Red", + "dry-wash.order-create.car-color-select.colors.blue": "Blue", + "dry-wash.order-create.car-color-select.colors.green": "Green", "dry-wash.order-create.car-body-select.placeholder": "Not specified", "dry-wash.order-create.car-body-select.options.sedan": "Sedan", "dry-wash.order-create.car-body-select.options.hatchback" : "Hatchback", diff --git a/locales/ru.json b/locales/ru.json index 6155f3f..b67ed19 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -81,6 +81,17 @@ "dry-wash.order-create.form.washing-location-field.label": "Где находится автомобиль?", "dry-wash.order-create.form.washing-location-field.placeholder": "Введите адрес или выберите на карте", "dry-wash.order-create.form.washing-location-field.help": "Например, 55.754364, 48.743295 Университетская улица, 1, Иннополис, Верхнеуслонский район, Республика Татарстан (Татарстан), 420500", + "dry-wash.order-create.car-color-select.placeholder": "Введите цвет", + "dry-wash.order-create.car-color-select.custom": "Другой", + "dry-wash.order-create.car-color-select.custom-label": "Другой:", + "dry-wash.order-create.car-color-select.colors.white": "Белый", + "dry-wash.order-create.car-color-select.colors.black": "Черный", + "dry-wash.order-create.car-color-select.colors.silver": "Серебристый", + "dry-wash.order-create.car-color-select.colors.gray": "Серый", + "dry-wash.order-create.car-color-select.colors.beige-brown": "Бежево-коричневый", + "dry-wash.order-create.car-color-select.colors.red": "Красный", + "dry-wash.order-create.car-color-select.colors.blue": "Синий", + "dry-wash.order-create.car-color-select.colors.green": "Зеленый", "dry-wash.order-create.car-body-select.placeholder": "Не указан", "dry-wash.order-create.car-body-select.options.sedan": "Седан", "dry-wash.order-create.car-body-select.options.hatchback": "Хэтчбек", diff --git a/src/components/order-form/form/car-color/car-color-input.tsx b/src/components/order-form/form/car-color/car-color-input.tsx deleted file mode 100644 index 0bf94f3..0000000 --- a/src/components/order-form/form/car-color/car-color-input.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { forwardRef, useId } from 'react'; -import { Input, InputProps } from '@chakra-ui/react'; - -import { CAR_COLORS } from './helper'; - -export const CarColorInput = forwardRef( - function CarColorInput(props, ref) { - const listId = useId(); - - return ( - <> - - - {CAR_COLORS.map(({ code, name }) => ( - - ))} - - - ); - }, -); - -// todo: add option color visual indication \ No newline at end of file diff --git a/src/components/order-form/form/car-color/car-color-select.tsx b/src/components/order-form/form/car-color/car-color-select.tsx new file mode 100644 index 0000000..cf591b2 --- /dev/null +++ b/src/components/order-form/form/car-color/car-color-select.tsx @@ -0,0 +1,162 @@ +import React, { forwardRef, useState } from 'react'; +import { + Input, + Box, + Stack, + Text, + Flex, +} from '@chakra-ui/react'; +import { useTranslation } from 'react-i18next'; + +import { CAR_COLORS } from './helper'; + +interface CarColorSelectProps { + value?: string; + onChange?: (event: React.ChangeEvent) => void; + name?: string; + isInvalid?: boolean; +} + +export const CarColorSelect = forwardRef( + function CarColorSelect(props) { + const [customColor, setCustomColor] = useState(''); + const [isCustom, setIsCustom] = useState(false); + + const handleColorChange = (value: string) => { + if (value === 'custom') { + setIsCustom(true); + return; + } + setIsCustom(false); + props.onChange?.({ + target: { value }, + } as React.ChangeEvent); + }; + + const handleCustomColorChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setCustomColor(value); + props.onChange?.({ + target: { value }, + } as React.ChangeEvent); + }; + + const { t } = useTranslation('~', { + keyPrefix: 'dry-wash.order-create.car-color-select', + }); + + const currentValue = isCustom ? 'custom' : props.value; + + return ( + + + {CAR_COLORS.map(({ name, code }) => ( + handleColorChange(name)} + > + + + + {currentValue === name && ( + + {t(`colors.${name}`)} + + )} + + + + ))} + handleColorChange('custom')} + > + + {isCustom ? ( + + + {t('custom-label')} + + e.stopPropagation()} + borderColor="primary.200" + _focus={{ + borderColor: 'primary.500', + boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)' + }} + /> + + ) : ( + + + + {t('custom')} + + + )} + + + + + ); + }, +); \ No newline at end of file diff --git a/src/components/order-form/form/car-color/helper.ts b/src/components/order-form/form/car-color/helper.ts index b080ed1..60de538 100644 --- a/src/components/order-form/form/car-color/helper.ts +++ b/src/components/order-form/form/car-color/helper.ts @@ -1,4 +1,4 @@ -export const CAR_COLORS: Record<'name' | 'code', string>[] = [ +export const CAR_COLORS = [ { name: 'white', code: '#ffffff' @@ -31,4 +31,4 @@ export const CAR_COLORS: Record<'name' | 'code', string>[] = [ name: 'green', code: '#078d51' }, -]; \ No newline at end of file +] as const satisfies { name: string; code: string }[]; \ No newline at end of file diff --git a/src/components/order-form/form/car-color/index.ts b/src/components/order-form/form/car-color/index.ts index 4cc34e5..bc310dd 100644 --- a/src/components/order-form/form/car-color/index.ts +++ b/src/components/order-form/form/car-color/index.ts @@ -1 +1 @@ -export { CarColorInput } from './car-color-input'; \ No newline at end of file +export { CarColorSelect } from './car-color-select'; \ No newline at end of file diff --git a/src/components/order-form/form/order-form.tsx b/src/components/order-form/form/order-form.tsx index f024275..d429d5c 100644 --- a/src/components/order-form/form/order-form.tsx +++ b/src/components/order-form/form/order-form.tsx @@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'; import { Box, Flex, FormControl, FormLabel, VStack } from '@chakra-ui/react'; import { CarBodySelect } from './car-body'; -import { CarColorInput } from './car-color'; import { CarNumberInput } from './car-number'; import { FormInputField, FormControllerField } from './field'; import { OrderFormProps, OrderFormValues } from './types'; @@ -18,6 +17,7 @@ import { StringLocation, YMapsProvider, } from './location'; +import { CarColorSelect } from './car-color'; export const OrderForm = ({ onSubmit, loading, ...props }: OrderFormProps) => { const { @@ -72,7 +72,7 @@ export const OrderForm = ({ onSubmit, loading, ...props }: OrderFormProps) => { name='carColor' label={t('car-color-field.label')} errors={errors} - Input={CarColorInput} + Input={CarColorSelect} />