main
UI Deploy (Next-Auth Support) 🎨 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-04-25 14:37:34 +02:00
parent ec3b67010b
commit cf12fc3942
3 changed files with 145 additions and 11 deletions
@@ -3,7 +3,7 @@
import { useState } from "react";
import { useRouter } from "next/navigation";
import { cn } from "@/lib/utils";
import { useCreateFromDocument } from "@/hooks/use-api";
import { useExtractDocumentTopics, useCreateFromExtractedText } from "@/hooks/use-api";
import { useToast } from "@/components/ui/toast";
import {
FileText,
@@ -42,9 +42,13 @@ export default function DocumentToVideoPage() {
const router = useRouter();
const { toast } = useToast();
const createFromDocument = useCreateFromDocument();
const extractDocumentTopics = useExtractDocumentTopics();
const createFromExtractedText = useCreateFromExtractedText();
const [file, setFile] = useState<File | null>(null);
const [extractedData, setExtractedData] = useState<{text: string; topics: string[]; originalFilename: string} | null>(null);
const [selectedTopic, setSelectedTopic] = useState<string | null>(null);
const [style, setStyle] = useState("CINEMATIC");
const [cinematicReference, setCinematicReference] = useState("");
const [duration, setDuration] = useState(60);
@@ -54,18 +58,40 @@ export default function DocumentToVideoPage() {
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) {
setFile(e.target.files[0]);
setExtractedData(null);
setSelectedTopic(null);
}
};
const handleGenerate = async () => {
const handleExtractTopics = async () => {
if (!file) {
toast("error", "Lütfen bir belge seçin.");
return;
}
try {
const result: any = await createFromDocument.mutateAsync({
file,
const result = await extractDocumentTopics.mutateAsync({ file });
setExtractedData(result);
if (result.topics.length > 0) {
setSelectedTopic(result.topics[0]);
}
toast("success", "Belge incelendi ve konular çıkarıldı!");
} catch (error) {
toast("error", "Konu çıkarılırken hata oluştu. Belki belge okunamıyor veya çok büyük.");
}
};
const handleGenerate = async () => {
if (!extractedData || !selectedTopic) {
toast("error", "Lütfen bir belge yükleyip konu seçin.");
return;
}
try {
const result: any = await createFromExtractedText.mutateAsync({
text: extractedData.text,
topic: selectedTopic,
originalFilename: extractedData.originalFilename,
language,
aspectRatio,
videoStyle: style,
@@ -73,7 +99,7 @@ export default function DocumentToVideoPage() {
targetDuration: duration,
});
toast("success", "Belge → Video projesi oluşturuldu!");
toast("success", "Video projesi oluşturuldu!");
router.push(`/dashboard/projects/${result.id}`);
} catch (error) {
toast("error", "Proje oluşturulurken hata oluştu.");
@@ -115,6 +141,51 @@ export default function DocumentToVideoPage() {
/>
</div>
</div>
{!extractedData && file && (
<button
onClick={handleExtractTopics}
disabled={extractDocumentTopics.isPending}
className="w-full flex items-center justify-center gap-2 py-3.5 rounded-xl font-medium text-white shadow-lg bg-blue-500 hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed"
>
{extractDocumentTopics.isPending ? (
<>
<Loader2 size={18} className="animate-spin" />
Belge İnceleniyor...
</>
) : (
<>
<FileText size={18} />
Konu Çıkar
</>
)}
</button>
)}
{extractedData && (
<div className="mt-6 p-4 rounded-xl bg-blue-500/5 border border-blue-500/20">
<h3 className="font-medium text-blue-400 mb-3 text-sm flex items-center gap-2">
<Wand2 size={16} />
Şu Konulardan Birini Seçin:
</h3>
<div className="space-y-2">
{extractedData.topics.map((topic, i) => (
<div
key={i}
onClick={() => setSelectedTopic(topic)}
className={cn(
"p-3 rounded-lg border text-sm cursor-pointer transition-all",
selectedTopic === topic
? "bg-blue-500/20 border-blue-500 text-blue-400"
: "bg-[var(--color-bg-surface)] border-[var(--color-border-faint)] text-[var(--color-text-secondary)] hover:border-blue-500/50"
)}
>
{topic}
</div>
))}
</div>
</div>
)}
</div>
{/* Video Settings */}
@@ -235,16 +306,16 @@ export default function DocumentToVideoPage() {
<button
onClick={handleGenerate}
disabled={createFromDocument.isPending || !file}
disabled={createFromExtractedText.isPending || !selectedTopic}
className={cn(
"w-full py-4 rounded-xl font-semibold text-base flex items-center justify-center gap-2 transition-all",
createFromDocument.isPending
createFromExtractedText.isPending
? "bg-blue-500/20 text-blue-400 cursor-wait"
: "bg-blue-500 hover:bg-blue-600 text-white shadow-lg shadow-blue-500/20",
!file && "opacity-50 cursor-not-allowed"
!selectedTopic && "opacity-50 cursor-not-allowed"
)}
>
{createFromDocument.isPending ? (
{createFromExtractedText.isPending ? (
<>
<Loader2 size={20} className="animate-spin" />
<span>Video Projesi Oluşturuluyor... (Bu işlem uzun sürebilir)</span>
@@ -252,7 +323,7 @@ export default function DocumentToVideoPage() {
) : (
<>
<Wand2 size={20} />
<span>Belge Video Oluştur</span>
<span>Konudan Video Oluştur</span>
<ArrowRight size={16} />
</>
)}