feat: translate SubmitForm and StatusView with next-intl
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslations, useLocale } from 'next-intl'
|
||||
|
||||
type DownloadData = {
|
||||
uuid: string
|
||||
@@ -15,6 +16,8 @@ type DownloadData = {
|
||||
}
|
||||
|
||||
export function StatusView({ uuid }: { uuid: string }) {
|
||||
const t = useTranslations('status')
|
||||
const locale = useLocale()
|
||||
const [data, setData] = useState<DownloadData | null>(null)
|
||||
const [notFound, setNotFound] = useState(false)
|
||||
|
||||
@@ -42,35 +45,35 @@ export function StatusView({ uuid }: { uuid: string }) {
|
||||
return () => { active = false }
|
||||
}, [uuid])
|
||||
|
||||
if (notFound) return <p>Telechargement introuvable.</p>
|
||||
if (!data) return <p>Chargement...</p>
|
||||
if (notFound) return <p>{t('notFound')}</p>
|
||||
if (!data) return <p>{t('loading')}</p>
|
||||
|
||||
if (data.status === 'PENDING' || data.status === 'PROCESSING') {
|
||||
return (
|
||||
<div>
|
||||
<p>Statut : {data.status === 'PENDING' ? 'En attente' : 'En cours...'}</p>
|
||||
<p>Cette page se rafraichit automatiquement toutes les 5 secondes.</p>
|
||||
<p>{data.status === 'PENDING' ? t('pending') : t('processing')}</p>
|
||||
<p>{t('polling')}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (data.status === 'DONE' && data.downloadToken) {
|
||||
const sizeMb = data.fileSize
|
||||
? `(${(Number(data.fileSize) / 1_048_576).toFixed(1)} Mo)`
|
||||
? `(${(Number(data.fileSize) / 1_048_576).toFixed(1)} MB)`
|
||||
: ''
|
||||
return (
|
||||
<div>
|
||||
<p>Telechargement pret {sizeMb}</p>
|
||||
<p>{t('ready')} {sizeMb}</p>
|
||||
<a
|
||||
href={`/api/download/${data.downloadToken}`}
|
||||
download={data.fileName ?? undefined}
|
||||
>
|
||||
Telecharger {data.fileName}
|
||||
{t('download')} {data.fileName}
|
||||
</a>
|
||||
{data.tokenExpiresAt && (
|
||||
<p style={{ fontSize: '0.85rem', color: '#666' }}>
|
||||
Lien valable jusqu'au{' '}
|
||||
{new Date(data.tokenExpiresAt).toLocaleString('fr-FR')}
|
||||
{t('linkExpires')}{' '}
|
||||
{new Date(data.tokenExpiresAt).toLocaleString(locale)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -80,7 +83,7 @@ export function StatusView({ uuid }: { uuid: string }) {
|
||||
if (data.status === 'FAILED') {
|
||||
return (
|
||||
<div>
|
||||
<p>Echec du telechargement.</p>
|
||||
<p>{t('failed')}</p>
|
||||
<pre style={{ background: '#fee', padding: '0.5rem', overflowX: 'auto' }}>
|
||||
{data.errorMsg}
|
||||
</pre>
|
||||
@@ -89,13 +92,8 @@ export function StatusView({ uuid }: { uuid: string }) {
|
||||
}
|
||||
|
||||
if (data.status === 'FILE_DELETED') {
|
||||
return (
|
||||
<p>
|
||||
Le fichier a expire et a ete supprime. Le telechargement n'est plus
|
||||
disponible.
|
||||
</p>
|
||||
)
|
||||
return <p>{t('deleted')}</p>
|
||||
}
|
||||
|
||||
return <p>Statut inconnu : {data.status}</p>
|
||||
return <p>{t('unknown')}: {data.status}</p>
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { useState, FormEvent } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { useRouter } from '@/navigation'
|
||||
|
||||
const FORMATS = ['mp4', 'mp3', 'webm', 'mkv']
|
||||
const QUALITIES = ['best', '1080p', '720p', '480p', '360p']
|
||||
|
||||
export function SubmitForm() {
|
||||
const t = useTranslations('home')
|
||||
const router = useRouter()
|
||||
const [url, setUrl] = useState('')
|
||||
const [format, setFormat] = useState('mp4')
|
||||
@@ -36,12 +38,12 @@ export function SubmitForm() {
|
||||
setLoading(false)
|
||||
|
||||
if (res.status === 429) {
|
||||
setError('Trop de soumissions. Reessayez dans une heure.')
|
||||
setError(t('errorRateLimit'))
|
||||
return
|
||||
}
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}))
|
||||
setError((body as { error?: string }).error ?? 'Erreur lors de la soumission.')
|
||||
setError((body as { error?: string }).error ?? t('errorGeneric'))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -52,7 +54,7 @@ export function SubmitForm() {
|
||||
return (
|
||||
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: 480 }}>
|
||||
<label>
|
||||
URL de la video
|
||||
{t('urlLabel')}
|
||||
<input
|
||||
type="url"
|
||||
value={url}
|
||||
@@ -64,14 +66,14 @@ export function SubmitForm() {
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Format
|
||||
{t('format')}
|
||||
<select value={format} onChange={(e) => setFormat(e.target.value)} style={{ display: 'block' }}>
|
||||
{FORMATS.map((f) => <option key={f}>{f}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Qualite
|
||||
{t('quality')}
|
||||
<select value={quality} onChange={(e) => setQuality(e.target.value)} style={{ display: 'block' }}>
|
||||
{QUALITIES.map((q) => <option key={q}>{q}</option>)}
|
||||
</select>
|
||||
@@ -83,11 +85,11 @@ export function SubmitForm() {
|
||||
checked={subtitles}
|
||||
onChange={(e) => setSubtitles(e.target.checked)}
|
||||
/>{' '}
|
||||
Telecharger les sous-titres (fr, en)
|
||||
{t('subtitles')}
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Options avancees (optionnel, JSON)
|
||||
{t('advanced')}
|
||||
<input
|
||||
type="text"
|
||||
value={extraArgs}
|
||||
@@ -100,7 +102,7 @@ export function SubmitForm() {
|
||||
{error && <p style={{ color: 'red' }}>{error}</p>}
|
||||
|
||||
<button type="submit" disabled={loading}>
|
||||
{loading ? 'Envoi...' : 'Telecharger'}
|
||||
{loading ? t('submitting') : t('submit')}
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user