feat: show overdue weekly tasks on Dashboard Tasks & Chores card #240

Merged
Copilot merged 3 commits from copilot/update-dashboard-chore-task-cards into main 2026-05-01 19:39:32 +00:00
Copilot commented 2026-05-01 18:46:37 +00:00 (Migrated from github.com)

Weekly-scheduled tasks whose assigned weekday has passed without completion are now surfaced in a dedicated Overdue section at the top of the Dashboard Tasks & Chores card, with colour-coded warning indicators.

Backend

  • DashboardService::getOverdueTasks(): finds schedule_type=weekly tasks (excluding today's day) where last_completed_at is null or predates the most recent occurrence of the scheduled weekday; attaches overdue_days (1–7) as a dynamic attribute; sorted ascending (most recently missed first)
  • getTasksData() return shape gains overdue key alongside today and upcoming
  • Date comparisons use config('app.display_timezone') consistent with TaskService

Frontend

  • DashboardTask interface gains overdue_days?: number; DashboardTasksData gains overdue: DashboardTask[]
  • TaskChip.vue: checks overdue_days before due_date — renders mdi-alert with warning colour (1–2 days) or error colour (3–7 days)
  • TasksSummaryCard.vue: conditional Overdue section above Today, hidden when empty
  • dashboardStore: clearCache, toggleTaskCompletion, and persistence defaults updated for the new list

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (code change that neither fixes a bug nor adds a feature)
  • Performance improvement
  • Test coverage improvement

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this manually (if applicable)

6 new feature tests in DashboardControllerTest: incomplete past-weekday task appears with correct overdue_days, 3-day value, today's task excluded, completed-this-cycle excluded, stale prior-week completion included, sort order.

Code Quality

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors

CI/CD Checks

  • All automated tests pass
  • Code formatting (Pint) passes
  • JavaScript/TypeScript linting passes
  • Build process completes successfully

Additional Notes

overdue_days is set as a dynamic Eloquent attribute before serialisation — no migration required.

Weekly-scheduled tasks whose assigned weekday has passed without completion are now surfaced in a dedicated **Overdue** section at the top of the Dashboard Tasks & Chores card, with colour-coded warning indicators. ### Backend - `DashboardService::getOverdueTasks()`: finds `schedule_type=weekly` tasks (excluding today's day) where `last_completed_at` is null or predates the most recent occurrence of the scheduled weekday; attaches `overdue_days` (1–7) as a dynamic attribute; sorted ascending (most recently missed first) - `getTasksData()` return shape gains `overdue` key alongside `today` and `upcoming` - Date comparisons use `config('app.display_timezone')` consistent with `TaskService` ### Frontend - `DashboardTask` interface gains `overdue_days?: number`; `DashboardTasksData` gains `overdue: DashboardTask[]` - `TaskChip.vue`: checks `overdue_days` before `due_date` — renders `mdi-alert` with `warning` colour (1–2 days) or `error` colour (3–7 days) - `TasksSummaryCard.vue`: conditional **Overdue** section above **Today**, hidden when empty - `dashboardStore`: `clearCache`, `toggleTaskCompletion`, and persistence defaults updated for the new list ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Documentation update - [ ] Refactoring (code change that neither fixes a bug nor adds a feature) - [ ] Performance improvement - [ ] Test coverage improvement ## Testing - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have tested this manually (if applicable) 6 new feature tests in `DashboardControllerTest`: incomplete past-weekday task appears with correct `overdue_days`, 3-day value, today's task excluded, completed-this-cycle excluded, stale prior-week completion included, sort order. ## Code Quality - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [x] My changes generate no new warnings or errors ## CI/CD Checks - [ ] All automated tests pass - [ ] Code formatting (Pint) passes - [ ] JavaScript/TypeScript linting passes - [ ] Build process completes successfully ## Additional Notes `overdue_days` is set as a dynamic Eloquent attribute before serialisation — no migration required.
coderabbitai[bot] commented 2026-05-01 18:46:46 +00:00 (Migrated from github.com)

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: b88c21f2-4816-4f0f-a6db-ca36a6c6b339

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands and usage tips.

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- This is an auto-generated comment: skip review by coderabbit.ai --> > [!IMPORTANT] > ## Review skipped > > Bot user detected. > > To trigger a single review, invoke the `@coderabbitai review` command. > > <details> > <summary>⚙️ Run configuration</summary> > > **Configuration used**: defaults > > **Review profile**: CHILL > > **Plan**: Free > > **Run ID**: `b88c21f2-4816-4f0f-a6db-ca36a6c6b339` > > </details> > > You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file. > > Use the checkbox below for a quick retry: > - [ ] <!-- {"checkboxId": "e9bb8d72-00e8-4f67-9cb2-caf3b22574fe"} --> 🔍 Trigger review <!-- end of auto-generated comment: skip review by coderabbit.ai --> <!-- tips_start --> --- <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end -->
copilot-pull-request-reviewer[bot] (Migrated from github.com) reviewed 2026-05-01 18:54:25 +00:00
copilot-pull-request-reviewer[bot] (Migrated from github.com) left a comment

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an “Overdue” section to the Dashboard Tasks & Chores card to surface weekly tasks whose scheduled day has passed without completion, including an overdue_days indicator used for warning/error styling.

Changes:

  • Backend: DashboardService::getTasksData() now returns an overdue list computed by a new getOverdueTasks() helper using the display timezone.
  • Frontend: store/types and dashboard UI updated to accept/render overdue tasks; TaskChip shows an alert icon and color based on overdue_days.
  • Tests/docs: feature tests added for overdue weekly task behavior; DEVLOG/CHANGELOG updated.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/Feature/Http/Controllers/DashboardControllerTest.php Adds feature tests asserting overdue inclusion/exclusion rules, overdue_days, and sort order.
resources/js/stores/dashboardStore.ts Extends tasks data shape with overdue and updates cache/persistence + completion toggling.
resources/js/Pages/Dashboard/Partials/TasksSummaryCard.vue Renders a conditional “Overdue” section above “Today”.
resources/js/Pages/Dashboard.vue Plumbs tasksData.overdue into TasksSummaryCard.
resources/js/Components/Calendar/TaskChip.vue Adds overdue-specific icon + color logic based on overdue_days.
app/Services/DashboardService.php Implements overdue weekly task detection with overdue_days and returns it in tasks payload.
DEVLOG.md Documents the new overdue dashboard behavior and related code changes.
CHANGELOG.md Announces the new overdue section and indicator thresholds.
## Pull request overview > [!NOTE] > Copilot was unable to run its full agentic suite in this review. Adds an “Overdue” section to the Dashboard Tasks & Chores card to surface weekly tasks whose scheduled day has passed without completion, including an `overdue_days` indicator used for warning/error styling. **Changes:** - Backend: `DashboardService::getTasksData()` now returns an `overdue` list computed by a new `getOverdueTasks()` helper using the display timezone. - Frontend: store/types and dashboard UI updated to accept/render overdue tasks; `TaskChip` shows an alert icon and color based on `overdue_days`. - Tests/docs: feature tests added for overdue weekly task behavior; DEVLOG/CHANGELOG updated. ### Reviewed changes Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments. <details> <summary>Show a summary per file</summary> | File | Description | | ---- | ----------- | | tests/Feature/Http/Controllers/DashboardControllerTest.php | Adds feature tests asserting overdue inclusion/exclusion rules, `overdue_days`, and sort order. | | resources/js/stores/dashboardStore.ts | Extends tasks data shape with `overdue` and updates cache/persistence + completion toggling. | | resources/js/Pages/Dashboard/Partials/TasksSummaryCard.vue | Renders a conditional “Overdue” section above “Today”. | | resources/js/Pages/Dashboard.vue | Plumbs `tasksData.overdue` into `TasksSummaryCard`. | | resources/js/Components/Calendar/TaskChip.vue | Adds overdue-specific icon + color logic based on `overdue_days`. | | app/Services/DashboardService.php | Implements overdue weekly task detection with `overdue_days` and returns it in tasks payload. | | DEVLOG.md | Documents the new overdue dashboard behavior and related code changes. | | CHANGELOG.md | Announces the new overdue section and indicator thresholds. | </details>
@ -44,0 +114,4 @@
if ($isIncomplete) {
$task->overdue_days = $daysAgo;
$overdueTasks[] = $task;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-01 18:54:24 +00:00

orderBy('priority', 'desc') is effectively discarded because the result is later reordered with usort() by overdue_days. Either remove this DB ordering to avoid unnecessary work, or incorporate priority as a secondary key in the final sort (e.g., sort by overdue_days asc, then priority desc) so the query ordering remains meaningful.

`orderBy('priority', 'desc')` is effectively discarded because the result is later reordered with `usort()` by `overdue_days`. Either remove this DB ordering to avoid unnecessary work, or incorporate `priority` as a secondary key in the final sort (e.g., sort by `overdue_days` asc, then `priority` desc) so the query ordering remains meaningful.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-01 18:54:24 +00:00

The usort comparator only compares overdue_days, so ties are not deterministically ordered (and can vary between runs). If stable ordering matters (e.g., keep priority ordering for equal overdue_days), add a secondary/tertiary comparison (such as priority desc, then id asc) to ensure deterministic output.

        // Sort ascending so most-recently-overdue tasks appear first.
        // Use deterministic tie-breakers so tasks with the same overdue_days
        // keep a consistent order.
        usort($overdueTasks, static function ($a, $b): int {
            $overdueDaysComparison = $a->overdue_days <=> $b->overdue_days;
            if ($overdueDaysComparison !== 0) {
                return $overdueDaysComparison;
            }

            $priorityComparison = $b->priority <=> $a->priority;
            if ($priorityComparison !== 0) {
                return $priorityComparison;
            }

            return $a->id <=> $b->id;
        });
The `usort` comparator only compares `overdue_days`, so ties are not deterministically ordered (and can vary between runs). If stable ordering matters (e.g., keep priority ordering for equal `overdue_days`), add a secondary/tertiary comparison (such as `priority` desc, then `id` asc) to ensure deterministic output. ```suggestion // Sort ascending so most-recently-overdue tasks appear first. // Use deterministic tie-breakers so tasks with the same overdue_days // keep a consistent order. usort($overdueTasks, static function ($a, $b): int { $overdueDaysComparison = $a->overdue_days <=> $b->overdue_days; if ($overdueDaysComparison !== 0) { return $overdueDaysComparison; } $priorityComparison = $b->priority <=> $a->priority; if ($priorityComparison !== 0) { return $priorityComparison; } return $a->id <=> $b->id; }); ```
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-01 18:54:25 +00:00

This template block is hard to read/maintain due to inline tags and split closing tags across lines (e.g., </v-card-text followed by >), which also makes future diffs noisier. Reformat the markup so tags/attributes are on consistent lines and closing tags aren’t broken across lines; this reduces the risk of accidental template syntax issues and improves reviewability.

This template block is hard to read/maintain due to inline tags and split closing tags across lines (e.g., `</v-card-text` followed by `>`), which also makes future diffs noisier. Reformat the markup so tags/attributes are on consistent lines and closing tags aren’t broken across lines; this reduces the risk of accidental template syntax issues and improves reviewability.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-01 18:54:25 +00:00

Toggling completion updates items in-place in the overdue list, which can leave completed tasks still displayed under the “Overdue” section until a refresh, and can retain a stale overdue_days attribute on the client object. To keep the UI consistent with the section semantics, consider either (a) removing the task from tasksData.overdue when it becomes completed (and optionally clearing overdue_days), or (b) refetching/reconciling tasksData after the toggle succeeds so list membership is recalculated by the backend.

Toggling completion updates items in-place in the `overdue` list, which can leave completed tasks still displayed under the “Overdue” section until a refresh, and can retain a stale `overdue_days` attribute on the client object. To keep the UI consistent with the section semantics, consider either (a) removing the task from `tasksData.overdue` when it becomes completed (and optionally clearing `overdue_days`), or (b) refetching/reconciling `tasksData` after the toggle succeeds so list membership is recalculated by the backend.
@ -120,0 +163,4 @@
'last_completed_at' => null,
]);
$response = $this->getJson(route('api.dashboard.tasks'));
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-01 18:54:25 +00:00

