Hogwarts Logo
Hogwarts
FeaturesBlogPricingDocumentation

Command Palette

Search for a command to run...

10
Login

Build by Databayt, source code available on GitHub

  • Introduction
  • Pitch
  • MVP
  • PRD
  • Get Started
  • Architecture
  • Structure
  • Pattern
  • Stack
  • Icons
  • Dashboard
  • Rebound
  • Database
  • Attendance
  • Localhost
  • Contributing
  • Shared Economy
  • Competitors
  • Inspiration
  • Demo
  • Listings
  • Business

Listings

PreviousNext

A unified pattern for data tables, grids, and CRUD operations across the platform with optimistic updates, auto-refresh, and consistent UX.

Overview

Listings are the backbone of data-driven features in the platform. They provide a unified pattern for displaying, searching, filtering, creating, editing, and deleting records—all with a consistent UX and optimistic updates.

Every listing follows the same structure, making it predictable for developers and consistent for users. Whether you're working with Students, Teachers, Classes, Events, or any other entity—the pattern remains the same.

Key Features

Optimistic Updates

Add, update, and remove items instantly with automatic rollback on errors.

URL-Persisted Views

Table/Grid view toggle persists via URL query params using nuqs.

Infinite Scroll

Load-more pagination for seamless data browsing without page reloads.

Centralized Queries

Type-safe query builders with role-based authorization per module.


Listing Structure

Every listing follows the mirror pattern — the URL route produces two directories: one in app/ for routing, one in components/ for feature logic. Replace abc with your feature name.

prisma/— Database layer
models/abc.prisma— Model with schoolId scope
seeds/abc.ts— Test seed data
src/— Source code
app/[lang]/s/[subdomain]/(school-dashboard)/(listings)/— Route layer
layout.tsx— Shared listings layout
abc/— Feature route
page.tsx— Imports AbcContent
layout.tsx— Feature layout
loading.tsx— Loading skeleton
error.tsx— Error boundary
[id]/page.tsx— Detail view
components/— Component layer
atom/— Reusable UI atoms
page-title.tsx— Page title display
page-nav.tsx— Sub-navigation tabs
toolbar.tsx— Action toolbar
search-input.tsx— Debounced search
view-toggle.tsx— Grid/Table toggle
grid-container.tsx— Responsive grid
empty-state.tsx— Empty state display
modal/— Modal system
context.tsx— Modal state (useModal)
modal.tsx— Modal wrapper
modal-form-layout.tsx— Two-column layout
modal-footer.tsx— Progress + navigation
table/— Reusable table components
data-table.tsx— Main DataTable
data-table-toolbar.tsx— Table toolbar
data-table-column-header.tsx— Sortable header
use-data-table.ts— Table state hook
school-dashboard/listings/— Listings components
card.tsx— Generic listing card
form.tsx— Generic form base
index.ts— Shared exports
abc/— Feature logic (mirrors route)
content.tsx— Server: data fetching
table.tsx— Client: interactive table
columns.tsx— Column definitions
form.tsx— Extends generic form
card.tsx— Extends generic card
actions.ts— Server actions
queries.ts— Query builders
authorization.ts— RBAC checks
validation.ts— Zod schemas
types.ts— TypeScript types
hooks/— Shared hooks
use-school-dashboard-data.ts— Optimistic updates + infinite scroll
use-school-dashboard-view.ts— View mode (URL-persisted)

Standardized File Patterns

Each listing directory follows these naming conventions:

FilePurpose
content.tsxServer component: data fetching, tenant context
table.tsxClient component: interactive table with state
columns.tsxColumn definitions (client, uses hooks)
form.tsxCreate/Edit form with validation
actions.tsServer actions: validate, scope tenant, mutate
queries.tsQuery builders with Prisma
authorization.tsRBAC permission checks
validation.tsZod schemas & refinements
types.tsTypeScript interfaces
config.tsConstants, options, labels
list-params.tsURL params (nuqs)
README.mdFeature documentation
ISSUE.mdKnown issues tracker

Page Layout Composition

┌─────────────────────────────────────────────────────────────────┐
│  PageTitle                     src/components/atom/page-title.tsx│
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ Abc Management                                              ││
│  │ Manage all abc records in your school                       ││
│  └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│  PageNav                         src/components/atom/page-nav.tsx│
│  ┌──────────┬──────────┬──────────┬──────────┐                  │
│  │ All      │ Active   │ Archive  │ Settings │                  │
│  └──────────┴──────────┴──────────┴──────────┘                  │
├─────────────────────────────────────────────────────────────────┤
│  Toolbar                         src/components/atom/toolbar.tsx │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ SearchInput    Filters           ViewToggle Export Create   ││
│  │ [🔍 Search...] [Status▾][Type▾]  [≡/⊞]     [↓]    [+]      ││
│  └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│  DataTable                   src/components/table/data-table.tsx │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ ☐ │ Name        │ Status   │ Created    │ Actions          ││
│  │───┼─────────────┼──────────┼────────────┼──────────────────││
│  │ ☐ │ Item 1      │ Active   │ 2025-01-20 │ [···]            ││
│  │ ☐ │ Item 2      │ Draft    │ 2025-01-19 │ [···]            ││
│  └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│  OR GridContainer          src/components/atom/grid-container.tsx│
│  ┌─────────┐ ┌─────────┐ ┌─────────┐                            │
│  │ Card 1  │ │ Card 2  │ │ Card 3  │                            │
│  └─────────┘ └─────────┘ └─────────┘                            │
├─────────────────────────────────────────────────────────────────┤
│  Modal (when open)              src/components/atom/modal/modal  │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │ ModalFormLayout  src/components/atom/modal/modal-form-layout ││
│  │ ┌──────────────┐  ┌───────────────────────────────────────┐││
│  │ │ Create Abc   │  │  Form (listings/abc/form.tsx)         │││
│  │ │ Add new item │  │  - Field 1                           │││
│  │ └──────────────┘  └───────────────────────────────────────┘││
│  │ ModalFooter      src/components/atom/modal/modal-footer     ││
│  │ [━━━━━━━━━━━━━━━━━━━━━━━━━━━━]                              ││
│  │ Step 1 of 2: Basic Info              [Cancel] [Next]       ││
│  └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Component Flow

