feat: create order stubs (#65)

This commit is contained in:
RustamRu
2025-01-19 15:29:58 +03:00
parent 3382ae3ada
commit adb812280d
29 changed files with 540 additions and 1367 deletions

View File

@@ -18,7 +18,9 @@ import { CarBodySelectOption } from './types';
export const CarBodySelect = forwardRef<HTMLInputElement, InputProps>(
function CarBodySelect(props, ref) {
const [selected, setSelected] = useState<Partial<CarBodySelectOption>>({});
const initialOption = carBodySelectOptions.find(({ value }) => value === Number(props.value));
const [selected, setSelected] = useState<Partial<CarBodySelectOption>>(initialOption);
const handleOptionClick = (option: CarBodySelectOption) => {
setSelected(option);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@@ -1,9 +1,4 @@
import { useTranslation } from "react-i18next";
import { getConfigValue } from '@brojs/cli';
import { InputProps, SelectProps } from "@chakra-ui/react";
import dayjs from "dayjs";
import { Order } from "../../../models/landing";
import { FormFieldProps } from "./field";
import { OrderFormValues } from "./types";
@@ -31,50 +26,4 @@ export const useGetValidationRules = () => {
validate: (value: string) => isValidCarNumber(value) || t('car-number-field.invalid')
},
} satisfies Record<string, FormFieldProps['rules']>;
};
const removeAllSpaces = (str: string) => str.replace(/\s+/g, '');
const getValidCarBodyStyle = (fieldValue: string) => {
const carBodyAsNumber = Number(fieldValue);
return Number.isNaN(carBodyAsNumber) ? undefined : carBodyAsNumber;
};
export const formatFormValues = ({ phone, carNumber, carBody, carColor, carLocation, availableDatetimeBegin, availableDatetimeEnd }: OrderFormValues): Order.Create => {
return {
customer: {
phone
},
car: {
number: removeAllSpaces(carNumber),
body: getValidCarBodyStyle(carBody),
color: carColor
},
washing: {
location: carLocation,
begin: dayjs(availableDatetimeBegin).toISOString(),
end: dayjs(availableDatetimeEnd).toISOString(),
}
};
};
const endpoint = getConfigValue('dry-wash.api');
export const onSubmit = async (values: OrderFormValues) => {
const response = await fetch(`${endpoint}/order/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formatFormValues(values)),
});
if (!response.ok) {
throw new Error(`Failed to create order: ${response.status}`);
}
return await response.json();
};
export const inputCommonStyles: Partial<InputProps & SelectProps> = {
};

View File

@@ -1 +1,2 @@
export type { OrderFormValues, OrderFormProps } from './types';
export { OrderForm } from './order-form';

View File

@@ -1,4 +1,4 @@
import React, { FC } from 'react';
import React from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { Box, Flex, FormControl, FormLabel, VStack } from '@chakra-ui/react';
@@ -7,14 +7,19 @@ import { CarBodySelect } from './car-body';
import { CarColorInput } from './car-color';
import { CarNumberInput } from './car-number';
import { FormInputField, FormControllerField } from './field';
import { OrderFormValues } from './types';
import { OrderFormProps, OrderFormValues } from './types';
import { PhoneInput } from './phone';
import { SubmitButton } from './submit';
import { defaultValues, onSubmit, useGetValidationRules } from './helper';
import { defaultValues, useGetValidationRules } from './helper';
import { DateTimeInput } from './date-time';
import { LocationInput, MapComponent, StringLocation, YMapsProvider } from './location';
import {
LocationInput,
MapComponent,
StringLocation,
YMapsProvider,
} from './location';
export const OrderForm: FC = () => {
export const OrderForm = ({ onSubmit, loading }: OrderFormProps) => {
const {
handleSubmit,
control,
@@ -123,7 +128,7 @@ export const OrderForm: FC = () => {
}}
/>
</YMapsProvider>
<SubmitButton isLoading={isSubmitting} mt={4} />
<SubmitButton isLoading={isSubmitting || loading} mt={4} />
</VStack>
</Box>
);

View File

@@ -1,3 +1,5 @@
import { SubmitHandler } from "react-hook-form";
export type OrderFormValues = {
phone: string;
carNumber: string;
@@ -6,4 +8,9 @@ export type OrderFormValues = {
carLocation: string;
availableDatetimeBegin: string;
availableDatetimeEnd: string;
};
export type OrderFormProps = {
onSubmit: SubmitHandler<OrderFormValues>;
loading: boolean;
};

View File

@@ -17,7 +17,19 @@ import { carBodySelectOptions } from '../../order-form/form/car-body/helper';
import { OrderStatus } from './status';
type OrderDetailsProps = Order.View;
type OrderDetailsProps = Pick<
Order.View,
| 'id'
| 'status'
| 'phone'
| 'carNumber'
| 'carBody'
| 'carColor'
| 'location'
| 'startWashTime'
| 'endWashTime'
| 'created'
>;
export const OrderDetails: FC<OrderDetailsProps> = ({
id,
@@ -27,8 +39,8 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
carBody,
carColor,
location,
datetimeBegin,
datetimeEnd,
startWashTime,
endWashTime,
}) => {
const { t } = useTranslation('~', {
keyPrefix: 'dry-wash.order-view.details',
@@ -75,8 +87,8 @@ export const OrderDetails: FC<OrderDetailsProps> = ({
{
label: t('datetime-range'),
value: [
formatDatetime(datetimeBegin),
formatDatetime(datetimeEnd),
formatDatetime(startWashTime),
formatDatetime(endWashTime),
].join(' - '),
},
].map(({ label, value }, i) => (