diff --git a/index.html b/index.html index 33096b7..7dbee47 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,11 @@ - + + + - archnest + ArchNest
diff --git a/public/favicon-32.png b/public/favicon-32.png new file mode 100644 index 0000000..f9ac039 Binary files /dev/null and b/public/favicon-32.png differ diff --git a/public/favicon-48.png b/public/favicon-48.png new file mode 100644 index 0000000..eb96a81 Binary files /dev/null and b/public/favicon-48.png differ diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..8db14b5 Binary files /dev/null and b/public/favicon.png differ diff --git a/public/favicon.svg b/public/favicon.svg deleted file mode 100644 index 6893eb1..0000000 --- a/public/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 0115309..2977c54 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ import Containers from './pages/Containers' import RemoteDesktop from './pages/RemoteDesktop' import HostMetrics from './pages/HostMetrics' import Settings from './pages/Settings' +import Help from './pages/Help' import Login from './pages/Login' import Enrollment from './pages/Enrollment' import { useAuth } from './lib/AuthContext' @@ -93,6 +94,7 @@ function Dashboard() { } /> } /> } /> + } /> diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 202b941..9af9393 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -11,6 +11,7 @@ import { MonitorSmartphone, Gauge, Settings, + HelpCircle, ChevronLeft, ChevronRight, } from 'lucide-react' @@ -32,6 +33,7 @@ const navItems = [ { icon: MonitorSmartphone, label: 'Remote Desktop', route: '/remote-desktop' }, { icon: Gauge, label: 'Host Metrics', route: '/host-metrics' }, { icon: Settings, label: 'Settings', route: '/settings' }, + { icon: HelpCircle, label: 'Help', route: '/help' }, ] export default function Sidebar({ collapsed, onToggle }: SidebarProps) { diff --git a/src/components/TopBar.tsx b/src/components/TopBar.tsx index 2543fb2..90cf360 100644 --- a/src/components/TopBar.tsx +++ b/src/components/TopBar.tsx @@ -10,6 +10,7 @@ const pageTitles: Record = { '/booknest': 'BookNest', '/terminal': 'Terminal', '/settings': 'Settings', + '/help': 'Help', } const pageSubtitles: Record = { @@ -27,6 +28,7 @@ const staticPages: { name: string; path: string }[] = [ { name: 'Remote Desktop', path: '/remote-desktop' }, { name: 'Host Metrics', path: '/host-metrics' }, { name: 'Settings', path: '/settings' }, + { name: 'Help', path: '/help' }, ] type SearchResult = @@ -225,10 +227,13 @@ export default function TopBar() { Security - +
- - +
+ + {iconMode === 'manual' && ( + + )} +
+ {iconMode === 'auto' ? ( +
+
+ + + {isIconUrl(icon) ? 'Detected from title/URL' : 'No match yet — type a title or pick one'} + +
+ +
+ ) : ( + + )}
@@ -390,7 +451,7 @@ export default function BookNest() { [...groups] .sort((a, b) => b.links.length - a.links.length) .slice(0, 5) - .map((g) => ({ label: g.title, icons: g.links.slice(0, 5).map((l) => resolveIcon(l.icon)), count: g.links.length })), + .map((g) => ({ label: g.title, icons: g.links.slice(0, 5).map((l) => l.icon), count: g.links.length })), [groups] ) @@ -464,9 +525,9 @@ export default function BookNest() {
{qa.label}
- {qa.icons.map((Icon, i) => ( + {qa.icons.map((icon, i) => (
- +
))}
@@ -503,15 +564,12 @@ export default function BookNest() {

Favorites

{favorites.length > 0 ? ( - favorites.map((f) => { - const Icon = resolveIcon(f.icon) - return ( - - - {f.title} - - ) - }) + favorites.map((f) => ( + + + {f.title} + + )) ) : (

No favorites yet

)} diff --git a/src/pages/Help.tsx b/src/pages/Help.tsx new file mode 100644 index 0000000..d5cf4dc --- /dev/null +++ b/src/pages/Help.tsx @@ -0,0 +1,145 @@ +import { + LayoutGrid, + Server, + Bookmark, + Terminal, + Waypoints, + FolderOpen, + Box, + MonitorSmartphone, + Gauge, + Settings, + Search, + type LucideIcon, +} from 'lucide-react' + +const cardBase: React.CSSProperties = { + backgroundColor: 'rgba(10, 10, 12, 0.92)', + border: '1px solid rgba(200, 164, 52, 0.08)', + borderRadius: '12px', + padding: '22px', +} + +interface GuideEntry { + icon: LucideIcon + title: string + description: string + tips?: string[] +} + +const guideEntries: GuideEntry[] = [ + { + icon: LayoutGrid, + title: 'Glance', + description: + 'The home dashboard. Shows overall system health, a rollup of connected integrations, recent activity, and shortcuts into the rest of the app.', + tips: ['Click "Connected Integrations" entries to jump straight to Infrastructure.'], + }, + { + icon: Server, + title: 'Infrastructure', + description: + 'Lists every connected integration (Proxmox, AWS, Docker, NetBird, Cloudflare, Uptime Kuma, Weather, SSH hosts) and the live resources/health each one reports.', + tips: ['Add new integrations from Settings → Integrations — they show up here automatically.'], + }, + { + icon: Bookmark, + title: 'BookNest', + description: 'A categorized bookmark manager for the links you use most — internal tools, dashboards, docs, anything.', + tips: [ + 'Icons are auto-detected from the title or URL (e.g. typing "Proxmox" picks up the real Proxmox logo) — pick "Choose manually" if it guesses wrong.', + 'Star a bookmark to pin it to the Favorites panel.', + ], + }, + { + icon: Terminal, + title: 'Terminal', + description: 'A full SSH terminal to any host you\'ve added as an integration — supports tabs, split panes, jump hosts, and certificate auth.', + tips: ['Session output can be logged; theme and font preferences are remembered between visits.'], + }, + { + icon: Waypoints, + title: 'Tunnels', + description: 'Local, remote, and dynamic (SOCKS5) SSH tunnels. Tunnels can be set to auto-start whenever the backend boots.', + }, + { + icon: FolderOpen, + title: 'Files', + description: 'Browse, edit, upload, and download files over SFTP on any connected SSH host — and transfer files directly between two hosts without round-tripping through your machine.', + tips: ['Use the "Send to another host" action on a file row to start a host-to-host transfer; progress shows live in the panel at the bottom.'], + }, + { + icon: Box, + title: 'Containers', + description: 'Manage Docker containers on remote hosts — start, stop, view logs, and exec into a running container.', + }, + { + icon: MonitorSmartphone, + title: 'Remote Desktop', + description: 'RDP, VNC, and Telnet sessions to remote machines, streamed through the built-in Guacamole proxy — no separate client needed.', + }, + { + icon: Gauge, + title: 'Host Metrics', + description: 'Live CPU, memory, disk, network, listening-port, firewall, process, and login-activity widgets for any SSH-managed host.', + }, + { + icon: Settings, + title: 'Settings', + description: 'Your profile, integrations, appearance, notifications, and full data export/import (back up or migrate every integration, bookmark, and tunnel as a single JSON file).', + }, + { + icon: Search, + title: 'Search (top bar)', + description: 'The search box at the top of every page looks across pages, integrations, and bookmarks at once — press Enter to jump to the top match.', + }, +] + +export default function Help() { + return ( +
+
+

How ArchNest works

+

+ A quick tour of every page and what it's for. Use the sidebar to navigate, or the search bar at the top to jump straight to something. +

+
+ +
+ {guideEntries.map((entry) => { + const Icon = entry.icon + return ( +
+
+
+ +
+

{entry.title}

+
+

{entry.description}

+ {entry.tips && entry.tips.length > 0 && ( +
    + {entry.tips.map((tip, i) => ( +
  • + {tip} +
  • + ))} +
+ )} +
+ ) + })} +
+
+ ) +}