diff --git a/src/App.tsx b/src/App.tsx
index ba4b6ed..7835fb1 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,7 +1,20 @@
+import { useEffect } from 'react'
import { Toaster } from 'sonner'
import { AppRoutes } from './app/AppRoutes'
+const SESSION_KEY = 'yimaru_session_active'
+
export default function App() {
+ useEffect(() => {
+ if (!sessionStorage.getItem(SESSION_KEY)) {
+ localStorage.removeItem('access_token')
+ localStorage.removeItem('refresh_token')
+ localStorage.removeItem('member_id')
+ localStorage.removeItem('role')
+ sessionStorage.setItem(SESSION_KEY, '1')
+ }
+ }, [])
+
return (
<>
diff --git a/src/api/http.ts b/src/api/http.ts
index 3fccbc0..6e9d62f 100644
--- a/src/api/http.ts
+++ b/src/api/http.ts
@@ -109,6 +109,12 @@ http.interceptors.response.use(
}
}
+ // Backend is down (network error, timeout, connection refused)
+ if (!error.response) {
+ clearAuthAndRedirect();
+ return Promise.reject(error);
+ }
+
return Promise.reject(error);
}
);
diff --git a/src/layouts/AppLayout.tsx b/src/layouts/AppLayout.tsx
index 38c74d2..113f260 100644
--- a/src/layouts/AppLayout.tsx
+++ b/src/layouts/AppLayout.tsx
@@ -1,11 +1,16 @@
import { useState, useCallback } from "react"
-import { Outlet } from "react-router-dom"
+import { Navigate, Outlet } from "react-router-dom"
import { Sidebar } from "../components/sidebar/Sidebar"
import { Topbar } from "../components/topbar/Topbar"
export function AppLayout() {
const [sidebarOpen, setSidebarOpen] = useState(false)
+ const token = localStorage.getItem("access_token")
+ if (!token) {
+ return
+ }
+
const handleMenuClick = useCallback(() => {
setSidebarOpen(true)
}, [])
diff --git a/src/pages/auth/LoginPage.tsx b/src/pages/auth/LoginPage.tsx
index 518ed9e..2ac84ef 100644
--- a/src/pages/auth/LoginPage.tsx
+++ b/src/pages/auth/LoginPage.tsx
@@ -71,6 +71,7 @@ export function LoginPage() {
const [googleLoading, setGoogleLoading] = useState(false);
const [error, setError] = useState(null);
const [googleReady, setGoogleReady] = useState(false);
+ const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string }>({});
const googleBtnRef = useRef(null);
@@ -156,6 +157,16 @@ export function LoginPage() {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
+
+ const errors: { email?: string; password?: string } = {};
+ if (!email.trim()) errors.email = "Please enter your email address";
+ if (!password) errors.password = "Please enter your password";
+ if (Object.keys(errors).length > 0) {
+ setFieldErrors(errors);
+ return;
+ }
+ setFieldErrors({});
+
setError(null);
setLoading(true);
@@ -309,7 +320,7 @@ export function LoginPage() {
>
)}
-