sozsoft-platform/ui/src/components/template/Theme.tsx

105 lines
3.6 KiB
TypeScript
Raw Normal View History

2026-02-24 20:44:16 +00:00
import type { CommonProps } from '@/proxy/common'
import ConfigProvider from '@/components/ui/ConfigProvider'
import { themeConfig } from '@/proxy/theme/theme.config'
import { useStoreActions, useStoreState } from '@/store'
import useDarkMode from '@/utils/hooks/useDarkmode'
import useNotification from '@/utils/hooks/useNotification'
import { useSetting } from '@/utils/hooks/useSetting'
import useTabFocus from '@/utils/hooks/useTabFocus'
import { ComponentProps, useEffect } from 'react'
2026-02-24 20:44:16 +00:00
import { Helmet } from 'react-helmet'
2026-04-23 10:36:51 +00:00
import { useNavigate, useLocation } from 'react-router-dom'
import { getSetupStatus } from '@/services/setup.service'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useAppVersionNotice } from '@/views/version/useAppVersionNotice'
2026-02-24 20:44:16 +00:00
let didInit = false
const Theme = (props: CommonProps) => {
const { getConfig } = useStoreActions((a) => a.abpConfig)
const { setSetupMode, setBootstrapFailed } = useStoreActions((a) => a.base.common)
2026-04-23 10:36:51 +00:00
const navigate = useNavigate()
const location = useLocation()
2026-02-24 20:44:16 +00:00
useEffect(() => {
if (didInit) return
didInit = true
2026-04-23 10:36:51 +00:00
// Direkt /setup'a gelindiyse — hemen setupMode=true yap (loading gate açılsın)
if (location.pathname === ROUTES_ENUM.setup) {
setSetupMode(true)
return
}
// Doğrudan config yüklenir. Her sayfa açılışında ayrıca veritabanı probe'u
// atılmaz — bu, canlı sistemde gereksiz bir istek ve DB bağlantısıydı.
//
// silentError: açılıştaki config hatası global hata diyaloğunu tetiklemez;
// kurulum modu kararı aşağıda verilir. Aksi halde kullanıcı kurulum sayfasının
// üstünde anlamsız bir "503" penceresi görüyordu.
getConfig({ silentError: true }).catch(async () => {
// Config alınamadı. Sunucu gerçekten kurulum modunda mı, yoksa geçici bir
// arıza mı? Yönlendirme SADECE sunucu kurulum modundayken yapılır; böylece
// çalışan bir sistemde veritabanı sorunu kullanıcıyı kurulum ekranına düşürmez.
try {
const { data } = await getSetupStatus()
if (data.setupMode) {
setSetupMode(true)
navigate(ROUTES_ENUM.setup, { replace: true })
return
}
} catch {
// Sunucuya hiç ulaşılamıyor — aşağıdaki bakım ekranı gösterilir.
2026-04-23 10:36:51 +00:00
}
// Sunucu kurulum modunda değil ama uygulama da açılamıyor.
// Bu bayrak olmadan loading gate hiç kapanmıyor ve ekran sonsuza kadar
// spinner'da kalıyordu.
setBootstrapFailed(true)
})
2026-02-24 20:44:16 +00:00
}, [])
function getThemeStyle() {
const mode = theme.mode
const style = setting('App.SiteManagement.Theme.Style')
return style?.replace(mode === 'dark' ? 'light' : 'dark', mode)
}
const { setting } = useSetting()
const theme = useStoreState((state) => state.theme)
const locale =
useStoreState((state) => state.abpConfig.config?.localization.currentCulture.cultureName) ??
'en'
2026-02-24 20:44:16 +00:00
useDarkMode()
useTabFocus()
useNotification()
useAppVersionNotice()
2026-02-24 20:44:16 +00:00
type ConfigProviderValue = NonNullable<ComponentProps<typeof ConfigProvider>['value']>
2026-02-24 20:44:16 +00:00
const currentTheme = {
...themeConfig,
...theme,
...{ locale },
} as ConfigProviderValue
2026-02-24 20:44:16 +00:00
return (
<>
{setting('App.SiteManagement.Theme.Style') && (
<Helmet key="Devexpress stylesheet Helmet">
<link
key="Devexpress stylesheet Helmet link"
rel="stylesheet"
href={`/css/${getThemeStyle()}.css`}
/>
</Helmet>
)}
<ConfigProvider value={currentTheme}>{props.children}</ConfigProvider>
</>
)
}
export default Theme