/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Button, LoadingOverlay, Modal, ModalProps, NumberInput, Select, TextInput, } from "@mantine/core"; import { useForm, zodResolver } from "@mantine/form"; import _ from "lodash"; import { useEffect, useRef, useState } from "react"; import { z } from "zod"; import { createBid, updateBid } from "../../apis/bid"; import { useConfirmStore } from "../../lib/zustand/use-confirm"; import { IBid, IMetadata } from "../../system/type"; import { formatTimeFromMinutes } from "../../utils"; export interface IBidModelProps extends ModalProps { data: IBid | null; onUpdated?: () => void; } const schema = { url: z.string({ message: "Url is required" }).url("Invalid url format"), max_price: z .number({ message: "Max price is required" }) .min(1, "Max price must be at least 1"), plus_price: z.number().min(0, "Plus price must be at least 1").optional(), quantity: z.number().min(1, "Quantity must be at least 1").optional(), arrival_offset_seconds_live: z .number({ message: "Arrival offset seconds is required" }) .refine((val) => val >= 60, { message: "Arrival offset seconds must be at least 60 seconds (1 minute)", }) .optional(), early_tracking_seconds_live: z .number({ message: "Early login seconds is required" }) .refine((val) => val >= 600, { message: "Early login seconds must be at least 600 seconds (10 minute)", }) .optional(), arrival_offset_seconds_sandbox: z .number({ message: "Arrival offset seconds is required" }) .refine((val) => val >= 60, { message: "Arrival offset seconds must be at least 60 seconds (1 minute)", }) .optional(), early_tracking_seconds_sandbox: z .number({ message: "Early login seconds is required" }) .refine((val) => val >= 600, { message: "Early login seconds must be at least 600 seconds (10 minute)", }) .optional(), }; export default function BidModal({ data, onUpdated, ...props }: IBidModelProps) { const form = useForm({ validate: zodResolver(z.object(schema)), }); const prevData = useRef(data); const { setConfirm } = useConfirmStore(); const [loading, setLoading] = useState(false); const handleSubmit = async (values: typeof form.values) => { if (data) { setConfirm({ title: "Update ?", message: `This product will be update`, handleOk: async () => { setLoading(true); const metadata = valuesToMetadata( values as IBid & Record ); const result = await updateBid({ ...values, metadata }); setLoading(false); if (!result) return; props.onClose(); if (onUpdated) { onUpdated(); } }, okButton: { color: "blue", value: "Update", }, }); } else { const { url, max_price, plus_price } = values; setLoading(true); const result = await createBid({ url, max_price, plus_price } as IBid); setLoading(false); if (!result) return; props.onClose(); if (onUpdated) { onUpdated(); } } }; const mappingValues = (ignore: string[] = []) => { if (!data) return {}; let values: IBid & Record = data; const followKey = ["arrival_offset_seconds", "early_tracking_seconds"]; if ( data.metadata.length && data.metadata.some((item) => item.key_name === "mode_key") ) { data.metadata.reduce((prev, cur) => { if (ignore.includes(cur.key_name)) { prev[cur.key_name as string] = form.values[cur.key_name]; return prev; } if (cur.key_name === "mode_key") { prev[cur.key_name as string] = cur.value; return prev; } prev[cur.key_name as string] = cur.value; return prev; }, values); } else { const metadata = Object.assign( { mode_key: "live" }, ...followKey.map((item) => ({ [`${item}_live`]: data.web_bid[item as keyof typeof data.web_bid], [`${item}_sandbox`]: data.web_bid[item as keyof typeof data.web_bid], })) ); values = { ...values, ...metadata }; } return values; }; const valuesToMetadata = (values: IBid & Record) => { const keys = [ "mode_key", "arrival_offset_seconds_live", "arrival_offset_seconds_sandbox", "early_tracking_seconds_live", "early_tracking_seconds_sandbox", ]; if (values.metadata.length <= 0) { return keys.map((item) => { return { key_name: item, value: values[item], } as IMetadata; }); } return values.metadata.map((item) => { return { ...item, value: values[item.key_name], }; }); }; useEffect(() => { form.reset(); if (!data) return; const values = mappingValues(); form.setValues(values); prevData.current = data; // eslint-disable-next-line react-hooks/exhaustive-deps }, [data]); useEffect(() => { if (!props.opened) { form.reset(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.opened]); useEffect(() => { const values = mappingValues(["mode_key"]); form.setValues(values); prevData.current = data; // eslint-disable-next-line react-hooks/exhaustive-deps }, [form.values["mode_key"]]); return ( Bid} centered >
{!!data && (