import { useEffect, useMemo, useState } from "react"; import { useLocation } from "react-router-dom"; import MobileHeader from "@/components/MobileHeader"; import SectionMenuItem from "@/components/Settings/SectionMenuItem"; import { DEFAULT_SETTING_SECTION, isSettingSectionKey, SETTINGS_SECTIONS, type SettingSectionDefinition, type SettingSectionKey, } from "@/components/Settings/settingSections"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useInstance } from "@/contexts/InstanceContext"; import useCurrentUser from "@/hooks/useCurrentUser"; import useMediaQuery from "@/hooks/useMediaQuery"; import { User_Role } from "@/types/proto/api/v1/user_service_pb"; import { useTranslate } from "@/utils/i18n"; const Setting = () => { const t = useTranslate(); const sm = useMediaQuery("sm"); const location = useLocation(); const user = useCurrentUser(); const { fetchSettings } = useInstance(); const [selectedSection, setSelectedSection] = useState(DEFAULT_SETTING_SECTION); const isHost = user?.role === User_Role.ADMIN; const sectionGroups = useMemo(() => { const visibleSections = SETTINGS_SECTIONS.filter((section) => section.scope === "basic" || isHost); return { basic: visibleSections.filter((section) => section.scope === "basic"), admin: visibleSections.filter((section) => section.scope === "admin"), all: visibleSections, }; }, [isHost]); const visibleSectionKeys = useMemo(() => new Set(sectionGroups.all.map((section) => section.key)), [sectionGroups.all]); const sectionOptions = useMemo( () => sectionGroups.all.map((section) => ({ value: section.key, label: t(section.labelKey) })), [sectionGroups.all, t], ); useEffect(() => { const hash = location.hash.slice(1); const nextSection = isSettingSectionKey(hash) && visibleSectionKeys.has(hash) ? hash : DEFAULT_SETTING_SECTION; setSelectedSection(nextSection); }, [location.hash, visibleSectionKeys]); useEffect(() => { if (!isHost) { return; } const preloadSettingKeys = new Set(sectionGroups.admin.flatMap((section) => section.preloadSettingKeys ?? [])); void fetchSettings([...preloadSettingKeys]); }, [fetchSettings, isHost, sectionGroups.admin]); const handleSectionSelectorItemClick = (section: SettingSectionKey) => { window.location.hash = section; }; const selectedSectionDefinition = sectionGroups.all.find((section) => section.key === selectedSection) ?? SETTINGS_SECTIONS.find((section) => section.key === DEFAULT_SETTING_SECTION) ?? SETTINGS_SECTIONS[0]; const ActiveSection = selectedSectionDefinition.component; const renderSectionMenuItems = (sections: SettingSectionDefinition[]) => sections.map((section) => ( handleSectionSelectorItemClick(section.key)} /> )); return (
{!sm && }
{sm && (
{t("common.basic")}
{renderSectionMenuItems(sectionGroups.basic)}
{isHost && ( <> {t("common.admin")}
{renderSectionMenuItems(sectionGroups.admin)}
)}
)}
{!sm && (
)}
); }; export default Setting;