diff --git a/index.html b/index.html index f3e7e41..464390e 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,18 @@ NearleXpress Developer Docs + diff --git a/package-lock.json b/package-lock.json index 9bf76ae..96a37fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -1478,7 +1477,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -2337,7 +2335,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -2694,7 +2691,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2916,7 +2912,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3405,7 +3400,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3531,7 +3525,6 @@ "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -3625,7 +3618,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/App.jsx b/src/App.jsx index e2dbf5a..3f035a9 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,9 @@ import { useMemo, useState } from 'react' +import { Menu, Layers } from 'lucide-react' import Sidebar from './components/Sidebar' import Introduction from './components/Introduction' import TopicView from './components/TopicView' +import ThemeToggle from './components/ThemeToggle' import { legacyTopics, restTopics, LEGACY_BASE_URL, REST_BASE_URL } from './data/topics' const processTopics = (topics, baseUrl, type) => @@ -26,31 +28,68 @@ function filterTopics(topics, q) { export default function App() { const [activeTopic, setActiveTopic] = useState(null) const [searchQuery, setSearchQuery] = useState('') + const [sidebarOpen, setSidebarOpen] = useState(false) const visibleLegacy = useMemo(() => filterTopics(allLegacy, searchQuery.trim().toLowerCase()), [searchQuery]) const visibleRest = useMemo(() => filterTopics(allRest, searchQuery.trim().toLowerCase()), [searchQuery]) + // Picking a topic (or Introduction) should also close the drawer on mobile + const selectTopic = (t) => { + setActiveTopic(t) + setSidebarOpen(false) + } + return ( -
+
{/* Ambient background glows */} -
-
-
+
+
+
+ + {/* Theme toggle (floating, top-right) */} + + + {/* Mobile top bar */} +
+ + +
+ + {/* Mobile drawer backdrop */} + {sidebarOpen && ( +
setSidebarOpen(false)} + className="md:hidden fixed inset-0 z-30 bg-slate-900/40 dark:bg-black/60 backdrop-blur-sm animate-fade-in" + /> + )} setSidebarOpen(false)} /> -
+
{activeTopic ? ( -
+
) @@ -59,7 +98,7 @@ export default function App() {
)} diff --git a/src/components/EndpointCard.jsx b/src/components/EndpointCard.jsx index 26503f2..24ae789 100644 --- a/src/components/EndpointCard.jsx +++ b/src/components/EndpointCard.jsx @@ -114,20 +114,20 @@ export default function EndpointCard({ endpoint, baseUrl, isLegacy, onSend, resu } const methodColor = { - GET: 'bg-emerald-100/50 text-emerald-700 border-emerald-200', - POST: 'bg-blue-100/50 text-blue-700 border-blue-200', - PUT: 'bg-amber-100/50 text-amber-700 border-amber-200', - DELETE: 'bg-red-100/50 text-red-700 border-red-200', - PATCH: 'bg-purple-100/50 text-purple-700 border-purple-200', - }[endpoint.method] || 'bg-slate-100/50 text-slate-700 border-slate-200' + GET: 'bg-emerald-100/50 dark:bg-emerald-500/10 text-emerald-700 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/20', + POST: 'bg-blue-100/50 dark:bg-blue-500/10 text-blue-700 dark:text-blue-400 border-blue-200 dark:border-blue-500/20', + PUT: 'bg-amber-100/50 dark:bg-amber-500/10 text-amber-700 dark:text-amber-400 border-amber-200 dark:border-amber-500/20', + DELETE: 'bg-red-100/50 dark:bg-red-500/10 text-red-700 dark:text-red-400 border-red-200 dark:border-red-500/20', + PATCH: 'bg-purple-100/50 dark:bg-purple-500/10 text-purple-700 dark:text-purple-400 border-purple-200 dark:border-purple-500/20', + }[endpoint.method] || 'bg-slate-100/50 dark:bg-slate-500/10 text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-500/20' const isOk = result?.kind === 'response' && result.ok const isErr = result?.kind === 'response' && !result.ok const isNet = result?.kind === 'network-error' return ( -
-
+
+
{/* Left Column: Description & Parameters */}
@@ -136,39 +136,39 @@ export default function EndpointCard({ endpoint, baseUrl, isLegacy, onSend, resu {endpoint.method} -

+

{endpoint.name}

{endpoint.description && ( -

{endpoint.description}

+

{endpoint.description}

)}
{/* URL bar */} -
+
-
{baseUrl}
-
{path}
+
{baseUrl}
+
{path}
{/* Query Parameters */} {paramDefs.length > 0 && (
-

- Query Parameters +

+ Query Parameters

{paramDefs.map((p) => (
-