Skip to content

Commit ebb31b1

Browse files
committed
menu
1 parent d7d98f9 commit ebb31b1

File tree

2 files changed

+74
-30
lines changed

2 files changed

+74
-30
lines changed

app/root.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function App() {
4141
<Links />
4242
</head>
4343
<body className="h-full">
44-
<header className="flex items-center justify-between bg-slate-800 p-4 text-white relative">
44+
<header className="fixed top-0 left-0 right-0 flex items-center justify-between bg-slate-800 p-4 text-white z-50 shadow-md">
4545
<div className="flex items-center">
4646
<button onClick={() => setDrawerOpen(!drawerOpen)} className="text-white hover:text-gray-300 focus:outline-none mr-4">
4747
<svg className="h-6 w-6 fill-current" viewBox="0 0 24 24">
@@ -63,7 +63,7 @@ export default function App() {
6363
</button>
6464

6565
{profilePopupOpen && (
66-
<div className="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
66+
<div className="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-60">
6767
<div className="px-4 py-2 text-sm text-gray-700">
6868
Signed in as: {user?.email}
6969
</div>
@@ -94,7 +94,7 @@ export default function App() {
9494
</div>
9595
</header>
9696

97-
<div className={`fixed top-0 left-0 h-full w-64 bg-white shadow-md p-4 ${drawerOpen ? 'translate-x-0' : '-translate-x-full'} transition-transform duration-300 z-50`}>
97+
<div className={`fixed top-0 left-0 h-full w-64 bg-white shadow-md p-4 ${drawerOpen ? 'translate-x-0' : '-translate-x-full'} transition-transform duration-300 z-40`} style={{ marginTop: '64px' }}>
9898
<button onClick={() => setDrawerOpen(false)} className="absolute top-2 right-2 text-gray-500 hover:text-gray-800 focus:outline-none">
9999
<svg className="h-6 w-6 fill-current" viewBox="0 0 24 24">
100100
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
@@ -108,7 +108,7 @@ export default function App() {
108108
</ul>
109109
</div>
110110

111-
<div className="ml-0 transition-margin duration-300" style={{ marginLeft: drawerOpen ? '64px' : '0' }}>
111+
<div className="ml-0 transition-margin duration-300" style={{ marginLeft: drawerOpen ? '64px' : '0', marginTop: '64px' }}>
112112
<Outlet />
113113
<ScrollRestoration />
114114
<Scripts />

app/routes/notes.tsx

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Form, Link, NavLink, Outlet, useLoaderData } from "@remix-run/react";
44
import { getNoteListItems } from "~/models/note.server";
55
import { requireUserId } from "~/session.server";
66
import { useUser } from "~/utils";
7+
import React, { useState } from 'react';
78

89
export const loader = async ({ request }: LoaderFunctionArgs) => {
910
const userId = await requireUserId(request);
@@ -14,38 +15,81 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
1415
export default function NotesPage() {
1516
const data = useLoaderData<typeof loader>();
1617
const user = useUser();
18+
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
1719

1820
return (
1921
<div className="flex h-full min-h-screen flex-col">
20-
<main className="flex h-full bg-white">
21-
<div className="h-full w-80 border-r bg-gray-50">
22-
<Link to="new" className="block p-4 text-xl text-blue-500">
23-
+ New Note
24-
</Link>
25-
26-
<hr />
27-
28-
{data.noteListItems.length === 0 ? (
29-
<p className="p-4">No notes yet</p>
30-
) : (
31-
<ol>
32-
{data.noteListItems.map((note) => (
33-
<li key={note.id}>
34-
<NavLink
35-
className={({ isActive }) =>
36-
`block border-b p-4 text-xl ${isActive ? "bg-white" : ""}`
37-
}
38-
to={note.id}
39-
>
40-
📝 {note.title}
41-
</NavLink>
42-
</li>
43-
))}
44-
</ol>
22+
{/* Main container with padding-top to account for header */}
23+
<main className="flex-1 flex flex-col md:flex-row-reverse h-full bg-white" style={{ paddingTop: '64px' }}>
24+
{/* Hamburger menu button for mobile only, positioned below header on the right, hides when sidebar is open */}
25+
{!isSidebarOpen && (
26+
<button
27+
onClick={() => setIsSidebarOpen(true)}
28+
className="md:hidden fixed top-16 right-4 z-50 p-4 text-blue-500 focus:outline-none"
29+
>
30+
<svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
31+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16m-7 6h7" />
32+
</svg>
33+
</button>
34+
)}
35+
36+
{/* Sidebar for notes list - hidden on mobile by default, fixed width on desktop, now on the right */}
37+
<div className={`
38+
fixed inset-y-0 right-0 transform ${isSidebarOpen ? 'translate-x-0' : 'translate-x-full'}
39+
md:relative md:translate-x-0 md:flex md:w-80 md:border-l md:bg-gray-50 md:shadow
40+
transition-transform duration-300 ease-in-out z-40
41+
h-full
42+
`} style={{ top: '64px', boxShadow: '-2px 0 5px rgba(0, 0, 0, 0.1)' }}>
43+
<div className="h-full w-full overflow-y-auto">
44+
<Link to="new" className="block p-4 text-xl text-black">
45+
+ New Note
46+
</Link>
47+
48+
<hr />
49+
50+
{data.noteListItems.length === 0 ? (
51+
<p className="p-4">No notes yet</p>
52+
) : (
53+
<ol className="space-y-2">
54+
{data.noteListItems.map((note) => (
55+
<li key={note.id}>
56+
<NavLink
57+
className={({ isActive }) =>
58+
`block p-3 text-lg hover:bg-gray-100 ${isActive ? "bg-white border-r-4 border-blue-500" : ""}`
59+
}
60+
to={note.id}
61+
>
62+
📝 {note.title}
63+
</NavLink>
64+
</li>
65+
))}
66+
</ol>
67+
)}
68+
</div>
69+
70+
{/* Close button for mobile sidebar - now on the right when sidebar is open */}
71+
{isSidebarOpen && (
72+
<button
73+
onClick={() => setIsSidebarOpen(false)}
74+
className="md:hidden absolute top-4 right-4 text-gray-500 hover:text-gray-800 focus:outline-none"
75+
>
76+
<svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
77+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
78+
</svg>
79+
</button>
4580
)}
4681
</div>
4782

48-
<div className="flex-1 p-6">
83+
{/* Overlay for mobile when sidebar is open - now covers left side */}
84+
{isSidebarOpen && (
85+
<div
86+
className="fixed inset-0 bg-black opacity-50 md:hidden z-30"
87+
onClick={() => setIsSidebarOpen(false)}
88+
></div>
89+
)}
90+
91+
{/* Main content area - adjusts for sidebar width on desktop, now on the left */}
92+
<div className="flex-1 p-4 md:p-6" style={{ marginRight: '320px', transition: 'margin-right 300ms ease-in-out' }}>
4993
<Outlet />
5094
</div>
5195
</main>

0 commit comments

Comments
 (0)