diff --git a/app/(admin)/adminDashboard/page.tsx b/app/(admin)/adminDashboard/page.tsx index 3fdf0cf..83c287a 100644 --- a/app/(admin)/adminDashboard/page.tsx +++ b/app/(admin)/adminDashboard/page.tsx @@ -68,28 +68,40 @@ const AdminDashboard = () => { // near other refs const loggingRef = useRef(null); - useEffect(() => { - const checkAuth = async () => { - try { - const res = await fetch('/api/auth/me', { credentials: 'include' }); - if (!res.ok) { - router.replace('/login'); - return; - } - const data = await res.json(); - if (!data.user) { - router.replace('/login'); - return; - } - } catch { - router.replace('/login'); - } finally { - setAuthChecked(true); - } - }; + const API = process.env.NEXT_PUBLIC_FASTAPI_URL || 'http://127.0.0.1:8000'; - checkAuth(); - }, [router]); +useEffect(() => { + let cancelled = false; + + const checkAuth = async () => { + try { + const res = await fetch(`${API}/auth/me`, { + credentials: 'include', + cache: 'no-store', + }); + + if (!res.ok) { + router.replace('/login'); + return; + } + + const user = await res.json().catch(() => null); + if (!user?.id) { + router.replace('/login'); + return; + } + // authenticated + } catch { + router.replace('/login'); + return; + } finally { + if (!cancelled) setAuthChecked(true); + } + }; + + checkAuth(); + return () => { cancelled = true; }; +}, [router, API]); diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index ee9e9bc..b1dcf64 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -10,30 +10,48 @@ export default function LoginPage() { const router = useRouter(); const [ready, setReady] = useState(false); // gate to avoid UI flash + // Use ONE client-exposed API env var everywhere + const API = process.env.NEXT_PUBLIC_FASTAPI_URL || 'http://127.0.0.1:8000'; + useEffect(() => { let cancelled = false; + const controller = new AbortController(); (async () => { try { - const res = await fetch('/api/auth/me', { - method: 'GET', - cache: 'no-store', - credentials: 'include', // safe even if same-origin + const res = await fetch(`${API}/auth/me`, { + credentials: 'include', + cache: 'no-store', // don't reuse a cached 401 + signal: controller.signal, }); - if (!cancelled && res.ok) { + + if (!res.ok) { + if (!cancelled) setReady(true); + return; + } + + const user = await res.json().catch(() => null); + if (user?.id) { + // already logged in -> go straight to dashboard router.replace('/adminDashboard'); return; } + + // not logged in -> show form + if (!cancelled) setReady(true); } catch { - // ignore errors; just show the form + // network/error -> show form + if (!cancelled) setReady(true); } - if (!cancelled) setReady(true); })(); - return () => { cancelled = true; }; - }, [router]); + return () => { + cancelled = true; + controller.abort(); + }; + }, [router, API]); - if (!ready) return null; // or a small spinner if you prefer + if (!ready) return null; // or a spinner/skeleton return (
@@ -66,10 +84,8 @@ export default function LoginPage() { bg-[linear-gradient(45deg,#fffbe6_0%,rgba(255,251,230,0)_25%,rgba(255,251,230,0)_75%,#fffbe6_100%)] dark:bg-[linear-gradient(52.22deg,#facc15_0%,rgba(250,204,21,0)_20%,rgba(250,204,21,0)_80%,#facc15_100%)]" > - {/* Inner card (glassmorphic effect) */}
- {/* Header */}

Sign In

@@ -77,10 +93,8 @@ export default function LoginPage() { Enter your email and password to access your account.

- {/* Login form */} - {/* Footer link */}
Don’t have an account?{' '} { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const router = useRouter(); + const API = process.env.NEXT_PUBLIC_FASTAPI_URL; // e.g. http://localhost:8000 - const submitForm = async (e: React.FormEvent) => { + const submitForm = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { - const res = await axios.post('/api/login', { email, password }); - toast.success(res.data?.message || 'Login successful!'); + const res = await fetch(`${API}/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }), + credentials: 'include', // cookie from FastAPI + }); + + let data: any = null; + try { + data = await res.json(); + } catch { + // non-JSON error + } + + if (!res.ok) { + const msg = data?.detail || data?.message || 'Invalid credentials'; + throw new Error(msg); + } + + const user: User = data; + toast.success(`Welcome ${user.email}`); router.push('/adminDashboard'); router.refresh(); - // token cookie is already set by the server: } catch (err: any) { - console.error('Login error:', err); - const msg = - err?.response?.data?.message || - err?.message || - 'Invalid credentials'; - toast.error(msg); + toast.error(err?.message ?? 'Login failed'); } finally { setLoading(false); } @@ -52,6 +67,7 @@ const ComponentsAuthLoginForm = () => {
+
@@ -70,6 +86,7 @@ const ComponentsAuthLoginForm = () => {
+ -
- +
{/* Right-side actions */}
@@ -124,21 +131,21 @@ useEffect(() => { )} {/* User dropdown */} -
+
{loadingUser ? (
) : user ? ( - - -
- } + + +
+ } > -
    {/* make sure this stays transparent */} +
    • {user.email}