refactor: streamline, refine and polish

This commit is contained in:
2026-02-27 12:35:02 +01:00
parent efe3c81576
commit ee7e5ec06c
21 changed files with 606 additions and 735 deletions

View File

@@ -3,6 +3,7 @@
import * as React from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Slider } from '@/components/ui/slider';
import {
@@ -366,13 +367,12 @@ export function FileConverter() {
const completedCount = conversionJobs.filter(job => job.status === 'completed').length;
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 w-full">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 w-full">
{/* Left Column: Upload and Conversion Options */}
<div className="space-y-6">
{/* Upload Card */}
<Card className="glass">
<CardContent className="p-6">
{/* File upload */}
<Card>
<CardContent>
<FileUpload
onFileSelect={handleFileSelect}
onFileRemove={handleFileRemove}
@@ -386,14 +386,14 @@ export function FileConverter() {
{/* Conversion Options Card */}
{inputFormat && compatibleFormats.length > 0 && (
<Card className="glass">
<Card>
<CardHeader>
<CardTitle>Conversion Options</CardTitle>
<CardTitle>Options</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
<CardContent className="space-y-4">
{/* Output Format Select */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Output Format</label>
<div className="space-y-1.5">
<Label className="text-xs">Output Format</Label>
<Select
value={outputFormat?.id || ''}
onValueChange={(formatId) => {
@@ -422,7 +422,7 @@ export function FileConverter() {
<div className="space-y-4 pt-4 border-t border-border">
{/* Video Codec */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Video Codec</label>
<Label className="text-xs">Video Codec</Label>
<Select
value={conversionOptions.videoCodec || 'default'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, videoCodec: value === 'default' ? undefined : value })}
@@ -444,7 +444,7 @@ export function FileConverter() {
{/* Video Bitrate */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">Video Bitrate</label>
<Label className="text-xs">Video Bitrate</Label>
<span className="text-xs text-muted-foreground">{conversionOptions.videoBitrate || '2M'}</span>
</div>
<Slider
@@ -460,7 +460,7 @@ export function FileConverter() {
{/* Resolution */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Resolution</label>
<Label className="text-xs">Resolution</Label>
<Select
value={conversionOptions.videoResolution || 'original'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, videoResolution: value === 'original' ? undefined : value })}
@@ -481,7 +481,7 @@ export function FileConverter() {
{/* FPS */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Frame Rate (FPS)</label>
<Label className="text-xs">Frame Rate (FPS)</Label>
<Select
value={conversionOptions.videoFps?.toString() || 'original'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, videoFps: value === 'original' ? undefined : parseInt(value) })}
@@ -503,7 +503,7 @@ export function FileConverter() {
{/* Audio Bitrate */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">Audio Bitrate</label>
<Label className="text-xs">Audio Bitrate</Label>
<span className="text-xs text-muted-foreground">{conversionOptions.audioBitrate || '128k'}</span>
</div>
<Slider
@@ -522,7 +522,7 @@ export function FileConverter() {
<div className="space-y-4 pt-4 border-t border-border">
{/* Audio Codec */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Audio Codec</label>
<Label className="text-xs">Audio Codec</Label>
<Select
value={conversionOptions.audioCodec || 'default'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, audioCodec: value === 'default' ? undefined : value })}
@@ -545,7 +545,7 @@ export function FileConverter() {
{/* Bitrate */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">Bitrate</label>
<Label className="text-xs">Bitrate</Label>
<span className="text-xs text-muted-foreground">{conversionOptions.audioBitrate || '192k'}</span>
</div>
<Slider
@@ -560,7 +560,7 @@ export function FileConverter() {
{/* Sample Rate */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Sample Rate</label>
<Label className="text-xs">Sample Rate</Label>
<Select
value={conversionOptions.audioSampleRate?.toString() || 'original'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, audioSampleRate: value === 'original' ? undefined : parseInt(value) })}
@@ -580,7 +580,7 @@ export function FileConverter() {
{/* Channels */}
<div className="space-y-2">
<label className="text-sm font-medium text-foreground block">Channels</label>
<Label className="text-xs">Channels</Label>
<Select
value={conversionOptions.audioChannels?.toString() || 'original'}
onValueChange={(value) => setConversionOptions({ ...conversionOptions, audioChannels: value === 'original' ? undefined : parseInt(value) })}
@@ -604,7 +604,7 @@ export function FileConverter() {
{/* Quality */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium text-foreground">Quality</label>
<Label className="text-xs">Quality</Label>
<span className="text-xs text-muted-foreground">{conversionOptions.imageQuality || 85}%</span>
</div>
<Slider
@@ -619,7 +619,7 @@ export function FileConverter() {
{/* Width */}
<div>
<label className="text-sm font-medium text-foreground mb-2 block">Width (px)</label>
<Label className="text-xs mb-1.5">Width (px)</Label>
<Input
type="number"
value={conversionOptions.imageWidth || ''}
@@ -632,7 +632,7 @@ export function FileConverter() {
{/* Height */}
<div>
<label className="text-sm font-medium text-foreground mb-2 block">Height (px)</label>
<Label className="text-xs mb-1.5">Height (px)</Label>
<Input
type="number"
value={conversionOptions.imageHeight || ''}
@@ -652,13 +652,12 @@ export function FileConverter() {
onClick={handleConvert}
disabled={isConvertDisabled}
className="w-full"
size="lg"
>
{isConverting
? 'Converting...'
: `Convert ${selectedFiles.length} File${selectedFiles.length > 1 ? 's' : ''}`}
</Button>
<Button onClick={handleReset} variant="outline" size="lg" className="w-full">
<Button onClick={handleReset} variant="outline" className="w-full">
Reset
</Button>
</CardContent>
@@ -670,13 +669,11 @@ export function FileConverter() {
<div className="space-y-6">
{/* Download All Button */}
{completedCount > 0 && (
<Card className="glass">
<CardContent className="p-6">
<Card>
<CardContent>
<Button
onClick={handleDownloadAll}
className="w-full"
size="lg"
variant="default"
>
Download All ({completedCount} file{completedCount > 1 ? 's' : ''})
{completedCount > 1 && ' as ZIP'}