import { InAppEscape } from "@/components/in-app-escape"; import { useAuth } from "@/hooks/use-auth"; import { api } from "@/lib/api-client"; import { resetChatwootUser, setChatwootUser } from "@/lib/chatwoot"; import { useTranslation } from "@/lib/i18n"; import { trackPageView as trackMetaPageView } from "@/lib/meta-pixel"; import { capturePageView, identifyUser, resetUser } from "@/lib/posthog"; import { Toaster } from "@/lib/toast"; import { getUserSettings } from "@/lib/user-settings"; import { Button } from "@sase/ui"; import type { QueryClient } from "@tanstack/react-query"; import { Link, Outlet, createRootRouteWithContext, useLocation } from "@tanstack/react-router"; import { ArrowLeft, Home, Search } from "lucide-react"; import { useEffect, useRef } from "react"; interface RouterContext { queryClient: QueryClient; } export const Route = createRootRouteWithContext()({ component: RootComponent, notFoundComponent: NotFoundComponent, }); function NotFoundComponent() { return (
{/* Ambient brand glow */}

404 — sayfa bulunamadı

Yanlış parça,
yanlış adres.

Aradığın sayfa silinmiş ya da hiç olmamış olabilir. Aşağıdan ana sayfaya dönebilir veya doğrudan şase aramaya gidebilirsin.

Anasayfa
); } function applyTheme(theme: "light" | "dark" | "system") { const isDark = theme === "dark" || (theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches); document.documentElement.classList.toggle("dark", isDark); } function RootComponent() { const location = useLocation(); const { user, isLoading } = useAuth(); const { t } = useTranslation(); // Pageview tracking useEffect(() => { capturePageView(location.pathname); trackMetaPageView(); }, [location.pathname]); // User identification. // // CRITICAL: never call posthog.reset() while the session is still resolving, // nor for first-time anonymous visitors. reset() rotates the anonymous // distinct_id; firing it on every load (user is briefly null while the // session loads) orphaned the pre-signup anonymous person — the one that // carries `user_signed_up` and the first-touch `$initial_utm_*`. The later // identify() then merged a fresh, empty anon id instead, so signups never // linked to trial/payment and channel attribution read "(none)" for everyone. // Only reset on a genuine identified -> anonymous transition (logout); // explicit logout also resets via dashboard.tsx's handleSignOut. const wasIdentifiedRef = useRef(false); useEffect(() => { if (isLoading) return; // session still resolving — leave identity untouched if (user) { wasIdentifiedRef.current = true; identifyUser({ id: user.id, email: user.email, name: user.name, role: user.role, }); // Verified Chatwoot identity: fetch the server-computed HMAC, then set the // widget user. On failure the widget stays anonymous (chat still works). api .get<{ identifier: string; identifierHash: string }>("/chatwoot/identity") .then((res) => setChatwootUser(user, res.identifierHash)) .catch(() => {}); } else if (wasIdentifiedRef.current) { wasIdentifiedRef.current = false; resetUser(); resetChatwootUser(); } }, [user, isLoading]); useEffect(() => { const theme = getUserSettings().theme ?? "dark"; applyTheme(theme); if (theme === "system") { const mq = window.matchMedia("(prefers-color-scheme: dark)"); const handler = () => applyTheme("system"); mq.addEventListener("change", handler); return () => mq.removeEventListener("change", handler); } }, []); return ( <> {t("a11y.skipToContent")} ); }