Files
HaBit/components/pet/room-style-selector.tsx
Harkamal Randhawa 3470d444b4 Add customize-screen shop preview and purchase flow.
Locked items can be previewed on the pet from the editor, purchased with points in the preview modal, and opened in the full customize view from the shop.
2026-05-24 05:05:46 -06:00

88 lines
2.5 KiB
TypeScript

"use client";
import { Lock } from "lucide-react";
import { PIECE_SLOT_COUNT } from "@/lib/character/presets";
import {
ROOM_BACKGROUNDS,
isRoomBackgroundUnlocked,
type RoomBackgroundId,
} from "@/lib/room-backgrounds";
import { cn } from "@/lib/utils";
type RoomStyleSelectorProps = {
activeId: RoomBackgroundId;
ownedItemIds: readonly string[];
onSelect: (roomId: RoomBackgroundId) => void;
onLockedSelect?: (roomId: RoomBackgroundId) => void;
};
export function RoomStyleSelector({
activeId,
ownedItemIds,
onSelect,
onLockedSelect,
}: RoomStyleSelectorProps) {
const slots = Array.from({ length: PIECE_SLOT_COUNT }, (_, index) =>
ROOM_BACKGROUNDS[index] ?? null,
);
return (
<div className="grid grid-cols-8 gap-2">
{slots.map((room, index) => {
if (!room) {
return (
<div
key={`empty-${index}`}
aria-hidden
className="size-14 rounded-lg border border-dashed border-border/50 bg-muted/15"
/>
);
}
const locked = !isRoomBackgroundUnlocked(room.id, ownedItemIds);
return (
<button
key={room.id}
type="button"
title={
locked ? `${room.name} — preview in shop` : room.name
}
aria-label={
locked ? `${room.name}, locked — preview to unlock` : room.name
}
aria-pressed={activeId === room.id}
onClick={() => {
if (locked) {
onLockedSelect?.(room.id);
return;
}
onSelect(room.id);
}}
className={cn(
"relative size-14 overflow-hidden rounded-lg border transition-colors",
locked
? "border-border/40 opacity-80 hover:border-border"
: activeId === room.id
? "border-foreground shadow-[inset_0_0_0_1px_hsl(var(--foreground)/0.15)]"
: "border-border/60 hover:border-border",
)}
>
<div className={cn("absolute inset-0", room.previewClassName)} />
{locked ? (
<span
aria-hidden
className="absolute inset-0 flex items-center justify-center bg-background/75"
>
<Lock className="size-4 text-muted-foreground" strokeWidth={2.25} />
</span>
) : null}
</button>
);
})}
</div>
);
}