I am migrating the back office of a project developed using classic Laravel 10 to Filament 3.
I have understood the CRUD system in Filament 3, and the documentation is quite clear. However, I have a page in my back office with a complex table that calls multiple models. This table is supposed to display the menus of an establishment over 7 days. For each day, there are 3 meals, and for each meal, there are several recipes/dishes with the number of servings.
It doesn’t seem possible to use the standard Filament functions because it’s not really a classic CRUD. Therefore, I decided to create a custom page, which seems to be the best solution since the page needs to call multiple models and has a very specific design with various manipulations (moving a menu from one day to another by drag-and-drop, moving a menu item similarly, adding guests, etc.).
My current problem is that I cannot create a modal that displays the content of a specific model. Here, it’s about $recettemenu
.
Another question: Is this the right direction to create a complex page?
Here’s my setup:
I created my page, and I have the app/Filament/Pages/Menu.php
file with the following content:
namespace AppFilamentPages;
use CarbonCarbon;
use CarbonCarbonPeriod;
use AppModelsRecette;
use AppModelsRecettesMenu;
use FilamentActionsAction;
use FilamentFormsComponentsTextInput;
use FilamentPagesPage;
use IlluminateHttpRequest;
class Menu extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.menu';
public $debutsemaine;
public $finsemaine;
public $dates = [];
public $recettes = [];
public $matinmidisoir;
public $entreeplatdessert;
public $allrecette = [];
public $recette;
public function mount(Request $request)
{
$next = $request->input('next');
$last = $request->input('last');
$datedebut = $request->input('datedebut');
if (isset($next)) {
$this->debutsemaine = Carbon::parse($next)->nextWeekday()->format('d-M-y');
$this->finsemaine = Carbon::parse($this->debutsemaine)->nextWeekday()->endOfWeek()->format('d-M-y');
} elseif (isset($last)) {
$this->debutsemaine = Carbon::parse($last)->previous(Carbon::MONDAY)->format('d-M-y');
$this->finsemaine = Carbon::parse($this->debutsemaine)->endOfWeek()->format('d-M-y');
} elseif (isset($datedebut)) {
$this->debutsemaine = Carbon::parse($datedebut)->format('d-M-y');
$this->finsemaine = Carbon::parse($this->debutsemaine)->endOfWeek()->format('d-M-y');
} else {
$this->debutsemaine = Carbon::now()->startOfWeek()->format('d-M-y');
$this->finsemaine = Carbon::now()->endOfWeek()->format('d-M-y');
}
$period = new CarbonPeriod(Carbon::parse($this->debutsemaine), 7);
foreach ($period as $date) {
$this->dates[] = $date->format('Y-m-d');
}
$this->recettes = Recette::all()->pluck('nomrecette', 'id')->prepend(trans('global.pleaseSelect'), '')->toArray();
$this->matinmidisoir = ['Midi', 'Gouter', 'Soir'];
$this->entreeplatdessert = ['Entree' => 'Entree', 'Plat' => 'Plat', 'Dessert' => 'Dessert'];
$this->allrecette = RecettesMenu::with('recette')
->whereDate('date', '>=', Carbon::parse($this->debutsemaine))
->whereDate('date', '<=', Carbon::parse($this->finsemaine))
->get()
->toArray();
}
public function showmenuAction($recetteId = null): Action
{
return Action::make('showmenu')
->label('Voir le menu')
->modalHeading('Détails du Menu')
->modalContent(function () use ($recetteId) {
$this->recette = Recette::where('id', $recetteId)->first();
$recette = $this->recette; // Ensure the variable is defined correctly
return view('filament.pages.modal-menu', compact('recette'));
})
->form([
TextInput::make('recetteId')
->label('ID de la recette')
->default($recetteId)
->hidden(),
]);
}
}
And on the other side, I have my Blade file in resources/views/filament/pages/menu.blade.php
where I have a loop like this:
@foreach ($allrecette as $recettemenu)
@if ($recettemenu['perioderepas'] == $period && $recettemenu['entreeplatdessert'] == $entreeplatdessertd2 && CarbonCarbon::parse($recettemenu['date'])->isSameDay(CarbonCarbon::parse($date)))
<div class="">
<a href="#" class="text-blue-600 hover:underline">
{{ $recettemenu['recette']['nomrecette'] }}
</a>
{{ ($this->showmenuAction)(['recetteId' => '46']) }}
<span id="prixrecette_{{ $recettemenu['id'] }}" class="{{ $period }}_{{ CarbonCarbon::parse($date)->format('d-m-Y') }}">{{ $recettemenu['prixrecette'] }}€</span>
<input type="text" id="nbpersonnerecette_{{ $recettemenu['id'] }}" name="nbpersonnerepas" class="align-middle border rounded w-1/6 h-3 p-1.5 text-[12px]" value="{{ $recettemenu['nbpersonne'] }}">
</div>
@endif
@endforeach
How can I correctly create a modal that displays the content of a specific model (in this case, $recettemenu)?
Is creating a custom page the right approach for building a complex page with various models and specific design requirements?
Any help or guidance would be greatly appreciated! Thank you.