1"use client"
2
3import { Check, HandPeace } from "@phosphor-icons/react"
4
5import type { CapturePhase } from "@/features/capture/machine"
6import type { GestureAction } from "@/features/gesture/thresholds"
7import type { GestureStatus } from "@/features/gesture/useGestureSnap"
8
9/* DESIGN-SYSTEM §9: `GestureHUD` adalah pil di atas tengah area kamera dengan
10 empat keadaan acuan (siap, menahan, mati, selesai) plus keadaan memuat dari
11 GS-07. Semuanya noninteraktif `role="status"`: klik pada acuan hanya demo dan
12 tidak punya makna produk. Markup mengikuti docs/ui-reference/capture.html. */
13
14type HudState =
15 | "hidden"
16 | "loading"
17 | "ready"
18 | "holding"
19 | "off"
20 | "done"
21
22interface ResolveHudInput {
23 cameraActive: boolean
24 enabled: boolean
25 status: GestureStatus
26 phase: CapturePhase
27 holdAction: GestureAction | null
28}
29
30export function resolveHudState({
31 cameraActive,
32 enabled,
33 status,
34 phase,
35 holdAction,
36}: ResolveHudInput): HudState {
37 if (!cameraActive || status === "failed") {
38 return "hidden"
39 }
40 if (holdAction !== null) {
41 return "holding"
42 }
43 if (!enabled) {
44 return phase === "complete" ? "done" : phase === "ready" ? "off" : "hidden"
45 }
46 if (status === "loading") {
47 return phase === "ready" ? "loading" : "hidden"
48 }
49 if (status === "ready") {
50 return phase === "complete" ? "done" : phase === "ready" ? "ready" : "hidden"
51 }
52 return "hidden"
53}
54
55const PILL =
56 "inline-flex min-h-11 items-center rounded-pill border-2 border-ink px-4 text-[15px] font-bold text-ink"
57
58export function GestureHUD({
59 state,
60 progress = 0,
61 shotCount = 0,
62}: {
63 state: HudState
64 progress?: number
65 shotCount?: number
66}) {
67 if (state === "hidden") {
68 return null
69 }
70
71 if (state === "holding") {
72 return (
73 <div
74 role="status"
75 className="flex min-w-60 flex-col gap-1.5 rounded-stage border-2 border-ink bg-lime px-4 py-2.5 text-[15px] font-bold text-ink"
76 >
77 Terdeteksi. Tahan...
78 <div className="h-2 overflow-hidden rounded-pill border-2 border-ink bg-paper">
79 <div
80 className="h-full bg-violet transition-[width] duration-[80ms] ease-linear"
81 style={{ width: `${Math.round(progress * 100)}%` }}
82 />
83 </div>
84 </div>
85 )
86 }
87
88 if (state === "loading") {
89 return (
90 <div role="status" className={`${PILL} bg-paper`}>
91 Menyiapkan gesture...
92 </div>
93 )
94 }
95
96 if (state === "off") {
97 return (
98 <div role="status" className={`${PILL} bg-paper`}>
99 Gesture mati. Pakai tombol kamera.
100 </div>
101 )
102 }
103
104 if (state === "done") {
105 return (
106 <div role="status" className={`${PILL} gap-2 bg-lime`}>
107 <Check weight="bold" className="size-[18px]" aria-hidden />
108 {shotCount} foto siap dihias
109 </div>
110 )
111 }
112
113 return (
114 <div role="status" className={`${PILL} gap-2.5 bg-paper`}>
115 <HandPeace weight="bold" className="size-[22px]" aria-hidden />
116 Angkat dua jari, tahan sebentar
117 </div>
118 )
119}
120