2024-11-10 11:01:59 +01:00
|
|
|
"use client"
|
|
|
|
|
|
2026-02-10 17:02:06 +01:00
|
|
|
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
|
2024-11-10 11:01:59 +01:00
|
|
|
|
|
|
|
|
export function ModeToggle() {
|
2026-02-10 17:02:06 +01:00
|
|
|
const { theme } = useTheme()
|
2025-12-22 20:32:18 +01:00
|
|
|
|
2026-02-10 17:02:06 +01:00
|
|
|
|
|
|
|
|
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 })
|
|
|
|
|
}
|
2024-11-10 11:01:59 +01:00
|
|
|
|
|
|
|
|
return (
|
2026-02-11 14:42:07 +01:00
|
|
|
<div className="flex items-center justify-center rounded-full bg-muted/50 p-0.5 border border-border/50 relative w-fit">
|
2026-02-10 17:02:06 +01:00
|
|
|
<motion.div
|
2026-02-11 14:42:07 +01:00
|
|
|
className="absolute h-6 w-7 rounded-full bg-background shadow-sm z-0 border border-border/20"
|
2026-02-10 17:02:06 +01:00
|
|
|
initial={false}
|
2026-02-11 14:42:07 +01:00
|
|
|
animate={{ x: activeIndex * 28 }}
|
2026-02-10 17:02:06 +01:00
|
|
|
transition={{ type: "spring", stiffness: 400, damping: 30 }}
|
2026-02-11 14:42:07 +01:00
|
|
|
style={{ left: "2px" }}
|
2026-02-10 17:02:06 +01:00
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<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(
|
2026-02-11 14:42:07 +01:00
|
|
|
"flex h-6 w-7 items-center justify-center rounded-full transition-colors duration-200 hover:text-foreground outline-none",
|
2026-02-10 17:02:06 +01:00
|
|
|
isActive ? "text-primary" : "text-muted-foreground"
|
|
|
|
|
)}
|
|
|
|
|
aria-label={t.label}
|
|
|
|
|
>
|
2026-02-11 14:42:07 +01:00
|
|
|
<Icon className="h-3.5 w-3.5" />
|
2026-02-10 17:02:06 +01:00
|
|
|
</button>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-10 11:01:59 +01:00
|
|
|
)
|
2026-02-10 17:02:06 +01:00
|
|
|
}
|