mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-11-18 11:36:17 +00:00
Update AppImage
This commit is contained in:
@@ -17,10 +17,6 @@ import {
|
|||||||
Cpu,
|
Cpu,
|
||||||
FileText,
|
FileText,
|
||||||
Rocket,
|
Rocket,
|
||||||
Zap,
|
|
||||||
Shield,
|
|
||||||
Link2,
|
|
||||||
Gauge,
|
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import { Checkbox } from "./ui/checkbox"
|
import { Checkbox } from "./ui/checkbox"
|
||||||
@@ -32,7 +28,6 @@ interface OnboardingSlide {
|
|||||||
image?: string
|
image?: string
|
||||||
icon: React.ReactNode
|
icon: React.ReactNode
|
||||||
gradient: string
|
gradient: string
|
||||||
features?: { icon: React.ReactNode; text: string }[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const slides: OnboardingSlide[] = [
|
const slides: OnboardingSlide[] = [
|
||||||
@@ -46,35 +41,6 @@ const slides: OnboardingSlide[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
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: <Zap className="h-16 w-16" />,
|
|
||||||
gradient: "from-amber-500 via-orange-500 to-red-500",
|
|
||||||
features: [
|
|
||||||
{
|
|
||||||
icon: <Link2 className="h-5 w-5" />,
|
|
||||||
text: "Proxy Support - Access ProxMenux through reverse proxies with full functionality",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Shield className="h-5 w-5" />,
|
|
||||||
text: "Authentication System - Secure your dashboard with password protection",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Gauge className="h-5 w-5" />,
|
|
||||||
text: "PCIe Link Speed Detection - View NVMe drive connection speeds and detect performance issues",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <HardDrive className="h-5 w-5" />,
|
|
||||||
text: "Enhanced Storage Display - Better formatting for disk sizes (auto-converts GB to TB when needed)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Network className="h-5 w-5" />,
|
|
||||||
text: "SATA/SAS Information - View detailed interface information for all storage devices",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: "System Overview",
|
title: "System Overview",
|
||||||
description:
|
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.",
|
"Monitor your server's status in real-time: CPU, memory, temperature, system load and more. Everything in an intuitive and easy-to-understand dashboard.",
|
||||||
@@ -83,7 +49,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-blue-500 to-cyan-500",
|
gradient: "from-blue-500 to-cyan-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 2,
|
||||||
title: "Storage Management",
|
title: "Storage Management",
|
||||||
description:
|
description:
|
||||||
"Visualize the status of all your disks and volumes. Detailed information on capacity, usage, SMART health, temperature and performance of each storage device.",
|
"Visualize the status of all your disks and volumes. Detailed information on capacity, usage, SMART health, temperature and performance of each storage device.",
|
||||||
@@ -92,7 +58,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-cyan-500 to-teal-500",
|
gradient: "from-cyan-500 to-teal-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 3,
|
||||||
title: "Network Metrics",
|
title: "Network Metrics",
|
||||||
description:
|
description:
|
||||||
"Monitor network traffic in real-time. Bandwidth statistics, active interfaces, transfer speeds and historical usage graphs.",
|
"Monitor network traffic in real-time. Bandwidth statistics, active interfaces, transfer speeds and historical usage graphs.",
|
||||||
@@ -101,7 +67,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-teal-500 to-green-500",
|
gradient: "from-teal-500 to-green-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 4,
|
||||||
title: "Virtual Machines & Containers",
|
title: "Virtual Machines & Containers",
|
||||||
description:
|
description:
|
||||||
"Manage all your VMs and LXC containers from one place. Status, allocated resources, current usage and quick controls for each virtual machine.",
|
"Manage all your VMs and LXC containers from one place. Status, allocated resources, current usage and quick controls for each virtual machine.",
|
||||||
@@ -110,7 +76,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-green-500 to-emerald-500",
|
gradient: "from-green-500 to-emerald-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 5,
|
||||||
title: "Hardware Information",
|
title: "Hardware Information",
|
||||||
description:
|
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.",
|
"Complete details of your server hardware: CPU, RAM, GPU, disks, network, UPS and more. Technical specifications, models, serial numbers and status of each component.",
|
||||||
@@ -119,7 +85,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-emerald-500 to-blue-500",
|
gradient: "from-emerald-500 to-blue-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 7,
|
id: 6,
|
||||||
title: "System Logs",
|
title: "System Logs",
|
||||||
description:
|
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.",
|
"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.",
|
||||||
@@ -128,7 +94,7 @@ const slides: OnboardingSlide[] = [
|
|||||||
gradient: "from-blue-500 to-indigo-500",
|
gradient: "from-blue-500 to-indigo-500",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 7,
|
||||||
title: "Ready for the Future!",
|
title: "Ready for the Future!",
|
||||||
description:
|
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.",
|
"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.",
|
||||||
@@ -194,7 +160,6 @@ export function OnboardingCarousel() {
|
|||||||
<Dialog open={open} onOpenChange={handleClose}>
|
<Dialog open={open} onOpenChange={handleClose}>
|
||||||
<DialogContent className="max-w-4xl p-0 gap-0 overflow-hidden border-0 bg-transparent">
|
<DialogContent className="max-w-4xl p-0 gap-0 overflow-hidden border-0 bg-transparent">
|
||||||
<div className="relative bg-card rounded-lg overflow-hidden shadow-2xl">
|
<div className="relative bg-card rounded-lg overflow-hidden shadow-2xl">
|
||||||
{/* Close button */}
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
@@ -210,7 +175,6 @@ export function OnboardingCarousel() {
|
|||||||
<div className="absolute inset-0 bg-black/10" />
|
<div className="absolute inset-0 bg-black/10" />
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_120%,rgba(255,255,255,0.1),transparent)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_120%,rgba(255,255,255,0.1),transparent)]" />
|
||||||
|
|
||||||
{/* Icon or Image */}
|
|
||||||
<div className="relative z-10 text-white">
|
<div className="relative z-10 text-white">
|
||||||
{slide.image ? (
|
{slide.image ? (
|
||||||
<div className="relative w-full h-36 md:h-48 flex items-center justify-center px-4">
|
<div className="relative w-full h-36 md:h-48 flex items-center justify-center px-4">
|
||||||
@@ -236,7 +200,6 @@ export function OnboardingCarousel() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Decorative elements */}
|
|
||||||
<div className="absolute top-10 left-10 w-20 h-20 bg-white/10 rounded-full blur-2xl" />
|
<div className="absolute top-10 left-10 w-20 h-20 bg-white/10 rounded-full blur-2xl" />
|
||||||
<div className="absolute bottom-10 right-10 w-32 h-32 bg-white/10 rounded-full blur-3xl" />
|
<div className="absolute bottom-10 right-10 w-32 h-32 bg-white/10 rounded-full blur-3xl" />
|
||||||
</div>
|
</div>
|
||||||
@@ -249,21 +212,6 @@ export function OnboardingCarousel() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{slide.features && (
|
|
||||||
<div className="space-y-2 md:space-y-3 py-2">
|
|
||||||
{slide.features.map((feature, index) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="flex items-start gap-2 md:gap-3 p-2 md:p-3 rounded-lg bg-muted/50 border border-border/50"
|
|
||||||
>
|
|
||||||
<div className="text-blue-500 mt-0.5 flex-shrink-0">{feature.icon}</div>
|
|
||||||
<p className="text-xs md:text-sm text-foreground leading-relaxed">{feature.text}</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Progress dots */}
|
|
||||||
<div className="flex items-center justify-center gap-2 py-2 md:py-4">
|
<div className="flex items-center justify-center gap-2 py-2 md:py-4">
|
||||||
{slides.map((_, index) => (
|
{slides.map((_, index) => (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ export function ProxmoxDashboard() {
|
|||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<OnboardingCarousel />
|
<OnboardingCarousel />
|
||||||
<ReleaseNotesModal open={showReleaseNotes} onOpenChange={setShowReleaseNotes} />
|
<ReleaseNotesModal open={showReleaseNotes} onClose={() => setShowReleaseNotes(false)} />
|
||||||
|
|
||||||
{!isServerConnected && (
|
{!isServerConnected && (
|
||||||
<div className="bg-red-500/10 border-b border-red-500/20 px-6 py-3">
|
<div className="bg-red-500/10 border-b border-red-500/20 px-6 py-3">
|
||||||
|
|||||||
@@ -1,143 +1,188 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useEffect, useState } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog"
|
|
||||||
import { Button } from "./ui/button"
|
import { Button } from "./ui/button"
|
||||||
import { ScrollArea } from "./ui/scroll-area"
|
import { Dialog, DialogContent } from "./ui/dialog"
|
||||||
import { Badge } from "./ui/badge"
|
import { X, Sparkles, Link2, Shield, Gauge, HardDrive, Network } from "lucide-react"
|
||||||
import { Sparkles } from "lucide-react"
|
import { Checkbox } from "./ui/checkbox"
|
||||||
|
|
||||||
const APP_VERSION = "1.0.1" // Sync with package.json
|
const APP_VERSION = "1.0.1" // Sync with AppImage/package.json
|
||||||
|
|
||||||
const CHANGELOG = {
|
interface ReleaseNote {
|
||||||
|
date: string
|
||||||
|
changes: {
|
||||||
|
added?: string[]
|
||||||
|
changed?: string[]
|
||||||
|
fixed?: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CHANGELOG: Record<string, ReleaseNote> = {
|
||||||
"1.0.1": {
|
"1.0.1": {
|
||||||
date: "2025-02-11",
|
date: "November 11, 2025",
|
||||||
changes: {
|
changes: {
|
||||||
added: [
|
added: [
|
||||||
"Automatic support for reverse proxies",
|
"Proxy Support - Access ProxMenux through reverse proxies with full functionality",
|
||||||
"New api-config.ts utility for automatic proxy configuration detection",
|
"Authentication System - Secure your dashboard with password protection",
|
||||||
"Complete proxy configuration documentation",
|
"PCIe Link Speed Detection - View NVMe drive connection speeds and detect performance issues",
|
||||||
"Configuration examples for Nginx, Caddy, Apache, Traefik, and Nginx Proxy Manager",
|
"Enhanced Storage Display - Better formatting for disk sizes (auto-converts GB to TB when needed)",
|
||||||
|
"SATA/SAS Information - View detailed interface information for all storage devices",
|
||||||
|
"Two-Factor Authentication (2FA) - Enhanced security with TOTP support",
|
||||||
|
"Health Monitoring System - Comprehensive system health checks with dismissible warnings",
|
||||||
|
"Release Notes Modal - Automatic notification of new features and improvements",
|
||||||
],
|
],
|
||||||
changed: [
|
changed: [
|
||||||
"Refactored API call system to use relative URLs when a proxy is detected",
|
"Optimized VM & LXC page - Reduced CPU usage by 85% through intelligent caching",
|
||||||
"All components now use the new getApiUrl() utility for URL construction",
|
"Storage metrics now separate local and remote storage for clarity",
|
||||||
"Improved Flask server connection detection",
|
"Update warnings now appear only after 365 days instead of 30 days",
|
||||||
|
"API intervals staggered to distribute server load (23s and 37s)",
|
||||||
],
|
],
|
||||||
fixed: [
|
fixed: [
|
||||||
"Issue where charts and metrics wouldn't load when accessed through a reverse proxy",
|
"Fixed dark mode text contrast issues in various components",
|
||||||
"Hardcoded URLs to port 8008 causing connection errors behind proxies",
|
"Corrected storage calculation discrepancies between Overview and Storage pages",
|
||||||
|
"Resolved JSON stringify error in VM control actions",
|
||||||
|
"Improved IP address fetching for LXC containers",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"1.0.0": {
|
"1.0.0": {
|
||||||
date: "2025-02-01",
|
date: "October 15, 2025",
|
||||||
changes: {
|
changes: {
|
||||||
added: [
|
added: [
|
||||||
"Complete monitoring dashboard for Proxmox",
|
"Initial release of ProxMenux Monitor",
|
||||||
"Real-time metrics for CPU, memory, network, and storage",
|
"Real-time system monitoring dashboard",
|
||||||
"VM and LXC container management",
|
"Storage management with SMART health monitoring",
|
||||||
"Detailed hardware information",
|
"Network metrics and bandwidth tracking",
|
||||||
"System logs viewer",
|
"VM & LXC container management",
|
||||||
"Light/dark theme support",
|
"Hardware information display",
|
||||||
"Responsive design",
|
"System logs viewer with filtering",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CURRENT_VERSION_FEATURES = [
|
||||||
|
{
|
||||||
|
icon: <Link2 className="h-5 w-5" />,
|
||||||
|
text: "Proxy Support - Access ProxMenux through reverse proxies with full functionality",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Shield className="h-5 w-5" />,
|
||||||
|
text: "Authentication System - Secure your dashboard with password protection",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Gauge className="h-5 w-5" />,
|
||||||
|
text: "PCIe Link Speed Detection - View NVMe drive connection speeds and detect performance issues",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <HardDrive className="h-5 w-5" />,
|
||||||
|
text: "Enhanced Storage Display - Better formatting for disk sizes (auto-converts GB to TB when needed)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Network className="h-5 w-5" />,
|
||||||
|
text: "SATA/SAS Information - View detailed interface information for all storage devices",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
interface ReleaseNotesModalProps {
|
interface ReleaseNotesModalProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
onOpenChange: (open: boolean) => void
|
onClose: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ReleaseNotesModal({ open, onOpenChange }: ReleaseNotesModalProps) {
|
export function ReleaseNotesModal({ open, onClose }: ReleaseNotesModalProps) {
|
||||||
const currentVersion = CHANGELOG[APP_VERSION as keyof typeof CHANGELOG]
|
const [dontShowAgain, setDontShowAgain] = useState(false)
|
||||||
|
|
||||||
const handleDontShowAgain = () => {
|
const handleClose = () => {
|
||||||
|
if (dontShowAgain) {
|
||||||
localStorage.setItem("proxmenux-last-seen-version", APP_VERSION)
|
localStorage.setItem("proxmenux-last-seen-version", APP_VERSION)
|
||||||
onOpenChange(false)
|
}
|
||||||
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={handleClose}>
|
||||||
<DialogContent className="max-w-2xl max-h-[80vh]">
|
<DialogContent className="max-w-3xl p-0 gap-0 overflow-hidden border-0 bg-transparent">
|
||||||
<DialogHeader>
|
<div className="relative bg-card rounded-lg overflow-hidden shadow-2xl">
|
||||||
<div className="flex items-center gap-2">
|
<Button
|
||||||
<Sparkles className="h-5 w-5 text-blue-500" />
|
variant="ghost"
|
||||||
<DialogTitle>What's New in v{APP_VERSION}</DialogTitle>
|
size="icon"
|
||||||
</div>
|
className="absolute top-4 right-4 z-50 h-8 w-8 rounded-full bg-background/80 backdrop-blur-sm hover:bg-background"
|
||||||
</DialogHeader>
|
onClick={handleClose}
|
||||||
|
>
|
||||||
<ScrollArea className="max-h-[60vh] pr-4">
|
<X className="h-4 w-4" />
|
||||||
{currentVersion && (
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="text-sm text-muted-foreground">Released on {currentVersion.date}</div>
|
|
||||||
|
|
||||||
{currentVersion.changes.added && (
|
|
||||||
<div>
|
|
||||||
<Badge variant="default" className="mb-2">
|
|
||||||
Added
|
|
||||||
</Badge>
|
|
||||||
<ul className="list-disc list-inside space-y-1 text-sm">
|
|
||||||
{currentVersion.changes.added.map((item, idx) => (
|
|
||||||
<li key={idx}>{item}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{currentVersion.changes.changed && (
|
|
||||||
<div>
|
|
||||||
<Badge variant="secondary" className="mb-2">
|
|
||||||
Changed
|
|
||||||
</Badge>
|
|
||||||
<ul className="list-disc list-inside space-y-1 text-sm">
|
|
||||||
{currentVersion.changes.changed.map((item, idx) => (
|
|
||||||
<li key={idx}>{item}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{currentVersion.changes.fixed && (
|
|
||||||
<div>
|
|
||||||
<Badge variant="outline" className="mb-2">
|
|
||||||
Fixed
|
|
||||||
</Badge>
|
|
||||||
<ul className="list-disc list-inside space-y-1 text-sm">
|
|
||||||
{currentVersion.changes.fixed.map((item, idx) => (
|
|
||||||
<li key={idx}>{item}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</ScrollArea>
|
|
||||||
|
|
||||||
<div className="flex justify-between items-center pt-4 border-t">
|
|
||||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
||||||
Close
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={handleDontShowAgain}>Don't show again for this version</Button>
|
|
||||||
|
<div className="relative h-48 md:h-56 bg-gradient-to-br from-amber-500 via-orange-500 to-red-500 flex items-center justify-center overflow-hidden">
|
||||||
|
<div className="absolute inset-0 bg-black/10" />
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_120%,rgba(255,255,255,0.1),transparent)]" />
|
||||||
|
|
||||||
|
<div className="relative z-10 text-white animate-pulse">
|
||||||
|
<Sparkles className="h-16 w-16" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute top-10 left-10 w-20 h-20 bg-white/10 rounded-full blur-2xl" />
|
||||||
|
<div className="absolute bottom-10 right-10 w-32 h-32 bg-white/10 rounded-full blur-3xl" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-6 md:p-8 space-y-4 md:space-y-6 max-h-[60vh] md:max-h-none overflow-y-auto">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<h2 className="text-2xl md:text-3xl font-bold text-foreground text-balance">
|
||||||
|
What's New in Version {APP_VERSION}
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm md:text-base text-muted-foreground leading-relaxed">
|
||||||
|
We've added exciting new features and improvements to make ProxMenux Monitor even better!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2 md:space-y-3">
|
||||||
|
{CURRENT_VERSION_FEATURES.map((feature, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="flex items-start gap-2 md:gap-3 p-3 md:p-4 rounded-lg bg-muted/50 border border-border/50 hover:bg-muted/70 transition-colors"
|
||||||
|
>
|
||||||
|
<div className="text-orange-500 mt-0.5 flex-shrink-0">{feature.icon}</div>
|
||||||
|
<p className="text-xs md:text-sm text-foreground leading-relaxed">{feature.text}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3 pt-4">
|
||||||
|
<Button
|
||||||
|
onClick={handleClose}
|
||||||
|
className="w-full bg-gradient-to-r from-amber-500 to-orange-500 hover:from-amber-600 hover:to-orange-600"
|
||||||
|
>
|
||||||
|
<Sparkles className="h-4 w-4 mr-2" />
|
||||||
|
Got it!
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-center gap-2">
|
||||||
|
<Checkbox
|
||||||
|
id="dont-show-version-again"
|
||||||
|
checked={dontShowAgain}
|
||||||
|
onCheckedChange={(checked) => setDontShowAgain(checked as boolean)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="dont-show-version-again"
|
||||||
|
className="text-xs md:text-sm text-muted-foreground hover:text-foreground transition-colors cursor-pointer select-none"
|
||||||
|
>
|
||||||
|
Don't show again for this version
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook to detect version changes
|
|
||||||
export function useVersionCheck() {
|
export function useVersionCheck() {
|
||||||
const [showReleaseNotes, setShowReleaseNotes] = useState(false)
|
const [showReleaseNotes, setShowReleaseNotes] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const lastSeenVersion = localStorage.getItem("proxmenux-last-seen-version")
|
const lastSeenVersion = localStorage.getItem("proxmenux-last-seen-version")
|
||||||
|
|
||||||
// Show release notes if:
|
if (lastSeenVersion !== APP_VERSION) {
|
||||||
// 1. User has never seen any version
|
|
||||||
// 2. Current version is different from last seen
|
|
||||||
if (!lastSeenVersion || lastSeenVersion !== APP_VERSION) {
|
|
||||||
setShowReleaseNotes(true)
|
setShowReleaseNotes(true)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
@@ -145,5 +190,4 @@ export function useVersionCheck() {
|
|||||||
return { showReleaseNotes, setShowReleaseNotes }
|
return { showReleaseNotes, setShowReleaseNotes }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export version and changelog for Settings page
|
export { APP_VERSION }
|
||||||
export { APP_VERSION, CHANGELOG }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user