Gantt-Like Grid: Calendar with Colors

Filament 4

This project demonstrates how to build a Gantt-style fleet availability calendar as a Filament dashboard widget. The widget displays a 14-day grid where each row is a car and each cell is color-coded by availability status — available, booked, buffer/cleaning, maintenance, or inactive. It uses eager-loaded relationships for bookings and maintenance logs, a priority-based status resolver with per-car buffer periods, and a custom Blade view with a sticky first column, today highlighting, and dark mode support.

Untitled design

Get the Source Code:

How it works

This project consists of two components: a Filament widget class that builds the availability data and resolves each cell's status, and a Blade view that renders the Gantt-style grid.

1. FleetAvailability Widget — Data Loading & Grid Building

The widget extends Filament's Widget class with a custom Blade view. The getFleetData() method builds the entire grid in a single pass.

app/Filament/Widgets/FleetAvailability.php

class FleetAvailability extends Widget
{
protected static ?int $sort = 2;
 
protected int|string|array $columnSpan = 'full';
 
protected string $view = 'filament.widgets.fleet-availability';
 
public function getFleetData(): array
{
$today = Carbon::today();
$days = collect(range(0, 13))->map(fn (int $offset): Carbon => $today->copy()->addDays($offset));
 
$cars = Car::query()
->orderBy('name')
->with([
'bookings' => function ($query) use ($today) {
$query->whereNotIn('status', [BookingStatus::Cancelled, BookingStatus::NoShow])
->where('dropoff_at', '>=', $today)
->where('pickup_at', '<=', $today->copy()->addDays(14));
},
'maintenanceLogs' => function ($query) use ($today) {
$query->where(function ($q) use ($today) {
$q->where('ended_at', '>=', $today->toDateString())
->orWhereNull('ended_at');
})->where('started_at', '<=', $today->copy()->addDays(14)->toDateString());
},
])
->get();
 
$grid = [];
 
foreach ($cars as $car) {
$row = [
'car' => $car,
'cells' => [],
];
 
foreach ($days as $day) {
$row['cells'][] = [
'date' => $day,
'status' => $this->resolveCellStatus($car, $day),
];
}
 
$grid[] = $row;
}
 
return [
'days' => $days,
'grid' => $grid,
];
}
}

The key points:

The FULL tutorial is available after the purchase: in the Readme file of the official repository you would get invited to.
Get the Source Code: All 158 Premium Examples for $99