/** * Application initialization: language sync, access-denied logic, deep link routing. * Runs effects that depend on Telegram auth (isAllowed, startParam); caller provides those. */ "use client"; import { useEffect } from "react"; import { useAppStore } from "@/store/app-store"; import { getLang } from "@/i18n/messages"; import { useTranslation } from "@/i18n/use-translation"; import { RETRY_DELAY_MS } from "@/lib/constants"; export interface UseAppInitParams { /** Whether the user is allowed (localhost or has valid initData). */ isAllowed: boolean; /** Telegram Mini App start_param (e.g. "duty" for current duty deep link). */ startParam: string | undefined; } /** * Syncs language from backend config, applies document lang/title, handles access denied * when not allowed, and routes to current duty view when opened via startParam=duty. */ export function useAppInit({ isAllowed, startParam }: UseAppInitParams): void { const setLang = useAppStore((s) => s.setLang); const lang = useAppStore((s) => s.lang); const setAccessDenied = useAppStore((s) => s.setAccessDenied); const setLoading = useAppStore((s) => s.setLoading); const setCurrentView = useAppStore((s) => s.setCurrentView); const { t } = useTranslation(); // Sync lang from backend config (window.__DT_LANG). useEffect(() => { if (typeof window === "undefined") return; setLang(getLang()); }, [setLang]); // Apply lang to document (title and html lang) for accessibility and i18n. useEffect(() => { if (typeof document === "undefined") return; document.documentElement.lang = lang; document.title = t("app.title"); }, [lang, t]); // When not allowed (no initData and not localhost), show access denied after delay. useEffect(() => { if (isAllowed) { setAccessDenied(false); return; } const id = setTimeout(() => { setAccessDenied(true); setLoading(false); }, RETRY_DELAY_MS); return () => clearTimeout(id); }, [isAllowed, setAccessDenied, setLoading]); // When opened via deep link startParam=duty, show current duty view first. useEffect(() => { if (startParam === "duty") setCurrentView("currentDuty"); }, [startParam, setCurrentView]); }