jam/src/components/error/ErrorPage.tsx
Parth d66f5e9c82
Some checks failed
Build / build (v26.3.0) (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
Deploy Storybook / deploy (push) Has been cancelled
chore(ui): improve mobile responsiveness (#1292)
2026-07-05 15:54:37 +02:00

94 lines
2.9 KiB
TypeScript

import { t } from 'i18next'
import { Trans, useTranslation } from 'react-i18next'
import { useRouteError } from 'react-router-dom'
import { Alert, AlertDescription } from '@/components/ui/alert'
import PageTitle from '@/components/ui/jam/PageTitle'
interface ErrorViewProps {
title: string
subtitle: string
reason: string
stacktrace?: string
}
function ErrorView({ title, subtitle, reason, stacktrace }: ErrorViewProps) {
return (
<div className="mx-auto max-w-4xl space-y-3 p-4">
<PageTitle title={title} subtitle={subtitle} variant="error" />
<p>
<Trans i18nKey="error_page.report_bug">
Please{' '}
<a
href="https://github.com/joinmarket-webui/jam/issues/new?labels=bug&template=bug_report.md"
target="_blank"
rel="noopener noreferrer"
className="font-semibold underline hover:no-underline"
>
open an issue on GitHub
</a>{' '}
for this error to be reviewed and resolved in an upcoming version.
</Trans>
</p>
<div className="my-4">
<h6 className="font-semibold">{t('error_page.heading_reason')}</h6>
<Alert variant="destructive" className="overflow-x-auto">
<AlertDescription className="min-w-0 break-words">{reason}</AlertDescription>
</Alert>
</div>
{stacktrace && (
<div className="my-4">
<h6 className="font-semibold">{t('error_page.heading_stacktrace')}</h6>
<pre className="max-w-full overflow-x-auto rounded-lg border p-2">
<code>{stacktrace}</code>
</pre>
</div>
)}
</div>
)
}
function UnknownError({ error }: { error: unknown }) {
const { t } = useTranslation()
const title = t('error_page.unknown_error.title')
const subtitle = t('error_page.unknown_error.subtitle')
if (!error || typeof error !== 'object') {
return <ErrorView title={title} subtitle={subtitle} reason={t('global.errors.reason_unknown')} />
}
const reason = 'message' in error && typeof error.message === 'string' ? error.message : undefined
const stacktrace = 'stack' in error && typeof error.stack === 'string' ? error.stack : undefined
return (
<ErrorView
title={title}
subtitle={subtitle}
reason={reason || t('global.errors.reason_unknown')}
stacktrace={stacktrace}
/>
)
}
function ErrorWithDetails({ error }: { error: Error }) {
const { t } = useTranslation()
return (
<ErrorView
title={t('error_page.error_with_details.title')}
subtitle={t('error_page.error_with_details.subtitle')}
reason={error.message || t('global.errors.reason_unknown')}
stacktrace={error.stack}
/>
)
}
export default function ErrorPage() {
const error = useRouteError()
if (error instanceof Error) {
return <ErrorWithDetails error={error} />
} else {
return <UnknownError error={error} />
}
}