Weave.js

Enter Room page

Learn how to set up the Enter Room page on Next.js

In this guide, we will walk through the process of building the Enter Room page:

Enter room page

This page allows users to define the room they wish to join and set their username. Let's build it step by step.

Prerequisites

Before you begin, ensure that you have completed the frontend installation guide, up to the "Set up the Enter Room page" step.

Step by step

To set up the Enter Room page in your Next.js project, follow these steps:

Define the page component

Replace the contents of the file app/page.tsx with the following content:

app/page.tsx
import { Home } from "@/components/home/home";

export default function HomePage() {
  return <Home />;
}

Install the UI building block components

Set up the necessary Shadcn/UI components for the Enter Room page.

We will be using the Shadcn/UI CLI to install the UI components. Accept all the defaults from the CLI options.

In the root directory of your project, follow these steps:

  • Install the Form component:

    npx shadcn@latest add form
  • Install the Input component:

    npx shadcn@latest add input

Define the base styles

Now, let's tune up a little bit the styling of the Enter Room page.

On the app/globals.css file, replace the @layer base directive configuration with:

app/globals.css
@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  html {
    @apply w-full h-full outline-transparent;
  }
  body {
    @apply w-full h-full outline-transparent bg-background text-foreground;
  }
}

Set up the page React component

Create a home folder on the components folder.


Home component

On the components/home folder, create a file named home.tsx with the following content:

components/home/home.tsx
"use client";

import React from "react";
import LoginForm from "./login-form";

export const Home = () => {
  return (
    <>
      <main className="w-full h-full">
        <section
          className="relative flex h-full w-full flex-col items-center justify-center p-6"
        >
          <h3 className="text-2xl font-noto-sans-mono font-extralight text-muted-foreground uppercase mb-8">
            Join a Room
          </h3>
          <LoginForm />
        </section>
      </main>
    </>
  );
};

LoginForm component

On the components/home folder, create a file named login-form.tsx with the following content:

components/home/login-form.tsx
"use client";

import React from "react";
import { useRouter } from "next/navigation";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { useCollaborationRoom } from "@/store/store";

const formSchema = z
  .object({
    username: z
      .string()
      .trim()
      .min(1, { message: "The username is required" })
      .max(50, { message: "The username must be maximum 50 characters long" }),
    roomId: z
      .string()
      .trim()
      .min(1, { message: "The room name is required" })
      .max(50, { message: "The room name must be maximum 50 characters long" }),
  })
  .required();

function LoginForm() {
  const router = useRouter();

  const setRoom = useCollaborationRoom((state) => state.setRoom);
  const setUser = useCollaborationRoom((state) => state.setUser);

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      username: "",
      roomId: "",
    },
  });

  function onSubmit(values: z.infer<typeof formSchema>) {
    setRoom(values.roomId);
    setUser({
      name: values.username,
      email: `${values.username}@weavejs.com`,
    });
    router.push(`/room/${values.roomId}?userName=${values.username}`);
  }

  return (
    <div
      className="w-full max-w-md"
    >
      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="w-full space-y-5"
        >
          <FormField
            control={form.control}
            name="roomId"
            render={({ field }) => (
              <FormItem>
                <FormLabel className="font-noto-sans-mono">ROOM</FormLabel>
                <FormControl>
                  <Input
                    placeholder="the room name to join"
                    className="font-noto-sans-mono rounded-none shadow-none"
                    {...field}
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="username"
            render={({ field }) => (
              <FormItem>
                <FormLabel className="font-noto-sans-mono">USERNAME</FormLabel>
                <FormControl>
                  <Input
                    placeholder="your username"
                    className="font-noto-sans-mono rounded-none shadow-none"
                    {...field}
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button
            type="submit"
            className="w-full cursor-pointer font-mono rounded-none"
          >
            ENTER THE ROOM
          </Button>
        </form>
      </Form>
    </div>
  );
}

export default LoginForm;

Run the project

Once the Enter Room page setup is complete, run the project by executing the following command:

npm run dev

Navigate to http://localhost:3000 on a browser. You should see the following:

Enter room page

Next steps

Let's now set up the Room page of the Next.js application.