"use client"
import * as React from "react"
import { Navigate, Outlet, useParams } from "react-router"
import { useAppStore } from "@exxatdesignux/product-framework/app-store"
import { resolveProductFromPath } from "@exxatdesignux/product-framework/product-routing"
import { usePersistHydrated } from "../../hooks/use-persist-hydrated"
import { useShippedCatalogReady } from "../../hooks/use-shipped-catalog-ready"
export interface ProductRootGateProps {
/**
* Rendered while the persisted store is hydrating from localStorage.
* Defaults to `null` (renders nothing). Pass a route-shaped skeleton
* (e.g. ``) for a smoother first paint.
*/
loadingFallback?: React.ReactNode
/**
* Where to redirect when the URL segment doesn't resolve to a registered
* product. Defaults to `/prism/dashboard`. Customer apps can override
* (e.g. `//dashboard`).
*/
fallbackPath?: string
}
/**
* Validates `:productRootSegment` against built-in slugs and configured
* custom products. Unknown segments bounce to `fallbackPath`; known
* segments render the child route via ``.
*
* Mount as the `element` of a `:productRootSegment` parent route:
*
* ```tsx
* }>
* } />
* …
*
* ```
*/
export function ProductRootGate({
loadingFallback = null,
fallbackPath = "/prism/dashboard",
}: ProductRootGateProps = {}) {
const { productRootSegment = "" } = useParams()
const customProducts = useAppStore(s => s.customProducts)
const hydrated = usePersistHydrated()
const shippedReady = useShippedCatalogReady()
const resolved = resolveProductFromPath(`/${productRootSegment}`, customProducts)
if (resolved) {
return
}
// Built-in product slugs resolve without persisted custom product state.
// For unknown segments, wait until hydration + shipped catalog load finish
// before redirecting so tenant suffixes resolve from store or deploy JSON.
if (!hydrated || !shippedReady) {
return <>{loadingFallback}>
}
return
}