@@ -154,7 +154,7 @@ export function ProjectTabsClient({
|
||||
) : (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
|
||||
{shots.map((shot) => (
|
||||
<ShotCard key={shot.id} shot={shot} projectId={projectId} />
|
||||
<ShotCard key={shot.id} shot={shot} projectId={projectId} canManage={canManage} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -20,10 +20,12 @@ import {
|
||||
Settings,
|
||||
ListTodo,
|
||||
Video,
|
||||
Copy,
|
||||
} from "lucide-react";
|
||||
import type { ShotWithDetails } from "@/types";
|
||||
import { ShotSettingsTab } from "@/components/shots/ShotSettingsTab";
|
||||
import { FootageViewer } from "@/components/shots/FootageViewer";
|
||||
import { duplicateShot } from "@/actions/shots";
|
||||
|
||||
const STATUS_CONFIG: Record<
|
||||
string,
|
||||
@@ -43,9 +45,12 @@ const PRIORITY_CONFIG: Record<string, { label: string; dot: string }> = {
|
||||
CRITICAL: { label: "Critical", dot: "bg-red-500" },
|
||||
};
|
||||
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
|
||||
export default function ShotDetailPage() {
|
||||
const params = useParams<{ id: string; shotId: string }>();
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
const [shot, setShot] = useState<ShotWithDetails | null>(null);
|
||||
const [projectName, setProjectName] = useState<string>("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -53,6 +58,7 @@ export default function ShotDetailPage() {
|
||||
const [tasks, setTasks] = useState<any[]>([]);
|
||||
const [artists, setArtists] = useState<any[]>([]);
|
||||
const [canManage, setCanManage] = useState(false);
|
||||
const [isDuplicating, setIsDuplicating] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<"tasks" | "footage" | "settings">("tasks");
|
||||
|
||||
const fetchShot = async () => {
|
||||
@@ -80,6 +86,20 @@ export default function ShotDetailPage() {
|
||||
fetchShot();
|
||||
}, [params.shotId]);
|
||||
|
||||
const handleDuplicate = async () => {
|
||||
if (!shot) return;
|
||||
setIsDuplicating(true);
|
||||
try {
|
||||
const { shot: newShot } = await duplicateShot(shot.id);
|
||||
toast({ title: "Shot duplicated", description: `Created ${newShot.shotCode}` });
|
||||
router.push(`/projects/${params.id}/shots/${newShot.id}`);
|
||||
} catch (e) {
|
||||
toast({ title: "Duplicate failed", description: e instanceof Error ? e.message : undefined, variant: "destructive" });
|
||||
} finally {
|
||||
setIsDuplicating(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
@@ -172,7 +192,20 @@ export default function ShotDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{canManage && (
|
||||
<div className="ml-auto shrink-0">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleDuplicate}
|
||||
disabled={isDuplicating}
|
||||
className="gap-2"
|
||||
>
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
{isDuplicating ? "Duplicating…" : "Duplicate Shot"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
Reference in New Issue
Block a user