Files
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

65 lines
2.1 KiB
TypeScript

"use client";
import { useActionState } from "react";
import { createOffer } from "@/lib/actions/offers";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { ImageUploader } from "@/components/shared/image-uploader";
export function OfferForm({ needId }: { needId: string }) {
const [state, action, pending] = useActionState(createOffer, undefined);
return (
<form action={action} className="flex flex-col gap-4">
<input type="hidden" name="needId" value={needId} />
<div className="flex flex-col gap-2">
<Label htmlFor="offer-title">Titre de l&apos;offre</Label>
<Input
id="offer-title"
name="title"
placeholder="Ex: Intervention sous 48h avec garantie"
/>
{state?.errors?.title && (
<p className="text-sm text-destructive">{state.errors.title[0]}</p>
)}
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="offer-description">Description</Label>
<Textarea
id="offer-description"
name="description"
rows={4}
placeholder="Détaille ce que tu proposes, tes conditions, ton expérience..."
/>
{state?.errors?.description && (
<p className="text-sm text-destructive">
{state.errors.description[0]}
</p>
)}
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="offer-price">Prix ()</Label>
<Input id="offer-price" name="price" type="number" min="0" step="0.01" />
{state?.errors?.price && (
<p className="text-sm text-destructive">{state.errors.price[0]}</p>
)}
</div>
<ImageUploader name="images" maxFiles={5} />
{state?.message && (
<p className="text-sm text-destructive">{state.message}</p>
)}
<Button type="submit" disabled={pending} className="mt-2 w-fit">
{pending ? "Envoi..." : "Envoyer l'offre"}
</Button>
</form>
);
}