diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx
new file mode 100644
index 0000000..afc4686
--- /dev/null
+++ b/frontend/src/components/Layout.tsx
@@ -0,0 +1,65 @@
+import { ReactNode } from 'react'
+import { useNavigate, useLocation } from 'react-router-dom'
+import Box from '@mui/material/Box'
+import Drawer from '@mui/material/Drawer'
+import List from '@mui/material/List'
+import ListItemButton from '@mui/material/ListItemButton'
+import ListItemIcon from '@mui/material/ListItemIcon'
+import ListItemText from '@mui/material/ListItemText'
+import Typography from '@mui/material/Typography'
+import Divider from '@mui/material/Divider'
+import IconButton from '@mui/material/IconButton'
+import Tooltip from '@mui/material/Tooltip'
+import DnsIcon from '@mui/icons-material/Dns'
+import LogoutIcon from '@mui/icons-material/Logout'
+import { useAuth } from '../store/auth'
+
+const DRAWER_WIDTH = 240
+
+interface Props { children: ReactNode; title: string }
+
+export default function Layout({ children, title }: Props) {
+ const navigate = useNavigate()
+ const location = useLocation()
+ const { user, logout } = useAuth()
+
+ return (
+
+
+
+
+ Shorefront
+
+
+ Shorewall Manager
+
+
+
+
+ navigate('/configs')}
+ sx={{ '&.Mui-selected': { backgroundColor: '#2d3748' }, '&:hover': { backgroundColor: '#2d3748' } }}
+ >
+
+
+
+
+
+
+ {user?.username}
+
+
+
+
+
+
+
+
+ {title}
+
+ {children}
+
+
+ )
+}
diff --git a/frontend/src/components/ProtectedRoute.tsx b/frontend/src/components/ProtectedRoute.tsx
new file mode 100644
index 0000000..a0f8a19
--- /dev/null
+++ b/frontend/src/components/ProtectedRoute.tsx
@@ -0,0 +1,11 @@
+import { Navigate, Outlet } from 'react-router-dom'
+import { useAuth } from '../store/auth'
+import CircularProgress from '@mui/material/CircularProgress'
+import Box from '@mui/material/Box'
+
+export default function ProtectedRoute() {
+ const { user, loading } = useAuth()
+ if (loading) return
+ if (!user) return
+ return
+}