From 40d626437c9bc66682a5cefc6a6024a55c04f625 Mon Sep 17 00:00:00 2001 From: seaznCode Date: Fri, 30 Jan 2026 15:34:43 +0100 Subject: [PATCH] + SUSPENDED AUTH CHECK feat: add suspended account handling with dedicated page and redirect logic --- src/app/hooks/useUserStatus.ts | 20 +++++++++++++++- src/app/login/components/LoginForm.tsx | 3 +++ src/app/login/hooks/useLogin.ts | 9 +++++--- src/app/suspended/page.tsx | 32 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/app/suspended/page.tsx diff --git a/src/app/hooks/useUserStatus.ts b/src/app/hooks/useUserStatus.ts index 7c818d5..3b4e7a0 100644 --- a/src/app/hooks/useUserStatus.ts +++ b/src/app/hooks/useUserStatus.ts @@ -1,4 +1,5 @@ import { useState, useEffect, useCallback } from 'react' +import { useRouter } from 'next/navigation' import useAuthStore from '../store/authStore' export interface UserStatus { @@ -20,6 +21,7 @@ export interface UserStatusResponse { } export const useUserStatus = () => { + const router = useRouter() const [userStatus, setUserStatus] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) @@ -86,6 +88,14 @@ export const useUserStatus = () => { } }) + if (response.status === 403) { + useAuthStore.getState().clearAuth() + setUserStatus(null) + setError(null) + router.push('/suspended') + return + } + // If 401, try token refresh once if (response.status === 401) { console.log('Got 401, attempting token refresh...') @@ -104,6 +114,14 @@ export const useUserStatus = () => { } }) + if (retryResponse.status === 403) { + useAuthStore.getState().clearAuth() + setUserStatus(null) + setError(null) + router.push('/suspended') + return + } + if (!retryResponse.ok) { throw new Error(`Failed to fetch user status: ${retryResponse.status}`) } @@ -138,7 +156,7 @@ export const useUserStatus = () => { } finally { setLoading(false) } - }, [isClient, accessToken, user]) + }, [isClient, accessToken, user, router]) // Fetch status on mount and when auth changes useEffect(() => { diff --git a/src/app/login/components/LoginForm.tsx b/src/app/login/components/LoginForm.tsx index 457aace..398e265 100644 --- a/src/app/login/components/LoginForm.tsx +++ b/src/app/login/components/LoginForm.tsx @@ -81,6 +81,9 @@ export default function LoginForm() { const redirectPath = (result as any).redirectPath || '/dashboard' // instant redirect; toast persists via global store router.push(redirectPath) + } else if ((result as any)?.redirectPath) { + router.push((result as any).redirectPath) + return } else { showToast({ variant: 'error', diff --git a/src/app/login/hooks/useLogin.ts b/src/app/login/hooks/useLogin.ts index ce25e29..28dfdd4 100644 --- a/src/app/login/hooks/useLogin.ts +++ b/src/app/login/hooks/useLogin.ts @@ -45,9 +45,14 @@ export function useLogin() { }) console.log('Login response status:', response.status) - + + const data = await response.json().catch(() => null) + if (!response.ok) { // Handle HTTP errors + if (response.status === 403) { + return { success: false, error: 'Account suspended', redirectPath: '/suspended' } + } if (response.status === 401) { throw new Error('Invalid credentials') } else if (response.status === 404) { @@ -58,8 +63,6 @@ export function useLogin() { throw new Error('Login failed. Please try again.') } } - - const data = await response.json() console.log('Login response data:', data) if (data.success && data.accessToken && data.user) { diff --git a/src/app/suspended/page.tsx b/src/app/suspended/page.tsx new file mode 100644 index 0000000..f39b7ec --- /dev/null +++ b/src/app/suspended/page.tsx @@ -0,0 +1,32 @@ +'use client' + +import Link from 'next/link' +import PageLayout from '../components/PageLayout' +import PageTransitionEffect from '../components/animation/pageTransitionEffect' + +export default function SuspendedPage() { + return ( + + +
+
+
!
+

Account suspended

+

+ Your account has been suspended. For more information, contact + {' '}office@profit-planet.com. +

+
+ + Back to login + +
+
+
+
+
+ ) +}