These tests freeze time without pinning the timezone used by the production code (DashboardService uses config('app.display_timezone')). If app.display_timezone differs from the default timezone used by Carbon::setTestNow() in the test environment, the perceived weekday can shift and make the suite flaky. Consider explicitly setting the display timezone in the test (via config override) and/or setting testNow with an explicit timezone-aware Carbon instance.

            $this->originalDisplayTimezone = config('app.display_timezone');
            config(['app.display_timezone' => 'UTC']);

            Carbon::setTestNow(Carbon::parse('2026-05-06 10:00:00', 'UTC')); // Wednesday
            $this->actingAs($this->user);
        });

        afterEach(function () {
            Carbon::setTestNow();
            config(['app.display_timezone' => $this->originalDisplayTimezone]);
These tests freeze time without pinning the timezone used by the production code (`DashboardService` uses `config('app.display_timezone')`). If `app.display_timezone` differs from the default timezone used by `Carbon::setTestNow()` in the test environment, the perceived weekday can shift and make the suite flaky. Consider explicitly setting the display timezone in the test (via config override) and/or setting `testNow` with an explicit timezone-aware Carbon instance. ```suggestion $this->originalDisplayTimezone = config('app.display_timezone'); config(['app.display_timezone' => 'UTC']); Carbon::setTestNow(Carbon::parse('2026-05-06 10:00:00', 'UTC')); // Wednesday $this->actingAs($this->user); }); afterEach(function () { Carbon::setTestNow(); config(['app.display_timezone' => $this->originalDisplayTimezone]); ```
Sign in to join this conversation.
No description provided.