1"use client"
2
3import { Check, Lock } from "@phosphor-icons/react"
4
5import { cn } from "@/lib/utils"
6import type { Shot } from "@/stores/booth"
7
8/* DESIGN-SYSTEM §9: kisi dua kolom, slot terisi bergaris dengan lencana centang
9 violet, slot kosong bergaris putus-putus dengan nomor. FR-07: tiap slot terisi
10 adalah tombol ulang foto tertentu.
11
12 M8 (SE-04): slot yang jadi milik pihak lain di strip estafet dikunci. Slot
13 terkunci bukan tombol (tidak ada jalur ulang), dan lencananya gembok, bukan
14 centang, supaya bedanya tidak hanya warna. */
15export function ShotTray({
16 shots,
17 slotRatio,
18 busy,
19 onRetake,
20 lockedSlots = [],
21}: {
22 shots: (Shot | null)[]
23 slotRatio: number
24 busy: boolean
25 onRetake: (index: number) => void
26 lockedSlots?: number[]
27}) {
28 return (
29 <div className="grid grid-cols-2 gap-2.5">
30 {shots.map((shot, index) =>
31 shot === null ? (
32 <div
33 key={index}
34 style={{ aspectRatio: slotRatio }}
35 aria-label={
36 lockedSlots.includes(index) ? `Slot teman ${index + 1}` : undefined
37 }
38 role={lockedSlots.includes(index) ? "group" : undefined}
39 className="flex items-center justify-center rounded-thumb border-2 border-dashed border-muted bg-cream"
40 >
41 {lockedSlots.includes(index) ? (
42 <Lock weight="bold" className="size-5 text-muted" aria-hidden />
43 ) : (
44 <span className="font-mono text-lg font-bold text-muted">
45 {index + 1}
46 </span>
47 )}
48 </div>
49 ) : lockedSlots.includes(index) ? (
50 <div
51 key={index}
52 role="group"
53 aria-label={`Slot teman ${index + 1}`}
54 className="relative rounded-thumb"
55 >
56 {/* DataURL hasil kamera, bukan aset: next/image tidak dipakai di sini. */}
57 {/* eslint-disable-next-line @next/next/no-img-element */}
58 <img
59 src={shot.still}
60 alt=""
61 style={{ aspectRatio: slotRatio }}
62 className="w-full rounded-thumb border-2 border-ink object-cover"
63 />
64 <span className="absolute -top-2 -right-2 flex size-[22px] items-center justify-center rounded-pill border-2 border-ink bg-violet text-paper">
65 <Lock weight="bold" className="size-3" aria-hidden />
66 </span>
67 </div>
68 ) : (
69 <button
70 key={index}
71 type="button"
72 disabled={busy}
73 onClick={() => onRetake(index)}
74 aria-label={`Ulang foto ${index + 1}`}
75 className={cn(
76 "relative rounded-thumb",
77 "focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-violet",
78 "disabled:pointer-events-none disabled:opacity-60"
79 )}
80 >
81 {/* DataURL hasil kamera, bukan aset: next/image tidak dipakai di sini. */}
82 {/* eslint-disable-next-line @next/next/no-img-element */}
83 <img
84 src={shot.still}
85 alt=""
86 style={{ aspectRatio: slotRatio }}
87 className="w-full rounded-thumb border-2 border-ink object-cover"
88 />
89 <span className="absolute -top-2 -right-2 flex size-[22px] items-center justify-center rounded-pill border-2 border-ink bg-violet text-paper">
90 <Check weight="bold" className="size-3" aria-hidden />
91 </span>
92 </button>
93 )
94 )}
95 </div>
96 )
97}
98