120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import Card from "@/components/ui/Card";
|
|
import Button from "@/components/ui/Button";
|
|
import {
|
|
acceptRequest,
|
|
rejectRequest,
|
|
} from "@/actions/houses/requests";
|
|
import Alert from "@/components/ui/Alert";
|
|
|
|
interface Request {
|
|
id: string;
|
|
requester: {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
};
|
|
status: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
interface RequestListProps {
|
|
requests: Request[];
|
|
onUpdate?: () => void;
|
|
}
|
|
|
|
export default function RequestList({
|
|
requests,
|
|
onUpdate,
|
|
}: RequestListProps) {
|
|
const [isPending, startTransition] = useTransition();
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const handleAccept = (requestId: string) => {
|
|
setError(null);
|
|
startTransition(async () => {
|
|
const result = await acceptRequest(requestId);
|
|
if (result.success) {
|
|
onUpdate?.();
|
|
} else {
|
|
setError(result.error || "Erreur lors de l'acceptation");
|
|
}
|
|
});
|
|
};
|
|
|
|
const handleReject = (requestId: string) => {
|
|
setError(null);
|
|
startTransition(async () => {
|
|
const result = await rejectRequest(requestId);
|
|
if (result.success) {
|
|
onUpdate?.();
|
|
} else {
|
|
setError(result.error || "Erreur lors du refus");
|
|
}
|
|
});
|
|
};
|
|
|
|
if (requests.length === 0) {
|
|
return (
|
|
<p className="text-sm" style={{ color: "var(--muted-foreground)" }}>
|
|
Aucune demande en attente
|
|
</p>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{error && <Alert variant="error">{error}</Alert>}
|
|
{requests.map((request) => (
|
|
<Card key={request.id} className="p-4">
|
|
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3">
|
|
<div className="flex-1 min-w-0">
|
|
<h4 className="font-bold mb-1 break-words" style={{ color: "var(--foreground)" }}>
|
|
{request.requester.username}
|
|
</h4>
|
|
<p className="text-sm break-words" style={{ color: "var(--muted-foreground)" }}>
|
|
souhaite rejoindre votre maison
|
|
</p>
|
|
</div>
|
|
{request.status === "PENDING" && (
|
|
<div className="flex gap-2 sm:flex-nowrap">
|
|
<Button
|
|
onClick={() => handleAccept(request.id)}
|
|
disabled={isPending}
|
|
variant="success"
|
|
size="sm"
|
|
className="flex-1 sm:flex-none"
|
|
>
|
|
Accepter
|
|
</Button>
|
|
<Button
|
|
onClick={() => handleReject(request.id)}
|
|
disabled={isPending}
|
|
variant="danger"
|
|
size="sm"
|
|
className="flex-1 sm:flex-none"
|
|
>
|
|
Refuser
|
|
</Button>
|
|
</div>
|
|
)}
|
|
{request.status === "ACCEPTED" && (
|
|
<span className="text-xs flex-shrink-0" style={{ color: "var(--success)" }}>
|
|
✓ Acceptée
|
|
</span>
|
|
)}
|
|
{request.status === "REJECTED" && (
|
|
<span className="text-xs flex-shrink-0" style={{ color: "var(--destructive)" }}>
|
|
✗ Refusée
|
|
</span>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|