feat: layout responsive mobile (bottom nav) / laptop (sidebar) + page d'accueil
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { NavLink } from 'react-router-dom'
|
||||
|
||||
const NAV_ITEMS = [
|
||||
{ to: '/', icon: 'house', label: 'Accueil' },
|
||||
{ to: '/todos', icon: 'list-check', label: 'Todos' },
|
||||
{ to: '/shopping', icon: 'cart-shopping', label: 'Courses' },
|
||||
{ to: '/notes', icon: 'note-sticky', label: 'Notes' },
|
||||
]
|
||||
|
||||
export default function BottomNav() {
|
||||
return (
|
||||
<nav style={{
|
||||
display: 'flex',
|
||||
background: 'var(--bg-2)',
|
||||
borderTop: '1px solid var(--border-2)',
|
||||
paddingBottom: 'env(safe-area-inset-bottom)',
|
||||
}}>
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<NavLink
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
end={item.to === '/'}
|
||||
style={({ isActive }) => ({
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: 56,
|
||||
gap: 4,
|
||||
color: isActive ? 'var(--accent)' : 'var(--ink-3)',
|
||||
textDecoration: 'none',
|
||||
fontSize: 10,
|
||||
fontFamily: 'var(--font-ui)',
|
||||
letterSpacing: '0.05em',
|
||||
textTransform: 'uppercase',
|
||||
})}
|
||||
>
|
||||
<i className={`fa-solid fa-${item.icon}`} style={{ fontSize: 20 }} />
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,24 @@
|
||||
import { Outlet } from 'react-router-dom'
|
||||
import BottomNav from './BottomNav'
|
||||
import SideNav from './SideNav'
|
||||
|
||||
export default function Layout() {
|
||||
return <div><Outlet /></div>
|
||||
return (
|
||||
<div style={{ display: 'flex', height: '100dvh', background: 'var(--bg-1)' }}>
|
||||
{/* Sidebar — visible uniquement sur laptop (lg et +) */}
|
||||
<div className="hidden lg:flex" style={{ flexShrink: 0 }}>
|
||||
<SideNav />
|
||||
</div>
|
||||
|
||||
{/* Contenu principal */}
|
||||
<main style={{ flex: 1, overflow: 'auto', paddingBottom: 0 }} className="lg:pb-0 pb-14">
|
||||
<Outlet />
|
||||
</main>
|
||||
|
||||
{/* Navigation bas — visible uniquement sur mobile */}
|
||||
<div className="lg:hidden" style={{ position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 50 }}>
|
||||
<BottomNav />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { NavLink } from 'react-router-dom'
|
||||
|
||||
const NAV_ITEMS = [
|
||||
{ to: '/', icon: 'house', label: 'Accueil' },
|
||||
{ to: '/todos', icon: 'list-check', label: 'Todos' },
|
||||
{ to: '/shopping', icon: 'cart-shopping', label: 'Courses' },
|
||||
{ to: '/notes', icon: 'note-sticky', label: 'Notes' },
|
||||
]
|
||||
|
||||
export default function SideNav() {
|
||||
return (
|
||||
<nav style={{
|
||||
width: 220,
|
||||
background: 'var(--bg-2)',
|
||||
borderRight: '1px solid var(--border-1)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: '16px 0',
|
||||
height: '100%',
|
||||
}}>
|
||||
<div style={{ padding: '0 16px 16px', borderBottom: '1px solid var(--border-1)', marginBottom: 8 }}>
|
||||
<span style={{ color: 'var(--accent)', fontFamily: 'var(--font-mono)', fontWeight: 700, fontSize: 16 }}>
|
||||
HomeHub
|
||||
</span>
|
||||
</div>
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<NavLink
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
end={item.to === '/'}
|
||||
style={({ isActive }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 12,
|
||||
padding: '10px 16px',
|
||||
color: isActive ? 'var(--accent)' : 'var(--ink-2)',
|
||||
background: isActive ? 'var(--accent-tint)' : 'transparent',
|
||||
borderLeft: isActive ? '2px solid var(--accent)' : '2px solid transparent',
|
||||
textDecoration: 'none',
|
||||
fontFamily: 'var(--font-ui)',
|
||||
fontSize: 14,
|
||||
minHeight: 40,
|
||||
})}
|
||||
>
|
||||
<i className={`fa-solid fa-${item.icon}`} style={{ width: 18 }} />
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,30 @@
|
||||
export default function HomePage() {
|
||||
return <div>HomeHub</div>
|
||||
return (
|
||||
<div className="p-4">
|
||||
<div className="glass" style={{ padding: 20, borderRadius: 10, marginBottom: 16 }}>
|
||||
<h1 style={{ color: 'var(--accent)', fontFamily: 'var(--font-mono)', margin: 0 }}>
|
||||
HomeHub
|
||||
</h1>
|
||||
<p style={{ color: 'var(--ink-2)', marginTop: 8 }}>
|
||||
Application d'organisation personnelle
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 12 }}>
|
||||
{[
|
||||
{ label: 'Todos', icon: 'list', path: '/todos' },
|
||||
{ label: 'Courses', icon: 'cart-shopping', path: '/shopping' },
|
||||
{ label: 'Notes', icon: 'note-sticky', path: '/notes' },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.path}
|
||||
className="glass interactive"
|
||||
style={{ padding: 20, borderRadius: 10, textAlign: 'center', cursor: 'pointer', minHeight: 80, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 8 }}
|
||||
>
|
||||
<i className={`fa-solid fa-${item.icon}`} style={{ fontSize: 24, color: 'var(--accent)' }} />
|
||||
<span style={{ color: 'var(--ink-1)', fontFamily: 'var(--font-ui)', fontSize: 14 }}>{item.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user