Files
wamarket/components/shared/image-uploader.tsx
T
softgrey af81124d48 Initial commit: WaMarket MVP
Marketplace inversée (Next.js 16 App Router + Supabase Cloud) : auth,
schéma + RLS, publication de besoins avec upload d'images, feed avec
filtres, offres, acceptation via RPC, messagerie temps réel,
dashboards, et Dockerfile pour déploiement Coolify.
2026-07-30 14:33:17 +00:00

57 lines
1.4 KiB
TypeScript

"use client";
import { useState } from "react";
import Image from "next/image";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
export function ImageUploader({
name,
maxFiles = 5,
}: {
name: string;
maxFiles?: number;
}) {
const [previews, setPreviews] = useState<string[]>([]);
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const files = Array.from(e.target.files ?? []).slice(0, maxFiles);
setPreviews((old) => {
old.forEach((url) => URL.revokeObjectURL(url));
return files.map((file) => URL.createObjectURL(file));
});
}
return (
<div className="flex flex-col gap-2">
<Label htmlFor={name}>Photos (optionnel, {maxFiles} max)</Label>
<Input
id={name}
name={name}
type="file"
accept="image/*"
multiple
onChange={handleChange}
/>
{previews.length > 0 && (
<div className="mt-2 flex flex-wrap gap-2">
{previews.map((src, i) => (
<div
key={src}
className="relative h-20 w-20 overflow-hidden rounded-md border"
>
<Image
src={src}
alt={`Aperçu ${i + 1}`}
fill
className="object-cover"
unoptimized
/>
</div>
))}
</div>
)}
</div>
);
}