Dyrected
Examples & RecipesRecipe Library

Build a walk-in check-in form

Replace a collection's create screen with a small desk form that saves a guest as attending and checked in, through the normal create path.

Replace a collection's create screen with a small desk form that saves a guest as attending and checked in, through the normal create path.

Use this when

  • replace the create form with my own component
  • build a custom create screen for a collection
  • check in a guest from a custom admin form
  • save a record with values the editor does not type
  • use built-in field inputs inside a custom form

Dyrected concepts

admin.components.createForm, formShell, components.forms, useDocumentForm, DyrectedField, submit overrides

Additional packages: @dyrected/react

Decisions and cautions

Use this recipe only when its runtime matches the project you are documenting or building. Cloud recipes must stay inside the managed content backend boundary. Self-hosted recipes may use the server runtime, database, hooks, and infrastructure you control.

Complete recipe

This is the canonical source compiled and behavior-tested by @dyrected/knowledge.

import { useState } from "react";
import {
  defineBooleanField,
  defineCollection,
  defineDateTimeField,
  defineNumberField,
  defineTextField,
} from "@dyrected/core";
import { DyrectedField, defineAdminComponents, useAdminNotify, useDocumentForm } from "@dyrected/react";

export const GuestResponses = defineCollection({
  slug: "guest-responses",
  labels: { singular: "Guest response", plural: "Guest responses" },
  admin: {
    useAsTitle: "name",
    components: {
      // Used when creating. Editing keeps the built-in form.
      createForm: "guest-responses.walkIn",
      // The form brings its own button, so Dyrected keeps only the header.
      formShell: "header",
    },
  },
  fields: [
    defineTextField({ name: "name", label: "Full name", required: true }),
    defineTextField({ name: "email", label: "Email" }),
    defineNumberField({ name: "guestCount", label: "Plus-ones", defaultValue: 0 }),
    defineBooleanField({ name: "attending", label: "Attending", defaultValue: false }),
    defineBooleanField({ name: "checkedIn", label: "Checked in", defaultValue: false }),
    defineDateTimeField({ name: "checkedInAt", label: "Checked in at" }),
  ],
});

export function WalkInForm() {
  const { submit, permissions, cancel } = useDocumentForm();
  const notify = useAdminNotify();
  const [saving, setSaving] = useState(false);

  async function registerAndCheckIn() {
    setSaving(true);
    const result = await submit({
      // Values the editor never types: they are what "walk-in" means.
      overrides: { attending: true, checkedIn: true, checkedInAt: new Date().toISOString() },
      redirect: "list",
      silent: true,
    });
    setSaving(false);

    if (result.ok) {
      notify.success("Guest registered and checked in");
    } else {
      notify.error(result.errors.name ?? result.errors._form ?? "Could not register this guest");
    }
  }

  return (
    <div>
      <h2>Walk-in guest</h2>
      <DyrectedField path="name" />
      <DyrectedField path="email" />
      <DyrectedField path="guestCount" />

      <button type="button" onClick={cancel}>
        Cancel
      </button>
      <button type="button" disabled={saving || !permissions.canCreate} onClick={() => void registerAndCheckIn()}>
        {saving ? "Registering…" : "Register and check in"}
      </button>
    </div>
  );
}

// Registered on <DyrectedAdmin components={components} /> under the key the config uses.
export const components = defineAdminComponents({
  forms: { "guest-responses.walkIn": WalkInForm },
});

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend