Skip to content

Commit 82f4ec5

Browse files
authored
feat: introduce desktop sidebar layout ahead of the v1.1.0 release (#7)
Add a responsive desktop (md+) Sidebar with collapsible navigation, Lucide outline icons, animated active indicators, and persistent collapse state. Integrate Sidebar into App while preserving the existing TopNav-driven mobile layout. Hide the Home link when already on the home route. Update frontend and monorepo versions to v1.1.0, add lucide-react dependency, refresh README release highlights, and regenerate lockfiles.
1 parent 2738b18 commit 82f4ec5

8 files changed

Lines changed: 304 additions & 50 deletions

File tree

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ PermLens helps developers and reviewers understand what data a GitHub App *decla
3434
- [Vercel backend API deployment](#vercel-backend-api-deployment)
3535
- [Vercel frontend deployment](#vercel-frontend-deployment)
3636
- [🟢 Project status](#-project-status)
37-
- [✨ Release highlights (v1.0.0)](#-release-highlights-v100)
37+
- [✨ Release highlights (v1.1.0)](#-release-highlights-v110)
3838
- [🔐 Security and privacy](#-security-and-privacy)
3939
- [🏷️ Branding](#️-branding)
4040
- [⚖️ License](#️-license)
@@ -244,17 +244,17 @@ Frontend:
244244

245245
## 🟢 Project status
246246

247-
PermLens is in stable release **v1.0.0**.
247+
PermLens is in stable release **v1.1.0**.
248248

249249
The API response schema is stable, and deployments are ready for production use. Future releases will extend capabilities while preserving the v1 contract.
250250

251251

252-
## ✨ Release highlights (v1.0.0)
252+
## ✨ Release highlights (v1.1.0)
253253

254-
- Stable v1 schema with full app identity fields for audits and tooling
255-
- Response envelope now surfaces cache hits and rate-limit status explicitly
256-
- Predictable fallback + error signaling when a slug cannot be resolved
257-
- Vercel-ready deployment split for backend API and frontend with env guidance
254+
- Desktop sidebar layout with collapsible navigation and icon cues
255+
- Mobile layout focuses on the top nav for legal routes
256+
- Home link now hides when already on the home page
257+
- Added Lucide icon dependency for navigation visuals
258258

259259

260260
## 🔐 Security and privacy

backend/package-lock.json

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package-lock.json

Lines changed: 56 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "permlens-frontend",
33
"private": true,
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"description": "Web interface for inspecting GitHub App permissions and visualizing privacy labels generated by PermLens",
66
"type": "module",
77
"scripts": {
@@ -11,6 +11,7 @@
1111
"preview": "vite preview"
1212
},
1313
"dependencies": {
14+
"lucide-react": "^0.568.0",
1415
"react": "^19.2.0",
1516
"react-dom": "^19.2.0",
1617
"react-router-dom": "^6.30.1"

frontend/src/App.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { BrowserRouter, Routes, Route } from "react-router-dom";
22
import TopNav from "./components/TopNav";
3+
import Sidebar from "./layouts/Sidebar";
34
import Home from "./pages/Home";
45
import TermsOfService from "./pages/TermsOfService";
56
import PrivacyPolicy from "./pages/PrivacyPolicy";
67

78
function App() {
89
return (
910
<BrowserRouter>
10-
<main className="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
11+
<div className="md:hidden min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
1112
<div className="mx-auto max-w-3xl px-4 py-8 sm:px-6 sm:py-10">
1213
<TopNav />
1314
<Routes>
@@ -16,7 +17,15 @@ function App() {
1617
<Route path="/privacy" element={<PrivacyPolicy />} />
1718
</Routes>
1819
</div>
19-
</main>
20+
</div>
21+
22+
<Sidebar>
23+
<Routes>
24+
<Route path="/" element={<Home />} />
25+
<Route path="/tos" element={<TermsOfService />} />
26+
<Route path="/privacy" element={<PrivacyPolicy />} />
27+
</Routes>
28+
</Sidebar>
2029
</BrowserRouter>
2130
);
2231
}

frontend/src/components/TopNav.jsx

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { useState } from "react";
2-
import { Link, NavLink } from "react-router-dom";
2+
import { Link, NavLink, useLocation } from "react-router-dom";
33

44
function TopNav() {
55
const [menuOpen, setMenuOpen] = useState(false);
66

7+
const location = useLocation();
8+
const isHome = location.pathname === "/";
9+
710
const closeMenu = () => setMenuOpen(false);
811

912
return (
@@ -33,23 +36,27 @@ function TopNav() {
3336
</svg>
3437
</button>
3538

36-
<Link
37-
to="/"
38-
onClick={closeMenu}
39-
className="hidden text-sm font-semibold uppercase tracking-wide text-gray-200 hover:text-white md:inline"
40-
>
41-
Home
42-
</Link>
39+
{!isHome && (
40+
<Link
41+
to="/"
42+
onClick={closeMenu}
43+
className="hidden text-sm font-semibold uppercase tracking-wide text-gray-200 hover:text-white md:inline"
44+
>
45+
Home
46+
</Link>
47+
)}
4348
</div>
4449

4550
<div className="flex items-center gap-3">
46-
<Link
47-
to="/"
48-
onClick={closeMenu}
49-
className="text-sm font-semibold uppercase tracking-wide text-gray-200 hover:text-white md:hidden"
50-
>
51-
Home
52-
</Link>
51+
{!isHome && (
52+
<Link
53+
to="/"
54+
onClick={closeMenu}
55+
className="text-sm font-semibold uppercase tracking-wide text-gray-200 hover:text-white md:hidden"
56+
>
57+
Home
58+
</Link>
59+
)}
5360
<div className="hidden items-center gap-3 text-sm font-semibold uppercase tracking-wide text-gray-300 md:flex">
5461
<NavLink
5562
to="/tos"
@@ -103,17 +110,19 @@ function TopNav() {
103110
</button>
104111
</div>
105112
<div className="flex flex-col gap-2">
106-
<NavLink
107-
to="/"
108-
onClick={closeMenu}
109-
className={({ isActive }) =>
110-
`rounded px-3 py-2 hover:text-white ${
111-
isActive ? "bg-white/10 text-white" : ""
112-
}`
113-
}
114-
>
115-
Home
116-
</NavLink>
113+
{!isHome && (
114+
<NavLink
115+
to="/"
116+
onClick={closeMenu}
117+
className={({ isActive }) =>
118+
`rounded px-3 py-2 hover:text-white ${
119+
isActive ? "bg-white/10 text-white" : ""
120+
}`
121+
}
122+
>
123+
Home
124+
</NavLink>
125+
)}
117126
<NavLink
118127
to="/tos"
119128
onClick={closeMenu}

0 commit comments

Comments
 (0)