import { useForm, Controller } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import { useTranslation } from "react-i18next"; import type { OrderRequestDTO } from "@/types/OrderType"; import { useOrder } from "@/hooks/useOrder"; import { useProfile } from "@/hooks/useProfile"; import { getAllCountries } from "@/utils/countries"; import Select from "react-select"; import { toast } from "sonner"; import { useNavigate } from "react-router-dom"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { MapPin, Flag, PackageCheck, Loader2, User } from "lucide-react"; interface OrderFormModalProps { isOpen: boolean; onClose: () => void; } const formatOptionLabel = ({ label, cca2 }: any) => (
flag {label}
); export const OrderFormModal = ({ isOpen, onClose }: OrderFormModalProps) => { const { t } = useTranslation(); const { createOrder } = useOrder(); const navigate = useNavigate(); const { user, loading: isUserLoading } = useProfile(); const countries = getAllCountries(); const locationSchema = z.object({ streetAddress: z.string().min(3, t("validation.streetMin", "Ulica jest za krótka")), postalCode: z.string().regex(/^\d{2}-\d{3}$/, t("validation.postalCode", "Niepoprawny kod")), city: z.string().min(2, t("validation.cityMin", "Miasto za krótkie")), country: z.string().length(3, t("validation.countryMin", "Wybierz kraj")), }); const orderSchema = z.object({ weight: z .number({ message: t("validation.positiveWeight", "Waga musi być dodatnia") }) .positive(t("validation.positiveWeight", "Waga musi być dodatnia")), volume: z .number({ message: t("validation.positiveVolume", "Objętość musi być dodatnia") }) .positive(t("validation.positiveVolume", "Objętość musi być dodatnia")), recipientFirstName: z.string().min(2, t("validation.required", "Wymagane")), recipientLastName: z.string().min(2, t("validation.required", "Wymagane")), recipientEmail: z.string().email(t("validation.email", "Niepoprawny email")), recipientPhone: z.string().min(9, t("validation.phone", "Niepoprawny telefon")), pickupLocation: locationSchema, deliveryLocation: locationSchema, }); type OrderFormValues = z.infer; const { register, handleSubmit, reset, control, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(orderSchema), defaultValues: { pickupLocation: { country: "POL" }, deliveryLocation: { country: "POL" }, }, }); const onSubmit = async (data: OrderFormValues) => { if (!user || !user.id) { toast.error( t( "errors.userNotFound", "Nie można zidentyfikować użytkownika. Spróbuj zalogować się ponownie.", ), ); return; } const payload: OrderRequestDTO = { ...data, customerId: user.id, }; try { const createdOrder = await createOrder(payload); if (!createdOrder || !createdOrder.id) { throw new Error("Missing order ID in response"); } reset(); onClose(); const calculatedAmount = data.weight * 5 + data.volume * 10; navigate(`/payment/${createdOrder.id}`, { state: { amount: calculatedAmount, customerEmail: user.email } }); } catch (error) { console.error("There was an error creating the order:", error); toast.error("Błąd podczas tworzenia zamówienia."); } }; const handleOpenChange = (open: boolean) => { if (!open) { reset(); onClose(); } }; const fillTestData = () => { const testData: OrderFormValues = { recipientFirstName: "Jan", recipientLastName: "Testowy", recipientEmail: "boatdelivery0@gmail.com", recipientPhone: "573583371", weight: 2.5, volume: 5.0, pickupLocation: { streetAddress: "Piotrkowska 100", postalCode: "90-004", city: "Łódź", country: "POL" }, deliveryLocation: { streetAddress: "Piotrkowska 10", postalCode: "90-270", city: "Łódź", country: "POL" }, }; reset(testData); }; return ( {t("orders.newOrder")} {isUserLoading ? (

{t("orders.loadingProfile", "Pobieranie danych użytkownika...")}

) : (

{t("orders.recipientData", "Dane Odbiorcy")}

{errors.recipientFirstName && (

{errors.recipientFirstName.message}

)}
{errors.recipientLastName && (

{errors.recipientLastName.message}

)}
{errors.recipientEmail && (

{errors.recipientEmail.message}

)}
{errors.recipientPhone && (

{errors.recipientPhone.message}

)}
{errors.weight && (

{errors.weight.message}

)}
{errors.volume && (

{errors.volume.message}

)}

{t("orders.pickup")}

{errors.pickupLocation?.streetAddress && (

{errors.pickupLocation.streetAddress.message}

)}
{ let val = e.target.value.replace(/\D/g, ""); if (val.length > 2) { val = val.slice(0, 2) + "-" + val.slice(2, 5); } e.target.value = val; }, })} className={ errors.pickupLocation?.postalCode ? "border-destructive focus-visible:ring-destructive" : "" } /> {errors.pickupLocation?.postalCode && (

{errors.pickupLocation.postalCode.message}

)}
{errors.pickupLocation?.city && (

{errors.pickupLocation.city.message}

)}
( {errors.deliveryLocation?.streetAddress && (

{errors.deliveryLocation.streetAddress.message}

)}
{ let val = e.target.value.replace(/\D/g, ""); if (val.length > 2) { val = val.slice(0, 2) + "-" + val.slice(2, 5); } e.target.value = val; }, })} className={ errors.deliveryLocation?.postalCode ? "border-destructive focus-visible:ring-destructive" : "" } /> {errors.deliveryLocation?.postalCode && (

{errors.deliveryLocation.postalCode.message}

)}
{errors.deliveryLocation?.city && (

{errors.deliveryLocation.city.message}

)}
(