"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { Image as ImageIcon, Loader2, LogIn, Upload, X } from "lucide-react"; import NextImage from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import * as React from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import * as z from "zod"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Spinner } from "@/components/ui/spinner"; import { useAuth } from "@/providers/auth-provider"; import { CategoryService } from "@/services/category.service"; import { ContentService } from "@/services/content.service"; import type { Category } from "@/types/content"; const uploadSchema = z.object({ title: z.string().min(3, "Le titre doit faire au moins 3 caractères"), type: z.enum(["meme", "gif"]), categoryId: z.string().optional(), tags: z.string().optional(), }); type UploadFormValues = z.infer; export default function UploadPage() { const router = useRouter(); const { isAuthenticated, isLoading } = useAuth(); const [categories, setCategories] = React.useState([]); const [file, setFile] = React.useState(null); const [preview, setPreview] = React.useState(null); const [isUploading, setIsUploading] = React.useState(false); const form = useForm({ resolver: zodResolver(uploadSchema), defaultValues: { title: "", type: "meme", tags: "", }, }); React.useEffect(() => { if (isAuthenticated) { CategoryService.getAll().then(setCategories).catch(console.error); } }, [isAuthenticated]); if (isLoading) { return (
); } if (!isAuthenticated) { return (
Connexion requise Vous devez être connecté pour partager vos meilleurs mèmes avec la communauté.
); } const handleFileChange = (e: React.ChangeEvent) => { const selectedFile = e.target.files?.[0]; if (selectedFile) { if (selectedFile.size > 10 * 1024 * 1024) { toast.error("Le fichier est trop volumineux (max 10Mo)"); return; } setFile(selectedFile); const reader = new FileReader(); reader.onloadend = () => { setPreview(reader.result as string); }; reader.readAsDataURL(selectedFile); } }; const onSubmit = async (values: UploadFormValues) => { if (!file) { toast.error("Veuillez sélectionner un fichier"); return; } setIsUploading(true); try { const formData = new FormData(); formData.append("file", file); formData.append("title", values.title); formData.append("type", values.type); if (values.categoryId) formData.append("categoryId", values.categoryId); if (values.tags) { const tagsArray = values.tags .split(",") .map((t) => t.trim()) .filter((t) => t !== ""); for (const tag of tagsArray) { formData.append("tags[]", tag); } } await ContentService.upload(formData); toast.success("Mème uploadé avec succès !"); router.push("/"); } catch (error: unknown) { console.error("Upload failed:", error); let errorMessage = "Échec de l'upload. Êtes-vous connecté ?"; if ( error && typeof error === "object" && "response" in error && error.response && typeof error.response === "object" && "data" in error.response && error.response.data && typeof error.response.data === "object" && "message" in error.response.data && typeof error.response.data.message === "string" ) { errorMessage = error.response.data.message; } toast.error(errorMessage); } finally { setIsUploading(false); } }; return (
Partager un mème
Fichier (Image ou GIF) {!preview ? ( ) : (
)}
( Titre )} />
( Format )} /> ( Catégorie )} />
( Tags Séparez les tags par des virgules. )} />
); }