All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m37s
247 lines
6.8 KiB
TypeScript
247 lines
6.8 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import { useSession } from "next-auth/react";
|
|
import Card from "@/components/ui/Card";
|
|
import Button from "@/components/ui/Button";
|
|
import SectionTitle from "@/components/ui/SectionTitle";
|
|
import BackgroundSection from "@/components/ui/BackgroundSection";
|
|
import HouseCard from "./HouseCard";
|
|
import HouseForm from "./HouseForm";
|
|
import HouseManagement from "./HouseManagement";
|
|
import InvitationList from "./InvitationList";
|
|
import Input from "@/components/ui/Input";
|
|
|
|
interface House {
|
|
id: string;
|
|
name: string;
|
|
description: string | null;
|
|
creator: {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
};
|
|
memberships?: Array<{
|
|
id: string;
|
|
role: string;
|
|
user: {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
score?: number;
|
|
level?: number;
|
|
};
|
|
}>;
|
|
_count?: {
|
|
memberships: number;
|
|
};
|
|
}
|
|
|
|
interface User {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
}
|
|
|
|
interface HousesSectionProps {
|
|
initialHouses?: House[];
|
|
initialMyHouse?: House | null;
|
|
initialUsers?: User[];
|
|
initialInvitations?: Array<{
|
|
id: string;
|
|
house: {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
inviter: {
|
|
id: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
};
|
|
status: string;
|
|
createdAt: string;
|
|
}>;
|
|
backgroundImage: string;
|
|
}
|
|
|
|
export default function HousesSection({
|
|
initialHouses = [],
|
|
initialMyHouse = null,
|
|
initialUsers = [],
|
|
initialInvitations = [],
|
|
backgroundImage,
|
|
}: HousesSectionProps) {
|
|
const { data: session } = useSession();
|
|
const [houses, setHouses] = useState<House[]>(initialHouses);
|
|
const [myHouse, setMyHouse] = useState<House | null>(initialMyHouse);
|
|
const [invitations, setInvitations] = useState(initialInvitations);
|
|
const [showCreateForm, setShowCreateForm] = useState(false);
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
|
|
const fetchHouses = async () => {
|
|
try {
|
|
const params = new URLSearchParams();
|
|
if (searchTerm) {
|
|
params.append("search", searchTerm);
|
|
}
|
|
params.append("include", "members,creator");
|
|
|
|
const response = await fetch(`/api/houses?${params}`);
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setHouses(data);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching houses:", error);
|
|
}
|
|
};
|
|
|
|
const fetchMyHouse = async () => {
|
|
try {
|
|
const response = await fetch("/api/houses/my-house");
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setMyHouse(data);
|
|
} else if (response.status === 404) {
|
|
setMyHouse(null);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching my house:", error);
|
|
}
|
|
};
|
|
|
|
const fetchInvitations = async () => {
|
|
try {
|
|
const response = await fetch("/api/invitations?status=PENDING");
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setInvitations(data);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching invitations:", error);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (searchTerm) {
|
|
const timeout = setTimeout(() => {
|
|
fetchHouses();
|
|
}, 300);
|
|
return () => clearTimeout(timeout);
|
|
} else {
|
|
fetchHouses();
|
|
}
|
|
}, [searchTerm]);
|
|
|
|
const handleUpdate = () => {
|
|
fetchMyHouse();
|
|
fetchHouses();
|
|
fetchInvitations();
|
|
};
|
|
|
|
const filteredHouses = houses.filter((house) => {
|
|
if (!myHouse) return true;
|
|
return house.id !== myHouse.id;
|
|
});
|
|
|
|
return (
|
|
<BackgroundSection backgroundImage={backgroundImage}>
|
|
{/* Title Section */}
|
|
<SectionTitle
|
|
variant="gradient"
|
|
size="xl"
|
|
subtitle="Rejoignez une maison ou créez la vôtre"
|
|
className="mb-16"
|
|
>
|
|
MAISONS
|
|
</SectionTitle>
|
|
<p className="text-gray-400 text-sm max-w-2xl mx-auto text-center mb-16">
|
|
Formez des équipes, créez votre propre maison et rivalisez avec les
|
|
autres maisons pour dominer le classement collectif
|
|
</p>
|
|
|
|
<div className="space-y-4 sm:space-y-6">
|
|
{session?.user && (
|
|
<>
|
|
{invitations.length > 0 && (
|
|
<Card className="p-4 sm:p-6">
|
|
<h2 className="text-lg sm:text-xl font-bold mb-4" style={{ color: "var(--foreground)" }}>
|
|
Mes Invitations
|
|
</h2>
|
|
<InvitationList invitations={invitations} onUpdate={handleUpdate} />
|
|
</Card>
|
|
)}
|
|
|
|
<Card className="p-4 sm:p-6">
|
|
<h2 className="text-lg sm:text-xl font-bold mb-4" style={{ color: "var(--foreground)" }}>
|
|
Ma Maison
|
|
</h2>
|
|
{myHouse ? (
|
|
<HouseManagement
|
|
house={myHouse}
|
|
users={initialUsers}
|
|
onUpdate={handleUpdate}
|
|
/>
|
|
) : (
|
|
<div>
|
|
{showCreateForm ? (
|
|
<HouseForm
|
|
onSuccess={() => {
|
|
setShowCreateForm(false);
|
|
handleUpdate();
|
|
}}
|
|
onCancel={() => setShowCreateForm(false)}
|
|
/>
|
|
) : (
|
|
<div>
|
|
<p className="text-sm mb-4 break-words" style={{ color: "var(--muted-foreground)" }}>
|
|
Vous n'êtes membre d'aucune maison. Créez-en une ou demandez à rejoindre une maison existante.
|
|
</p>
|
|
<Button
|
|
onClick={() => setShowCreateForm(true)}
|
|
variant="primary"
|
|
className="w-full sm:w-auto"
|
|
>
|
|
Créer une maison
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</Card>
|
|
</>
|
|
)}
|
|
|
|
<Card className="p-4 sm:p-6">
|
|
<h2 className="text-lg sm:text-xl font-bold mb-4" style={{ color: "var(--foreground)" }}>
|
|
Toutes les Maisons
|
|
</h2>
|
|
<div className="mb-4">
|
|
<Input
|
|
placeholder="Rechercher une maison..."
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
/>
|
|
</div>
|
|
{filteredHouses.length === 0 ? (
|
|
<p className="text-sm" style={{ color: "var(--muted-foreground)" }}>
|
|
Aucune maison trouvée
|
|
</p>
|
|
) : (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{filteredHouses.map((house) => (
|
|
<HouseCard
|
|
key={house.id}
|
|
house={house}
|
|
onRequestSent={handleUpdate}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</Card>
|
|
</div>
|
|
</BackgroundSection>
|
|
);
|
|
}
|
|
|