98 lines
2.9 KiB
TypeScript
98 lines
2.9 KiB
TypeScript
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
|