feat: restyle StatusView and status page with Tailwind

This commit is contained in:
2026-08-11 09:02:32 +02:00
parent 3f499177b6
commit f6dc3801c6
2 changed files with 62 additions and 15 deletions
+5 -2
View File
@@ -8,9 +8,12 @@ export default async function StatusPage({
}) {
const { locale, uuid } = await params
const t = await getTranslations({ locale, namespace: 'status' })
return (
<main style={{ padding: '2rem' }}>
<h1>{t('heading')}</h1>
<main className="flex flex-col items-center px-6 py-16">
<h1 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-gray-50 mb-10">
{t('heading')}
</h1>
<StatusView uuid={uuid} />
</main>
)
+57 -13
View File
@@ -15,6 +15,15 @@ type DownloadData = {
tokenExpiresAt: string | null
}
function Spinner() {
return (
<svg className="animate-spin w-8 h-8 text-violet-600 dark:text-violet-400" viewBox="0 0 24 24" fill="none" aria-hidden>
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
)
}
export function StatusView({ uuid }: { uuid: string }) {
const t = useTranslations('status')
const locale = useLocale()
@@ -45,14 +54,33 @@ export function StatusView({ uuid }: { uuid: string }) {
return () => { active = false }
}, [uuid])
if (notFound) return <p>{t('notFound')}</p>
if (!data) return <p>{t('loading')}</p>
const cardClass = 'max-w-md w-full mx-auto rounded-2xl border border-gray-100 dark:border-slate-800 bg-gray-50 dark:bg-slate-900 p-8'
if (notFound) {
return (
<div className={cardClass}>
<p className="text-gray-600 dark:text-gray-400 text-center">{t('notFound')}</p>
</div>
)
}
if (!data) {
return (
<div className={`${cardClass} flex flex-col items-center gap-4`}>
<Spinner />
<p className="text-gray-500 dark:text-gray-400 text-sm">{t('loading')}</p>
</div>
)
}
if (data.status === 'PENDING' || data.status === 'PROCESSING') {
return (
<div>
<p>{data.status === 'PENDING' ? t('pending') : t('processing')}</p>
<p>{t('polling')}</p>
<div className={`${cardClass} flex flex-col items-center gap-4`}>
<Spinner />
<p className="font-medium text-gray-900 dark:text-gray-50">
{data.status === 'PENDING' ? t('pending') : t('processing')}
</p>
<p className="text-sm text-gray-500 dark:text-gray-400 text-center">{t('polling')}</p>
</div>
)
}
@@ -62,16 +90,24 @@ export function StatusView({ uuid }: { uuid: string }) {
? `(${(Number(data.fileSize) / 1_048_576).toFixed(1)} MB)`
: ''
return (
<div>
<p>{t('ready')} {sizeMb}</p>
<div className={`${cardClass} flex flex-col items-center gap-5`}>
<div className="w-12 h-12 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-green-600 dark:text-green-400" aria-hidden>
<polyline points="20 6 9 17 4 12"/>
</svg>
</div>
<p className="font-medium text-gray-900 dark:text-gray-50">
{t('ready')} {sizeMb}
</p>
<a
href={`/api/download/${data.downloadToken}`}
download={data.fileName ?? undefined}
className="w-full text-center rounded-xl bg-violet-600 hover:bg-violet-700 dark:bg-violet-500 dark:hover:bg-violet-600 text-white font-medium py-3 transition-colors"
>
{t('download')} {data.fileName}
</a>
{data.tokenExpiresAt && (
<p style={{ fontSize: '0.85rem', color: '#666' }}>
<p className="text-xs text-gray-400 dark:text-slate-500">
{t('linkExpires')}{' '}
{new Date(data.tokenExpiresAt).toLocaleString(locale)}
</p>
@@ -82,9 +118,9 @@ export function StatusView({ uuid }: { uuid: string }) {
if (data.status === 'FAILED') {
return (
<div>
<p>{t('failed')}</p>
<pre style={{ background: '#fee', padding: '0.5rem', overflowX: 'auto' }}>
<div className={cardClass}>
<p className="font-medium text-red-600 dark:text-red-400 mb-3">{t('failed')}</p>
<pre className="text-xs bg-red-50 dark:bg-red-950/40 border border-red-100 dark:border-red-900/50 rounded-lg p-4 overflow-x-auto text-red-700 dark:text-red-300 whitespace-pre-wrap">
{data.errorMsg}
</pre>
</div>
@@ -92,8 +128,16 @@ export function StatusView({ uuid }: { uuid: string }) {
}
if (data.status === 'FILE_DELETED') {
return <p>{t('deleted')}</p>
return (
<div className={cardClass}>
<p className="text-gray-600 dark:text-gray-400 text-center">{t('deleted')}</p>
</div>
)
}
return <p>{t('unknown')}: {data.status}</p>
return (
<div className={cardClass}>
<p className="text-gray-500 dark:text-gray-400 text-center">{t('unknown')}: {data.status}</p>
</div>
)
}