CodeIssuesPull RequestsActionsSecurityInsights
✨ AI
More
Settings

Login import pinning #3743

ClosedSccantynz wants to mergecursor/login-import-pinning-cc1dmainopened Feb 14, 2026
3 changed files+29−4
Modifiedfrontend/src/App.js+24−1View fileUnifiedSplit
1111import SafeBookings from "./admin/SafeBookings";
1212
1313
14// -PinLoginImport — STAMP: HIBI_MEGA_PACK_003_FINISH_OVERNIGHT_20260210
15import PinLoginImport from "./pages/AdminLogin";
1416import RealAdminBookings from "./pages/AdminDashboard";
1517
18function ClearAdminSession() {
19 React.useEffect(() => {
20 try {
21 localStorage.removeItem("admin_token");
22 localStorage.removeItem("HIBI_ADMIN_TOKEN");
23 } catch {}
24 // Replace avoids a back-button loop.
25 window.location.replace("/admin/login");
26 }, []);
27
28 return (
29 <div style={{ padding: 28 }}>
30 <h1>Clearing admin session…</h1>
31 <p><b>STAMP:</b> HIBI_MEGA_PACK_003_FINISH_OVERNIGHT_20260210</p>
32 <p>If you are not redirected, <a href="/admin/login">click here</a>.</p>
33 </div>
34 );
35}
36
1637function AdminRoutes() {
1738 return (
1839 <Routes>
1940 <Route path="/admin" element={<Navigate to="/admin/bookings" replace />} />
20 <Route path="/admin/login" element={<div style={{padding:28}}><h1>Admin Login</h1><p><b>STAMP:</b> HIBI_MEGA_PACK_003_FINISH_OVERNIGHT_20260210</p><p>Login component not pinned yet. Provide -PinLoginImport.</p></div>} />
41 <Route path="/admin/login" element={<PinLoginImport />} />
42 <Route path="/admin/clear" element={<ClearAdminSession />} />
43 <Route path="/admin/dashboard" element={<Navigate to="/admin/bookings" replace />} />
2144
2245 <Route
2346 path="/admin/bookings"
Modifiedfrontend/src/admin/AdminShell.jsx+2−0View fileUnifiedSplit
22
33export default function AdminShell({ children }) {
44 const logout = () => {
5 // Support both legacy + current token keys.
6 localStorage.removeItem("admin_token");
57 localStorage.removeItem("HIBI_ADMIN_TOKEN");
68 window.location.href = "/admin/login";
79 };
Modifiedfrontend/src/pages/AdminLogin.jsx+3−3View fileUnifiedSplit
9595 useEffect(() => {
9696 const token = localStorage.getItem('admin_token');
9797 if (token && !hasSessionId) {
98 navigate('/admin/dashboard');
98 navigate('/admin/bookings');
9999 }
100100 }, [navigate, hasSessionId]);
101101
102102 const handleAuthSuccess = (data) => {
103 navigate('/admin/dashboard');
103 navigate('/admin/bookings');
104104 };
105105
106106 const handleAuthError = (message) => {
127127 const response = await axios.post(`${BACKEND_URL}/api/admin/login`, credentials);
128128 localStorage.setItem('admin_token', response.data.access_token);
129129 toast({ title: 'Login Successful!', description: 'Welcome back' });
130 navigate('/admin/dashboard');
130 navigate('/admin/bookings');
131131 } catch (error) {
132132 const message = error.response?.data?.detail || 'Invalid credentials';
133133 setAuthError(message);
134134
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts