0%
balqalam Logo
balqalam
FeaturesCommunityPricingDocumentation
Login
  • Introduction
  • Pitch
  • Hogwarts
  • Live Demo
  • MVP
  • Roadmap
  • Launch Sprint
  • PRD
  • Get Started
  • Localhost
  • Architecture
  • Structure
  • Pattern
  • Page
  • Layout
  • Content
  • Types
  • Config
  • Actions
  • Queries
  • Authorization
  • Validation
  • Form
  • Table
  • Detail
  • Card
  • Util
  • Hooks
  • List Params
  • Views
  • README.md
  • ISSUE.md
  • Technology Stack
  • Database
  • File
  • CDN Assets
  • Entry Points
  • Dashboard
  • Authentication
  • Credentials
  • OAuth
  • Flow Diagrams
  • Multi-Tenancy
  • Offline
  • Onboarding
  • Onboarding Videos
  • Add Values
  • Admission
  • Application
  • Attendance
  • Compliance
  • Profile
  • Exams
  • Exam Wizard
  • Timetable
  • Classrooms
  • Notifications
  • Conference
  • LMS (Lumos)
Finance
  • Finance
  • Fee Management
  • Invoice
  • Wallet
  • Salary
  • Payroll
  • Timesheet
  • Expenses
  • Budget
  • Receipt
  • Accounts
  • Banking
  • Reports
  • Dashboard
  • Permissions
  • Messages
  • Integration Flow
  • Provision
  • AI Document Processing
  • Document Intelligence
  • Internationalization
  • Translation
  • Translation Guide
  • Icons
  • Docs Factory
  • Inspiration
  • Listings
  • Teachers
  • Students
  • Catalog
  • Library
  • Contributing
  • Code of conduct
  • GitHub Workflow
  • Database Seeds
  • Database Safety
  • Test Accounts
  • Playwright
  • Prettier
  • Block Rebound
Sales & GTM
  • Marketing Brief
  • Sales
  • Go-to-market
  • Marketing
  • Admission — Feature Spotlight
  • Pilot Program
  • Leads
  • Proposal
  • Outreach Templates
  • Case Study
  • Competitors
  • Landing-page teardown
  • Competitor FAQ
  • Business model
  • Shared economy
  • Traction
Fundraising & Ecosystem
  • Get Support
  • Investor Deck
  • Data Room
  • Investors
  • Accelerators
  • Incubators
  • Grants
  • Sponsors
  • Partners
  • Competitions & Hackathons
  • Universities & Training Centers

Form

PreviousNext

Client component running RHF + Zod, calling a server action on submit.

form.tsx renders inputs, runs Zod validation via react-hook-form, and calls server actions on submit. Sits next to validation.ts (schemas) and actions.ts (server actions).

Categories

CategoryShapeReference
CRUD modalCreate / edit / view via useModal() (130–250 lines)listings/subjects/form.tsx
URL-routed wizard stepPage per step under WizardLayoutlistings/teachers/wizard/information/form.tsx
Application wizard stepforwardRef + useImperativeHandle exposing saveAndNext()apply/personal/form.tsx
Onboarding stepWizard step for school onboardingonboarding/branding/form.tsx
AuthLogin / register / reset / 2FA — pre-tenantauth/login/form.tsx
Settings / configInline update, no modaltimetable/settings/form.tsx
Exam / lumosDynamic field arraysexams/qbank/form.tsx

Rules

#Rule
1"use client" at the top
2Schema imported from validation.ts — never inline
3zodResolver typed with useForm<XInput> — never as any
4Use <Name>Input from validation.ts for values
5Stay under ~200 lines
6Submit through a dedicated onSubmit — call server action, handle response, toast, close

Canonical example

"use client"
 
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
 
import { createSubject, updateSubject } from "./actions"
import { subjectCreateSchema, type SubjectCreateInput } from "./validation"
 
const form = useForm<SubjectCreateInput>({
  resolver: zodResolver(subjectCreateSchema),
  defaultValues: { subjectName: "", departmentId: "" },
})
 
async function onSubmit(values: SubjectCreateInput) {
  const res = currentId
    ? await updateSubject({ id: currentId, ...values })
    : await createSubject(values)
  if (res?.success) {
    toast.success(currentId ? "Subject updated" : "Subject created")
    closeModal()
    onSuccess?.()
  } else {
    toast.error(res?.error || "Failed to save")
  }
}

Pattern selection

ScenarioPattern
Simple create form (1–5 fields)useActionState + native <form action={}>
Complex CRUD with edit modereact-hook-form + zodResolver
URL-routed multi-step wizardWizardLayout + WizardStep
Application wizard stepreact-hook-form + forwardRef
Real-time field validationreact-hook-form + zodResolver
File uploadsreact-hook-form + custom handlers

Progressive enhancement (React 19)

For simple forms, use native <form action={}> with useActionState:

"use client"
 
import { useActionState } from "react"
import { useFormStatus } from "react-dom"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
 
import { createItem } from "./actions"
 
export function SimpleForm() {
  const [state, action, pending] = useActionState(createItem, null)
  return (
    <form action={action} className="space-y-4">
      <Input name="title" required />
      {state?.error && <p className="text-destructive text-sm">{state.error}</p>}
      <SubmitButton />
    </form>
  )
}
 
function SubmitButton() {
  const { pending } = useFormStatus()
  return <Button type="submit" disabled={pending}>{pending ? "Saving…" : "Save"}</Button>
}

The action signature must accept (prevState, formData).

Wizard mechanics

  • useModal() exposes mode and id. id.startsWith("view:") means read-only.
  • createWizardProvider ships data with retry; the step reads initialData.
  • Application steps expose { saveAndNext: () => Promise<boolean> } via forwardRef.
  • onValidChange callback emits validity to the parent for next-button enable/disable.

Anti-patterns

  • zodResolver(schema) as any — fix the schema or defaultValues instead.
  • Inline schemas — schemas belong in validation.ts.
  • dictionary: any — type the slice.
  • Monolith forms over 200 lines — split into step components.
  • Mixed concerns — no fetching, no table rendering, no utils. Data arrives via props.

File layout

src/components/<feature>/
  config.ts         # Option arrays
  validation.ts     # Zod schemas + inferred types
  actions.ts        # Server actions
  types.ts          # Form props, ref types
  form.tsx          # Client component (this file)
  content.tsx       # Server component (renders form)

See also

  • Pattern
  • Validation
  • Actions
  • Content
ValidationTable

On This Page

CategoriesRulesCanonical examplePattern selectionProgressive enhancement (React 19)Wizard mechanicsAnti-patternsFile layoutSee also

Built by Databayt ·

Welcome to balqalam.

A great journey is about to begin.