modifica al Night Mode
This commit is contained in:
parent
af35df94d3
commit
dc7dbc4166
7 changed files with 19 additions and 99 deletions
|
|
@ -4,16 +4,12 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="color-scheme" content="light dark" />
|
<meta name="color-scheme" content="dark" />
|
||||||
<title>Academy Aziendale</title>
|
<title>Academy Aziendale</title>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
try {
|
try {
|
||||||
var theme = localStorage.getItem("academy-theme");
|
|
||||||
var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
||||||
if (theme === "dark" || (theme !== "light" && theme !== "dark" && prefersDark)) {
|
|
||||||
document.documentElement.classList.add("dark");
|
document.documentElement.classList.add("dark");
|
||||||
}
|
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import Statistiche from "@/pages/Statistiche";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem storageKey="academy-theme">
|
<ThemeProvider attribute="class" forcedTheme="dark" enableSystem={false}>
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
import { NavLink, useNavigate } from "react-router-dom";
|
import { NavLink, useNavigate } from "react-router-dom";
|
||||||
import { LogOut } from "lucide-react";
|
import { LogOut } from "lucide-react";
|
||||||
import ThemeToggle from "@/components/ThemeToggle";
|
|
||||||
import { getNavItemsForRole } from "@/config/navigation";
|
import { getNavItemsForRole } from "@/config/navigation";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
|
@ -35,14 +34,9 @@ export default function AppSidebar({ onNavigate }: AppSidebarProps) {
|
||||||
return (
|
return (
|
||||||
<aside className="flex min-h-svh w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground">
|
<aside className="flex min-h-svh w-64 shrink-0 flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground">
|
||||||
<div className="border-b px-4 py-4">
|
<div className="border-b px-4 py-4">
|
||||||
<div className="flex items-start justify-between gap-2">
|
|
||||||
<div>
|
|
||||||
<p className="text-sm font-semibold">Academy Aziendale</p>
|
<p className="text-sm font-semibold">Academy Aziendale</p>
|
||||||
<p className="text-xs text-muted-foreground">Gestione formazione</p>
|
<p className="text-xs text-muted-foreground">Gestione formazione</p>
|
||||||
</div>
|
</div>
|
||||||
<ThemeToggle compact />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav className="flex flex-1 flex-col gap-1 p-3">
|
<nav className="flex flex-1 flex-col gap-1 p-3">
|
||||||
{navItems.map((item) => (
|
{navItems.map((item) => (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
//===============================================
|
||||||
|
// File: ThemeProvider.tsx
|
||||||
|
// Componente wrapper per il tema scuro fisso (Night Mode)
|
||||||
|
// @author: "villari.andrea@libero.it"
|
||||||
|
// @version: "1.0.0 2026-07-14"
|
||||||
|
//===============================================
|
||||||
import type { ComponentProps } from "react";
|
import type { ComponentProps } from "react";
|
||||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Monitor, Moon, Sun } from "lucide-react";
|
|
||||||
import { useTheme } from "next-themes";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
|
|
||||||
interface ThemeToggleProps {
|
|
||||||
className?: string;
|
|
||||||
compact?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ThemeToggle({ className, compact = false }: ThemeToggleProps) {
|
|
||||||
const { theme, setTheme, resolvedTheme } = useTheme();
|
|
||||||
const [mounted, setMounted] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => setMounted(true), []);
|
|
||||||
|
|
||||||
if (!mounted) {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size={compact ? "icon-sm" : "sm"}
|
|
||||||
className={className}
|
|
||||||
disabled
|
|
||||||
aria-hidden
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const icon =
|
|
||||||
theme === "system" ? (
|
|
||||||
<Monitor className="size-4" />
|
|
||||||
) : resolvedTheme === "dark" ? (
|
|
||||||
<Moon className="size-4" />
|
|
||||||
) : (
|
|
||||||
<Sun className="size-4" />
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger
|
|
||||||
render={
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size={compact ? "icon-sm" : "sm"}
|
|
||||||
className={className}
|
|
||||||
aria-label="Cambia tema"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{icon}
|
|
||||||
{!compact && <span className="sr-only">Cambia tema</span>}
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
|
||||||
<Sun className="size-4" />
|
|
||||||
Chiaro
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
|
||||||
<Moon className="size-4" />
|
|
||||||
Scuro
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
|
||||||
<Monitor className="size-4" />
|
|
||||||
Sistema
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import { useTheme } from "next-themes"
|
|
||||||
import { Toaster as Sonner, type ToasterProps } from "sonner"
|
import { Toaster as Sonner, type ToasterProps } from "sonner"
|
||||||
import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
|
import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
|
||||||
|
|
||||||
const Toaster = ({ ...props }: ToasterProps) => {
|
const Toaster = ({ ...props }: ToasterProps) => {
|
||||||
const { theme = "system" } = useTheme()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sonner
|
<Sonner
|
||||||
theme={theme as ToasterProps["theme"]}
|
theme="dark"
|
||||||
className="toaster group"
|
className="toaster group"
|
||||||
icons={{
|
icons={{
|
||||||
success: (
|
success: (
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
|
//===========================================
|
||||||
|
// File: Login.tsx
|
||||||
|
// Componente per la gestione pagine di Login
|
||||||
|
// @author: "villari.andrea@libero.it"
|
||||||
|
// @version: "1.0.0 2026-07-14"
|
||||||
|
//===========================================
|
||||||
import { CircleAlert } from "lucide-react";
|
import { CircleAlert } from "lucide-react";
|
||||||
import { useState, type FormEvent } from "react";
|
import { useState, type FormEvent } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import ThemeToggle from "@/components/ThemeToggle";
|
|
||||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -38,10 +43,7 @@ export default function Login() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex min-h-svh items-center justify-center bg-muted/40 p-4">
|
<div className="flex min-h-svh items-center justify-center bg-muted/40 p-4">
|
||||||
<div className="absolute top-4 right-4">
|
|
||||||
<ThemeToggle />
|
|
||||||
</div>
|
|
||||||
<Card className="w-full max-w-md">
|
<Card className="w-full max-w-md">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Academy Aziendale</CardTitle>
|
<CardTitle className="text-xl">Academy Aziendale</CardTitle>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue