Add budget progress gauge inside mobile category buttons

Each depense/epargne category button on the mobile quick-entry form
now shows a fill bar plus percentage of its monthly budget already
tracked, so the user sees at a glance which categories are close to
their limit while picking one. Categories without a budget defined
in Plan show no gauge (avoids a misleading 0%). Capped at 100% —
overspend detail already lives on the dashboard's "Manque" column.

3 new Pest tests for the percentage calculation (normal, capped,
no-budget cases). 61/61 tests pass, Pint clean, verified on mobile
against production data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jeremy bayse
2026-07-26 12:48:29 +02:00
co-authored by Claude Sonnet 5
parent 5861fc49fc
commit 613220f43a
3 changed files with 113 additions and 5 deletions
+48
View File
@@ -184,6 +184,54 @@ it('shows the recurrence again the following month after being confirmed', funct
expect($component->viewData('pendingRecurrences')->pluck('id'))->toContain($recurring->id);
});
it('computes the percentage of budget already tracked for a category this month', function (): void {
$this->travelTo(now()->setDate(2026, 3, 10));
$user = User::factory()->create();
$household = $user->currentHousehold;
$category = $household->categories()->create(['name' => 'Loyer', 'type' => 'depense', 'position' => 1]);
$category->budgetLines()->create(['household_id' => $household->id, 'year' => 2026, 'month' => null, 'amount' => 1000]);
$household->transactions()->create([
'category_id' => $category->id, 'user_id' => $user->id,
'date' => '2026-03-05', 'date_effective' => '2026-03-05', 'amount' => 600,
]);
$component = Livewire::actingAs($user)->test(Index::class);
expect($component->viewData('categoryProgress')[$category->id])->toBe(60.0);
});
it('caps the category progress percentage at 100', function (): void {
$this->travelTo(now()->setDate(2026, 3, 10));
$user = User::factory()->create();
$household = $user->currentHousehold;
$category = $household->categories()->create(['name' => 'Loyer', 'type' => 'depense', 'position' => 1]);
$category->budgetLines()->create(['household_id' => $household->id, 'year' => 2026, 'month' => null, 'amount' => 1000]);
$household->transactions()->create([
'category_id' => $category->id, 'user_id' => $user->id,
'date' => '2026-03-05', 'date_effective' => '2026-03-05', 'amount' => 1500,
]);
$component = Livewire::actingAs($user)->test(Index::class);
expect($component->viewData('categoryProgress')[$category->id])->toBe(100);
});
it('returns no progress for a category without a budget defined', function (): void {
$this->travelTo(now()->setDate(2026, 3, 10));
$user = User::factory()->create();
$household = $user->currentHousehold;
$category = $household->categories()->create(['name' => 'Loyer', 'type' => 'depense', 'position' => 1]);
$component = Livewire::actingAs($user)->test(Index::class);
expect($component->viewData('categoryProgress')[$category->id])->toBeNull();
});
it('does not show another household transactions', function (): void {
$ownerA = User::factory()->create();
$ownerB = User::factory()->create();