[dyad] Create video editor UI - wrote 2 file(s), deleted 1 file(s)
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
import { MadeWithDyad } from "@/components/made-with-dyad";
|
||||
import { VideoEditor } from "@/components/video-editor";
|
||||
|
||||
export default function Home() {
|
||||
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)]">
|
||||
<main className="flex flex-col gap-8 row-start-1 items-center sm:items-start">
|
||||
<h1>Blank page</h1>
|
||||
<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="w-full max-w-4xl">
|
||||
<VideoEditor />
|
||||
</main>
|
||||
<MadeWithDyad />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
90
src/components/video-editor.tsx
Normal file
90
src/components/video-editor.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user