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) => (
{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 (
);
};