Getting Started

Create Your First Page

Learn to Create Admin Pages with SmartCrudPage in 15 Minutes

Preparation ยท Creation Steps ยท Verification


๐Ÿ“‹ Overview

This tutorial will guide you through creating a complete CRUD admin page using the SmartCrudPage template.

What You'll Learn

  • โœ… How to design Prisma data models
  • โœ… How to create Server Actions
  • โœ… How to configure SmartCrudPage
  • โœ… How to add admin menu items

Final Result

Create an "Announcement Management" page with:

  • ๐Ÿ“‹ Data List (pagination, sorting, search)
  • โž• Create Announcement
  • โœ๏ธ Edit Announcement
  • ๐Ÿ—‘๏ธ Delete Announcement
  • ๐Ÿ‘๏ธ View Details

๐Ÿ”ง Preparation

1. Design Data Model

Add the announcement model to prisma/schema.prisma:

model Announcement {
  id        String    @id @default(cuid())
  title     String                        // Announcement Title
  content   String    @db.Text            // Announcement Content
  type      String    @default("info")    // Type: info/warning/success
  enable    Boolean   @default(true)      // Enabled
  sort      Int       @default(0)         // Sort Order
  remark    String?                       // Remarks
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  deletedAt DateTime?                     // Soft Delete
}

2. Execute Database Migration

npx prisma migrate dev --name add_announcement

๐Ÿ“ Creation Steps

Step 1: Create Server Actions

Create file app/(admin)/actions/content/crud-action.announcement.js:

'use server'

import { createCrudActions } from '@/lib/core/crud-helper'

/**
 * Announcement Management - Server Actions
 * 
 * Naming Conventions:
 * - sys prefix: Requires admin permission
 * - auth prefix: Requires login
 * - pub prefix: Public access
 */

// Resource Configuration
const announcementConfig = {
  // Basic Configuration
  modelName: 'announcement',
  primaryKey: 'id',
  softDelete: true,
  
  // Field Configuration
  fields: {
    creatable: ['title', 'content', 'type', 'enable', 'sort', 'remark'],
    updatable: ['title', 'content', 'type', 'enable', 'sort', 'remark'],
    searchable: ['title', 'content', 'type'],
  },
  
  // Query Configuration
  query: {
    defaultSort: { sort: 'asc', createdAt: 'desc' },
    defaultPageSize: 20,
  },
  
  // Validation Rules
  validation: {
    title: {
      required: true,
      maxLength: 100,
      message: 'Title is required, max 100 characters'
    },
    content: {
      required: true,
      message: 'Content is required'
    },
    type: {
      enum: ['info', 'warning', 'success'],
      message: 'Type must be info/warning/success'
    }
  }
}

// Export CRUD Actions
export const {
  getList: getAnnouncementListAction,
  getDetail: getAnnouncementDetailAction,
  create: createAnnouncementAction,
  update: updateAnnouncementAction,
  delete: deleteAnnouncementAction,
} = createCrudActions(announcementConfig)

Step 2: Create Frontend Page

Create file app/(admin)/admin/content/announcements/page.js:

'use client'

import SmartCrudPage from '@/components/admin/smart-crud-page'
import * as announcementActions from '@/app/(admin)/actions/content/crud-action.announcement'

/**
 * Announcement Management Page
 */
export default function AnnouncementsPage() {
  // Fields Configuration - Core configuration that drives the entire page
  const fieldsConfig = [
    {
      key: 'id',
      title: 'ID',
      type: 'text',
      table: { width: 80, copyable: true },
      form: { hidden: true },
    },
    {
      key: 'title',
      title: 'Announcement Title',
      type: 'text',
      table: { width: 200, ellipsis: true },
      form: { required: true, placeholder: 'Enter announcement title' },
      search: { enabled: true, mode: 'like' },
    },
    {
      key: 'content',
      title: 'Announcement Content',
      type: 'textarea',
      table: { width: 300, ellipsis: true },
      form: { required: true, rows: 4 },
    },
    {
      key: 'type',
      title: 'Type',
      type: 'select',
      options: [
        { label: '๐Ÿ“ข Notice', value: 'info' },
        { label: 'โš ๏ธ Warning', value: 'warning' },
        { label: 'โœ… Success', value: 'success' },
      ],
      table: { width: 100 },
      form: { required: true },
      search: { enabled: true, mode: 'exact' },
    },
    {
      key: 'enable',
      title: 'Status',
      type: 'switch',
      table: {
        width: 80,
        render: (value) => value ? 'โœ… Enabled' : 'โŒ Disabled'
      },
      form: { defaultValue: true },
      search: { enabled: true, mode: 'exact' },
    },
    {
      key: 'sort',
      title: 'Sort',
      type: 'number',
      table: { width: 80, sorter: true },
      form: { defaultValue: 0, min: 0 },
    },
    {
      key: 'remark',
      title: 'Remarks',
      type: 'textarea',
      table: { hidden: true },
      form: { rows: 2 },
    },
    {
      key: 'createdAt',
      title: 'Created At',
      type: 'datetime',
      table: { width: 180, sorter: true },
      form: { hidden: true },
      search: { enabled: true, mode: 'range' },
    },
  ]

  // Actions Configuration
  const actions = {
    getList: announcementActions.getAnnouncementListAction,
    getDetail: announcementActions.getAnnouncementDetailAction,
    create: announcementActions.createAnnouncementAction,
    update: announcementActions.updateAnnouncementAction,
    delete: announcementActions.deleteAnnouncementAction,
  }

  return (
    <SmartCrudPage
      title="Announcement Management"
      fieldsConfig={fieldsConfig}
      actions={actions}
      enableCreate={true}
      enableEdit={true}
      enableDelete={true}
      enableDetail={true}
    />
  )
}

Step 3: Add Menu (Optional)

Add a new menu item in the admin panel's "Menu Management" page:

FieldValue
NameAnnouncement Management
URL/admin/content/announcements
IconBellOutlined
Parent MenuContent Management (if exists)
Sort10

โœ… Verification

1. Start Development Server

bun run dev
pnpm run dev
npm run dev
yarn run dev

2. Access Page

Open browser and visit: http://localhost:3000/admin/content/announcements

3. Functionality Testing

  • List displays correctly
  • Click "New" opens form
  • Can save after filling form
  • Click "Edit" can modify data
  • Click "Delete" can delete data
  • Search functionality works
  • Pagination works correctly

๐ŸŽจ Advanced Configuration

Add Custom Row Actions

const customRowActions = [
  {
    key: 'publish',
    label: 'Publish',
    onClick: async (record) => {
      // Custom action logic
      console.log('Publish announcement:', record.id)
    },
    showCondition: (record) => !record.enable,
  },
]

<SmartCrudPage
  // ...other configurations
  customRowActions={customRowActions}
/>

Add Toolbar Buttons

const toolbarExtra = (
  <Button onClick={() => console.log('Export')}>
    Export Data
  </Button>
)

<SmartCrudPage
  // ...other configurations
  toolbarExtra={toolbarExtra}
/>

Use Hooks for Business Logic

Add to crud-action.announcement.js:

const announcementConfig = {
  // ...other configurations
  
  hooks: {
    beforeCreate: async (data) => {
      // Pre-create processing
      console.log('About to create announcement:', data.title)
      return data
    },
    afterCreate: async (record) => {
      // Post-create processing
      console.log('Announcement created successfully:', record.id)
    },
    beforeUpdate: async (id, data) => {
      // Pre-update processing
      return data
    },
    beforeDelete: async (id) => {
      // Pre-delete check
      // If returns false or throws error, deletion will be prevented
      return true
    },
  }
}