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.
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { useActionState } from "react";
|
|
import Link from "next/link";
|
|
import { login } from "@/lib/actions/auth";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
|
|
export function LoginForm() {
|
|
const [state, action, pending] = useActionState(login, undefined);
|
|
|
|
return (
|
|
<Card className="w-full max-w-sm">
|
|
<CardHeader>
|
|
<CardTitle>Se connecter</CardTitle>
|
|
<CardDescription>Accède à tes besoins et tes offres.</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<form action={action} className="flex flex-col gap-4">
|
|
<div className="flex flex-col gap-2">
|
|
<Label htmlFor="email">Email</Label>
|
|
<Input id="email" name="email" type="email" placeholder="vous@exemple.com" />
|
|
{state?.errors?.email && (
|
|
<p className="text-sm text-destructive">{state.errors.email[0]}</p>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-col gap-2">
|
|
<Label htmlFor="password">Mot de passe</Label>
|
|
<Input id="password" name="password" type="password" />
|
|
{state?.errors?.password && (
|
|
<p className="text-sm text-destructive">
|
|
{state.errors.password[0]}
|
|
</p>
|
|
)}
|
|
</div>
|
|
{state?.message && (
|
|
<p className="text-sm text-destructive">{state.message}</p>
|
|
)}
|
|
<Button type="submit" disabled={pending} className="mt-2">
|
|
{pending ? "Connexion..." : "Se connecter"}
|
|
</Button>
|
|
</form>
|
|
<p className="mt-4 text-center text-sm text-muted-foreground">
|
|
Pas encore de compte ?{" "}
|
|
<Link href="/auth/signup" className="underline">
|
|
S'inscrire
|
|
</Link>
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|