Files
convert-ui/app/page.tsx

106 lines
3.7 KiB
TypeScript
Raw Normal View History

'use client';
import * as React from 'react';
import { Settings } from 'lucide-react';
import { FileConverter } from '@/components/converter/FileConverter';
import { ConversionHistory } from '@/components/converter/ConversionHistory';
import { ThemeToggle } from '@/components/layout/ThemeToggle';
import { Button } from '@/components/ui/Button';
import { SettingsModal } from '@/components/ui/SettingsModal';
import { ToastProvider } from '@/components/ui/Toast';
import { getSettings } from '@/lib/storage/settings';
export default function Home() {
const [showSettings, setShowSettings] = React.useState(false);
const [settings, setSettings] = React.useState(getSettings());
// Listen for settings updates
React.useEffect(() => {
const handleSettingsUpdate = (e: Event) => {
const customEvent = e as CustomEvent;
setSettings(customEvent.detail);
};
window.addEventListener('settingsUpdated', handleSettingsUpdate);
return () => window.removeEventListener('settingsUpdated', handleSettingsUpdate);
}, []);
return (
<ToastProvider>
<div className="min-h-screen bg-background">
{/* Header */}
<header className="border-b border-border">
<div className="container mx-auto px-3 sm:px-4 py-3 sm:py-4 flex items-center justify-between gap-2">
<div className="min-w-0 flex-1">
<h1 className="text-xl sm:text-2xl font-bold text-foreground">Convert UI</h1>
<p className="text-xs sm:text-sm text-muted-foreground">
File conversion in your browser
</p>
</div>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="icon"
onClick={() => setShowSettings(true)}
title="Settings"
>
<Settings className="h-5 w-5" />
</Button>
<ThemeToggle />
</div>
</div>
</header>
{/* Main content */}
<main className="container mx-auto px-3 sm:px-4 py-6 sm:py-8 md:py-16">
<div className="space-y-6 sm:space-y-8">
<FileConverter />
{settings.showConversionHistory && <ConversionHistory />}
</div>
</main>
{/* Settings Modal */}
<SettingsModal isOpen={showSettings} onClose={() => setShowSettings(false)} />
{/* Footer */}
<footer className="border-t border-border mt-8 sm:mt-12 md:mt-16">
<div className="container mx-auto px-3 sm:px-4 py-6 text-center text-xs sm:text-sm text-muted-foreground">
<p>
Powered by{' '}
<a
href="https://github.com/ffmpegwasm/ffmpeg.wasm"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
FFmpeg.wasm
</a>
,{' '}
<a
href="https://github.com/dlemstra/magick-wasm"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
ImageMagick WASM
</a>
{' '}&{' '}
<a
href="https://nextjs.org"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
Next.js 16
</a>
</p>
<p className="mt-2">
All conversions happen locally in your browser. No files are uploaded to any server.
</p>
</div>
</footer>
</div>
</ToastProvider>
);
}