+ {/* Sidebar for desktop */}
+
+
+
+
POP3 Forwarder
+
+
+
+
+
+
+
+
+ {/* Mobile sidebar */}
+ {sidebarOpen && (
+
+
setSidebarOpen(false)} />
+
+
+
POP3 Forwarder
+
+
+
+
+
+
+
+
+ )}
+
+ {/* Main content */}
+
+ {/* Top bar */}
+
+
+
+
+
+ {navigation.find((item) => item.href === pathname)?.name || 'Dashboard'}
+
+
+
+
+
+
+
+
+
{user?.full_name}
+
{user?.email}
+
+
+
+
+
+
+ {/* Page content */}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/QueryProvider.tsx b/frontend/src/components/QueryProvider.tsx
new file mode 100644
index 0000000..1a0fe97
--- /dev/null
+++ b/frontend/src/components/QueryProvider.tsx
@@ -0,0 +1,24 @@
+'use client';
+
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { useState } from 'react';
+
+export function QueryProvider({ children }: { children: React.ReactNode }) {
+ const [queryClient] = useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ staleTime: 60 * 1000,
+ refetchOnWindowFocus: false,
+ },
+ },
+ })
+ );
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/frontend/src/store/authStore.ts b/frontend/src/store/authStore.ts
new file mode 100644
index 0000000..f41119f
--- /dev/null
+++ b/frontend/src/store/authStore.ts
@@ -0,0 +1,31 @@
+import { create } from 'zustand';
+import { User } from '@/lib/api';
+
+interface AuthState {
+ user: User | null;
+ isAuthenticated: boolean;
+ isLoading: boolean;
+ setUser: (user: User | null) => void;
+ setLoading: (loading: boolean) => void;
+ logout: () => void;
+}
+
+export const useAuthStore = create
((set) => ({
+ user: null,
+ isAuthenticated: false,
+ isLoading: true,
+
+ setUser: (user) => set({
+ user,
+ isAuthenticated: !!user,
+ isLoading: false,
+ }),
+
+ setLoading: (loading) => set({ isLoading: loading }),
+
+ logout: () => {
+ localStorage.removeItem('access_token');
+ localStorage.removeItem('user');
+ set({ user: null, isAuthenticated: false });
+ },
+}));
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
new file mode 100644
index 0000000..cf9c65d
--- /dev/null
+++ b/frontend/tsconfig.json
@@ -0,0 +1,34 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts",
+ "**/*.mts"
+ ],
+ "exclude": ["node_modules"]
+}