+12
-1
@@ -197,6 +197,7 @@ export async function duplicateShot(sourceShotId: string) {
|
||||
|
||||
const updateShotSchema = z.object({
|
||||
shotId: z.string().cuid(),
|
||||
shotCode: z.string().min(1).max(120).regex(/^[A-Z0-9_]+$/i, "Alphanumeric and underscores only").optional(),
|
||||
description: z.string().optional(),
|
||||
status: z.nativeEnum(ShotStatus).optional(),
|
||||
priority: z.nativeEnum(ShotPriority).optional(),
|
||||
@@ -218,12 +219,22 @@ export async function updateShot(data: z.infer<typeof updateShotSchema>) {
|
||||
}
|
||||
|
||||
const parsed = updateShotSchema.parse(data);
|
||||
const { shotId, dueDate, artistId, ...rest } = parsed;
|
||||
const { shotId, dueDate, artistId, shotCode, ...rest } = parsed;
|
||||
|
||||
// Check uniqueness if shotCode is being changed
|
||||
if (shotCode) {
|
||||
const existing = await db.shot.findFirst({
|
||||
where: { projectId: (await db.shot.findUnique({ where: { id: shotId }, select: { projectId: true } }))!.projectId, shotCode, id: { not: shotId } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (existing) throw new Error(`Shot code "${shotCode}" is already used in this project.`);
|
||||
}
|
||||
|
||||
const shot = await db.shot.update({
|
||||
where: { id: shotId },
|
||||
data: {
|
||||
...rest,
|
||||
...(shotCode ? { shotCode: shotCode.toUpperCase() } : {}),
|
||||
dueDate: dueDate ? new Date(dueDate) : dueDate === null ? null : undefined,
|
||||
artistId: artistId === "" ? null : artistId,
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ import { useToast } from "@/components/ui/use-toast";
|
||||
import { Upload, X, Film, ImageIcon, Video } from "lucide-react";
|
||||
|
||||
const settingsSchema = z.object({
|
||||
shotCode: z.string().min(1, "Required").max(120).regex(/^[A-Z0-9_]+$/i, "Alphanumeric and underscores only"),
|
||||
description: z.string().optional(),
|
||||
status: z.enum(["WAITING", "IN_PROGRESS", "IN_REVIEW", "REVISIONS", "COMPLETE"]),
|
||||
priority: z.enum(["LOW", "NORMAL", "HIGH", "URGENT"]),
|
||||
@@ -128,6 +129,7 @@ export function ShotSettingsTab({ shot, artists, onSaved }: ShotSettingsTabProps
|
||||
} = useForm<SettingsFormValues>({
|
||||
resolver: zodResolver(settingsSchema),
|
||||
defaultValues: {
|
||||
shotCode: shot.shotCode,
|
||||
description: shot.description ?? "",
|
||||
status: shot.status as SettingsFormValues["status"],
|
||||
priority: shot.priority as SettingsFormValues["priority"],
|
||||
@@ -209,6 +211,7 @@ export function ShotSettingsTab({ shot, artists, onSaved }: ShotSettingsTabProps
|
||||
|
||||
await updateShot({
|
||||
shotId: shot.id,
|
||||
shotCode: values.shotCode,
|
||||
description: values.description || undefined,
|
||||
status: values.status,
|
||||
priority: values.priority,
|
||||
@@ -240,6 +243,16 @@ export function ShotSettingsTab({ shot, artists, onSaved }: ShotSettingsTabProps
|
||||
</div>
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-1.5">
|
||||
<Label>Shot Code</Label>
|
||||
<Input
|
||||
{...register("shotCode")}
|
||||
className="font-mono uppercase"
|
||||
placeholder="SHOW_SC010_0010"
|
||||
/>
|
||||
{errors.shotCode && <p className="text-xs text-destructive">{errors.shotCode.message}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1.5">
|
||||
<Label>Description</Label>
|
||||
<Textarea {...register("description")} rows={3} placeholder="Shot description…" />
|
||||
|
||||
Reference in New Issue
Block a user