web2-client/src/pages/root/steps/price-step/index.tsx

128 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useEffect, useMemo } from "react";
import { FormLabel } from "~/shared/ui/form-label";
import { Input } from "~/shared/ui/input";
import { Button } from "~/shared/ui/button";
import { useRootStore } from "~/shared/stores/root";
import { BackButton } from "~/shared/ui/back-button";
const MIN_PRICE = 0.15;
const MIN_RESALE_PRICE = 0.15;
// const RECOMMENDED_PRICE = 0.15;
// const RECOMMENDED_RESALE_PRICE = 0.15;
type PriceStepProps = {
prevStep(): void;
nextStep(): void;
};
export const PriceStep = ({ nextStep, prevStep }: PriceStepProps) => {
const rootStore = useRootStore();
const formSchema = useMemo(() => {
const parsePrice = (value: unknown) => {
if (typeof value === "string" || typeof value === "number") {
const stringValue = value.toString().replace(",", ".");
const parsedValue = parseFloat(stringValue);
return isNaN(parsedValue) ? undefined : parsedValue;
}
return undefined;
};
if (rootStore.allowResale) {
return z.object({
price: z.preprocess(
parsePrice,
z.number({required_error: 'Цена не соответствует требованиям'}).min(MIN_PRICE, `Цена должна быть минимум ${MIN_PRICE} TON.`)
),
resaleLicensePrice: z
.preprocess(parsePrice, z.number({required_error: 'Цена не соответствует требованиям'}).min(MIN_RESALE_PRICE, `Цена копии должна быть минимум ${MIN_RESALE_PRICE} TON.`))
.optional(),
});
}
return z.object({
price: z.preprocess(
parsePrice,
z.number({required_error: 'Цена не соответствует требованиям'}).min(MIN_PRICE, `Цена должна быть минимум ${MIN_PRICE} TON.`)
),
});
}, [rootStore.allowResale]);
type FormValues = z.infer<typeof formSchema>;
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
mode: "onChange",
defaultValues: {
price: rootStore.price || MIN_PRICE,
//@ts-expect-error Fix typings
resaleLicensePrice: rootStore?.licenseResalePrice || MIN_RESALE_PRICE,
},
});
useEffect(() => {
void form.trigger();
}, [rootStore.allowResale, form]);
const handleSubmit = () => {
form.handleSubmit(async (values: FormValues) => {
try {
rootStore.setPrice(values.price);
//@ts-expect-error Fix typings
if (values?.resaleLicensePrice) {
//@ts-expect-error Fix typings
rootStore.setLicenseResalePrice(values?.resaleLicensePrice);
}
nextStep();
} catch (error) {
console.error("Error: ", error);
}
})();
};
return (
<section className={"mt-4 px-4 pb-8"}>
<BackButton onClick={prevStep} />
<div className={"mb-[30px] flex flex-col text-sm"}>
<span className={"ml-4"}>/Укажите цену</span>
<div>
4/<span className={"text-[#7B7B7B]"}>5</span>
</div>
</div>
<div className={"flex flex-col gap-[20px]"}>
<FormLabel label={"Цена продажи TON"}>
<div className={"my-2 flex flex-col gap-1.5"}>
<p className={"text-xs"}>Минимальная стоимость {MIN_PRICE} TON.</p>
{/* <p className={"text-xs"}>Рекомендуемая стоимость {RECOMMENDED_PRICE} TON.</p> */}
</div>
<Input
error={form.formState.errors?.price}
placeholder={"[ Введите цену ]"}
inputMode="decimal"
pattern="[0-9]*[.,]?[0-9]*"
{...form.register("price", {
onChange: (e) => {
const value = e.target.value;
if (!/^\d*[.,]?\d*$/.test(value)) {
e.target.value = value.replace(/[^\d.,]/g, '');
}
}
})}
/>
</FormLabel>
</div>
<Button
className={"mt-[30px]"}
onClick={handleSubmit}
includeArrows={true}
label={"Далее"}
disabled={!form.formState.isValid}
/>
</section>
);
};