update: ui

This commit is contained in:
Théo LAGACHE
2026-02-10 17:02:06 +01:00
parent 80bdca138e
commit d24e534828
6 changed files with 330 additions and 136 deletions
+50 -33
View File
@@ -1,41 +1,58 @@
"use client"
import * as React from "react"
import {Moon, Sun} from "lucide-react"
import {Button} from "@/components/ui/button"
import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger} from "@/components/ui/dropdown-menu"
import {authClient} from "@/lib/auth/auth-client";
import {toast} from "sonner";
import { Moon, Sun, Monitor } from "lucide-react"
import { authClient } from "@/lib/auth/auth-client"
import { motion } from "motion/react"
import { useTheme } from "next-themes"
import { cn } from "@/lib/utils"
const themes = [
{ id: "light", icon: Sun, label: "Light" },
{ id: "system", icon: Monitor, label: "System" },
{ id: "dark", icon: Moon, label: "Dark" },
] as const
export function ModeToggle() {
const { theme } = useTheme()
const setTheme = async (theme: "light" | "dark" | "system") => {
toast.success("Your theme preference has been updated.");
await authClient.updateUser({theme: theme});
};
const currentIndex = themes.findIndex((t) => t.id === theme)
const activeIndex = currentIndex === -1 ? 1 : currentIndex
const handleThemeChange = async (newTheme: "light" | "system" | "dark") => {
await authClient.updateUser({ theme: newTheme })
}
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm">
<Sun className="size-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"/>
<Moon className="absolute size-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"/>
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<div className="flex items-center justify-center rounded-full bg-muted/50 p-1 border border-border/50 relative w-fit">
<motion.div
className="absolute h-7 w-8 rounded-full bg-background shadow-sm z-0 border border-border/20"
initial={false}
animate={{ x: activeIndex * 32 }}
transition={{ type: "spring", stiffness: 400, damping: 30 }}
style={{ left: "4px" }}
/>
<div className="flex gap-0 relative z-10">
{themes.map((t) => {
const Icon = t.icon
const isActive = theme === t.id
return (
<button
key={t.id}
onClick={() => handleThemeChange(t.id)}
className={cn(
"flex h-7 w-8 items-center justify-center rounded-full transition-colors duration-200 hover:text-foreground outline-none",
isActive ? "text-primary" : "text-muted-foreground"
)}
aria-label={t.label}
>
<Icon className="h-4 w-4" />
</button>
)
})}
</div>
</div>
)
}
}