1"use client"
2
3import { useState } from "react"
4import { Users } from "@phosphor-icons/react"
5
6import { Button } from "@/components/ui/button"
7import {
8 Dialog,
9 DialogClose,
10 DialogContent,
11 DialogDescription,
12 DialogFooter,
13 DialogHeader,
14 DialogTitle,
15} from "@/components/ui/dialog"
16
17/* M8 (SE-01 sampai SE-03): kartu estafet di rel kanan langkah Ambil Foto.
18 Susunannya mengikuti docs/ui-reference/capture.html: kartu `violet-soft`,
19 judul berikon, satu kalimat, lalu tombol sekunder.
20
21 Tiga keadaan: belum cukup foto (tombol nonaktif dengan teks bantu), siap
22 (tombol membuka dialog persetujuan), dan link sudah dibuat (alamat, tombol
23 bagikan, tautan status). Tidak ada aksi `tangerine` di sini: aksi utama
24 layar tetap "Lanjut Hias" (DESIGN-SYSTEM §2). */
25
26export function RelayInviteCard({
27 relayId,
28 canInvite,
29 filled,
30 required,
31 busy,
32 statusText,
33 onInvite,
34 onShare,
35}: {
36 relayId: string | null
37 canInvite: boolean
38 filled: number
39 required: number
40 busy: boolean
41 statusText?: string
42 onInvite: () => void
43 onShare: (url: string) => void
44}) {
45 const [confirmOpen, setConfirmOpen] = useState(false)
46 const relayUrl =
47 relayId === null
48 ? ""
49 : `${typeof window === "undefined" ? "" : window.location.origin}/r/${relayId}`
50 const missing = Math.max(0, required - filled)
51
52 return (
53 <div className="flex flex-col gap-2.5 rounded-card border-2 border-ink bg-violet-soft p-4">
54 <h2 className="flex items-center gap-2 font-display text-base font-extrabold">
55 <Users weight="bold" className="size-[22px] shrink-0" aria-hidden />
56 Strip Estafet
57 </h2>
58
59 {relayId === null ? (
60 <>
61 <p className="text-[15px] leading-[1.4]">
62 Cukup ambil {required} foto. Sisanya diisi temanmu lewat link.
63 </p>
64 {busy || statusText !== undefined ? (
65 <p role="status" className="text-sm leading-[1.4]">
66 {statusText ?? "Menyiapkan link estafet..."}
67 </p>
68 ) : (
69 <Button
70 variant="secondary"
71 className="w-full"
72 disabled={!canInvite}
73 onClick={() => setConfirmOpen(true)}
74 >
75 Estafet ke Teman
76 </Button>
77 )}
78 {missing > 0 ? (
79 <p aria-live="polite" className="text-sm leading-[1.4] text-ink">
80 {`Butuh ${missing} foto dulu.`}
81 </p>
82 ) : null}
83 </>
84 ) : (
85 <>
86 <p data-testid="relay-url" className="font-mono text-[13px] break-all">
87 {relayUrl}
88 </p>
89 <Button
90 variant="neutral"
91 size="sm"
92 className="w-full"
93 onClick={() => onShare(relayUrl)}
94 >
95 Bagikan tautan
96 </Button>
97 <a
98 href={`/r/${relayId}`}
99 className="text-center text-sm font-bold underline underline-offset-4"
100 >
101 Lihat status
102 </a>
103 </>
104 )}
105
106 {/* SE-02: persetujuan menyebut apa yang diunggah, siapa yang bisa
107 melihat, dan kapan terhapus. */}
108 <Dialog open={confirmOpen} onOpenChange={setConfirmOpen}>
109 <DialogContent>
110 <DialogHeader>
111 <DialogTitle className="title text-ink">
112 Unggah foto estafet?
113 </DialogTitle>
114 <DialogDescription className="text-[15px] leading-[1.5]">
115 {`Foto strip kamu (${required} foto) dikirim ke link pribadi. Hanya orang yang kamu kirimi link yang bisa melengkapi. Link aktif 48 jam, lalu foto terhapus otomatis.`}
116 </DialogDescription>
117 </DialogHeader>
118 <DialogFooter>
119 <DialogClose asChild>
120 <Button variant="neutral">Batal</Button>
121 </DialogClose>
122 <Button
123 variant="secondary"
124 onClick={() => {
125 setConfirmOpen(false)
126 onInvite()
127 }}
128 >
129 Buat Link Estafet
130 </Button>
131 </DialogFooter>
132 </DialogContent>
133 </Dialog>
134 </div>
135 )
136}
137