"use client"; import { useState, useEffect } from "react"; import { ChevronDown } from "lucide-react"; import { Switch } from "@/app/_components/ui/switch"; import { Separator } from "@/app/_components/ui/separator"; import { ScrollArea } from "@/app/_components/ui/scroll-area"; import { ThemeSwitcher } from "../../../../_components/theme-switcher"; import DropdownSwitcher from "../../../../_components/custom-dropdown-switcher"; import { type CookiePreferences, defaultCookiePreferences, getCookiePreferences, saveCookiePreferences, getLanguagePreference, saveLanguagePreference, getTimezonePreference, saveTimezonePreference, getWeekStartPreference, saveWeekStartPreference, getAutoTimezonePreference, saveAutoTimezonePreference, applyCookiePreferences, } from "@/app/_utils/cookies/cookies-manager"; import { toast } from "sonner"; import { initialTimezones, TimezoneType } from "@/prisma/data/timezones"; import { languages, LanguageType } from "@/prisma/data/languages"; export default function PreferencesSettings() { const [language, setLanguage] = useState("en-US"); const [languageLabel, setLanguageLabel] = useState("English"); const [startWeekOnMonday, setStartWeekOnMonday] = useState(false); const [autoTimezone, setAutoTimezone] = useState(true); const [timezone, setTimezone] = useState("Asia/Jakarta"); const [timezoneLabel, setTimezoneLabel] = useState("(GMT+7:00) Jakarta"); const [timezones, setTimezones] = useState([]); const [availableLanguages, setAvailableLanguages] = useState( [] ); const [isLoading, setIsLoading] = useState(true); const [cookiePreferences, setCookiePreferences] = useState( defaultCookiePreferences ); const [lastToastTime, setLastToastTime] = useState(0); // Show toast with debounce to prevent too many notifications const showSavedToast = () => { const now = Date.now(); // Only show toast if it's been at least 2 seconds since the last one // if (now - lastToastTime > 2000) { // toast("Preferences saved"); // setLastToastTime(now); // } }; // Load data when component mounts useEffect(() => { try { // Load cookie preferences const savedCookiePreferences = getCookiePreferences(); setCookiePreferences(savedCookiePreferences); // Load language preference const savedLanguage = getLanguagePreference(); if (savedLanguage) { setLanguage(savedLanguage); } // Load week start preference const savedWeekStart = getWeekStartPreference(); setStartWeekOnMonday(savedWeekStart); // Load auto timezone preference const savedAutoTimezone = getAutoTimezonePreference(); setAutoTimezone(savedAutoTimezone); // Load timezone preference const savedTimezone = getTimezonePreference(); if (savedTimezone) { setTimezone(savedTimezone); } // Load timezone and language data if (Array.isArray(initialTimezones)) { setTimezones(initialTimezones); } else { console.warn("Using fallback timezone data"); setTimezones([ { value: "Asia/Jakarta", prefix: ChevronDown, label: "Jakarta", subLabel: "(GMT+7:00)", }, ]); } if (Array.isArray(languages)) { setAvailableLanguages(languages); } else { console.warn("Using fallback language data"); setAvailableLanguages([ { value: "en-US", prefix: ChevronDown, label: "English", subLabel: "English (US)", }, ]); } } catch (error) { console.error("Error loading data:", error); setTimezones([ { value: "Asia/Jakarta", prefix: ChevronDown, label: "Jakarta", subLabel: "(GMT+7:00)", }, ]); setAvailableLanguages([ { value: "en-US", prefix: ChevronDown, label: "English", subLabel: "English (US)", }, ]); } finally { setIsLoading(false); } }, []); // Update labels when data is loaded useEffect(() => { if (!isLoading) { // Set language label const selectedLanguage = availableLanguages.find( (lang) => lang.value === language ); if (selectedLanguage) { setLanguageLabel(selectedLanguage.label); } // Set timezone label const selectedTimezone = timezones.find((tz) => tz.value === timezone); if (selectedTimezone) { setTimezoneLabel( selectedTimezone.subLabel + " " + selectedTimezone.label ); } } }, [isLoading, language, timezone, availableLanguages, timezones]); // Detect browser language useEffect(() => { if ( !isLoading && availableLanguages.length > 0 && !getLanguagePreference() ) { const browserLang = navigator.language; const matchedLang = availableLanguages.find( (lang) => lang.value === browserLang || lang.value.split("-")[0] === browserLang.split("-")[0] ); if (matchedLang) { setLanguage(matchedLang.value); setLanguageLabel(matchedLang.label); // Save the detected language saveLanguagePreference(matchedLang.value); } } }, [isLoading, availableLanguages]); // Handle language change const handleLanguageChange = (value: string) => { setLanguage(value); const selectedLanguage = availableLanguages.find( (lang) => lang.value === value ); if (selectedLanguage) { setLanguageLabel(selectedLanguage.label); } // Save immediately saveLanguagePreference(value); showSavedToast(); }; // Handle timezone change const handleTimezoneChange = (value: string) => { setTimezone(value); const selectedTimezone = timezones.find((tz) => tz.value === value); if (selectedTimezone) { setTimezoneLabel( selectedTimezone.subLabel + " " + selectedTimezone.label ); } // Save immediately saveTimezonePreference(value); showSavedToast(); }; // Handle week start change const handleWeekStartChange = (value: boolean) => { setStartWeekOnMonday(value); // Save immediately saveWeekStartPreference(value); showSavedToast(); }; // Handle auto timezone change const handleAutoTimezoneChange = (value: boolean) => { setAutoTimezone(value); // Save immediately saveAutoTimezonePreference(value); showSavedToast(); }; // Handle cookie preference changes const handleCookiePreferenceChange = ( type: keyof CookiePreferences, value: boolean ) => { const newPreferences = { ...cookiePreferences, [type]: value }; setCookiePreferences(newPreferences); // Save and apply immediately saveCookiePreferences(newPreferences); applyCookiePreferences(newPreferences); showSavedToast(); }; if (isLoading) { return (
Loading...
); } return (

Preferences

{/* Appearance Section */}

Appearance

Customize how the application looks on your device.

{/* Language & Time Section */}

Language & Time

{/* Language Subsection */}

Language

Change the language used in the user interface.

{/* Start week on Monday Subsection */}

Start week on Monday

This will change how all calendars in your app look.

{/* Auto Timezone Subsection */}

Set timezone automatically using your location

Reminders, notifications and emails are delivered based on your time zone.

{/* Timezone Subsection */}

Timezone

Current timezone setting.

{/* Privacy Section */}

Privacy

{/* Cookies Settings */}

Necessary Cookies

Required for the website to function properly. Cannot be disabled.

Functional Cookies

Enable enhanced functionality and personalization.

handleCookiePreferenceChange("functional", checked) } />

Analytics Cookies

Help us improve by collecting anonymous information about how you use the site.

handleCookiePreferenceChange("analytics", checked) } />

Marketing Cookies

Used to display personalized advertisements based on your browsing habits.

handleCookiePreferenceChange("marketing", checked) } />
); }