SubDomain için ayrı Layout

This commit is contained in:
Sedat ÖZTÜRK 2025-08-11 16:43:39 +03:00
parent 64ccc150df
commit 91be964a39
5 changed files with 49 additions and 32 deletions

View file

@ -14,6 +14,7 @@ import useDirection from '@/utils/hooks/useDirection'
import useLocale from '@/utils/hooks/useLocale' import useLocale from '@/utils/hooks/useLocale'
import { useDynamicRoutes } from '@/routes/dynamicRoutesContext' import { useDynamicRoutes } from '@/routes/dynamicRoutesContext'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import { hasSubdomain } from '@/utils/subdomain'
export type LayoutType = export type LayoutType =
| typeof LAYOUT_TYPE_CLASSIC | typeof LAYOUT_TYPE_CLASSIC
@ -65,7 +66,7 @@ const Layout = () => {
return layouts[layoutType] return layouts[layoutType]
} }
if (route?.routeType === 'authenticated') { if (route?.routeType === 'authenticated' || hasSubdomain()) {
return AuthLayout return AuthLayout
} }

View file

@ -64,31 +64,31 @@ const PublicLayout = () => {
{ {
resourceKey: 'Public.nav.home', resourceKey: 'Public.nav.home',
name: translate('::Public.nav.home'), name: translate('::Public.nav.home'),
path: '/home', path: ROUTES_ENUM.public.home,
icon: Home, icon: Home,
}, },
{ {
resourceKey: 'Public.nav.about', resourceKey: 'Public.nav.about',
name: translate('::Public.nav.about'), name: translate('::Public.nav.about'),
path: '/about', path: ROUTES_ENUM.public.about,
icon: Info, icon: Info,
}, },
{ {
resourceKey: 'Public.nav.services', resourceKey: 'Public.nav.services',
name: translate('::Public.nav.services'), name: translate('::Public.nav.services'),
path: '/services', path: ROUTES_ENUM.public.services,
icon: Briefcase, icon: Briefcase,
}, },
{ {
resourceKey: 'Public.nav.products', resourceKey: 'Public.nav.products',
name: translate('::Public.nav.products'), name: translate('::Public.nav.products'),
path: '/products', path: ROUTES_ENUM.public.products,
icon: Package, icon: Package,
}, },
{ {
resourceKey: 'Public.nav.blog', resourceKey: 'Public.nav.blog',
name: translate('::Public.nav.blog'), name: translate('::Public.nav.blog'),
path: '/blog', path: ROUTES_ENUM.public.blog,
icon: BookOpen, icon: BookOpen,
}, },
{ {
@ -100,10 +100,14 @@ const PublicLayout = () => {
{ {
resourceKey: 'Public.nav.contact', resourceKey: 'Public.nav.contact',
name: translate('::Public.nav.contact'), name: translate('::Public.nav.contact'),
path: '/contact', path: ROUTES_ENUM.public.contact,
icon: Phone, icon: Phone,
}, },
{ resourceKey: 'Public.nav.giris', name: translate('::Public.nav.giris'), path: '/login' }, {
resourceKey: 'Public.nav.giris',
name: translate('::Public.nav.giris'),
path: ROUTES_ENUM.authenticated.login,
},
] ]
const getNavItemClass = (resourceKey?: string) => { const getNavItemClass = (resourceKey?: string) => {

View file

@ -7,6 +7,7 @@ import ProtectedRoute from '@/components/route/ProtectedRoute'
import PermissionGuard from '@/components/route/PermissionGuard' import PermissionGuard from '@/components/route/PermissionGuard'
import PageContainer from '@/components/template/PageContainer' import PageContainer from '@/components/template/PageContainer'
import { ROUTES_ENUM } from './route.constant' import { ROUTES_ENUM } from './route.constant'
import { hasSubdomain } from '@/utils/subdomain'
export const DynamicRouter: React.FC = () => { export const DynamicRouter: React.FC = () => {
const { routes, loading, error } = useDynamicRoutes() const { routes, loading, error } = useDynamicRoutes()
@ -18,7 +19,6 @@ export const DynamicRouter: React.FC = () => {
return ( return (
<Routes> <Routes>
{/* Protected Admin Routes */}
<Route path="/admin/*" element={<ProtectedRoute />}> <Route path="/admin/*" element={<ProtectedRoute />}>
{dynamicRoutes {dynamicRoutes
.filter((r) => r.routeType === 'protected') .filter((r) => r.routeType === 'protected')
@ -40,11 +40,9 @@ export const DynamicRouter: React.FC = () => {
/> />
) )
})} })}
{/* /admin -> /admin/home yönlendirmesi */}
<Route index element={<Navigate to={ROUTES_ENUM.protected.dashboard} replace />} /> <Route index element={<Navigate to={ROUTES_ENUM.protected.dashboard} replace />} />
</Route> </Route>
{/* Public Routes (dinamik) */}
{dynamicRoutes {dynamicRoutes
.filter((r) => r.routeType !== 'protected') .filter((r) => r.routeType !== 'protected')
.map((route) => { .map((route) => {
@ -62,8 +60,15 @@ export const DynamicRouter: React.FC = () => {
) )
})} })}
{/* / yönlendirmesi → /home */} <Route
<Route path="/" element={<Navigate to="/home" replace />} /> path="/"
element={
<Navigate
to={hasSubdomain() ? ROUTES_ENUM.authenticated.login : ROUTES_ENUM.public.home}
replace
/>
}
/>
{/* Not Found */} {/* Not Found */}
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />

24
ui/src/utils/subdomain.ts Normal file
View file

@ -0,0 +1,24 @@
const defaultSubDomain = 'KURS'
export const getSubdomain = (): string | null => {
if (typeof window === 'undefined') return null
const hostname = window.location.hostname
const parts = hostname.split('.')
// localhost veya normal domain ise subdomain yok
if (hostname === 'localhost' || parts.length < 3) {
return null
}
// Default subdomain ise null döndür
if (parts[0].toUpperCase() === defaultSubDomain) {
return null
}
return parts[0].toUpperCase()
}
export const hasSubdomain = (): boolean => {
return getSubdomain() !== null
}

View file

@ -20,6 +20,7 @@ import { motion } from 'framer-motion'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import * as Yup from 'yup' import * as Yup from 'yup'
import { getSubdomain } from '@/utils/subdomain'
type SignInFormSchema = { type SignInFormSchema = {
userName: string userName: string
@ -67,24 +68,6 @@ const Login = () => {
const defaultSubDomain = 'KURS' const defaultSubDomain = 'KURS'
const getSubdomain = () => {
if (typeof window === 'undefined') return null
const hostname = window.location.hostname
const parts = hostname.split('.')
if (hostname === 'localhost' || parts.length < 3) {
return null
}
if (parts[0].toUpperCase() === defaultSubDomain) {
return null
}
return parts[0].toUpperCase()
}
const onSignIn = async ( const onSignIn = async (
values: SignInFormSchema, values: SignInFormSchema,
{ setSubmitting, isSubmitting, setFieldValue, setFieldTouched }: any, { setSubmitting, isSubmitting, setFieldValue, setFieldTouched }: any,