Vitron-Front/app/components/SunMoonToggle.tsx
2026-04-29 01:44:16 +03:30

100 lines
3.5 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
import { saveSession } from "../cookie";
import { ThemeTypes } from "../types/theme";
import { Moon, Sun } from "lucide-react";
export const SunMoonToggle = ({
theme: initialTheme,
}: {
theme: ThemeTypes;
}) => {
const [theme, setTheme] = useState<ThemeTypes>(initialTheme);
useEffect(() => {
// Apply theme class to document body to match root.tsx
const body = document.body;
if (theme === "dark") {
body.classList.add("dark");
} else {
body.classList.remove("dark");
}
}, [theme]);
const changeTheme = useCallback(async () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
// Update document body class immediately to match root.tsx
const body = document.body;
if (newTheme === "dark") {
body.classList.add("dark");
} else {
body.classList.remove("dark");
}
await saveSession("theme", newTheme);
// Refresh the page to ensure all components update with new theme
window.location.reload();
}, [theme]);
return (
<div className="relative">
<input
type="checkbox"
checked={theme === "dark"}
onChange={changeTheme}
className="sr-only"
aria-label={`Switch to ${theme === "light" ? "dark" : "light"} theme`}
/>
<div
onClick={changeTheme}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter") {
changeTheme();
}
}}
className="relative w-14 h-7 bg-gradient-to-r from-blue-400 to-blue-500 dark:from-indigo-600 dark:to-purple-600 rounded-full cursor-pointer transition-all duration-300 ease-in-out shadow-lg hover:shadow-xl"
>
{/* Track background with gradient */}
<div className="absolute inset-0 rounded-full bg-gradient-to-r from-sky-300 via-blue-400 to-blue-500 dark:from-slate-700 dark:via-slate-600 dark:to-slate-800 transition-all duration-300"></div>
{/* Sliding circle */}
<div
className={`absolute top-0.5 w-6 h-6 bg-WHITE rounded-full shadow-lg transform transition-all duration-300 ease-in-out flex items-center justify-center ${
theme === "dark" ? "-translate-x-8" : ""
}`}
>
{/* Icon inside the circle */}
<div className="transition-all duration-300">
{theme === "light" ? (
<Sun className="w-4 h-4 text-yellow-500" />
) : (
<Moon className="w-4 h-4 text-indigo-600" />
)}
</div>
</div>
{/* Stars for dark mode */}
{theme === "dark" && (
<div className="absolute inset-0 rounded-full overflow-hidden">
<div className="absolute top-1 left-1 w-1 h-1 bg-WHITE rounded-full opacity-60 animate-pulse"></div>
<div className="absolute top-2 left-4 w-0.5 h-0.5 bg-WHITE rounded-full opacity-40 animate-pulse delay-75"></div>
<div className="absolute top-1.5 right-2 w-0.5 h-0.5 bg-WHITE rounded-full opacity-50 animate-pulse delay-150"></div>
</div>
)}
{/* Clouds for light mode */}
{theme === "light" && (
<div className="absolute inset-0 rounded-full overflow-hidden">
<div className="absolute top-1 right-1 w-2 h-1 bg-WHITE/30 rounded-full"></div>
<div className="absolute top-2 right-2.5 w-1.5 h-0.5 bg-WHITE/20 rounded-full"></div>
</div>
)}
</div>
</div>
);
};