Admin Panel para Laravel 11: Orchid

uso del panel de administración Orchid

Laravel 11 y Orchid

Orchid Documentation

Añadir el panel Orchid al proyecto Todo

ssh usuario@alumno.me
cd ~/todo

 

Crear el proyecto

Ya está creado

 

Añadir dependencia

composer require orchid/platform

 

Instalar paquete

php artisan orchid:install

 

Crear usuario de administración

php artisan orchid:admin admin admin@alumno.me malaga2324

 

Acceder al panel de administración y asignarroles a los usuarios

laravel.alumno.me/admin

Editar usuarios

Crear un nuevo usuario

Crear roles administrator y guest

Asignar roles a los usuarios

Modificación del panel
fichero app/Orchid/PlatformProvider.php

comentar las opciones del menú

->active(‘* /examples/form/*’),

    public function menu(): array
    {
        return [
/*
            Menu::make('Get Started')
                ->icon('bs.book')
                ->title('Navigation')
                ->route(config('platform.index')),

            Menu::make('Sample Screen')
                ->icon('bs.collection')
                ->route('platform.example')
                ->badge(fn () => 6),

            Menu::make('Form Elements')
                ->icon('bs.card-list')
                ->route('platform.example.fields')
                ->active('* /examples/form/*'),

            Menu::make('Overview Layouts')
                ->icon('bs.window-sidebar')
                ->route('platform.example.layouts'),

            Menu::make('Grid System')
                ->icon('bs.columns-gap')
                ->route('platform.example.grid'),

            Menu::make('Charts')
                ->icon('bs.bar-chart')
                ->route('platform.example.charts'),

            Menu::make('Cards')
                ->icon('bs.card-text')
                ->route('platform.example.cards')
                ->divider(),
*/
            Menu::make(__('Users'))
                ->icon('bs.people')
                ->route('platform.systems.users')
                ->permission('platform.systems.users')
                ->title(__('Access Controls')),

            Menu::make(__('Roles'))
                ->icon('bs.shield')
                ->route('platform.systems.roles')
                ->permission('platform.systems.roles')
                ->divider(),

            Menu::make('Documentation')
                ->title('Docs')
                ->icon('bs.box-arrow-up-right')
                ->url('https://orchid.software/en/docs')
                ->target('_blank'),
/*
            Menu::make('Changelog')
                ->icon('bs.box-arrow-up-right')
                ->url('https://github.com/orchidsoftware/platform/blob/master/CHANGELOG.md')
                ->target('_blank')
                ->badge(fn () => Dashboard::version(), Color::DARK),
*/
        ];
    }

 

Instalación de CRUD

composer require orchid/crud

 

Crear el modelo

Ya existe Task.php

php artisan make:model Task -m (no ejecutar el comando, porque ya está creado el modelo Task.php)

Modificar el fichero Fichero Task.php

Añadir

use Orchid\Attachment\Attachable;
use Orchid\Filters\Filterable;
use Orchid\Screen\AsSource;

class Task extends Model
{
    use HasFactory;
    use AsSource, Filterable, Attachable;

 

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

use App\Models\User;

use Orchid\Attachment\Attachable;
use Orchid\Filters\Filterable;
use Orchid\Screen\AsSource;

class Task extends Model
{
    use HasFactory;
    use AsSource, Filterable, Attachable;
    
    protected $fillable = ['description'];

