sozsoft-platform/ui/src/components/layouts/Layouts.tsx

105 lines
3 KiB
TypeScript
Raw Normal View History

2026-02-24 20:44:16 +00:00
import { useMemo, lazy, Suspense } from 'react'
import Loading from '@/components/shared/Loading'
import { useStoreState } from '@/store'
import {
LAYOUT_TYPE_CLASSIC,
LAYOUT_TYPE_MODERN,
LAYOUT_TYPE_SIMPLE,
LAYOUT_TYPE_STACKED_SIDE,
LAYOUT_TYPE_DECKED,
LAYOUT_TYPE_BLANK,
} from '@/constants/theme.constant'
import useAuth from '@/utils/hooks/useAuth'
import useDirection from '@/utils/hooks/useDirection'
import useLocale from '@/utils/hooks/useLocale'
import { useDynamicRoutes } from '@/routes/dynamicRoutesContext'
import { useLocation } from 'react-router-dom'
import { hasSubdomain } from '@/utils/subdomain'
export type LayoutType =
| typeof LAYOUT_TYPE_CLASSIC
| typeof LAYOUT_TYPE_MODERN
| typeof LAYOUT_TYPE_SIMPLE
| typeof LAYOUT_TYPE_STACKED_SIDE
| typeof LAYOUT_TYPE_DECKED
| typeof LAYOUT_TYPE_BLANK
const layouts = {
[LAYOUT_TYPE_CLASSIC]: lazy(() => import('./ClassicLayout')),
[LAYOUT_TYPE_MODERN]: lazy(() => import('./ModernLayout')),
[LAYOUT_TYPE_STACKED_SIDE]: lazy(() => import('./StackedSideLayout')),
[LAYOUT_TYPE_SIMPLE]: lazy(() => import('./SimpleLayout')),
[LAYOUT_TYPE_DECKED]: lazy(() => import('./DeckedLayout')),
[LAYOUT_TYPE_BLANK]: lazy(() => import('./BlankLayout')),
}
const AuthLayout = lazy(() => import('./AuthLayout'))
const PublicLayout = lazy(() => import('./PublicLayout'))
const Layout = () => {
const location = useLocation()
const layoutType = useStoreState((s) => s.theme.layout.type) as LayoutType
const { routes, loading } = useDynamicRoutes()
const { authenticated } = useAuth()
useDirection()
useLocale()
const currentPath = location.pathname
const isAdminPath = currentPath.startsWith('/admin')
const route = useMemo(() => {
if (!routes || routes.length === 0) return undefined
const matched = routes.find((route) => {
if (!route.path.includes(':')) return route.path === currentPath
const regexPath = route.path.replace(/:[^/]+/g, '[^/]+')
const regex = new RegExp(`^${regexPath}$`)
return regex.test(currentPath)
})
return matched
}, [routes, currentPath])
const AppLayout = useMemo(() => {
// 1) Admin path ise, route bulunmasa bile admin layout'u göster
if (isAdminPath) {
return layouts[layoutType]
}
// 2) Admin değil ve route bulunamadı -> PublicLayout
if (!route) {
return PublicLayout
}
// 3) Mevcut kurallar
if (authenticated && route.routeType === 'protected') {
return layouts[layoutType]
}
if (route.routeType === 'authenticated' || hasSubdomain()) {
return AuthLayout
}
return PublicLayout
}, [isAdminPath, route, layoutType, authenticated])
if (loading) {
return (
<div className="flex flex-auto flex-col h-[100vh]">
<Loading loading />
</div>
)
}
return (
<Suspense
fallback={
<div className="flex flex-auto flex-col h-[100vh]">
<Loading loading />
</div>
}
>
<AppLayout />
</Suspense>
)
}
export default Layout