101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import type { LayoutType } from '@/proxy/theme/models'
|
||
import Loading from '@/components/shared/Loading'
|
||
import { Alert, Button } from '@/components/ui'
|
||
import { store, useStoreState } from '@/store'
|
||
import { Suspense, useEffect } from 'react'
|
||
import ErrorBoundary from '@/components/shared/ErrorBoundary'
|
||
import type { FallbackProps } from '@/components/shared/ErrorBoundary'
|
||
import { FaArrowLeft } from 'react-icons/fa'
|
||
import { Navigate, useLocation } from 'react-router-dom'
|
||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||
import DialogProvider from './shared/DialogContext'
|
||
import DialogShowComponent from './shared/DialogContext/DialogShowComponent'
|
||
import UiDialog from './shared/UiDialog'
|
||
import { DynamicRouter } from '@/routes/dynamicRouter'
|
||
import { getAccessDeniedPath } from '@/utils/routing'
|
||
|
||
interface ViewsProps {
|
||
pageContainerType?: 'default' | 'gutterless' | 'contained'
|
||
layout?: LayoutType
|
||
}
|
||
|
||
// `error` `unknown` tipinde geliyor; throw edilen her şey Error olmayabilir,
|
||
// o yüzden daraltıyoruz.
|
||
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||
const { translate } = useLocalization()
|
||
const { name, message } =
|
||
error instanceof Error
|
||
? error
|
||
: { name: translate('::App.Platform.Error'), message: String(error) }
|
||
|
||
return (
|
||
<Alert showIcon className="mb-4" type="danger">
|
||
<h5>{name ?? translate('::App.Platform.Error')}</h5>
|
||
<div>{message}</div>
|
||
<Button
|
||
icon={<FaArrowLeft />}
|
||
size="sm"
|
||
className="mt-2"
|
||
variant="default"
|
||
onClick={resetErrorBoundary}
|
||
></Button>
|
||
</Alert>
|
||
)
|
||
}
|
||
|
||
const Views = (props: ViewsProps) => {
|
||
const { setWarning, removeError } = store.getActions().base.messages
|
||
const { errors, warning } = useStoreState((state) => state.base.messages)
|
||
const location = useLocation()
|
||
|
||
useEffect(() => {
|
||
setWarning('')
|
||
}, [location, setWarning])
|
||
|
||
return (
|
||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||
<Suspense fallback={<Loading loading={true} />}>
|
||
{!!warning?.length && (
|
||
<Alert showIcon className="mb-4 text-sm text-left" type="warning">
|
||
{warning.map((w, i) => (
|
||
<div key={i} className="whitespace-normal break-words">
|
||
{w}
|
||
</div>
|
||
))}
|
||
</Alert>
|
||
)}
|
||
{errors?.some((e) => e.statusCode === '403' || e.statusCode === '401') && (
|
||
<Navigate
|
||
to={getAccessDeniedPath(location.pathname)}
|
||
replace
|
||
state={{ from: location }}
|
||
/>
|
||
)}
|
||
{errors?.map((e) => (
|
||
<UiDialog
|
||
key={e.id}
|
||
isOpen={true}
|
||
type={'danger'}
|
||
onConfirm={() => {
|
||
removeError(e.id)
|
||
}}
|
||
onClose={() => {
|
||
removeError(e.id)
|
||
}}
|
||
title={e.title}
|
||
>
|
||
{e.message}
|
||
<p>{e.statusCode}</p>
|
||
<small className="italic">{e.cid}</small>
|
||
</UiDialog>
|
||
))}
|
||
<DialogProvider>
|
||
<DialogShowComponent />
|
||
<DynamicRouter />
|
||
</DialogProvider>
|
||
</Suspense>
|
||
</ErrorBoundary>
|
||
)
|
||
}
|
||
|
||
export default Views
|