From f1f7a0162d9a1f7180f4e7060077aad6f962c869 Mon Sep 17 00:00:00 2001 From: Anthony GAEREMYNCK <1@anthony.sh> Date: Fri, 31 Jul 2026 16:02:06 +0200 Subject: [PATCH] feat(frontend): add icon/size header, spinner, and styled download button to FileCard Co-Authored-By: Claude Sonnet 5 --- frontend/src/FileCard.jsx | 20 +++++++++++++----- frontend/src/styles/home.css | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/frontend/src/FileCard.jsx b/frontend/src/FileCard.jsx index 0d4ff54..d85491a 100644 --- a/frontend/src/FileCard.jsx +++ b/frontend/src/FileCard.jsx @@ -1,9 +1,10 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { DownloadSimple } from '@phosphor-icons/react'; +import { File as FileIcon, CircleNotch, DownloadSimple } from '@phosphor-icons/react'; import { fetchJobStatus, downloadUrl } from './api.js'; +import { formatBytes } from './utils/formatBytes.js'; -export function FileCard({ fileName, jobId, initialError }) { +export function FileCard({ fileName, fileSize, jobId, initialError }) { const { t } = useTranslation(); const [status, setStatus] = useState(initialError ? 'failed' : 'pending'); const [errorMessage, setErrorMessage] = useState(initialError ?? null); @@ -28,10 +29,19 @@ export function FileCard({ fileName, jobId, initialError }) { return (
  • - {fileName} - {(status === 'pending' || status === 'processing') && {t('job.converting')}} +
    + + {fileName} + {formatBytes(fileSize)} +
    + {(status === 'pending' || status === 'processing') && ( + + + {t('job.converting')} + + )} {status === 'done' && ( - + {t('job.download')} )} diff --git a/frontend/src/styles/home.css b/frontend/src/styles/home.css index 825469b..9988ac1 100644 --- a/frontend/src/styles/home.css +++ b/frontend/src/styles/home.css @@ -142,6 +142,45 @@ min-height: 44px; } +.job-status { + display: inline-flex; + align-items: center; + gap: 0.5rem; + color: var(--color-foreground); + opacity: 0.75; +} + +.spin { + animation: spin 900ms linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.download-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + background: var(--color-accent); + color: var(--color-on-primary); + border: none; + border-radius: 8px; + padding: 0.6rem 1.25rem; + font-weight: 600; + min-height: 44px; + text-decoration: none; +} + +.download-button:hover { + filter: brightness(1.05); +} + .error { color: var(--color-destructive); }