inertia-page-config

star 15

Create page configuration for a Goravel entity - i18n-aware simple filters with badges, stats cards, page actions, and bulk actions. All config functions receive TFunction.

liwoo By liwoo schedule Updated 2/7/2026

name: inertia-page-config description: Create page configuration for a Goravel entity - i18n-aware simple filters with badges, stats cards, page actions, and bulk actions. All config functions receive TFunction. argument-hint: "[EntityName]" allowed-tools: Read, Write, Edit, Grep, Glob

Inertia Page Configuration (i18n-aware)

Create page config for $ARGUMENTS.

File Location

resources/js/pages/<EntityName>/sections/<EntityName>PageConfig.tsx

Complete Template

import React from 'react';
import { TFunction } from 'i18next';
import { router } from '@inertiajs/react';
import { Upload, Download, BarChart3 } from 'lucide-react';
import {
    StatsCardConfig,
    PageActionConfig,
    SimpleFilterConfig,
} from '@/lib/crud-page-utils';

// =============================================
// Stats Card Configurations
// =============================================
export function getEntityStatsConfigs(t: TFunction): StatsCardConfig[] {
    return [
        {
            title: t('stats.total'),
            getValue: (stats) => stats?.totalCount || 0,
        },
        // {
        //     title: t('stats.active'),
        //     getValue: (stats) => stats?.activeCount || 0,
        //     valueClassName: 'text-green-600',
        // },
        // {
        //     title: t('stats.inactive'),
        //     getValue: (stats) => stats?.inactiveCount || 0,
        //     valueClassName: 'text-red-600',
        // },
    ];
}

// =============================================
// Simple Filters (Tab/Dropdown with Badges)
// =============================================
export function getEntitySimpleFilters(t: TFunction, stats: any): SimpleFilterConfig[] {
    return [
        {
            key: 'status-active',
            label: t('status.active'),
            value: 'ACTIVE',
            badge: stats?.activeCount || 0,
            filterParams: { status: 'ACTIVE' },
        },
        {
            key: 'status-inactive',
            label: t('status.inactive'),
            value: 'INACTIVE',
            badge: stats?.inactiveCount || 0,
            filterParams: { status: 'INACTIVE' },
        },
    ];
}

// =============================================
// Page Actions (Export, Import, etc.)
// =============================================
export function getEntityPageActions(
    t: TFunction,
    permissions: any,
    handlers: {
        onImport?: () => void;
        onExport?: () => void;
    }
): PageActionConfig[] {
    return [
        // {
        //     key: 'import',
        //     label: t('actions.importEntities'),
        //     icon: <Upload className="h-4 w-4" />,
        //     handler: handlers.onImport || (() => {}),
        //     permission: permissions.canCreate,
        // },
        // {
        //     key: 'export',
        //     label: t('actions.exportEntities'),
        //     icon: <Download className="h-4 w-4" />,
        //     handler: handlers.onExport || (() => {}),
        // },
    ];
}

// =============================================
// Bulk Actions
// =============================================
export function getEntityBulkActions(t: TFunction) {
    return {
        handleBulkDelete: (ids: number[]) => {
            const confirmMessage = t('confirm.bulkDelete', { count: ids.length });
            if (confirm(confirmMessage)) {
                router.delete('/api/entity-names/bulk', {
                    data: { ids },
                });
            }
        },
    };
}

Key i18n Pattern: TFunction Parameter

All config functions receive t: TFunction as first parameter because they are plain functions, not React components.

import { TFunction } from 'i18next';

// CORRECT: TFunction as parameter
export function getEntitySimpleFilters(t: TFunction, stats: any): SimpleFilterConfig[] { ... }
export function getEntityStatsConfigs(t: TFunction): StatsCardConfig[] { ... }
export function getEntityPageActions(t: TFunction, permissions: any, handlers: {...}): PageActionConfig[] { ... }
export function getEntityBulkActions(t: TFunction) { ... }

Called from Index.tsx:

const { t } = useTranslation('entities');
const simpleFilters = createSimpleFilters(getEntitySimpleFilters(t, stats));
const pageActions = createPageActions(getEntityPageActions(t, permissions, handlers));

Interpolation in Confirmations

t('confirm.bulkDelete', { count: ids.length })
// JSON: "confirm.bulkDelete": "Are you sure you want to delete {{count}} item(s)?"

Using Simple Filters in Index.tsx

import { createSimpleFilters } from '@/lib/crud-page-utils';
import { getEntitySimpleFilters } from './sections';

const simpleFilters = createSimpleFilters(getEntitySimpleFilters(t, stats));

<CrudPage
    simpleFilters={simpleFilters}
    simpleFiltersVariant="dropdown"         // or "tabs"
    simpleFiltersDropdownLabel={t('filters.status')}
/>

Required Translation Keys

{
  "stats": {
    "total": "Total Entities",
    "active": "Active",
    "inactive": "Inactive"
  },
  "status": {
    "active": "Active",
    "inactive": "Inactive"
  },
  "actions": {
    "importEntities": "Import Entities",
    "exportEntities": "Export Entities"
  },
  "filters": {
    "status": "Status"
  },
  "confirm": {
    "bulkDelete": "Are you sure you want to delete {{count}} item(s)? This action cannot be undone."
  }
}

Barrel Export

Add to resources/js/pages/<EntityName>/sections/index.ts:

export { EntityDetailView } from './EntityDetailView';
export { EntityCreateForm } from './EntityCreateForm';
export { EntityEditForm } from './EntityEditForm';
export { getEntityColumns, getEntityColumnsMobile, getEntityFilters } from './EntityColumns';
export { getEntityStatsConfigs, getEntitySimpleFilters, getEntityPageActions, getEntityBulkActions } from './EntityPageConfig';

Verify

After creating the page config:

# TypeScript compiles
npx tsc --noEmit

# Lint the page config
npx eslint "resources/js/pages/<EntityName>/sections/<EntityName>PageConfig.tsx" --max-warnings=0

Reference

See resources/js/pages/Books/sections/bookPageConfig.tsx for a complete i18n-aware example.

Install via CLI
npx skills add https://github.com/liwoo/goravel-inertia-tw-starter --skill inertia-page-config
Repository Details
star Stars 15
call_split Forks 10
navigation Branch main
article Path SKILL.md
More from Creator