    public function user()
    {
    	return $this->belongsTo(User::class);
    }
}

modificar create_tasks_table.php

php artisan migrate

 

Crear un recurso para las tareas

php artisan orchid:resource TaskResource

modificar el fichero app/Orchid/Resources/TaskResource.php

use \App\Models\Task;
use Orchid\Screen\Fields\Input;
// use Orchid\Screen\TD;
use Orchid\Screen\Sight;
class TaskResource extends Resource
{
    /**
    * The model the resource corresponds to.
    *
    * @var string
    */
    publicstatic$model = Task::class;
public function fields(): array
{
    return [
        Input::make('description')
        ->title('Description')
        ->placeholder('Enter description here'),

        Input::make('user_id')
        ->title('User ID')
        ->placeholder('Enter user_id here'),
    ];
}
public function columns(): array
{
    return [
       TD::make('id'),
       TD::make('description'),
       TD::make('user_id'),
       TD::make('created_at', 'Date of creation')
       ->render(function ($model) {
       return $model->created_at->toDateTimeString();
       }),
       TD::make('updated_at', 'Update date')
       ->render(function ($model) {
       return $model->updated_at->toDateTimeString();
       }),
    ];
}
public function legend(): array
{
    return [
        Sight::make('id'),
        Sight::make('description'),
        Sight::make('user_id'),
    ];
}

fichero app/Orchid/Resources/TaskResource.php

<?php

namespace App\Orchid\Resources;

use Orchid\Crud\Resource;
use Orchid\Screen\TD;

use \App\Models\Task;

use Orchid\Screen\Fields\Input;
// use Orchid\Screen\TD;
use Orchid\Screen\Sight;

class TaskResource extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = Task::class;

    /**
     * Get the fields displayed by the resource.
     *
     * @return array
     */
    public function fields(): array
    {
        return [
            Input::make('description')
            ->title('Description')
            ->placeholder('Enter description here'),

            Input::make('user_id')
            ->title('User ID')
            ->placeholder('Enter user_id here'),
        ];
    }

    /**
     * Get the columns displayed by the resource.
     *
     * @return TD[]
     */
    public function columns(): array
    {
        return [
            TD::make('id'),

            TD::make('description'),

            TD::make('user_id'),

            TD::make('created_at', 'Date of creation')
                ->render(function ($model) {
                    return $model->created_at->toDateTimeString();
                }),

            TD::make('updated_at', 'Update date')
                ->render(function ($model) {
                    return $model->updated_at->toDateTimeString();
                }),
        ];
    }

    /**
     * Get the sights displayed by the resource.
     *
     * @return Sight[]
     */
    public function legend(): array
    {
        return [
            Sight::make('id'),
            Sight::make('description'),
            Sight::make('user_id'),
        ];
    }

    /**
     * Get the filters available for the resource.
     *
     * @return array
     */
    public function filters(): array
    {
        return [];
    }
}

 

Acceso al CRUD

laravel.alumno.me/dashboard

TasksController.php

App\Models\User::getCasts()?

No funciona el Dashboard!

 

modificar app/Models/User.php

añadir la relación 1 a muchos

public function tasks()
{
return $this->hasMany(Task::class);
}

añadir la configuración para verificar el email

fichero app/Models/User.php

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;

use Orchid\Filters\Types\Like;
use Orchid\Filters\Types\Where;
use Orchid\Filters\Types\WhereDateStartEnd;
use Orchid\Platform\Models\User as Authenticatable;

use App\Models\Task;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'email_verified_at',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array<int, string>
     */
    protected $appends = [
        'profile_photo_url',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    protected $allowedFilters = [
           'id'         => Where::class,
           'name'       => Like::class,
           'email'      => Like::class,
           'updated_at' => WhereDateStartEnd::class,
           'created_at' => WhereDateStartEnd::class,
    ];

    /**
     * The attributes for which can use sort in url.
     *
     * @var array
     */
    protected $allowedSorts = [
        'id',
        'name',
        'email',
        'updated_at',
        'created_at',
    ];

    public function tasks()
    {
    	return $this->hasMany(Task::class);
    }
    
}


 

Añadir la entrada Admin en el menú de la página principal

modificar el fichero resources/views/welcome.blade.php

añadir este código antes de login y register:

<a href="{{ url('/admin') }}" class="text-sm text-gray-700 underline dark:text-white">Admin</a>
&nbsp;
<body class="antialiased">
    <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
        @if (Route::has('login'))
            <div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
                @auth
                    <a href="{{ url('/dashboard') }}" class="text-sm text-gray-700 underline">Dashboard</a>
                @else
                    <a href="{{ url('/admin') }}" class="text-sm text-gray-700 underline dark:text-white">Admin</a>
                    &nbsp;
                    <a href="{{ route('login') }}" class="text-sm text-gray-700 underline dark:text-white">Log in</a>
                    @if (Route::has('register'))
                        <a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 underline dark:text-white">Register</a>
                    @endif
                @endauth
            </div>
        @endif

 

CRUD de caballos

crear el modelo

php artisan make:model Horse -m

modificar el fichero app/Models/Horse.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

use Orchid\Attachment\Attachable;
use Orchid\Filters\Filterable;
use Orchid\Screen\AsSource;

class Horse extends Model
{
    use HasFactory;
    use AsSource, Filterable, Attachable;
    
