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]>
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
import { redirect } from "next/navigation";
|
|
import { ActionForm, SubmitButton } from "@/components/forms";
|
|
import { PageHeader } from "@/components/status";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field";
|
|
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
|
|
import { api, getMe, unwrap } from "@/lib/api";
|
|
import { createRoom } from "../actions";
|
|
import { RoomFields } from "../room-fields";
|
|
|
|
export const metadata: Metadata = { title: "New room" };
|
|
|
|
export default async function NewRoom() {
|
|
const me = await getMe();
|
|
if (!me) redirect("/signin?next=/rooms/new");
|
|
const { links } = await api.account.get().then(unwrap);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<PageHeader title="New room">
|
|
<Link href="/rooms" className="underline-offset-4 hover:underline">
|
|
Back to rooms
|
|
</Link>
|
|
</PageHeader>
|
|
<Card>
|
|
<CardContent>
|
|
{links.length === 0 ? (
|
|
<p className="py-2 text-sm text-muted-foreground">
|
|
<Link href="/account" className="text-foreground underline underline-offset-4">
|
|
Link an IMVU account
|
|
</Link>{" "}
|
|
first: it's shown as the room's owner.
|
|
</p>
|
|
) : (
|
|
<ActionForm action={createRoom}>
|
|
<FieldGroup>
|
|
<RoomFields canAdult={links.some((l) => l.adult)} />
|
|
<Field>
|
|
<FieldLabel htmlFor="imvuId">Owner</FieldLabel>
|
|
<NativeSelect id="imvuId" name="imvuId" defaultValue={String(links[0]!.imvuId)} className="w-64">
|
|
{links.map((l) => (
|
|
<NativeSelectOption key={l.imvuId} value={String(l.imvuId)}>
|
|
{l.username}
|
|
</NativeSelectOption>
|
|
))}
|
|
</NativeSelect>
|
|
<FieldDescription>The IMVU account shown as owner. It can decorate the room.</FieldDescription>
|
|
</Field>
|
|
<div>
|
|
<SubmitButton pendingLabel="Making…">Make room</SubmitButton>
|
|
</div>
|
|
</FieldGroup>
|
|
</ActionForm>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|