CreateAnnonceForm.tsx 10,8 ko
Newer Older
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import Dropzone from "react-dropzone";

interface SessionUser {
    id: string;
    role: string;
}

export default function CreateAnnonceForm({ user }: { user: SessionUser }) {
    const router = useRouter();
    const [codePostal, setCodePostal] = useState("");
    const [country, setCountry] = useState("");
    const [title, setTitle] = useState("");
    const [address, setAddress] = useState("");
    const [city, setCity] = useState("");
    const [price, setPrice] = useState("");
    const [description, setDescription] = useState("");
    const [photoList, setPhotoList] = useState<File[]>([]);
    const [error, setError] = useState<string | null>(null);
    const [isSubmitting, setIsSubmitting] = useState(false);

    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        setError(null);

        if (photoList.length === 0) {
            setError("Veuillez ajouter au moins une image pour l'annonce.");
            return;
        }

        setIsSubmitting(true);

        // On utilise FormData pour envoyer les champs et les fichiers dans la même requête
        const formData = new FormData();
        formData.append("agentId", user.id);
        formData.append("title", title);
        formData.append("address", address);
        formData.append("pays", country);
        formData.append("ville", city);
        formData.append("codePostal", codePostal);
        formData.append("description", description);
        formData.append("prix", price);
        photoList.forEach((file) => {
            formData.append("images", file);
            const response = await fetch("/api/annonces", {
                method: "POST",
                body: formData,
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.message || "Une erreur est survenue lors de la création de l'annonce.");
            }
        } catch (error: any) {
            console.error("Erreur lors de la création de l'annonce:", error);
            setError(error.message);
        } finally {
            setIsSubmitting(false);
        }
    };

    return (
        <div className="flex min-h-screen flex-col items-center justify-center bg-gray-50 p-4">
            <div className="mx-auto w-full max-w-md">
                <div className="rounded-xl border border-gray-200 bg-white p-8 shadow-sm">
                    <form onSubmit={handleSubmit} className="space-y-6">
                        {/* ... (tous vos inputs restent les mêmes) ... */}
                        <div>
                            <label htmlFor="title" className="block text-sm font-medium text-gray-700">
                                Titre
                            </label>
                            <input
                                id="title"
                                type="text"
                                required
                                value={title}
                                onChange={(e) => setTitle(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="address" className="block text-sm font-medium text-gray-700">
                                Adresse
                            </label>
                            <input
                                id="address"
                                type="text"
                                required
                                value={address}
                                onChange={(e) => setAddress(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="country" className="block text-sm font-medium text-gray-700">
                                Pays
                            </label>
                            <input
                                id="country"
                                type="text"
                                required
                                value={country}
                                onChange={(e) => setCountry(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="city" className="block text-sm font-medium text-gray-700">
                                Ville
                            </label>
                            <input
                                id="city"
                                type="text"
                                required
                                value={city}
                                onChange={(e) => setCity(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="codePostal" className="block text-sm font-medium text-gray-700">
                                Code Postal
                            </label>
                            <input
                                id="codePostal"
                                type="text"
                                required
                                value={codePostal}
                                onChange={(e) => setCodePostal(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="price" className="block text-sm font-medium text-gray-700">
                                Prix
                            </label>
                            <input
                                id="price"
                                type="number"
                                required
                                value={price}
                                onChange={(e) => setPrice(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label htmlFor="description" className="block text-sm font-medium text-gray-700">
                                Description
                            </label>
                            <textarea
                                id="description"
                                required
                                value={description}
                                onChange={(e) => setDescription(e.target.value)}
                                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 text-gray-700 shadow-sm focus:border-gray-500 focus:ring-gray-500 focus:outline-none"
                            <label className="mb-2 block text-sm font-medium text-gray-700">Images</label>
                                onDrop={(acceptedFiles) => setPhotoList(acceptedFiles)}
                                    "image/png": [".png"],
                                    "image/jpeg": [".jpg", ".jpeg"],
                                    "image/svg+xml": [".svg"],
                                }}
                            >
                                {({ getRootProps, getInputProps }) => (
                                    <section>
                                        <div
                                            {...getRootProps()}
                                            className="cursor-pointer rounded-md border-2 border-dashed border-gray-300 p-4 text-center hover:bg-gray-100"
                                        >
                                            <input {...getInputProps()} />
                                            <p>Glissez-déposez vos photos ici, ou cliquez pour les sélectionner.</p>
                                            <p className="text-xs text-gray-500">
                                                Formats acceptés : PNG, JPG, JPEG, SVG
                                            </p>
                                        </div>
                                    </section>
                                )}
                            </Dropzone>
                            {photoList.length > 0 && (
                                <div className="mt-2 text-sm text-gray-600">
                                    <p>{photoList.length} fichier(s) sélectionné(s):</p>
                                    <ul className="list-inside list-disc">
                                        {photoList.map((file) => (
                                            <li key={file.name}>{file.name}</li>
                                        ))}
                                    </ul>
                                </div>
                            )}
                        </div>

                        {error && <p className="text-sm text-red-600">{error}</p>}

                        <div>
                            <button
                                type="submit"
                                disabled={isSubmitting}
                                className="flex w-full justify-center rounded-md border border-transparent bg-gray-900 px-4 py-3 text-sm font-medium text-white shadow-sm hover:bg-black focus:ring-2 focus:ring-black focus:ring-offset-2 focus:outline-none disabled:bg-gray-400"
                            >
                                {isSubmitting ? "Création en cours..." : "Ajouter l'annonce"}