    protected $fillable = ['name','description','birthday','available','photo','link','price'];

}

modificar fichero database/migrations/create_horses_table.php

añadir los campos de la tabla horses en la función up()

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('horses', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('description')->nullable(true);
            $table->date('birthday')->nullable(true);
            $table->boolean('available')->default(true);
            $table->string('photo')->nullable(true);
            $table->string('link')->nullable(true);
            $table->integer('price')->nullable(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('horses');
    }
};

realizar la migración para crear la tabla horses

php artisan migrate

crear el recurso

php artisan orchid:resource HorseResource

Modificar el recurso HorseResource para poner los campos

https://orchid.software/en/docs/field

modificar el fichero app/Orchid/Resources/HorseResource.php

<?php

namespace App\Orchid\Resources;

use Orchid\Crud\Resource;
use Orchid\Screen\TD;

use \App\Models\Horse;

use Orchid\Screen\Fields\Input;
// use Orchid\Screen\TD;
use Orchid\Screen\Sight;

use Orchid\Screen\Fields\TextArea;
use Orchid\Screen\Fields\DateTimer;
use Orchid\Screen\Fields\CheckBox;
use Orchid\Screen\Fields\Upload;

class HorseResource extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = Horse::class;

    /**
     * Get the fields displayed by the resource.
     *
     * @return array
     */
    public function fields(): array
        {
        return [
            Input::make('name')
            ->title('Name')
            ->placeholder('Enter name here'),

            TextArea::make('description')
            ->title('Description')
            ->placeholder('Enter description here')
            ->rows(2),

            DateTimer::make('birthday')
            ->title('Birthday')
            ->placeholder('Enter birthday here')
            ->format('Y-m-d'),

            CheckBox::make('available')
            ->value(1)
            ->title('Available')
            ->placeholder('Enter available here')
            ->help('Is available the horse?'),

            Input::make('photo')
            ->title('Photo')
            ->placeholder('Enter photo here'),
/*
            Upload::make('photo')
            ->title('Photo')
            ->placeholder('Enter photo here'),
            //->maxFileSize(1024), // Size in MB            
*/
            Input::make('link')
            ->title('Link')
            ->placeholder('Enter link here'),

            Input::make('price')
            ->title('Price')
            ->placeholder('Enter price here'),
        ];
    }

    /**
     * Get the columns displayed by the resource.
     *
     * @return TD[]
     */
    public function columns(): array
    {
        return [
            TD::make('id'),

            TD::make('name'),

            TD::make('description'),

            TD::make('birthday'),

            TD::make('unavailable'),

            TD::make('photo'),

            TD::make('link'),

            TD::make('price'),

            TD::make('created_at', 'Date of creation')
                ->render(function ($model) {
                    return $model->created_at->toDateTimeString();
                }),

            TD::make('updated_at', 'Update date')
                ->render(function ($model) {
                    return $model->updated_at->toDateTimeString();
                }),
        ];
    }

    /**
     * Get the sights displayed by the resource.
     *
     * @return Sight[]
     */
    public function legend(): array
    {
        return [
            Sight::make('id'),
            Sight::make('name'),
            Sight::make('description'),
            Sight::make('birthday'),
            Sight::make('unavailable'),
            Sight::make('photo'),
            Sight::make('link'),
            Sight::make('price'),
        ];
    }
    /**
     * Get the filters available for the resource.
     *
     * @return array
     */
    public function filters(): array
    {
        return [];
    }
}

 

Limpiar la caché de Laravel

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

 

Prueba

laravel.alumno.me

TODO:

Subir una foto del caballo

establecer una relación 1 a muchos entre caballos y reservas

mostrar únicamente las reservas de cada usuario en Orchid?

 

Más información:

How to Use a One-to-Many Relationship in Laravel

Deja una respuesta