[dyad] Create video editor UI - wrote 2 file(s), deleted 1 file(s)

This commit is contained in:
[dyad]
2026-01-30 08:08:01 +01:00
parent f3c1e3e041
commit ffd4b89308
3 changed files with 95 additions and 20 deletions

View File

@@ -1,12 +1,11 @@
import { MadeWithDyad } from "@/components/made-with-dyad"; import { VideoEditor } from "@/components/video-editor";
export default function Home() { export default function Home() {
return ( return (
<div className="grid grid-rows-[1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 sm:p-20 font-[family-name:var(--font-geist-sans)]"> <div className="flex flex-col items-center justify-center min-h-screen bg-gray-50 dark:bg-gray-900 p-4 sm:p-6 md:p-8 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-1 items-center sm:items-start"> <main className="w-full max-w-4xl">
<h1>Blank page</h1> <VideoEditor />
</main> </main>
<MadeWithDyad />
</div> </div>
); );
} }

View File

@@ -1,14 +0,0 @@
export const MadeWithDyad = () => {
return (
<div className="p-4 text-center">
<a
href="https://www.dyad.sh/"
target="_blank"
rel="noopener noreferrer"
className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
>
Made with Dyad
</a>
</div>
);
};

View File

@@ -0,0 +1,90 @@
"use client";
import { useState, useRef, ChangeEvent } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { UploadCloud, Scissors, Download } from "lucide-react";
export function VideoEditor() {
const [videoSrc, setVideoSrc] = useState<string | null>(null);
const [videoFile, setVideoFile] = useState<File | null>(null);
const videoRef = useRef<HTMLVideoElement>(null);
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
setVideoFile(file);
const url = URL.createObjectURL(file);
setVideoSrc(url);
}
};
return (
<Card className="w-full shadow-lg rounded-2xl border-0">
<CardHeader className="text-center">
<CardTitle className="text-3xl font-bold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-purple-500 to-pink-500">
Video Clip Cutter
</CardTitle>
<CardDescription className="text-lg text-gray-600 dark:text-gray-400 pt-2">
Upload, trim, and export your video in seconds.
</CardDescription>
</CardHeader>
<CardContent className="p-6">
{videoSrc ? (
<div className="space-y-6">
<div className="aspect-video w-full overflow-hidden rounded-lg border">
<video
ref={videoRef}
src={videoSrc}
controls
className="w-full h-full object-contain bg-black"
/>
</div>
<div>
<h3 className="text-lg font-semibold mb-2">Trim Video</h3>
<p className="text-sm text-muted-foreground">
Trimming controls will be added here in the next step.
</p>
</div>
</div>
) : (
<div className="flex items-center justify-center w-full">
<Label
htmlFor="video-upload"
className="flex flex-col items-center justify-center w-full h-64 border-2 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-bray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500"
>
<div className="flex flex-col items-center justify-center pt-5 pb-6">
<UploadCloud className="w-10 h-10 mb-4 text-gray-500 dark:text-gray-400" />
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
<span className="font-semibold">Click to upload</span> or drag and drop
</p>
<p className="text-xs text-gray-500 dark:text-gray-400">MP4, WebM, or OGG</p>
</div>
<Input
id="video-upload"
type="file"
className="hidden"
accept="video/*"
onChange={handleFileChange}
/>
</Label>
</div>
)}
</CardContent>
{videoSrc && (
<CardFooter className="flex justify-end space-x-4 p-6">
<Button variant="outline" size="lg" disabled>
<Scissors className="mr-2 h-5 w-5" />
Cut Video
</Button>
<Button variant="default" size="lg" disabled>
<Download className="mr-2 h-5 w-5" />
Export
</Button>
</CardFooter>
)}
</Card>
);
}