diff --git a/app/houses/page.tsx b/app/houses/page.tsx index 9e1d464..c33f898 100644 --- a/app/houses/page.tsx +++ b/app/houses/page.tsx @@ -5,9 +5,41 @@ import NavigationWrapper from "@/components/navigation/NavigationWrapper"; import HousesSection from "@/components/houses/HousesSection"; import { houseService } from "@/services/houses/house.service"; import { prisma } from "@/services/database"; +import type { House, HouseMembership, HouseInvitation } from "@/prisma/generated/prisma/client"; export const dynamic = "force-dynamic"; +// Types pour les données sérialisées +type HouseWithRelations = House & { + creator?: { + id: string; + username: string; + avatar: string | null; + } | null; + creatorId?: string; + memberships?: Array; +}; + +type InvitationWithRelations = HouseInvitation & { + house: { + id: string; + name: string; + }; + inviter: { + id: string; + username: string; + avatar: string | null; + }; +}; + export default async function HousesPage() { const session = await auth(); @@ -90,12 +122,12 @@ export default async function HousesPage() { ]); // Sérialiser les données pour le client - const houses = (housesData as any[]).map((house: any) => ({ + const houses = (housesData as HouseWithRelations[]).map((house: HouseWithRelations) => ({ id: house.id, name: house.name, description: house.description, - creator: house.creator || { id: house.creatorId, username: "Unknown", avatar: null }, - memberships: (house.memberships || []).map((m: any) => ({ + creator: house.creator || { id: house.creatorId || "", username: "Unknown", avatar: null }, + memberships: (house.memberships || []).map((m) => ({ id: m.id, role: m.role, user: { @@ -113,8 +145,8 @@ export default async function HousesPage() { id: myHouseData.id, name: myHouseData.name, description: myHouseData.description, - creator: (myHouseData as any).creator || { id: (myHouseData as any).creatorId, username: "Unknown", avatar: null }, - memberships: ((myHouseData as any).memberships || []).map((m: any) => ({ + creator: (myHouseData as HouseWithRelations).creator || { id: (myHouseData as HouseWithRelations).creatorId || "", username: "Unknown", avatar: null }, + memberships: ((myHouseData as HouseWithRelations).memberships || []).map((m) => ({ id: m.id, role: m.role, user: { @@ -128,7 +160,7 @@ export default async function HousesPage() { } : null; - const invitations = invitationsData.map((inv: any) => ({ + const invitations = (invitationsData as InvitationWithRelations[]).map((inv: InvitationWithRelations) => ({ id: inv.id, house: { id: inv.house.id, diff --git a/components/houses/HouseManagement.tsx b/components/houses/HouseManagement.tsx index 5a9be41..1511634 100644 --- a/components/houses/HouseManagement.tsx +++ b/components/houses/HouseManagement.tsx @@ -91,7 +91,9 @@ export default function HouseManagement({ const fetchRequests = async () => { if (!house || !isAdmin) return; try { - const response = await fetch(`/api/houses/${house.id}/requests?status=PENDING`); + const response = await fetch( + `/api/houses/${house.id}/requests?status=PENDING` + ); if (response.ok) { const data = await response.json(); setRequests(data); @@ -101,10 +103,13 @@ export default function HouseManagement({ } }; fetchRequests(); - }, [house?.id, isAdmin]); + }, [house, isAdmin]); const handleDelete = () => { - if (!house || !confirm("Êtes-vous sûr de vouloir supprimer cette maison ?")) { + if ( + !house || + !confirm("Êtes-vous sûr de vouloir supprimer cette maison ?") + ) { return; } @@ -168,11 +173,17 @@ export default function HouseManagement({ if (!house) { return ( -

+

Ma Maison

-

- Vous n'êtes membre d'aucune maison pour le moment. +

+ Vous n'êtes membre d'aucune maison pour le moment.

); @@ -180,27 +191,30 @@ export default function HouseManagement({ return (
-
-

{house.name}

{house.description && ( -

+

{house.description}

)} @@ -217,22 +231,40 @@ export default function HouseManagement({ {isEditing ? "Annuler" : "Modifier"} {isOwner && ( - )} )} {!isOwner && ( - )}
- {error && {error}} - {success && {success}} + {error && ( + + {error} + + )} + {success && ( + + {success} + + )} {isEditing ? ( ) : (
-

Membres ({house.memberships?.length ?? 0}) @@ -258,21 +290,25 @@ export default function HouseManagement({
{(house.memberships || []).map((membership) => { const isCurrentUser = membership.user.id === session?.user?.id; - const roleColor = - membership.role === "OWNER" ? "var(--accent)" : - membership.role === "ADMIN" ? "var(--primary)" : - "var(--muted-foreground)"; - + const roleColor = + membership.role === "OWNER" + ? "var(--accent)" + : membership.role === "ADMIN" + ? "var(--primary)" + : "var(--muted-foreground)"; + return (
@@ -285,16 +321,18 @@ export default function HouseManagement({ /> )}
- {membership.user.username} {isCurrentUser && " (Vous)"} - @@ -309,43 +347,55 @@ export default function HouseManagement({
- {membership.role === "OWNER" && "👑 "} {membership.role} - {isAdmin && - !isCurrentUser && + {isAdmin && + !isCurrentUser && (isOwner || membership.role === "MEMBER") && membership.role !== "OWNER" && ( - - )} + + )}
); @@ -411,15 +461,15 @@ export default function HouseManagement({ {isAdmin && pendingRequests.length > 0 && ( -

- Demandes d'adhésion + Demandes d'adhésion

@@ -427,4 +477,3 @@ export default function HouseManagement({
); } - diff --git a/components/houses/HousesSection.tsx b/components/houses/HousesSection.tsx index 8a0363e..7a6b6d4 100644 --- a/components/houses/HousesSection.tsx +++ b/components/houses/HousesSection.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; import { useSession } from "next-auth/react"; import Card from "@/components/ui/Card"; import Button from "@/components/ui/Button"; @@ -78,7 +78,7 @@ export default function HousesSection({ const [showCreateForm, setShowCreateForm] = useState(false); const [searchTerm, setSearchTerm] = useState(""); - const fetchHouses = async () => { + const fetchHouses = useCallback(async () => { try { const params = new URLSearchParams(); if (searchTerm) { @@ -94,7 +94,7 @@ export default function HousesSection({ } catch (error) { console.error("Error fetching houses:", error); } - }; + }, [searchTerm]); const fetchMyHouse = async () => { try { @@ -129,9 +129,13 @@ export default function HousesSection({ }, 300); return () => clearTimeout(timeout); } else { - fetchHouses(); + // Utiliser un timeout pour éviter setState synchrone dans effect + const timeout = setTimeout(() => { + fetchHouses(); + }, 0); + return () => clearTimeout(timeout); } - }, [searchTerm]); + }, [searchTerm, fetchHouses]); const handleUpdate = () => { fetchMyHouse(); @@ -165,15 +169,24 @@ export default function HousesSection({ <> {invitations.length > 0 && ( -

+

Mes Invitations

- +
)} -

+

Ma Maison

{myHouse ? ( @@ -194,8 +207,12 @@ export default function HousesSection({ /> ) : (
-

- Vous n'êtes membre d'aucune maison. Créez-en une ou demandez à rejoindre une maison existante. +

+ Vous n'êtes membre d'aucune maison. Créez-en + une ou demandez à rejoindre une maison existante.