5 Commits

Author SHA1 Message Date
redz1029 2946945ce3 fix(programmer-tasks): tab switching + help-given live data
Tab switching: _buildTabs was recreating TabController on every build
because `_tabs == tabs` compares List by reference identity, not content.
programmerTasksTabsFor() always returns a new list, so the guard was
always false, resetting the controller to initialIndex 0 on every tap.
Fixed by using listEquals from flutter/foundation.

Help given: computeProgrammerStats accumulated helpGivenThisMonth only
from approvedSnapshot rows, which only exist after admin approval.
Programmers who helped others but had pending sheets saw 0m indefinitely.
Fixed by adding helpGivenThisMonthProvider (FutureProvider.family) that
queries programmer_task_work_logs directly for the current Manila month,
and passing it as liveHelpThisMonthSec to computeProgrammerStats.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-28 22:25:25 +08:00
redz1029 2585cce36d feat(programmer): sheet-driven stats, monitor status, drill-down history
- Wire daySheetsForUserProvider(userId) into ProgrammerDashboard so
  computeProgrammerStats/computeBadges receive real sheet data instead of
  the placeholder const <ProgrammerDaySheet>[].
- Monitor tab: watch allDaySheetsProvider and build sheetStatusByUser map
  for today; pass it to buildMonitorEntries; add "Sheets pending" chip
  (pending + disapproved today) to the summary row.
- ProgrammerDrillDownScreen: add _RecentDaySheetsPanel below the dashboard
  showing the last 10 sheets (date + status pill) with tap-to-daySheetDetail.
- DaySheetDetailScreen (T17 gaps): replace const [] liveRows with
  programmerDayDataProvider(sheet.workDate) built rows for non-approved
  sheets; fix _onApprove timer check to filter only the sheet programmer's
  own tasks (QN-1).
- Add test/programmer_drill_down_test.dart (3 tests, all passing).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-28 18:29:28 +08:00
redz1029 a7fd1e74f1 feat(programmer): dashboard stat tiles + badges
Add StatTiles and BadgesStrip widgets wired into ProgrammerDashboard.

StatTiles shows 2 tiles (focus + completed) when showSheetStats is false,
and 5 tiles (+ streak, first-pass approval, help given) when the viewing
user's role is programmer. BadgesStrip renders earned/locked chips in a
horizontal Wrap with tap-to-dialog detail.

Dashboard feeds todayFocus via buildDayRows/totalSeconds, leaveDays via
approvedLeaveDays, and sheets: const [] until Task 20 wires real data.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-27 22:13:43 +08:00
redz1029 9a40ffec81 fix(programmer): move clock ticker watch to dashboard parent
NowWorkingCard was watching clockTickerProvider but received pre-computed
Duration values from ProgrammerDashboard, which never rebuilt on ticks.
Move ref.watch(clockTickerProvider) to ProgrammerDashboard.build() so
the parent rebuilds every 30 s and passes fresh durations to the card.
Remove the now-unused clockTickerProvider watch (and its import) from
NowWorkingCard.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-27 21:59:01 +08:00
redz1029 29bcbcaa4d feat(programmer): Mine dashboard hero + task sections
Replace the Mine tab flat list with ProgrammerDashboard — a NowWorkingCard
hero (running task with Pause/Complete, or idle with nextUp Start), a
TODO stub for Task 8 stat tiles/badges, and collapsible TaskSections
(In progress, Paused, Not started always-visible; Completed/Cancelled
start collapsed with Show-all at 10+). groupTasksForDashboard excludes
other assignees and sorts completed/cancelled by terminal date desc.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-09-27 21:52:13 +08:00