Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4c9b5a5cf | |||
| a830549069 | |||
| 13bea032e7 |
@@ -12,6 +12,32 @@ export default function ClipToolPage() {
|
|||||||
const [captions, setCaptions] = useState(true);
|
const [captions, setCaptions] = useState(true);
|
||||||
const [layout, setLayout] = useState("vertical");
|
const [layout, setLayout] = useState("vertical");
|
||||||
const [timeframe, setTimeframe] = useState("30s");
|
const [timeframe, setTimeframe] = useState("30s");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState("");
|
||||||
|
const [clips, setClips] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const handleGenerate = async () => {
|
||||||
|
if (!videoUrl) {
|
||||||
|
setError("Please enter a valid YouTube URL.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
setError("");
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/generate-clips', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ videoUrl, captions, layout, timeframe })
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.error) throw new Error(data.error);
|
||||||
|
setClips(data.clips || []);
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.message || "Something went wrong. Please try again.");
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
@@ -85,10 +111,22 @@ export default function ClipToolPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ButtonElasticEffect
|
<ButtonElasticEffect
|
||||||
text="Generate Clips Now"
|
text={loading ? "Processing..." : "Generate Clips Now"}
|
||||||
onClick={() => alert(`Generating ${timeframe} ${layout} clips for: ${videoUrl} (Captions: ${captions ? "On" : "Off"})`)}
|
onClick={handleGenerate}
|
||||||
|
disabled={loading}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{error && <p className="text-red-500 mt-4">{error}</p>}
|
||||||
|
|
||||||
|
{clips.length > 0 && (
|
||||||
|
<div className="mt-10 grid grid-cols-1 gap-6 w-full">
|
||||||
|
<h2 className="text-2xl font-semibold">Generated Clips</h2>
|
||||||
|
{clips.map((clip, i) => (
|
||||||
|
<video key={i} src={clip} controls className="w-full rounded-2xl shadow-lg" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ReactLenis>
|
</ReactLenis>
|
||||||
|
|||||||
Reference in New Issue
Block a user