GenBlocks
Menu
Browse
  • Blocks
  • Images
Agents
  • Connect
Categories
  • All
  • Banners
  • Blog
  • Cards
  • Charts
  • Contact
  • CTA
  • Dashboard
  • FAQ
  • Features
  • Footer
  • Forms & Auth
  • Gallery
  • Hero
  • Integrations
  • Navbar
  • Newsletter & Waitlist
  • Onboarding
  • Pricing
  • Social proof
  • States
  • Stats
  • Tables
  • Team
  • Testimonials
  • Timeline
Source
GenBlocks
Log in
Log inSign up
  1. Blocks

© 2026 GenBlocks. All rights reserved.

AboutImpressumPrivacyTerms

Interactive preview, sandboxed: nothing you type leaves this page.

Files
import { useState } from "react";type SetupStep = {  title: string;  consequence: string;};const steps: SetupStep[] = [  {    title: "Import the timetable",    consequence: "Without it, the lesson slots for the term will not be created.",  },  {    title: "Invite teaching staff",    consequence: "Without staff access, teachers cannot review or manage their classes.",  },  {    title: "Map rooms to departments",    consequence: "Without room assignments, departments cannot direct lessons to the right spaces.",  },  {    title: "Set the term dates",    consequence: "Without dates, the school calendar and parent portal cannot show the right term.",  },  {    title: "Publish the parent portal",    consequence: "Until it is published, families cannot see the term information online.",  },];export default function Block() {  const [completed, setCompleted] = useState<boolean[]>(steps.map(() => false));  const [firstDay, setFirstDay] = useState("");  const [roomPrefix, setRoomPrefix] = useState("");  const completedCount = completed.filter(Boolean).length;  function toggleStep(index: number) {    setCompleted((current) => current.map((value, i) => (i === index ? !value : value)));  }  return (    <section className="w-full bg-slate-50 px-4 py-8 text-slate-900 dark:bg-neutral-950 dark:text-slate-100 sm:px-8 sm:py-12">      <div className="mx-auto max-w-4xl">        <header className="mb-7 border-b border-slate-200 pb-6 dark:border-neutral-800 sm:mb-8 sm:pb-7">          <p className="mb-3 text-xs font-semibold uppercase tracking-[0.12em] text-slate-600 dark:text-slate-400">            School administration <span className="px-1.5 text-slate-400 dark:text-slate-600">/</span> New term setup          </p>          <div className="flex flex-col gap-5 sm:flex-row sm:items-end sm:justify-between">            <div>              <h1 className="text-2xl font-semibold tracking-tight sm:text-[30px]">Prepare the new term</h1>              <p className="mt-2 max-w-xl text-sm leading-6 text-slate-700 dark:text-slate-300">                Complete the setup tasks before term begins. Changes take effect as you work.              </p>            </div>            <div className="w-full sm:w-52 sm:shrink-0">              <div className="mb-2 flex items-center justify-between gap-3 text-sm">                <span className="font-medium text-slate-800 dark:text-slate-200">Setup progress</span>                <span aria-live="polite" className="tabular-nums text-slate-700 dark:text-slate-300">                  {completedCount} of {steps.length} complete                </span>              </div>              <div                aria-label={`${completedCount} of ${steps.length} steps complete`}                aria-valuemax={steps.length}                aria-valuemin={0}                aria-valuenow={completedCount}                className="h-2 overflow-hidden rounded-full bg-slate-200 dark:bg-neutral-800"                role="progressbar"              >                <div                  className="h-full rounded-full bg-blue-700 transition-[width] duration-200 dark:bg-blue-400"                  style={{ width: `${(completedCount / steps.length) * 100}%` }}                />              </div>            </div>          </div>        </header>        <div className="overflow-hidden rounded-lg border border-slate-300 bg-white dark:border-neutral-700 dark:bg-neutral-900">          <ul className="divide-y divide-slate-200 dark:divide-neutral-800">            {steps.map((step, index) => {              const isCurrent = index === 3;              const isComplete = completed[index];              return (                <li key={step.title} className={isCurrent ? "bg-slate-50/80 dark:bg-neutral-900" : ""}>                  <div className="flex items-start gap-3 px-4 py-4 sm:gap-4 sm:px-6 sm:py-5">                    <div className="flex min-h-7 min-w-7 items-center justify-center pt-0.5">                      <input                        checked={isComplete}                        onChange={() => toggleStep(index)}                        aria-label={`${isComplete ? "Mark incomplete" : "Mark complete"}: ${step.title}`}                        className="h-6 w-6 cursor-pointer rounded border-slate-400 accent-blue-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700 dark:border-neutral-500 dark:accent-blue-400 dark:focus-visible:outline-blue-300"                        type="checkbox"                      />                    </div>                    <div className="min-w-0 flex-1">                      <div className="flex flex-wrap items-center gap-x-3 gap-y-1.5">                        <h2 className={`text-base font-semibold leading-6 ${isComplete ? "text-slate-600 line-through dark:text-slate-400" : "text-slate-900 dark:text-slate-100"}`}>                          {step.title}                        </h2>                        {isCurrent && (                          <span className="rounded-sm border border-blue-300 bg-blue-50 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-200">                            Current step                          </span>                        )}                        {isComplete && <span className="text-xs font-medium text-emerald-800 dark:text-emerald-300">Complete</span>}                      </div>                      <p className="mt-1 text-sm leading-5 text-slate-700 dark:text-slate-300">{step.consequence}</p>                      {isCurrent && (                        <div className="mt-5 border-t border-slate-200 pt-4 dark:border-neutral-800 sm:mt-6 sm:pt-5">                          <p className="mb-4 text-sm font-medium text-slate-800 dark:text-slate-200">Term details</p>                          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-5">                            <div>                              <label htmlFor="term-first-day" className="mb-1.5 block text-sm font-medium text-slate-800 dark:text-slate-200">                                First day of term                              </label>                              <input                                id="term-first-day"                                type="date"                                value={firstDay}                                onChange={(event) => setFirstDay(event.target.value)}                                className="h-11 w-full rounded-md border border-slate-400 bg-white px-3 text-sm text-slate-900 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700 dark:border-neutral-600 dark:bg-neutral-950 dark:text-slate-100 dark:focus-visible:outline-blue-300"                              />                            </div>                            <div>                              <label htmlFor="room-prefix" className="mb-1.5 block text-sm font-medium text-slate-800 dark:text-slate-200">                                Room naming prefix <span className="font-normal text-slate-600 dark:text-slate-400">(for room mapping)</span>                              </label>                              <input                                id="room-prefix"                                type="text"                                value={roomPrefix}                                onChange={(event) => setRoomPrefix(event.target.value)}                                placeholder="e.g. B — rooms become B101, B102"                                className="h-11 w-full rounded-md border border-slate-400 bg-white px-3 text-sm text-slate-900 shadow-sm placeholder:text-slate-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700 dark:border-neutral-600 dark:bg-neutral-950 dark:text-slate-100 dark:placeholder:text-slate-400 dark:focus-visible:outline-blue-300"                              />                            </div>                          </div>                        </div>                      )}                    </div>                  </div>                </li>              );            })}          </ul>        </div>        <p className="mt-4 text-xs leading-5 text-slate-600 dark:text-slate-400">          Mark a task complete when it has been finished. You can update this checklist as setup progresses.        </p>      </div>    </section>  );}

Create a practical React onboarding checklist for a

Category
Onboarding
Date
23 Oct 2026
Model
gpt-6-luna
Source
AI-generated
Trace
65390d7ec01dcd63441c2cbd212144cb

Judge

Render
94
Accessibility
95
Visual
89
Copy
92
Compliance
96

Harness

assets
ok
safety
ok
imports
ok
ast
ok
Types
ok
Lint> genblocks-sandbox@0.0.0 lint > eslint . /tmp/tmppnmlqlhz/scripts/inline.mjs 25:24 error 'process' is not defined no-undef 190:3 error 'process' is not defined no-undef 190:47 error 'Buffer' is not defined no-undef /tmp/tmppnmlqlhz/scripts/scan.mjs 23:14 error 'process' is not defined no-undef 24:14 error 'process' is not defined no-undef 264:21 error 'URL' is not defined no-undef 353:3 error 'co
failed
Build
ok
bundle
ok
Render
ok
Desktop
ok
Laptop
ok
Tablet
ok
Phone
ok
Touch targets
ok
Keyboard focus
ok
Reduced motion
ok
Accessibility
ok
Accessibility, dark
ok
preview
ok
Sign in to report