Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

krayzed's avatar

Changing a badge based off of date

I am building a tool where I want to manage my vehicles dispatch. Dispatches are required to be done monthly by the 14th of every month. My plan is to make the badges like so: "Dispatched" (success), "Due Soon" (warning), "Over Due" (danger).

I have it in the database where the dispatch date is set to a date ex. 12 Dec 2024. Where can I find a way to determine that it is getting close to the due date?

Thank you for your support!

0 likes
9 replies
LaryAI's avatar
Level 58

To achieve the functionality of changing a badge based on the date, you can use a combination of PHP and JavaScript (or just PHP if you're working server-side only) to determine the status of each dispatch. Here's a simple approach using PHP:

  1. Fetch the dispatch date from the database.
  2. Calculate the difference between the current date and the dispatch date.
  3. Determine the badge status based on the difference.

Here's a basic example using PHP:

<?php
// Example dispatch date from the database
$dispatchDate = '2024-12-12';

// Convert the dispatch date to a DateTime object
$dispatchDateTime = new DateTime($dispatchDate);

// Get the current date
$currentDateTime = new DateTime();

// Calculate the difference in days
$interval = $currentDateTime->diff($dispatchDateTime);
$daysDifference = (int)$interval->format('%r%a');

// Determine the badge status
if ($daysDifference > 14) {
    $badgeStatus = 'Dispatched'; // Success
    $badgeClass = 'success';
} elseif ($daysDifference >= 0 && $daysDifference <= 14) {
    $badgeStatus = 'Due Soon'; // Warning
    $badgeClass = 'warning';
} else {
    $badgeStatus = 'Over Due'; // Danger
    $badgeClass = 'danger';
}

// Output the badge
echo "<span class='badge badge-$badgeClass'>$badgeStatus</span>";
?>

Explanation:

  • DateTime Objects: We use DateTime objects to handle date comparisons easily.
  • Date Difference: The diff method calculates the difference between the current date and the dispatch date.
  • Badge Logic:
    • If the dispatch date is more than 14 days away, it's considered "Dispatched".
    • If the dispatch date is within 14 days, it's "Due Soon".
    • If the dispatch date has passed, it's "Over Due".

Considerations:

  • Time Zones: Ensure that your server's time zone is set correctly, or adjust the DateTime objects to use the correct time zone.
  • Styling: The badge classes (success, warning, danger) are assumed to be styled with CSS. You can use Bootstrap classes or define your own.

This solution should help you dynamically change the badge status based on the dispatch date. Adjust the logic as needed to fit your specific requirements.

viraj's avatar

I assume you are using some column to track whether the vehicle is dispatched.

Option 1

You can use state(function ($record) to set the state for your column and use TextColumn::make('status')->badge() to make a badge column

use Carbon\Carbon;

TextColumn::make('status')
    ->badge()
    ->color(fn(string $state): string => match ($state) {
        'Dispatched' => 'success',
        'Due Soon' => 'warning',
        'Over Due' => 'danger',
    })
    ->state(function ($record) {
        if ($record->dispatched) {
            return 'Dispatched';
        }

        $dispatchDate = Carbon::parse($record->dispatch_date);
        $today = Carbon::today();

        if ($dispatchDate < $today) {
            return 'Over Due';
        } else {
            return 'Due Soon';
        }
    }),

Option 2

If you don't want to keep this logic in your filament file or you want to use the status anywhere else you can move this to model.

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Casts\Attribute;

protected $appends = ['status'];

protected function status(): Attribute
{
    return Attribute::make(
        get: function () {
            if ($this->dispatched) {
                return 'Dispatched';
            }

            $dispatchDate = Carbon::parse($this->dispatch_date);
            $today = Carbon::today();

            if ($dispatchDate < $today) {
                return 'Over Due';
            } else {
                return 'Due Soon';
            }
        }
    );
}

Then you can use the same column code

TextColumn::make('status')
    ->badge()
    ->color(fn(string $state): string => match ($state) {
        'Dispatched' => 'success',
        'Due Soon' => 'warning',
        'Over Due' => 'danger',
    })

Let me know if this works for you.

Merklin's avatar

@viraj The OP didn't say they use Filament. You should have made that clear in your post because if Filament is not used the proposed solution is not applicable.

1 like
krayzed's avatar

@viraj I like option one, and I could some of it to an Enum also.

Yes, I am using a column storing the date() method.

I see that you are retrieving "Todays" date in there. How would I make it where instead of it being today, it would be the 14th of every month would make it overdue? And lets say the 1st of every month makes it due soon?

I know I am asking a lot of questions, but this is super helpful to get me started.

viraj's avatar

Instead of

$today = Carbon::today();

You can use:

$monthlyDueDate = Carbon::today()->startOfMonth()->addDays(13);

This way you can compare it with the 14th of every month. However, I am still not sure about the flow and logic. If you can shed some light, I can provide a better solution

1 like
krayzed's avatar

@viraj Thank you for your continued assistance. As a beginner, it really means a lot.

Vehicle dispatches have to be renewed by the 14th of every month, but the dispatch has to be completed between the 1st and the 14th of the month (due to our job, not all vehicles can go at once).

The plan is to set it up where it'll show on the list and view pages which dispatches still have to be done and how close they are to requiring re-dispatch.

Maybe instead of a badge, a font color change based off of how much time left could be better.

Please or to participate in this conversation.