A powerful Laravel package that streamlines CRUD operations with a dynamic form builder and robust API integration. Build complex admin interfaces in minutes with our flexible, feature-rich solution.
- Dynamic Form Builder with multiple field types
- Built-in Laravel API integration
- Beautiful UI with Tailwind & DaisyUI
- Integrated permission system
- Highly customizable components
- Responsive design
- SPA experience with Inertia.js
- Laravel 8.x or higher
- PHP 8.0 or higher
- Tailwind CSS
- DaisyUI
- Inertia.js
composer require mariojgt/builder
php artisan install::builder
This command will:
- Copy required assets
- Run migrations
- Set up configuration files
- Install necessary dependencies
Add the following routes to your web.php
or route file:
use Mariojgt\Builder\Controllers\TableBuilderApiController;
Route::controller(TableBuilderApiController::class)->group(function () {
Route::post('/admin/api/generic/table', 'index')
->name('admin.api.generic.table');
Route::post('/admin/api/generic/table/create', 'store')
->name('admin.api.generic.table.create');
Route::post('/admin/api/generic/table/update', 'update')
->name('admin.api.generic.table.update');
Route::post('/admin/api/generic/table/delete', 'delete')
->name('admin.api.generic.table.delete');
});
Here's a basic example of implementing the Builder in your controller:
<?php
namespace Mariojgt\GameDev\Controllers\Backend;
use Inertia\Inertia;
use Mariojgt\GameDev\Models\Alert;
use App\Http\Controllers\Controller;
use Mariojgt\Builder\Enums\FieldTypes;
use Mariojgt\Builder\Helpers\FormHelper;
use Mariojgt\Builder\Enums\PermissionEnum;;
class AlertController extends Controller
{
public function index()
{
$breadcrumb = [
[
'label' => 'Alerts',
'url' => route('gamedev.alert.index'),
]
];
$form = new FormHelper();
$formConfig = $form
->addIdField()
// ->addIdField(label: 'product_id', key: 'product_id') // custom id field
->tab('General Info')
->addField(
label: 'Title',
key: 'title',
sortable: true,
type: FieldTypes::TEXT->value
)->withRules([ // You can pass laravel validation rules in the withRules method
'required',
'min:3',
new AlertTitleValidator()
])
// Example 2 with custom error message
->withRules([
'required',
'min:3',
new AlertTitleValidator()
], ['min' => 'Please add at least 3 characters'])
->addField(
label: 'HTML Content',
key: 'html_content',
sortable: false,
type: FieldTypes::EDITOR->value
)
->tab('Settings')
->addField(
label: 'Type',
key: 'type',
sortable: true,
type: FieldTypes::SELECT->value,
options: [
'info' => 'Information',
'warning' => 'Warning',
'error' => 'Error',
'maintenance' => 'Maintenance'
],
)
->addField(
label: 'Icon',
key: 'icon',
sortable: false,
type: FieldTypes::SELECT->value,
options: [
'AlertTriangle' => 'Warning Triangle',
'AlertCircle' => 'Info Circle',
'AlertOctagon' => 'Error Octagon',
'Clock' => 'Clock',
'Bell' => 'Bell',
'Info' => 'Info'
],
)
->addField(
label: 'Theme',
key: 'theme',
sortable: true,
type: FieldTypes::SELECT->value,
options: [
'dark' => 'Dark Theme',
'light' => 'Light Theme'
],
)
->addField(
label: 'Button Text',
key: 'button_text',
sortable: false,
type: FieldTypes::TEXT->value,
)
->addField(
label: 'Button Icon',
key: 'button_icon',
sortable: false,
type: FieldTypes::SELECT->value,
options: [
'Eye' => 'Eye',
'Check' => 'Checkmark',
'X' => 'Close',
'ThumbsUp' => 'Thumbs Up'
],
)
->addField(
label: 'Enabled',
key: 'is_enabled',
sortable: true,
type: FieldTypes::BOOLEAN->value,
)
->addField(
label: 'Full Screen',
key: 'is_full_screen',
sortable: true,
type: FieldTypes::BOOLEAN->value,
)
->addField(
label: 'Scheduled At',
key: 'scheduled_at',
sortable: true,
canEdit: false,
type: FieldTypes::TIMESTAMP->value,
)
->addField(
label: 'Start At',
key: 'start_at',
sortable: true,
canEdit: false,
type: FieldTypes::TIMESTAMP->value,
)
->addField(
label: 'End At',
key: 'end_at',
sortable: true,
canEdit: false,
type: FieldTypes::TIMESTAMP->value,
)
->addField(
label: 'Dismissible',
key: 'is_dismissible',
sortable: true,
type: FieldTypes::BOOLEAN->value,
)
->addField(
label: 'Display Order',
key: 'display_order',
sortable: true,
type: FieldTypes::NUMBER->value,
)
->setEndpoints(
listEndpoint: route('admin.api.generic.table'),
deleteEndpoint: route('admin.api.generic.table.delete'),
createEndpoint: route('admin.api.generic.table.create'),
editEndpoint: route('admin.api.generic.table.update')
)
->setModel(Alert::class)
->setPermissions(
guard: 'skeleton_admin',
type: 'permission',
permissions: [
'store' => PermissionEnum::CreatePermission->value,
'update' => PermissionEnum::EditPermission->value,
'delete' => PermissionEnum::DeletePermission->value,
'index' => PermissionEnum::ReadPermission->value,
]
)
->build();
return Inertia::render('BackEnd/Vendor/GameDev/Generic/Index', [
'title' => 'Alerts | Index',
'table_name' => 'alerts',
'breadcrumb' => $breadcrumb,
...$formConfig
]);
}
}
// Table filters example
$form = new FormHelper();
$formConfig = $form
->addIdField()
->tab('General Info')
->addField(
label: 'Name',
key: 'name',
sortable: true,
canCreate: true,
canEdit: true,
type: FieldTypes::TEXT->value,
filterable: true // Enable filtering for this field
)
->addField(
label: 'Is Active',
key: 'is_active',
sortable: true,
type: FieldTypes::BOOLEAN->value,
canCreate: true,
canEdit: true,
filterable: true
)
->addField(
label: 'Created At',
key: 'created_at',
type: FieldTypes::DATE->value,
filterable: true,
filterOptions: ['type' => 'date-range']
)
->addField(
label: 'Status',
key: 'status',
type: FieldTypes::SELECT->value,
options: [
'select_options' => [
['value' => 'active', 'label' => 'Active'],
['value' => 'inactive', 'label' => 'Inactive'],
['value' => 'pending', 'label' => 'Pending']
]
],
filterable: true
)
// ... rest of your fields
Vue js example
<template>
<Table :columns="props.columns" :model="props.model" :endpoint="props.endpoint"
:endpoint-delete="props.endpointDelete" :endpoint-create="props.endpointCreate"
:endpoint-edit="props.endpointEdit" :table-title="props.title" :permission="props.permission"
:defaultSortKey="props.defaultSortKey" />
</template>
<script setup>
// Import the table component from the builder api
import Table from "@builder/Table.vue";
const props = defineProps({
endpoint: {
type: String,
default: "",
},
columns: {
type: Object,
default: () => ({}),
},
model: {
type: String,
default: "",
},
endpointDelete: {
type: String,
default: "",
},
endpointCreate: {
type: String,
default: "",
},
endpointEdit: {
type: String,
default: "",
},
permission: {
type: String,
default: "",
},
title: {
type: String,
default: "",
},
defaultSortKey: {
type: String,
default: "",
},
});
</script>
Builder supports various field types:
text
- Text inputemail
- Email inputpassword
- Password inputdate
- Date pickertimestamp
- Datetime pickerselect
- Dropdown selectboolean
- Toggle switchmedia
- Media uploadeditor
- Rich text editornumber
- Number inputmodel_search
- Model relationship searchpivot_model
- Many-to-many relationshipchips
- Tags/chips inputicon
- Icon selector
Builder includes built-in permission support:
- Role-based access control
- Permission-based access control
- Encrypted permission handling
- Customizable guards
You can customize:
- Field types and validation
- UI components and styling
- API endpoints
- Permission handling
- Form layouts and sections
- Error handling and display
- Loading states and animations
Builder requires the following Node dependencies:
"@headlessui/vue": "^1.7.23"
"@inertiajs/vue3": "^2.0.3"
"@mariojgt/masterui": "^0.5.6"
"@mariojgt/wind-notify": "^1.0.3"
"lucide-vue-next": "^0.474.0",
Vite configuration:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import tailwindcss from '@tailwindcss/vite'
import path from 'path';
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './resources'),
'@css': path.resolve(__dirname, './resources/css'), // Used in the builder plugins to point ot the css
'@components': path.resolve(__dirname, './resources/js/components'),
'@builder': '/resources/vendor/Builder/Table',
},
},
server: {
host: '0.0.0.0',
hmr: {
host: 'localhost'
},
},
plugins: [
tailwindcss(),
laravel({
input: ['resources/js/app.js', 'resources/css/app.css'],
refresh: true,
}),
vue(),
],
});
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
If you found this package helpful, please consider giving it a star on GitHub!