[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() {
|
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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -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