'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; import { FolderInput, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; interface MoveTarget { id: string; name: string; } interface MoveVideosDialogProps { open: boolean; onOpenChange: (open: boolean) => void; /** Source project the videos currently belong to. */ projectId: string; /** Videos to move. */ videoIds: string[]; /** Called after a successful move with the ids that were moved. */ onMoved?: (movedIds: string[]) => void; } export function MoveVideosDialog({ open, onOpenChange, projectId, videoIds, onMoved, }: MoveVideosDialogProps) { const router = useRouter(); const [targets, setTargets] = useState(null); const [isLoading, setIsLoading] = useState(false); const [loadError, setLoadError] = useState(''); const [selectedId, setSelectedId] = useState(''); const [isMoving, setIsMoving] = useState(false); useEffect(() => { if (!open) return; let cancelled = false; setIsLoading(true); setLoadError(''); setTargets(null); setSelectedId(''); fetch(`/api/projects/${projectId}/videos/move`, { cache: 'no-store' }) .then(async (res) => { const body = await res.json().catch(() => null); if (!res.ok) { throw new Error(typeof body?.error === 'string' ? body.error : 'Failed to load projects'); } if (cancelled) return; setTargets((body?.data?.projects as MoveTarget[] | undefined) ?? []); }) .catch((err) => { if (!cancelled) { setLoadError(err instanceof Error ? err.message : 'Failed to load projects'); } }) .finally(() => { if (!cancelled) setIsLoading(false); }); return () => { cancelled = true; }; }, [open, projectId]); const count = videoIds.length; const noun = count === 1 ? 'video' : 'videos'; const handleMove = async () => { if (!selectedId || isMoving) return; setIsMoving(true); try { const res = await fetch(`/api/projects/${projectId}/videos/move`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ videoIds, targetProjectId: selectedId }), }); const body = await res.json().catch(() => null); if (!res.ok) { toast.error(typeof body?.error === 'string' ? body.error : 'Failed to move videos'); return; } toast.success(typeof body?.data?.message === 'string' ? body.data.message : 'Videos moved'); onOpenChange(false); onMoved?.(videoIds); router.refresh(); } catch { toast.error('Failed to move videos'); } finally { setIsMoving(false); } }; return ( Move {count === 1 ? 'video' : `${count} videos`} to another project Choose a destination project in this workspace. Versions, comments and assets move with the {noun}.
{isLoading ? (
Loading projects…
) : loadError ? (

{loadError}

) : targets && targets.length > 0 ? ( ) : (

No other projects in this workspace are available to move to.

)}
); }