feat: add submission form and status page
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
'use client'
|
||||
|
||||
import { useState, FormEvent } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
const FORMATS = ['mp4', 'mp3', 'webm', 'mkv']
|
||||
const QUALITIES = ['best', '1080p', '720p', '480p', '360p']
|
||||
|
||||
export function SubmitForm() {
|
||||
const router = useRouter()
|
||||
const [url, setUrl] = useState('')
|
||||
const [format, setFormat] = useState('mp4')
|
||||
const [quality, setQuality] = useState('best')
|
||||
const [subtitles, setSubtitles] = useState(false)
|
||||
const [extraArgs, setExtraArgs] = useState('')
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
async function handleSubmit(e: FormEvent) {
|
||||
e.preventDefault()
|
||||
setError(null)
|
||||
setLoading(true)
|
||||
|
||||
const res = await fetch('/api/downloads', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
url,
|
||||
format,
|
||||
quality,
|
||||
subtitles,
|
||||
extraArgs: extraArgs.trim() || null,
|
||||
}),
|
||||
})
|
||||
|
||||
setLoading(false)
|
||||
|
||||
if (res.status === 429) {
|
||||
setError('Trop de soumissions. Reessayez dans une heure.')
|
||||
return
|
||||
}
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}))
|
||||
setError((body as { error?: string }).error ?? 'Erreur lors de la soumission.')
|
||||
return
|
||||
}
|
||||
|
||||
const { uuid } = (await res.json()) as { uuid: string }
|
||||
router.push(`/status/${uuid}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: 480 }}>
|
||||
<label>
|
||||
URL de la video
|
||||
<input
|
||||
type="url"
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
required
|
||||
placeholder="https://www.youtube.com/watch?v=..."
|
||||
style={{ display: 'block', width: '100%' }}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
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
|
||||
<select value={quality} onChange={(e) => setQuality(e.target.value)} style={{ display: 'block' }}>
|
||||
{QUALITIES.map((q) => <option key={q}>{q}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={subtitles}
|
||||
onChange={(e) => setSubtitles(e.target.checked)}
|
||||
/>{' '}
|
||||
Telecharger les sous-titres (fr, en)
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Options avancees (optionnel, JSON)
|
||||
<input
|
||||
type="text"
|
||||
value={extraArgs}
|
||||
onChange={(e) => setExtraArgs(e.target.value)}
|
||||
placeholder='["--sponsorblock-remove","all"]'
|
||||
style={{ display: 'block', width: '100%' }}
|
||||
/>
|
||||
</label>
|
||||
|
||||
{error && <p style={{ color: 'red' }}>{error}</p>}
|
||||
|
||||
<button type="submit" disabled={loading}>
|
||||
{loading ? 'Envoi...' : 'Telecharger'}
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user