download link updated
Deploy / deploy (push) Successful in 2m38s

This commit is contained in:
twotalesanimation
2026-06-25 18:29:58 +02:00
parent 5b613b7107
commit 13d47315dd
2 changed files with 30 additions and 7 deletions
@@ -40,7 +40,7 @@ export async function GET(
task: { task: {
include: { include: {
project: { select: { id: true, name: true, code: true } }, project: { select: { id: true, name: true, code: true } },
shot: { select: { shotCode: true } }, shot: { select: { id: true, shotCode: true, highResKey: true, highResFilename: true } },
asset: { select: { assetCode: true, name: true } }, asset: { select: { assetCode: true, name: true } },
}, },
}, },
@@ -78,10 +78,17 @@ export async function GET(
}, },
}); });
// Resolve the shot that has the high-res file (comes from version.shot OR version.task.shot)
const highResShot = version.shot ?? (version.task as any)?.shot ?? null;
const serializedVersion = { const serializedVersion = {
...version, ...version,
fileSize: version.fileSize?.toString() ?? null, fileSize: version.fileSize?.toString() ?? null,
// Expose only whether a high-res file exists, never the storage key // Top-level high-res fields so the client works for both shot and task versions
hasHighRes: !!(highResShot?.highResKey),
highResShotId: highResShot?.highResKey ? (highResShot.id ?? null) : null,
highResFilename: highResShot?.highResFilename ?? null,
// Expose only whether a high-res file exists on the shot relation, never the storage key
shot: version.shot shot: version.shot
? { ? {
...version.shot, ...version.shot,
@@ -90,6 +97,17 @@ export async function GET(
highResKey: undefined, highResKey: undefined,
} }
: null, : null,
task: version.task
? {
...version.task,
shot: (version.task as any)?.shot
? {
...((version.task as any).shot),
highResKey: undefined, // strip storage key
}
: null,
}
: null,
}; };
return NextResponse.json({ version: serializedVersion, comments }); return NextResponse.json({ version: serializedVersion, comments });
+10 -5
View File
@@ -54,6 +54,10 @@ interface Version {
duration: number | null; duration: number | null;
approvalStatus: string; approvalStatus: string;
notes: string | null; notes: string | null;
// Top-level high-res flags (normalised from either shot or task.shot)
hasHighRes?: boolean;
highResShotId?: string | null;
highResFilename?: string | null;
shot?: { shot?: {
id: string; id: string;
shotCode: string; shotCode: string;
@@ -66,7 +70,7 @@ interface Version {
title: string; title: string;
type: string; type: string;
project: { id: string; name: string; code: string }; project: { id: string; name: string; code: string };
shot?: { shotCode: string } | null; shot?: { id: string; shotCode: string } | null;
asset?: { assetCode: string; name: string } | null; asset?: { assetCode: string; name: string } | null;
} | null; } | null;
} }
@@ -205,10 +209,11 @@ export default function ClientReviewPage({
}; };
const handleDownloadHighRes = async () => { const handleDownloadHighRes = async () => {
if (!version?.shot?.id || !token) return; const shotId = version?.highResShotId ?? version?.shot?.id;
if (!shotId || !token) return;
setDownloadingHighRes(true); setDownloadingHighRes(true);
try { try {
const res = await fetch(`/api/client/${token}/shots/${version.shot.id}/highres/download`); const res = await fetch(`/api/client/${token}/shots/${shotId}/highres/download`);
if (!res.ok) throw new Error("Could not get download link"); if (!res.ok) throw new Error("Could not get download link");
const { url } = await res.json(); const { url } = await res.json();
// Open the presigned URL — the Content-Disposition header forces a download // Open the presigned URL — the Content-Disposition header forces a download
@@ -384,14 +389,14 @@ export default function ClientReviewPage({
<CheckCircle2 className="h-3.5 w-3.5" /> <CheckCircle2 className="h-3.5 w-3.5" />
Approve Approve
</Button> </Button>
{version.shot?.hasHighRes && ( {(version.hasHighRes || version.shot?.hasHighRes) && (
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
className="h-8 text-xs gap-1 text-sky-400 border-sky-500/30 hover:bg-sky-500/10" className="h-8 text-xs gap-1 text-sky-400 border-sky-500/30 hover:bg-sky-500/10"
disabled={downloadingHighRes} disabled={downloadingHighRes}
onClick={handleDownloadHighRes} onClick={handleDownloadHighRes}
title={version.shot.highResFilename ?? "Download high-res file"} title={version.highResFilename ?? version.shot?.highResFilename ?? "Download high-res file"}
> >
<Download className="h-3.5 w-3.5" /> <Download className="h-3.5 w-3.5" />
<span className="hidden sm:inline">{downloadingHighRes ? "Getting link…" : "High Res"}</span> <span className="hidden sm:inline">{downloadingHighRes ? "Getting link…" : "High Res"}</span>