diff --git a/apps/web/src/components/nav/ModerationNotifications.tsx b/apps/web/src/components/nav/ModerationNotifications.tsx index a7d69724..acfc2dde 100644 --- a/apps/web/src/components/nav/ModerationNotifications.tsx +++ b/apps/web/src/components/nav/ModerationNotifications.tsx @@ -31,6 +31,7 @@ export function ModerationNotifications({ const [showJoinRequestToast, setShowJoinRequestToast] = useState(false) const [isAcceptingInvitation, setIsAcceptingInvitation] = useState(false) const [isProcessingRequest, setIsProcessingRequest] = useState(false) + const [requestError, setRequestError] = useState(null) const { mutateAsync: joinRoom } = useJoinRoom() // Handle report toast (for hosts) @@ -50,6 +51,7 @@ export function ModerationNotifications({ useEffect(() => { if (moderationEvent?.type === 'join-request') { setShowJoinRequestToast(true) + setRequestError(null) // Clear any previous errors } }, [moderationEvent]) @@ -58,6 +60,8 @@ export function ModerationNotifications({ if (!moderationEvent?.data.requestId || !moderationEvent?.data.roomId) return setIsProcessingRequest(true) + setRequestError(null) // Clear any previous errors + try { const response = await fetch( `/api/arcade/rooms/${moderationEvent.data.roomId}/join-requests/${moderationEvent.data.requestId}/approve`, @@ -68,10 +72,11 @@ export function ModerationNotifications({ ) if (!response.ok) { - throw new Error('Failed to approve join request') + const errorData = await response.json().catch(() => ({})) + throw new Error(errorData.error || 'Failed to approve join request') } - // Close toast and event + // Close toast and event on success setShowJoinRequestToast(false) onClose() @@ -79,7 +84,8 @@ export function ModerationNotifications({ queryClient.invalidateQueries({ queryKey: ['join-requests'] }) } catch (error) { console.error('Failed to approve join request:', error) - alert(error instanceof Error ? error.message : 'Failed to approve request') + // Keep toast visible and show error message + setRequestError(error instanceof Error ? error.message : 'Failed to approve request') } finally { setIsProcessingRequest(false) } @@ -90,6 +96,8 @@ export function ModerationNotifications({ if (!moderationEvent?.data.requestId || !moderationEvent?.data.roomId) return setIsProcessingRequest(true) + setRequestError(null) // Clear any previous errors + try { const response = await fetch( `/api/arcade/rooms/${moderationEvent.data.roomId}/join-requests/${moderationEvent.data.requestId}/deny`, @@ -100,10 +108,11 @@ export function ModerationNotifications({ ) if (!response.ok) { - throw new Error('Failed to deny join request') + const errorData = await response.json().catch(() => ({})) + throw new Error(errorData.error || 'Failed to deny join request') } - // Close toast and event + // Close toast and event on success setShowJoinRequestToast(false) onClose() @@ -111,7 +120,8 @@ export function ModerationNotifications({ queryClient.invalidateQueries({ queryKey: ['join-requests'] }) } catch (error) { console.error('Failed to deny join request:', error) - alert(error instanceof Error ? error.message : 'Failed to deny request') + // Keep toast visible and show error message + setRequestError(error instanceof Error ? error.message : 'Failed to deny request') } finally { setIsProcessingRequest(false) } @@ -515,6 +525,38 @@ export function ModerationNotifications({ {moderationEvent.data.requesterName} wants to join your room + {/* Error message */} + {requestError && ( +
+
+ ⚠️ Error +
+
+ {requestError} +
+
+ )} + {/* Action buttons */}