generated from fahricansecer/boilerplate-fe
This commit is contained in:
@@ -33,6 +33,7 @@ import { SceneCard } from '@/components/project/scene-card';
|
||||
import { RenderProgress } from '@/components/project/render-progress';
|
||||
import { VideoPlayer } from '@/components/project/video-player';
|
||||
import { projectsApi } from '@/lib/api/api-service';
|
||||
import { CINEMATIC_REFERENCES } from '@/constants/cinematic-references';
|
||||
|
||||
// X (Twitter) ikonunu burada da tanımlıyoruz
|
||||
const XIcon = ({ size = 16 }: { size?: number }) => (
|
||||
@@ -255,8 +256,18 @@ export default function ProjectDetailPage() {
|
||||
try {
|
||||
await projectsApi.update(id, { videoStyle: newStyleId } as any);
|
||||
refetch();
|
||||
} catch (err) {
|
||||
console.error('Üslup (Stil) değiştirme hatası:', err);
|
||||
} catch (error) {
|
||||
console.error('Failed to update style:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCinematicReferenceChange = async (newRef: string) => {
|
||||
if (newRef === project.cinematicReference) return;
|
||||
try {
|
||||
await projectsApi.update(id, { cinematicReference: newRef || undefined } as any);
|
||||
refetch();
|
||||
} catch (error) {
|
||||
console.error('Failed to update cinematic reference:', error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -354,6 +365,24 @@ export default function ProjectDetailPage() {
|
||||
) : (
|
||||
<span>{currentStyle ? `${currentStyle.emoji} ${currentStyle.label}` : project.videoStyle}</span>
|
||||
)}
|
||||
|
||||
{project.videoStyle === 'CINEMATIC' && isEditable ? (
|
||||
<select
|
||||
value={project.cinematicReference || ''}
|
||||
onChange={(e) => handleCinematicReferenceChange(e.target.value)}
|
||||
className="bg-[var(--color-bg-base)] border border-[var(--color-border-faint)] rounded-md px-2 py-0.5 text-xs text-[var(--color-text-secondary)] focus:outline-none focus:border-violet-500/50 cursor-pointer w-44 truncate"
|
||||
>
|
||||
<option value="">🎬 Sinematik Yönetmen/Film...</option>
|
||||
{CINEMATIC_REFERENCES.map(ref => (
|
||||
<option key={ref.value} value={ref.value}>{ref.label}</option>
|
||||
))}
|
||||
</select>
|
||||
) : project.videoStyle === 'CINEMATIC' && project.cinematicReference ? (
|
||||
<span className="flex items-center gap-1">
|
||||
🎬 <span className="truncate max-w-[150px]">{project.cinematicReference}</span>
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
<span className="uppercase text-[10px] tracking-wider">{project.language}</span>
|
||||
<span className="text-[10px]">
|
||||
{new Date(project.createdAt).toLocaleDateString('tr-TR', {
|
||||
@@ -485,7 +514,11 @@ export default function ProjectDetailPage() {
|
||||
isEditable={isEditable}
|
||||
onUpdate={handleSceneUpdate}
|
||||
onRegenerate={handleSceneRegenerate}
|
||||
onGenerateImage={handleGenerateImage}
|
||||
onUpscaleImage={handleUpscaleImage}
|
||||
isRegenerating={regeneratingSceneId === scene.id}
|
||||
isGeneratingImage={generatingImageId === scene.id}
|
||||
isUpscalingImage={upscalingImageId === scene.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,11 @@ import {
|
||||
AlertCircle,
|
||||
ExternalLink,
|
||||
Loader2,
|
||||
Trash2,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useProjects } from "@/hooks/use-api";
|
||||
import { useProjects, useDeleteProject } from "@/hooks/use-api";
|
||||
|
||||
const statusFilters = [
|
||||
{ id: "all", label: "Tümü" },
|
||||
@@ -84,6 +85,15 @@ export default function ProjectsPage() {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
const { data, isLoading } = useProjects({ limit: 100 });
|
||||
const deleteMutation = useDeleteProject();
|
||||
|
||||
const handleDelete = (e: React.MouseEvent, id: string) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (confirm("Bu projeyi silmek istediğinize emin misiniz?")) {
|
||||
deleteMutation.mutate(id);
|
||||
}
|
||||
};
|
||||
// useProjects returns PaginatedResponse<Project> which has .data as Project[]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const raw = data as any;
|
||||
@@ -243,10 +253,20 @@ export default function ProjectsPage() {
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className={`text-[10px] font-medium px-2.5 py-1 rounded-full border ${st.color} border-current/20 ${st.bgColor} shrink-0`}
|
||||
className={`text-[10px] font-medium px-2.5 py-1 rounded-full border ${st.color} border-current/20 ${st.bgColor} shrink-0 mr-2`}
|
||||
>
|
||||
{st.label}
|
||||
</span>
|
||||
|
||||
<button
|
||||
onClick={(e) => handleDelete(e, project.id)}
|
||||
className="p-2 rounded-lg text-[var(--color-text-ghost)] hover:text-red-400 hover:bg-red-500/10 transition-colors shrink-0 z-10 mr-1"
|
||||
title="Projeyi Sil"
|
||||
disabled={deleteMutation.isPending}
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
</button>
|
||||
|
||||
<ExternalLink
|
||||
size={14}
|
||||
className="text-[var(--color-text-ghost)] group-hover:text-violet-400 transition-colors shrink-0"
|
||||
|
||||
Reference in New Issue
Block a user