diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 789d00d2..363e4a51 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -54,6 +54,37 @@ type SignUpData = { agreeTerms: boolean; }; +const LoadingScreen = (): JSX.Element => ( +
+
+
+ +
+

Loading...

+
+
+); + // Protected Route Component const ProtectedRoute: React.FC = ({ children }) => { const navigate = useNavigate(); @@ -66,35 +97,7 @@ const ProtectedRoute: React.FC = ({ children }) => { }, [isAuthenticated, isLoading, navigate]); if (isLoading) { - return ( -
-
-
- - - - -
-

Loading...

-
-
- ); + return ; } return isAuthenticated ? <>{children} : null; @@ -107,45 +110,19 @@ const AdminRoute: React.FC = ({ children }) => { useEffect(() => { if (isLoading) return; + if (!isAuthenticated) { navigate("/login"); return; } + if ((user as { role?: string } | null | undefined)?.role !== "admin") { navigate("/dashboard"); } }, [isAuthenticated, isLoading, navigate, user]); if (isLoading) { - return ( -
-
-
- - - - -
-

Loading...

-
-
- ); + return ; } return isAuthenticated && @@ -154,7 +131,7 @@ const AdminRoute: React.FC = ({ children }) => { ) : null; }; -// Dashboard Layout Component (with sidebar) +// Dashboard Layout Component with sidebar const DashboardLayout: React.FC = ({ children, sidebarWidth, @@ -174,12 +151,19 @@ function App(): JSX.Element { const location = useLocation(); const navigate = useNavigate(); + const showPublicEnhancements = ["/", "/about", "/contact"].includes( + location.pathname, + ); + // Dashboard state const getInitialSidebarWidth = (): number => { if (typeof window === "undefined") return 220; + try { const stored = window.localStorage.getItem("sidebarExpanded"); + if (stored === null) return 220; + return stored === "true" ? 220 : 80; } catch { return 220; @@ -193,18 +177,24 @@ function App(): JSX.Element { // Theme management useEffect(() => { - localStorage.setItem('theme', 'dark'); - setIsDarkMode(true); + const theme = localStorage.getItem("theme") ?? "dark"; + const dark = theme === "dark"; + + setIsDarkMode(dark); const root = document.documentElement; - root.classList.remove('light'); + + if (dark) { + root.classList.remove("light"); + } else { + root.classList.add("light"); + } }, []); - // Scroll restoration: - // - On route changes without hash, go to top. - // - Keep hash-based anchor behavior (e.g. /#features) intact. + // Scroll restoration useEffect(() => { if (location.hash) return; + window.scrollTo({ top: 0, left: 0, behavior: "auto" }); }, [location.pathname, location.hash]); @@ -243,18 +233,20 @@ function App(): JSX.Element { navigate("/dashboard"); }; - // const handleThemeToggle = (): void => { - // const newThemeIsDark = !isDarkMode; - // setIsDarkMode(newThemeIsDark); - // localStorage.setItem('theme', newThemeIsDark ? 'dark' : 'light'); + const handleThemeToggle = (): void => { + const newThemeIsDark = !isDarkMode; - // const root = document.documentElement; - // if (newThemeIsDark) { - // root.classList.remove('light'); - // } else { - // root.classList.add('light'); - // } - // }; + setIsDarkMode(newThemeIsDark); + localStorage.setItem("theme", newThemeIsDark ? "dark" : "light"); + + const root = document.documentElement; + + if (newThemeIsDark) { + root.classList.remove("light"); + } else { + root.classList.add("light"); + } + }; const handleSidebarWidthChange = (width: number): void => { setSidebarWidth(width); @@ -418,14 +410,142 @@ function App(): JSX.Element { } /> - {/* Fallback route */} + {/* Fallback Route */} navigate("/login")} />} /> + + {showPublicEnhancements && ( + <> +
+
+
+ + Audit Readiness + + +

+ Built to support faster compliance preparation +

+ +

+ AutoAudit brings evidence review, cloud visibility, and audit + tracking into one streamlined workflow, helping teams stay + prepared before compliance reviews begin. +

+
+ +
+
+

+ Evidence Visibility +

+

+ Organise and review audit evidence across connected systems. +

+
+ +
+

+ Risk Awareness +

+

+ Highlight compliance gaps early so teams can respond before + audit deadlines. +

+
+ +
+

+ Workflow Clarity +

+

+ Keep compliance tasks clear, trackable, and easier to manage. +

+
+
+
+
+ +
+
+
+ + Platform Value + + +

+ Designed for clear, secure, and reliable audit workflows +

+ +

+ The public interface now communicates AutoAudit’s value more + clearly by highlighting usability, consistency, compliance + focus, and responsive access across different screen sizes. +

+
+ +
+
+ + 01 + +

+ Clear Navigation +

+

+ Supports users in understanding audit-related features with + less friction. +

+
+ +
+ + 02 + +

+ Consistent Interface +

+

+ Strengthens the visual structure of public-facing product + sections. +

+
+ +
+ + 03 + +

+ Compliance Focus +

+

+ Highlights evidence, risk, and governance workflows in a + professional way. +

+
+ +
+ + 04 + +

+ Responsive Layout +

+

+ Improves the presentation across desktop, tablet, and mobile + screens using Tailwind utility classes. +

+
+
+
+
+ + )} ); } -export default App; +export default App; \ No newline at end of file diff --git a/frontend/src/index.css b/frontend/src/index.css index 02adf836..6c8d1f71 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -35,10 +35,12 @@ --landing-bg-alt-mid: 26 58 79; --landing-bg-alt-end: 42 74 95; - /* Spacing & Radius */ + /* Spacing, Radius & Shadow */ --radius-1: 8px; --radius-2: 12px; --radius-3: 16px; + --shadow-1: 0 4px 12px rgba(0, 0, 0, 0.2); + --shadow-2: 0 10px 25px rgba(0, 0, 0, 0.3); /* Fonts */ --font-header: "League Spartan", ui-sans-serif, system-ui, "Segoe UI", @@ -129,7 +131,8 @@ outline-offset: 2px; } - a, button { + a, + button { @apply cursor-pointer; } @@ -162,7 +165,7 @@ } .stat-label { - @apply mb-1 font-medium text-sm; + @apply mb-1 text-sm font-medium; color: rgb(var(--text-muted)); } @@ -222,6 +225,7 @@ from { transform: rotate(0deg); } + to { transform: rotate(360deg); }