11"use client" ;
22
3- import { useEffect , useState } from "react" ;
3+ import { useState } from "react" ;
44import { useRouter } from "next/navigation" ;
5+ import useSWR , { mutate } from "swr" ;
56import {
67 ChevronDown ,
78 DoorClosed ,
@@ -26,11 +27,16 @@ interface Invite {
2627 invitedBy : { id : string ; name : string | null } ;
2728}
2829
30+ const fetcher = ( url : string ) =>
31+ fetch ( url , { credentials : "include" } ) . then ( ( res ) => {
32+ if ( ! res . ok ) throw new Error ( "Failed to fetch" ) ;
33+ return res . json ( ) ;
34+ } ) ;
35+
2936export default function RoomsPage ( ) {
3037 const { data : session , status } = useSession ( ) ;
3138 const router = useRouter ( ) ;
3239
33- const [ rooms , setRooms ] = useState < Room [ ] > ( [ ] ) ;
3440 const [ roomName , setRoomName ] = useState ( "" ) ;
3541 const [ showDeleteConfirm , setShowDeleteConfirm ] = useState ( false ) ;
3642 const [ selectedRoomToDelete , setSelectedRoomToDelete ] = useState < Room | null > (
@@ -39,51 +45,37 @@ export default function RoomsPage() {
3945 const [ selectedRoomSlug , setSelectedRoomSlug ] = useState ( "" ) ;
4046 const [ showInviteModal , setShowInviteModal ] = useState ( false ) ;
4147 const [ inviteEmail , setInviteEmail ] = useState ( "" ) ;
42- const [ pendingInvites , setPendingInvites ] = useState < Invite [ ] > ( [ ] ) ;
4348 const [ loading , setLoading ] = useState ( false ) ;
4449 const [ roomToLeave , setRoomToLeave ] = useState < Room | null > ( null ) ;
4550
46- const loadRoomsAndInvites = async ( ) => {
47- try {
48- const [ roomRes , inviteRes ] = await Promise . all ( [
49- fetch ( "/api/rooms" , { credentials : "include" } ) ,
50- fetch ( "api/invite" , { credentials : "include" } ) ,
51- ] ) ;
52-
53- const roomsData = await roomRes . json ( ) ;
54- const invitesData = await inviteRes . json ( ) ;
55-
56- setRooms ( Array . isArray ( roomsData ) ? roomsData : [ ] ) ;
57- setPendingInvites ( Array . isArray ( invitesData ) ? invitesData : [ ] ) ;
58- } catch ( error ) {
59- toast . error ( "Failed to load rooms or invites" ) ;
60- setRooms ( [ ] ) ;
61- setPendingInvites ( [ ] ) ;
62- }
63- } ;
64-
65- useEffect ( ( ) => {
66- if ( status === "unauthenticated" ) {
67- router . push ( "/login" ) ;
68- }
69- } , [ status ] ) ;
51+ const {
52+ data : rooms = [ ] ,
53+ isLoading : roomsLoading ,
54+ error : roomsError ,
55+ } = useSWR < Room [ ] > ( status === "authenticated" ? "/api/rooms" : null , fetcher ) ;
56+
57+ const {
58+ data : pendingInvites = [ ] ,
59+ isLoading : invitesLoading ,
60+ error : invitesError ,
61+ } = useSWR < Invite [ ] > (
62+ status === "authenticated" ? "/api/invite" : null ,
63+ fetcher
64+ ) ;
7065
71- useEffect ( ( ) => {
72- loadRoomsAndInvites ( ) ;
73- } , [ ] ) ;
66+ if ( status === "unauthenticated" ) {
67+ router . push ( "/login" ) ;
68+ }
7469
75- useEffect ( ( ) => {
76- if ( ! showInviteModal ) {
77- loadRoomsAndInvites ( ) ;
78- }
79- } , [ showInviteModal ] ) ;
70+ if ( status === "loading" || roomsLoading || invitesLoading ) {
71+ return < Loader /> ;
72+ }
8073
8174 const sendInvite = async ( ) => {
8275 if ( ! selectedRoomSlug ) {
8376 toast . error ( "Please select a room to invite to" ) ;
8477 return ;
8578 }
86-
8779 if ( ! inviteEmail . trim ( ) ) {
8880 toast . error ( "Please enter an email to invite" ) ;
8981 return ;
@@ -107,7 +99,8 @@ export default function RoomsPage() {
10799 toast . success ( "Invite sent successfully" ) ;
108100 setInviteEmail ( "" ) ;
109101 setSelectedRoomSlug ( "" ) ;
110- loadRoomsAndInvites ( ) ;
102+
103+ mutate ( "/api/invite" ) ;
111104 } catch ( error : any ) {
112105 toast . error ( error . message || "Something went wrong while sending invite" ) ;
113106 }
@@ -124,7 +117,8 @@ export default function RoomsPage() {
124117 body : JSON . stringify ( { action } ) ,
125118 } ) ;
126119
127- loadRoomsAndInvites ( ) ;
120+ mutate ( "/api/rooms" ) ;
121+ mutate ( "/api/invite" ) ;
128122 } catch ( err ) {
129123 console . error ( err ) ;
130124 toast . error ( "Failed to respond to invite" ) ;
@@ -150,9 +144,11 @@ export default function RoomsPage() {
150144
151145 if ( res . ok ) {
152146 const newRoom = await res . json ( ) ;
153- setRooms ( ( prev ) => [ ...prev , { ...newRoom , owned : true } ] ) ;
154147 setRoomName ( "" ) ;
155148 toast . success ( "Room created" ) ;
149+
150+ mutate ( "/api/rooms" ) ;
151+
156152 router . push ( `/room/${ newRoom . slug } ` ) ;
157153 } else {
158154 const error = await res . json ( ) ;
@@ -173,8 +169,8 @@ export default function RoomsPage() {
173169 } ) ;
174170
175171 if ( res . ok ) {
176- setRooms ( ( prev ) => prev . filter ( ( room ) => room . slug !== slug ) ) ;
177172 toast . success ( "Room deleted successfully" ) ;
173+ mutate ( "/api/rooms" ) ;
178174 } else {
179175 const error = await res . json ( ) ;
180176 toast . error ( error . error || "Failed to delete room" ) ;
@@ -192,8 +188,8 @@ export default function RoomsPage() {
192188 } ) ;
193189
194190 if ( res . ok ) {
195- setRooms ( ( prev ) => prev . filter ( ( room ) => room . slug !== slug ) ) ;
196- toast . success ( "Room leaved successfully ") ;
191+ toast . success ( "Room left successfully" ) ;
192+ mutate ( "/api/rooms ") ;
197193 } else {
198194 const error = await res . json ( ) ;
199195 toast . error ( error . error || "Failed to leave room" ) ;
@@ -204,10 +200,6 @@ export default function RoomsPage() {
204200 }
205201 } ;
206202
207- if ( status === "loading" ) {
208- return < Loader /> ;
209- }
210-
211203 return (
212204 < div className = "min-h-screen w-full bg-gradient-to-br from-black via-[#111111] to-gray-900 text-white" >
213205 < HomeNavbar />
0 commit comments