CI / test (push) Successful in 1m5s
Rooms made on the website (hosted_room, migration 0005), the REST routes in docs/hosted-rooms.md, and the realtime room.* protocol: joining with the capacity, adult and linked-account rules, seats, numbered messages with forged senders dropped and a rate limit, closing. The Rooms page lists them, with a form to make one and the owner's edit and close. Co-Authored-By: Claude Opus 5.5 <[email protected]>
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
// The fields of a hosted room, for making one and for editing it.
|
|
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field";
|
|
import { Input } from "@/components/ui/input";
|
|
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import type { HostedRoom } from "@/lib/api";
|
|
|
|
export function RoomFields({ room, canAdult }: { room?: HostedRoom; canAdult: boolean }) {
|
|
return (
|
|
<>
|
|
<Field>
|
|
<FieldLabel htmlFor="name">Name</FieldLabel>
|
|
<Input id="name" name="name" defaultValue={room?.name} required maxLength={64} className="max-w-md" />
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel htmlFor="description">Description</FieldLabel>
|
|
<Textarea id="description" name="description" defaultValue={room?.description} maxLength={512} rows={3} />
|
|
</Field>
|
|
<div className="grid gap-4 sm:grid-cols-3">
|
|
<Field>
|
|
<FieldLabel htmlFor="roomPid">Room shell</FieldLabel>
|
|
<Input
|
|
id="roomPid"
|
|
name="roomPid"
|
|
type="number"
|
|
inputMode="numeric"
|
|
min={1}
|
|
required
|
|
defaultValue={room?.roomPid}
|
|
placeholder="Product ID"
|
|
/>
|
|
<FieldDescription>An IMVU room product's ID, from its shop page.</FieldDescription>
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel htmlFor="rating">Rating</FieldLabel>
|
|
<NativeSelect id="rating" name="rating" defaultValue={room?.rating ?? "general"} className="w-full">
|
|
<NativeSelectOption value="general">General</NativeSelectOption>
|
|
<NativeSelectOption value="adult" disabled={!canAdult && room?.rating !== "adult"}>
|
|
Adult
|
|
</NativeSelectOption>
|
|
</NativeSelect>
|
|
{!canAdult && <FieldDescription>Adult needs an age-verified account.</FieldDescription>}
|
|
</Field>
|
|
<Field>
|
|
<FieldLabel htmlFor="maxUsers">Max people</FieldLabel>
|
|
<Input
|
|
id="maxUsers"
|
|
name="maxUsers"
|
|
type="number"
|
|
inputMode="numeric"
|
|
min={2}
|
|
max={30}
|
|
required
|
|
defaultValue={room?.maxUsers ?? 10}
|
|
/>
|
|
</Field>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|