Route (page.tsx)
    │
    ▼
Content (content.tsx) ──── Server Component
    │ • getTenantContext()
    │ • Parse URL params
    │ • Fetch data via queries.ts
    │
    ▼
Table (table.tsx) ──────── Client Component
    │ • useModal()
    │ • usePlatformView()
    │ • useDataTable()
    │
    ├──► Toolbar
    │      • SearchInput
    │      • ViewToggle
    │      • ExportButton
    │      • CreateButton
    │
    ├──► DataTable / GridContainer
    │      • Columns (columns.tsx)
    │      • Row actions
    │      • Pagination
    │
    └──► Modal
           • Form (form.tsx)
           • ModalFormLayout
           • ModalFooter

Reference Implementation

The Grades module serves as the reference implementation with the complete pattern:

PatternReference File
Server Actionssrc/components/platform/listings/grades/actions.ts
Queriessrc/components/platform/listings/grades/queries.ts
Authorizationsrc/components/platform/listings/grades/authorization.ts
Validationsrc/components/platform/listings/grades/validation.ts
Tablesrc/components/platform/listings/grades/table.tsx
Columnssrc/components/platform/listings/grades/columns.tsx
Formsrc/components/platform/listings/grades/form.tsx
Contentsrc/components/platform/listings/grades/content.tsx

Core Hooks

HookPathPurpose
usePlatformDatasrc/hooks/use-platform-data.tsData fetching with optimistic updates and infinite scroll
usePlatformViewsrc/hooks/use-platform-view.tsView mode (table/grid) with URL persistence
useDataTablesrc/components/table/use-data-table.tsTanStack Table state management
useModalsrc/components/atom/modal/context.tsxModal open/close state management

Modules Status

ModuleTableGridSearchExportqueries.tsauthorization.ts
Announcements✅✅✅✅✅✅
Grades✅✅✅✅✅✅
Students✅✅✅✅🔄🔄
Teachers✅✅✅✅🔄🔄
Classes✅✅✅✅🔄🔄
Subjects✅✅✅✅🔄🔄
Events✅✅✅✅🔄🔄
Lessons✅✅✅✅🔄🔄
Parents✅✅✅✅🔄🔄

✅ = Complete | 🔄 = Using pattern, needs queries.ts/authorization.ts


Best Practices

Multi-Tenant Safety

  • ALWAYS include schoolId in every database query
  • Get schoolId from session: const { schoolId } = session.user
  • Missing schoolId breaks tenant isolation

Column Definitions

  • Define handlers BEFORE columns useMemo
  • Columns with hooks (useModal) must be generated in client components
  • Pass callbacks via getColumns(dictionary, lang, { onDelete, onEdit, onView })

Optimistic Updates

  • Call optimisticRemove(id) before server request
  • Call refresh() on error to rollback
  • Use optimisticUpdate(id, updater) for in-place updates

Server Actions

  • Start with "use server" directive
  • Validate with Zod on both client (UX) and server (security)
  • Call revalidatePath() or redirect() after mutations
  • Return typed ActionResponse<T> results

Modal Forms

  • Use ModalFormLayout for two-column header/form layout
  • Use ModalFooter for progress bar and navigation
  • Call onSuccess() callback after successful mutations

Listing Maturity Levels

LevelFeatureStatus
1Basic CRUD (create, read, update, delete)✅ Complete
2Relationship context (counts, quick links)🔄 In Progress
3Rich detail pages with related data tabs🔄 In Progress
4Cross-listing actions (bulk operations)🔄 In Progress
5Automated workflows (triggers, notifications)⏳ Planned

The Listings pattern ensures consistency across all data-driven features. By following this pattern, you get auto-refresh, optimistic updates, view toggles, and export functionality—all with type-safe queries and role-based authorization.

InspirationContributing

On This Page

OverviewKey FeaturesListing StructureStandardized File PatternsPage Layout CompositionComponent FlowReference ImplementationCore HooksModules StatusBest PracticesMulti-Tenant SafetyColumn DefinitionsOptimistic UpdatesServer ActionsModal FormsListing Maturity Levels