"use client" import { useState } from "react" import { Check, FrameCorners, Palette, Sticker as StickerIcon, TextT, } from "@phosphor-icons/react" import { Switch } from "@/components/ui/switch" import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group" import { cn } from "@/lib/utils" import { TEXT_LENGTH_MAX, useBoothStore } from "@/stores/booth" import { EFFECTS, FRAMES, STICKERS, type EffectPreset } from "./presets" /* DESIGN-SYSTEM §10.3 dan acuan `customize.html`: rel kiri halaman Hias. Tab pil (toggle-group) dengan kisi tiga kolom. Semua kontrol bisa dipakai dengan keyboard; keadaan terpilih selalu diiringi lencana centang, bukan hanya warna (DESIGN-SYSTEM §2). */ type DecorTab = "frame" | "efek" | "stiker" | "teks" const TABS: { value: DecorTab; label: string; icon: typeof FrameCorners }[] = [ { value: "frame", label: "Frame", icon: FrameCorners }, { value: "efek", label: "Efek", icon: Palette }, { value: "stiker", label: "Stiker", icon: StickerIcon }, { value: "teks", label: "Teks", icon: TextT }, ] const SWATCH = "relative box-border border-2 border-ink outline-none transition-transform duration-[120ms] focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-violet motion-reduce:transition-none" const FRAME_BARS = [0, 1, 2, 3] const EFFECT_GRADIENT = "linear-gradient(135deg, var(--color-pink) 0%, var(--color-pink) 50%, var(--color-lime) 50%, var(--color-lime) 100%)" const EFFECT_PIXEL = "repeating-conic-gradient(var(--color-pink) 0% 25%, var(--color-lime) 0% 50%)" function effectSwatchStyle(effect: EffectPreset) { if (effect.params.kind === "pixelate") { return { backgroundImage: EFFECT_PIXEL, backgroundSize: "16px 16px", } } return { backgroundImage: EFFECT_GRADIENT, filter: effect.cssPreview.length > 0 ? effect.cssPreview : undefined, } } function SelectedBadge() { return ( ) } export function DecorPanel() { const frameId = useBoothStore((state) => state.frameId) const effectId = useBoothStore((state) => state.effectId) const textValue = useBoothStore((state) => state.texts[0]?.value ?? "") const showDate = useBoothStore((state) => state.showDate) const setFrame = useBoothStore((state) => state.setFrame) const setEffect = useBoothStore((state) => state.setEffect) const addSticker = useBoothStore((state) => state.addSticker) const setStripText = useBoothStore((state) => state.setStripText) const setShowDate = useBoothStore((state) => state.setShowDate) const [tab, setTab] = useState("frame") return ( { if (value !== "") { setTab(value as DecorTab) } }} aria-label="Pilihan hiasan" className="w-full flex-wrap justify-start gap-2 rounded-none border-0 bg-transparent p-0" > {TABS.map((item) => ( {item.label} ))} {tab === "frame" ? ( Pilih frame {FRAMES.map((frame) => ( setFrame(frame.id)} style={{ backgroundColor: `var(${frame.bg})` }} className={cn( SWATCH, "flex aspect-[2/3] w-full flex-col gap-1 rounded-thumb p-2 pb-3.5 hover:-translate-y-px", frame.id === frameId && "ring-selected" )} > {FRAME_BARS.map((bar) => ( ))} {frame.id === frameId ? : null} {frame.label} ))} ) : null} {tab === "efek" ? ( Efek foto {EFFECTS.map((effect) => ( setEffect(effect.id)} className={cn( SWATCH, "aspect-square w-full rounded-thumb hover:-translate-y-px", effect.id === effectId && "ring-selected" )} > {effect.id === effectId ? : null} {effect.label} ))} ) : null} {tab === "stiker" ? ( Stiker {STICKERS.map((sticker) => ( addSticker(sticker.id)} className={cn( SWATCH, "flex aspect-square w-full items-center justify-center rounded-card bg-paper hover:-translate-y-px" )} > ))} Ketuk untuk menempel. Geser, putar, dan ubah ukurannya di strip, atau pakai daftar di bawah kanvas. ) : null} {tab === "teks" ? ( Teks strip Teks setStripText(event.target.value)} className="h-11 rounded-pill border-2 border-ink bg-paper px-4 font-sans text-[15px] font-medium outline-none focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-violet" /> {Array.from(textValue).length}/{TEXT_LENGTH_MAX} Tanggal {showDate ? "Nyala" : "Mati"} ) : null} ) }
Ketuk untuk menempel. Geser, putar, dan ubah ukurannya di strip, atau pakai daftar di bawah kanvas.