Filament Custom Widgets: Create an Order Status Widget

The Filament admin panel has Charts, Tables and Stats Widgets by default. we can create our own custom widgets too.

we are going to create custom a widget that shows the status of an order in an e-commerce website.

Create Widget Class and View file

i installed Filament and in the panel, I created an OrderResource.

each order have an edit page that we can see the details of the order.

the goal is to create a status widget above the input fields.

first run this command:

php artisan make:filament-widget OrderStatus 

after running the command, it asks us if we want to use the widget inside a resource. respond yes. because we want to display it on the order edit page.

next, it asks us where we want to create it. choose admin panel.

you can also create the widget as a separate livewire component.

now two files are created.

a PHP class for the widget in app/Filament/Resources/CustomerResource/Widgets.

<?php

namespace App\Filament\Resources\YesResource\Widgets;

use Filament\Widgets\Widget;
use Illuminate\Database\Eloquent\Model;


class OrderStatus extends Widget
{

    protected static string $view = 'filament.resources.yes-resource.widgets.order-status';

  
}

a view file in resources/views/filament/resources/customer-resource/widgets.

<x-filament-widgets::widget>
    <x-filament::section>
        {{-- Widget content --}}
    </x-filament::section>
</x-filament-widgets::widget>

in the widget class define a $record property so you can access the current record in the database.

<?php

namespace App\Filament\Resources\YesResource\Widgets;

use Filament\Widgets\Widget;
use Illuminate\Database\Eloquent\Model;


class OrderStatus extends Widget
{
    protected static string $view = 'filament.resources.yes-resource.widgets.order-status';

    public $record;

}

using $record property, I’ll have access to the current order record in the database.

now we are going to write the widget’s UI code in the blade file.

since Filament does not compile all CSS classes except those that are being used, if you want to use Tailwind for styling you need to install a custom theme first.

run this artisan command:

php artisan make:filament-theme

theme.css will be created in resources/css/filament. also we will have tailwind.config.js in the root of the project.

to compile the assets go to vite.config.js and add the created theme address to the input array like this:

input: 
[
//...

'resources/css/filament/admin/theme.css'
],

next, you have to register the theme. go to app\Providers\AdminPanelServiceProvider.php and chain the viteTheme() method to $panel object like so:

//AdminPanelProvider.php
namespace App\Providers\Filament;

//...   
->authMiddleware([
                Authenticate::class,
            ])->viteTheme('resources/css/filament/admin/theme.css');

put the theme address as an argument in the viteTheme method.

Remember that Filament only compiles the CSS classes that your theme is using. so don’t forget to run npm run build after changing the classes in the widget’s blade file.

now we are ready to write the UI code of the widget.

in order-status.blade.php:

<x-filament-widgets::widget>
    <x-filament::section>

        <ul class=" flex ml-auto border-b pb-4">
            @foreach(config('shop.status') as $key => $status)
                <li class="mr-8">

                    {{$status}}

                    <div class="absolute mt-[10px] mx-auto w-3 h-3  rounded-full ml-4
                    {{( $key <= array_search($record->status,config('shop.status')))  ? 'bg-[#1da1f2]' : 'bg-gray-300' }}"></div>
                </li>

            @endforeach
        </ul>

    </x-filament::section>
</x-filament-widgets::widget>

x-filament-widgets::widget and x-filament::section tags exists by default. we should write our code between those tags.

I created a horizontal list of statuses using <ul> and <li> tags.

under every status title, there is a small round shape <div> element .its color changes based on the order’s status.

{{( $key <= array_search($record->status,config('shop.status')))  ? 'bg-[#1da1f2]' : 'bg-gray-300' }}

this code checks the current status and changes the color of its element color as well as all the statuses before it.

the widget is ready now.

we want to use the widget in the edit order page so we have to return the the getHeaderWidgets() method in EditOrder.php

//EditOrder.php
use App\Filament\Resources\YesResource\Widgets\OrderStatus;

class EditOrder extends EditRecord
{
//...


protected function getHeaderWidgets(): array
    {
        return [
            OrderStatus::class,
        ];
    }


//....
}
Filament custom widget that shows the status of an order in an ecommerce website.

you also can place the widget at the bottom of the page instead of the top.

you just need to return the widget in getFooterWidgets method in the resource page Class(EditOrder.php) file:

protected function getFooterWidgets(): array
    {
        return [
            OrderStatus::class,
        ];
    }

Conclusion

this was a simple custom widget for Filament Panel. you can chnage the style however you want. just make sure to run npm run buid to compile the assets.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *