mirror of
https://github.com/ConvoyPanel/panel.git
synced 2026-06-21 00:36:01 +08:00
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import PageContentBlock from '@/components/elements/PageContentBlock'
|
|
import { Button } from '@mantine/core'
|
|
import { ComponentType } from 'react'
|
|
import { ExclaimationCircleIcon, LinkIcon } from '@heroicons/react/24/outline'
|
|
|
|
export interface IconProps {
|
|
className?: string
|
|
}
|
|
|
|
interface BaseProps {
|
|
title: string
|
|
icon?: ComponentType<IconProps>
|
|
message: string
|
|
full?: boolean
|
|
center?: boolean
|
|
onRetry?: () => void
|
|
onBack?: () => void
|
|
}
|
|
|
|
interface PropsWithRetry extends BaseProps {
|
|
onRetry?: () => void
|
|
onBack?: never
|
|
}
|
|
|
|
interface PropsWithBack extends BaseProps {
|
|
onBack?: () => void
|
|
onRetry?: never
|
|
}
|
|
|
|
export type ScreenBlockProps = PropsWithBack | PropsWithRetry
|
|
|
|
const ScreenBlock = ({
|
|
title,
|
|
icon: Icon,
|
|
message,
|
|
center,
|
|
onBack,
|
|
onRetry,
|
|
full,
|
|
}: ScreenBlockProps) => {
|
|
return (
|
|
<PageContentBlock
|
|
className={`${full && 'grid place-items-center min-h-screen -mt-10'}`}
|
|
title={title}
|
|
>
|
|
<div className={`w-full sm:max-w-md p-12 md:p-20 bg-white dark:bg-black rounded-md shadow-md text-center ${center && 'mx-auto'}`}>
|
|
{Icon && <Icon className='w-16 h-16 border dark:border-stone-600 rounded-md p-3 text-black dark:text-stone-400 mx-auto' />}
|
|
|
|
<h2 className='text-stone-900 dark:text-white font-bold text-4xl mt-6'>{title}</h2>
|
|
<p className='description-small mt-3'>{message}</p>
|
|
{(onBack || onRetry) && (
|
|
<div className='flex justify-center mt-3'>
|
|
<Button
|
|
onClick={() => (onRetry ? onRetry() : onBack ? onBack() : null)}
|
|
>
|
|
{onBack ? 'Go Back' : 'Retry'}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</PageContentBlock>
|
|
)
|
|
}
|
|
|
|
type ServerErrorProps = (Omit<PropsWithBack, 'icon' | 'title'> | Omit<PropsWithRetry, 'icon' | 'title'>) & {
|
|
title?: string;
|
|
};
|
|
|
|
export const ServerError = ({ title, ...props }: ServerErrorProps) => (
|
|
<ScreenBlock title={title || 'Something went wrong'} center icon={ExclaimationCircleIcon} {...props} />
|
|
);
|
|
|
|
export const NotFound = ({
|
|
title,
|
|
message,
|
|
onBack,
|
|
full,
|
|
}: Partial<Pick<BaseProps, 'title' | 'message' | 'onBack' | 'full'>>) => (
|
|
<ScreenBlock
|
|
title={title || '404'}
|
|
message={
|
|
message || "The link is either broken or doesn't exist on the server."
|
|
}
|
|
icon={LinkIcon}
|
|
full={full}
|
|
onBack={onBack}
|
|
/>
|
|
)
|
|
|
|
export default ScreenBlock
|