From 4b2456859f692756f9549fdb3773880af4a7a79a Mon Sep 17 00:00:00 2001 From: Jaime Idolpx Date: Thu, 11 Jun 2026 04:04:02 -0400 Subject: [PATCH] feat(App): add Profile and AboutMeatloaf pages with navigation integration --- src/app/App.tsx | 64 +++++------------------- src/app/components/AboutMeatloafPage.tsx | 33 ++++++++++++ src/app/components/ProfilePage.tsx | 59 ++++++++++++++++++++++ 3 files changed, 105 insertions(+), 51 deletions(-) create mode 100644 src/app/components/AboutMeatloafPage.tsx create mode 100644 src/app/components/ProfilePage.tsx diff --git a/src/app/App.tsx b/src/app/App.tsx index 4c2ce1b..5abfb60 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense, useEffect, useState } from 'react'; -import { Cpu, Settings, Wifi, Network, HardDrive, Activity, Search, Wrench, User, LogOut, Bell, FileText, AppWindow, Folder, Edit, Eye, Database, Upload, Download, Code2, LayoutList, Image, ChevronLeft, Loader2, Terminal, Link, Printer, Maximize2, Minimize2, Info } from 'lucide-react'; +import { Cpu, Wifi, Network, HardDrive, Activity, Search, Wrench, User, FileText, AppWindow, Folder, Edit, Eye, Database, Upload, Download, Code2, LayoutList, Image, ChevronLeft, Loader2, Terminal, Link, Printer, Maximize2, Minimize2 } from 'lucide-react'; import { Toaster, toast } from 'sonner'; import StatusPage from './components/StatusPage'; import DevicesPage from './components/DevicesPage'; @@ -10,6 +10,8 @@ import ToolsPage from './components/ToolsPage'; import SearchOverlay from './components/SearchOverlay'; import RealityOverrideAdminPage from './components/RealityOverrideAdminPage'; import MediaManager from './components/MediaManager'; +import ProfilePage from './components/ProfilePage'; +import AboutMeatloafPage from './components/AboutMeatloafPage'; import logoSvg from '../imports/logo.svg'; import { useSettings } from './settings'; import { WsProvider } from './ws'; @@ -22,7 +24,7 @@ import { LazyLoader } from './components/ui/lazy-loader'; const RealityOverridePage = lazy(() => import('./components/RealityOverridePage')); const SerialConsolePage = lazy(() => import('./components/SerialConsolePage')); -type Page = 'status' | 'devices' | 'iec' | 'network' | 'general' | 'tools' | 'apps' | AppId; +type Page = 'status' | 'devices' | 'iec' | 'network' | 'general' | 'tools' | 'apps' | 'profile' | 'about-meatloaf' | AppId; type AppId = | 'file-manager' @@ -53,7 +55,6 @@ export default function App() { const [currentPage, setCurrentPage] = useState('status'); const { config, setConfig, saveStatus, pendingCount, flushNow, reload } = useSettings(); const [showSearch, setShowSearch] = useState(false); - const [showProfileMenu, setShowProfileMenu] = useState(false); const [devicesOpenId, setDevicesOpenId] = useState(null); const [isFullscreen, setIsFullscreen] = useState(false); @@ -104,6 +105,8 @@ export default function App() { network: , general: , tools: , + profile: setCurrentPage(p as Page)} />, + 'about-meatloaf': , apps: (

Apps

@@ -255,54 +258,13 @@ function AppPage({ title, onBack }: { title: string; onBack: () => void }) { > -
- - {showProfileMenu && ( -
- - - - -
- -
- )} -
+
diff --git a/src/app/components/AboutMeatloafPage.tsx b/src/app/components/AboutMeatloafPage.tsx new file mode 100644 index 0000000..761b7a3 --- /dev/null +++ b/src/app/components/AboutMeatloafPage.tsx @@ -0,0 +1,33 @@ +import logoSvg from '../../imports/logo.svg'; + +export default function AboutMeatloafPage() { + return ( +
+ Meatloaf + +
+

Meatloaf

+

Multi-device Commodore 64 Emulator

+
+ +
+ {[ + ['Project', 'Meatloaf Manipulator'], + ['Platform', 'Commodore 64 / C128'], + ['Website', 'meatloaf.cc'], + ['GitHub', 'github.com/idolpx/meatloaf'], + ].map(([label, value]) => ( +
+ {label} + {value} +
+ ))} +
+ +

+ Meatloaf is open-source firmware for retro computing enthusiasts.
+ Released under the GPL3 License. +

+
+ ); +} diff --git a/src/app/components/ProfilePage.tsx b/src/app/components/ProfilePage.tsx new file mode 100644 index 0000000..b62b64e --- /dev/null +++ b/src/app/components/ProfilePage.tsx @@ -0,0 +1,59 @@ +import { Bell, BookOpen, ChevronRight, Info, LogOut, Settings } from 'lucide-react'; + +interface Props { + onNavigate: (page: string) => void; +} + +interface Item { + icon: React.ReactNode; + label: string; + sublabel?: string; + page?: string; + destructive?: boolean; +} + +const ITEMS: Item[][] = [ + [ + { icon: , label: 'Preferences', sublabel: 'General settings', page: 'general' }, + { icon: , label: 'Notifications' }, + ], + [ + { icon: , label: 'Documentation' }, + { icon: , label: 'About Meatloaf', page: 'about-meatloaf' }, + ], + [ + { icon: , label: 'Log Out', destructive: true }, + ], +]; + +export default function ProfilePage({ onNavigate }: Props) { + return ( +
+

Profile

+ +
+ {ITEMS.map((group, gi) => ( +
+ {group.map((item, ii) => ( + + ))} +
+ ))} +
+
+ ); +}