From 6c5eb156a15b37c4cd5685c9a5f28e5be8f16c36 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Tue, 4 Nov 2025 18:07:13 +0100 Subject: [PATCH] Update AppImage --- AppImage/components/auth-setup.tsx | 32 +- AppImage/components/onboarding-carousel.tsx | 97 ++++- AppImage/components/proxmox-dashboard.tsx | 53 ++- AppImage/components/settings.tsx | 425 ++++++++++++++++++++ AppImage/components/sidebar.tsx | 7 +- 5 files changed, 573 insertions(+), 41 deletions(-) create mode 100644 AppImage/components/settings.tsx diff --git a/AppImage/components/auth-setup.tsx b/AppImage/components/auth-setup.tsx index a6ff242..7967cde 100644 --- a/AppImage/components/auth-setup.tsx +++ b/AppImage/components/auth-setup.tsx @@ -22,12 +22,9 @@ export function AuthSetup({ onComplete }: AuthSetupProps) { const [loading, setLoading] = useState(false) useEffect(() => { - // Check if onboarding is complete and auth setup is needed const hasSeenOnboarding = localStorage.getItem("proxmenux-onboarding-seen") - const authSetupComplete = localStorage.getItem("proxmenux-auth-setup-complete") - if (hasSeenOnboarding && !authSetupComplete) { - // Small delay to show after onboarding closes + if (hasSeenOnboarding) { setTimeout(() => setOpen(true), 500) } }, []) @@ -37,19 +34,25 @@ export function AuthSetup({ onComplete }: AuthSetupProps) { setError("") try { - const response = await fetch(getApiUrl("/api/auth/setup"), { + console.log("[v0] Skipping authentication setup...") + const response = await fetch(getApiUrl("/api/auth/skip"), { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ enable_auth: false }), }) - if (!response.ok) throw new Error("Failed to save preference") + const data = await response.json() + console.log("[v0] Auth skip response:", data) - localStorage.setItem("proxmenux-auth-setup-complete", "true") + if (!response.ok) { + throw new Error(data.error || "Failed to skip authentication") + } + + console.log("[v0] Authentication skipped successfully") setOpen(false) onComplete() } catch (err) { - setError("Failed to save preference. Please try again.") + console.error("[v0] Auth skip error:", err) + setError(err instanceof Error ? err.message : "Failed to save preference") } finally { setLoading(false) } @@ -76,29 +79,32 @@ export function AuthSetup({ onComplete }: AuthSetupProps) { setLoading(true) try { + console.log("[v0] Setting up authentication...") const response = await fetch(getApiUrl("/api/auth/setup"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password, - enable_auth: true, }), }) const data = await response.json() + console.log("[v0] Auth setup response:", data) if (!response.ok) { throw new Error(data.error || "Failed to setup authentication") } - // Save token - localStorage.setItem("proxmenux-auth-token", data.token) - localStorage.setItem("proxmenux-auth-setup-complete", "true") + if (data.token) { + localStorage.setItem("proxmenux-auth-token", data.token) + console.log("[v0] Authentication setup successful") + } setOpen(false) onComplete() } catch (err) { + console.error("[v0] Auth setup error:", err) setError(err instanceof Error ? err.message : "Failed to setup authentication") } finally { setLoading(false) diff --git a/AppImage/components/onboarding-carousel.tsx b/AppImage/components/onboarding-carousel.tsx index 32fddb6..866fecb 100644 --- a/AppImage/components/onboarding-carousel.tsx +++ b/AppImage/components/onboarding-carousel.tsx @@ -17,8 +17,13 @@ import { Cpu, FileText, Rocket, + Zap, + Shield, + Link2, + Gauge, } from "lucide-react" import Image from "next/image" +import { Checkbox } from "./ui/checkbox" interface OnboardingSlide { id: number @@ -27,6 +32,7 @@ interface OnboardingSlide { image?: string icon: React.ReactNode gradient: string + features?: { icon: React.ReactNode; text: string }[] } const slides: OnboardingSlide[] = [ @@ -40,6 +46,35 @@ const slides: OnboardingSlide[] = [ }, { id: 1, + title: "What's New in This Version", + description: "We've added exciting new features and improvements to make ProxMenux Monitor even better!", + icon: , + gradient: "from-amber-500 via-orange-500 to-red-500", + features: [ + { + icon: , + text: "Proxy Support - Access ProxMenux through reverse proxies with full functionality", + }, + { + icon: , + text: "Authentication System - Secure your dashboard with password protection", + }, + { + icon: , + text: "PCIe Link Speed Detection - View NVMe drive connection speeds and detect performance issues", + }, + { + icon: , + text: "Enhanced Storage Display - Better formatting for disk sizes (auto-converts GB to TB when needed)", + }, + { + icon: , + text: "SATA/SAS Information - View detailed interface information for all storage devices", + }, + ], + }, + { + id: 2, title: "System Overview", description: "Monitor your server's status in real-time: CPU, memory, temperature, system load and more. Everything in an intuitive and easy-to-understand dashboard.", @@ -48,7 +83,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-blue-500 to-cyan-500", }, { - id: 2, + id: 3, title: "Storage Management", description: "Visualize the status of all your disks and volumes. Detailed information on capacity, usage, SMART health, temperature and performance of each storage device.", @@ -57,7 +92,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-cyan-500 to-teal-500", }, { - id: 3, + id: 4, title: "Network Metrics", description: "Monitor network traffic in real-time. Bandwidth statistics, active interfaces, transfer speeds and historical usage graphs.", @@ -66,7 +101,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-teal-500 to-green-500", }, { - id: 4, + id: 5, title: "Virtual Machines & Containers", description: "Manage all your VMs and LXC containers from one place. Status, allocated resources, current usage and quick controls for each virtual machine.", @@ -75,7 +110,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-green-500 to-emerald-500", }, { - id: 5, + id: 6, title: "Hardware Information", description: "Complete details of your server hardware: CPU, RAM, GPU, disks, network, UPS and more. Technical specifications, models, serial numbers and status of each component.", @@ -84,7 +119,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-emerald-500 to-blue-500", }, { - id: 6, + id: 7, title: "System Logs", description: "Access system logs in real-time. Filter by event type, search for specific errors and keep complete track of your server activity. Download the displayed logs for further analysis.", @@ -93,7 +128,7 @@ const slides: OnboardingSlide[] = [ gradient: "from-blue-500 to-indigo-500", }, { - id: 7, + id: 8, title: "Ready for the Future!", description: "ProxMenux Monitor is prepared to receive updates and improvements that will be added gradually, improving the user experience and being able to execute ProxMenux functions from the web panel.", @@ -106,6 +141,7 @@ export function OnboardingCarousel() { const [open, setOpen] = useState(false) const [currentSlide, setCurrentSlide] = useState(0) const [direction, setDirection] = useState<"next" | "prev">("next") + const [dontShowAgain, setDontShowAgain] = useState(false) useEffect(() => { const hasSeenOnboarding = localStorage.getItem("proxmenux-onboarding-seen") @@ -119,6 +155,9 @@ export function OnboardingCarousel() { setDirection("next") setCurrentSlide(currentSlide + 1) } else { + if (dontShowAgain) { + localStorage.setItem("proxmenux-onboarding-seen", "true") + } setOpen(false) } } @@ -131,11 +170,9 @@ export function OnboardingCarousel() { } const handleSkip = () => { - setOpen(false) - } - - const handleDontShowAgain = () => { - localStorage.setItem("proxmenux-onboarding-seen", "true") + if (dontShowAgain) { + localStorage.setItem("proxmenux-onboarding-seen", "true") + } setOpen(false) } @@ -205,6 +242,20 @@ export function OnboardingCarousel() {

+ {slide.features && ( +
+ {slide.features.map((feature, index) => ( +
+
{feature.icon}
+

{feature.text}

+
+ ))} +
+ )} + {/* Progress dots */}
{slides.map((_, index) => ( @@ -255,17 +306,19 @@ export function OnboardingCarousel() {
- {/* Don't show again */} - {currentSlide === slides.length - 1 && ( -
- -
- )} +
+ setDontShowAgain(checked as boolean)} + /> + +
diff --git a/AppImage/components/proxmox-dashboard.tsx b/AppImage/components/proxmox-dashboard.tsx index f736556..c81974a 100644 --- a/AppImage/components/proxmox-dashboard.tsx +++ b/AppImage/components/proxmox-dashboard.tsx @@ -13,6 +13,7 @@ import { SystemLogs } from "./system-logs" import { OnboardingCarousel } from "./onboarding-carousel" import { AuthSetup } from "./auth-setup" import { Login } from "./login" +import { Settings } from "./settings" import { getApiUrl } from "../lib/api-config" import { RefreshCw, @@ -27,6 +28,7 @@ import { Box, Cpu, FileText, + SettingsIcon, } from "lucide-react" import Image from "next/image" import { ThemeToggle } from "./theme-toggle" @@ -220,6 +222,8 @@ export function ProxmoxDashboard() { return "Hardware" case "logs": return "System Logs" + case "settings": + return "Settings" default: return "Navigation Menu" } @@ -285,31 +289,47 @@ export function ProxmoxDashboard() { useEffect(() => { const checkAuth = async () => { + console.log("[v0] Checking authentication status...") try { const token = localStorage.getItem("proxmenux-auth-token") const headers: HeadersInit = { "Content-Type": "application/json" } if (token) { headers["Authorization"] = `Bearer ${token}` + console.log("[v0] Found token in localStorage") + } else { + console.log("[v0] No token found in localStorage") } - const response = await fetch(getApiUrl("/api/auth/status"), { + const apiUrl = getApiUrl("/api/auth/status") + console.log("[v0] Calling auth status API:", apiUrl) + + const response = await fetch(apiUrl, { headers, }) const data = await response.json() + console.log("[v0] Auth status response:", data) + + const authConfigured = data.auth_enabled || data.authenticated setAuthRequired(data.auth_enabled) setIsAuthenticated(data.authenticated) - setAuthSetupComplete(localStorage.getItem("proxmenux-auth-setup-complete") === "true") + setAuthSetupComplete(authConfigured) setAuthChecked(true) - // Setup token refresh if authenticated + console.log("[v0] Auth state:", { + authRequired: data.auth_enabled, + isAuthenticated: data.authenticated, + authSetupComplete: authConfigured, + }) + if (data.authenticated && token) { setupTokenRefresh() } } catch (error) { console.error("[v0] Failed to check auth status:", error) + setAuthSetupComplete(false) setAuthChecked(true) } } @@ -456,7 +476,7 @@ export function ProxmoxDashboard() { >
- + System Logs + + Settings + @@ -601,6 +627,21 @@ export function ProxmoxDashboard() { System Logs +
@@ -633,6 +674,10 @@ export function ProxmoxDashboard() { + + + +