refactor: apply consistent formatting to improve code quality
Some checks failed
Deploy to Production / deploy (push) Failing after 2m20s
Lint / lint (push) Successful in 9m37s

Ensure uniform code formatting across components by aligning with the established code style. Adjust imports, indentation, and spacing to enhance readability and maintainability.
This commit is contained in:
Mathis HERRIOT
2026-01-14 17:26:58 +01:00
parent 03e5915fcc
commit 35abd0496e
95 changed files with 6839 additions and 6659 deletions

View File

@@ -1,257 +1,283 @@
"use client";
import * as React from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Upload, Image as ImageIcon, Film, X, Loader2 } from "lucide-react";
import { Image as ImageIcon, Loader2, Upload, X } from "lucide-react";
import NextImage from "next/image";
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, CardHeader, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
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(),
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<typeof uploadSchema>;
export default function UploadPage() {
const router = useRouter();
const [categories, setCategories] = React.useState<Category[]>([]);
const [file, setFile] = React.useState<File | null>(null);
const [preview, setPreview] = React.useState<string | null>(null);
const [isUploading, setIsUploading] = React.useState(false);
const router = useRouter();
const [categories, setCategories] = React.useState<Category[]>([]);
const [file, setFile] = React.useState<File | null>(null);
const [preview, setPreview] = React.useState<string | null>(null);
const [isUploading, setIsUploading] = React.useState(false);
const form = useForm<UploadFormValues>({
resolver: zodResolver(uploadSchema),
defaultValues: {
title: "",
type: "meme",
tags: "",
},
});
const form = useForm<UploadFormValues>({
resolver: zodResolver(uploadSchema),
defaultValues: {
title: "",
type: "meme",
tags: "",
},
});
React.useEffect(() => {
CategoryService.getAll().then(setCategories).catch(console.error);
}, []);
React.useEffect(() => {
CategoryService.getAll().then(setCategories).catch(console.error);
}, []);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
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 handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
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;
}
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 !== "");
tagsArray.forEach(tag => formData.append("tags[]", tag));
}
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: any) {
console.error("Upload failed:", error);
toast.error(error.response?.data?.message || "Échec de l'upload. Êtes-vous connecté ?");
} finally {
setIsUploading(false);
}
};
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 (
<div className="max-w-2xl mx-auto py-8 px-4">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Upload className="h-5 w-5" />
Partager un mème
</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<div className="space-y-4">
<FormLabel>Fichier (Image ou GIF)</FormLabel>
{!preview ? (
<div
className="border-2 border-dashed rounded-lg p-12 flex flex-col items-center justify-center bg-zinc-50 dark:bg-zinc-900 cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors"
onClick={() => document.getElementById("file-upload")?.click()}
>
<div className="bg-primary/10 p-4 rounded-full mb-4">
<ImageIcon className="h-8 w-8 text-primary" />
</div>
<p className="font-medium">Cliquez pour choisir un fichier</p>
<p className="text-xs text-muted-foreground mt-1">PNG, JPG ou GIF jusqu'à 10Mo</p>
<input
id="file-upload"
type="file"
className="hidden"
accept="image/*,.gif"
onChange={handleFileChange}
/>
</div>
) : (
<div className="relative rounded-lg overflow-hidden border bg-zinc-100 dark:bg-zinc-800">
<img
src={preview}
alt="Preview"
className="max-h-[400px] mx-auto object-contain"
/>
<Button
type="button"
variant="destructive"
size="icon"
className="absolute top-2 right-2 rounded-full"
onClick={() => {
setFile(null);
setPreview(null);
}}
>
<X className="h-4 w-4" />
</Button>
</div>
)}
</div>
return (
<div className="max-w-2xl mx-auto py-8 px-4">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Upload className="h-5 w-5" />
Partager un mème
</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<div className="space-y-4">
<FormLabel>Fichier (Image ou GIF)</FormLabel>
{!preview ? (
<button
type="button"
className="w-full border-2 border-dashed rounded-lg p-12 flex flex-col items-center justify-center bg-zinc-50 dark:bg-zinc-900 cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors"
onClick={() => document.getElementById("file-upload")?.click()}
>
<div className="bg-primary/10 p-4 rounded-full mb-4">
<ImageIcon className="h-8 w-8 text-primary" />
</div>
<p className="font-medium">Cliquez pour choisir un fichier</p>
<p className="text-xs text-muted-foreground mt-1">
PNG, JPG ou GIF jusqu'à 10Mo
</p>
<input
id="file-upload"
type="file"
className="hidden"
accept="image/*,.gif"
onChange={handleFileChange}
/>
</button>
) : (
<div className="relative rounded-lg overflow-hidden border bg-zinc-100 dark:bg-zinc-800">
<div className="relative h-[400px] w-full">
<NextImage
src={preview}
alt="Preview"
fill
className="object-contain"
/>
</div>
<Button
type="button"
variant="destructive"
size="icon"
className="absolute top-2 right-2 rounded-full z-10"
onClick={() => {
setFile(null);
setPreview(null);
}}
>
<X className="h-4 w-4" />
</Button>
</div>
)}
</div>
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Titre</FormLabel>
<FormControl>
<Input placeholder="Un titre génial pour votre mème..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Titre</FormLabel>
<FormControl>
<Input placeholder="Un titre génial pour votre mème..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<FormLabel>Format</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Sélectionnez un format" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="meme">Image fixe</SelectItem>
<SelectItem value="gif">GIF Animé</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<FormLabel>Format</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Sélectionnez un format" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="meme">Image fixe</SelectItem>
<SelectItem value="gif">GIF Animé</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="categoryId"
render={({ field }) => (
<FormItem>
<FormLabel>Catégorie</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Sélectionnez une catégorie" />
</SelectTrigger>
</FormControl>
<SelectContent>
{categories.map(cat => (
<SelectItem key={cat.id} value={cat.id}>{cat.name}</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="categoryId"
render={({ field }) => (
<FormItem>
<FormLabel>Catégorie</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Sélectionnez une catégorie" />
</SelectTrigger>
</FormControl>
<SelectContent>
{categories.map((cat) => (
<SelectItem key={cat.id} value={cat.id}>
{cat.name}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="tags"
render={({ field }) => (
<FormItem>
<FormLabel>Tags</FormLabel>
<FormControl>
<Input placeholder="funny, coding, goat..." {...field} />
</FormControl>
<FormDescription>
Séparez les tags par des virgules.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="tags"
render={({ field }) => (
<FormItem>
<FormLabel>Tags</FormLabel>
<FormControl>
<Input placeholder="funny, coding, goat..." {...field} />
</FormControl>
<FormDescription>Séparez les tags par des virgules.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full" disabled={isUploading}>
{isUploading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Upload en cours...
</>
) : (
"Publier le mème"
)}
</Button>
</form>
</Form>
</CardContent>
</Card>
</div>
);
<Button type="submit" className="w-full" disabled={isUploading}>
{isUploading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Upload en cours...
</>
) : (
"Publier le mème"
)}
</Button>
</form>
</Form>
</CardContent>
</Card>
</div>
);
}