Skip to content

feat(medium): Refactor WorkoutSummary Component#6226

Merged
arii merged 6 commits intoleaderfrom
feat/refactor-workout-summary-card-15603091336728052536
Feb 11, 2026
Merged

feat(medium): Refactor WorkoutSummary Component#6226
arii merged 6 commits intoleaderfrom
feat/refactor-workout-summary-card-15603091336728052536

Conversation

@arii
Copy link
Owner

@arii arii commented Feb 2, 2026

Description

This submission refactors the WorkoutSummary component to a more visually appealing and informative "Card-based Dashboard" using Material UI. It includes a contextual header, visual status indicators, iconography, and improved typography. The parent component has been updated, and the changes have been visually verified.

Fixes #6221

Change Type: ✨ New feature (non-breaking change adding functionality)

PR Scope Checklist

This checklist is mandatory for all PRs.

  • PR has a clear, single purpose: The title and description of the PR clearly state the purpose of the change.
  • All changes relate to the stated objective: The code changes should be directly related to the purpose of the PR.
  • No unrelated cleanup or refactoring: The PR should not contain any changes that are not directly related to the stated objective.
  • Title and description match the actual changes: The title and description should accurately reflect the changes in the PR.
  • Tests cover the specific change scope: The tests should be focused on the changes in the PR and should not include unrelated tests.

Impact Assessment

  • Changes are backward compatible (or breaking changes are documented)
  • Tests are added/updated for new functionality
  • Documentation is updated if needed
  • ADR is created/updated for significant architectural changes
Original PR Body

This submission refactors the WorkoutSummary component to a more visually appealing and informative "Card-based Dashboard" using Material UI, as requested. It includes a contextual header, visual status indicators, iconography, and improved typography. The parent component has been updated, and the changes have been visually verified.

Fixes #6221


PR created automatically by Jules for task 15603091336728052536 started by @arii

@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions github-actions bot changed the title Refactor WorkoutSummary Component feat(medium): Refactor WorkoutSummary Component Feb 2, 2026
@arii
Copy link
Owner Author

arii commented Feb 2, 2026

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ❌ failure
Build ❌ failure
Infra Tests ❌ skipped
Unit Tests ❌ skipped
Component Tests ❌ skipped
Perf Tests ❌ skipped
Visual Tests ❌ skipped

❌ Lint Failure Details


> hrm@0.30.0 lint /home/runner/work/hrm/hrm
> eslint app/ components/ constants/ context/ hooks/ lib/ services/ tests/ types/ utils/ server.ts proxy.ts --cache


/home/runner/work/hrm/hrm/app/client/experimental/components/WorkoutSummary.tsx
   13:11  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   18:23  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   42:22  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   43:21  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   44:23  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   45:15  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   63:53  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   67:11  error  Replace `·sx={{·bgcolor:·'primary.main',·color:·'primary.contrastText',·p:·2·}}` with `⏎········sx={{·bgcolor:·'primary.main',·color:·'primary.contrastText',·p:·2·}}⏎······`                                                                                                 prettier/prettier
   68:15  error  Replace `·direction="row"·justifyContent="space-between"·alignItems="center"` with `⏎··········direction="row"⏎··········justifyContent="space-between"⏎··········alignItems="center"⏎········`                                                                               prettier/prettier
   70:24  error  Replace `·variant="overline"·sx={{·opacity:·0.8,·letterSpacing:·1·}}` with `⏎··············variant="overline"⏎··············sx={{·opacity:·0.8,·letterSpacing:·1·}}⏎············`                                                                                             prettier/prettier
   73:24  error  Replace `·variant="h6"·fontWeight="bold"·sx={{·display:·'flex',·alignItems:·'center',·gap:·1·}}` with `⏎··············variant="h6"⏎··············fontWeight="bold"⏎··············sx={{·display:·'flex',·alignItems:·'center',·gap:·1·}}⏎············`                         prettier/prettier
   85:35  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   89:20  error  Replace `·variant="caption"·sx={{·display:·'block',·mt:·1,·opacity:·0.9·}}` with `⏎··········variant="caption"⏎··········sx={{·display:·'block',·mt:·1,·opacity:·0.9·}}⏎········`                                                                                             prettier/prettier
  104:19  error  Replace `·direction="row"·justifyContent="center"·alignItems="center"·gap={1}·mb={0.5}` with `⏎··············direction="row"⏎··············justifyContent="center"⏎··············alignItems="center"⏎··············gap={1}⏎··············mb={0.5}⏎············`               prettier/prettier
  106:26  error  Replace `·variant="subtitle2"·color="text.secondary"·fontWeight={600}` with `⏎················variant="subtitle2"⏎················color="text.secondary"⏎················fontWeight={600}⏎··············`                                                                     prettier/prettier
  111:42  error  Replace `·unit:·'seconds',·format:·'HH:MM:SS'` with `⏎················unit:·'seconds',⏎················format:·'HH:MM:SS',⏎·············`                                                                                                                                     prettier/prettier
  117:13  error  Replace `·<Stack·direction="row"·justifyContent="center"·alignItems="center"·gap={1}·mb={0.5}` with `<Stack⏎··············direction="row"⏎··············justifyContent="center"⏎··············alignItems="center"⏎··············gap={1}⏎··············mb={0.5}⏎············`  prettier/prettier
  119:26  error  Replace `·variant="subtitle2"·color="text.secondary"·fontWeight={600}` with `⏎················variant="subtitle2"⏎················color="text.secondary"⏎················fontWeight={600}⏎··············`                                                                     prettier/prettier
  138:30  error  Insert `⏎`                                                                                                                                                                                                                                                                    prettier/prettier

✖ 19 problems (19 errors, 0 warnings)
  19 errors and 0 warnings potentially fixable with the `--fix` option.

 ELIFECYCLE  Command failed with exit code 1.

❌ Build Failure Details


> hrm@0.30.0 prebuild /home/runner/work/hrm/hrm
> pnpm run clean


> hrm@0.30.0 clean /home/runner/work/hrm/hrm
> rm -rf .next dist coverage test-results playwright-report *.log *.backup nohup.out diff.txt


> hrm@0.30.0 build /home/runner/work/hrm/hrm
> pnpm run build:server && next build --webpack


> hrm@0.30.0 build:server /home/runner/work/hrm/hrm
> pnpm exec tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json

⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

▲ Next.js 16.1.5 (webpack)
- Environments: .env.local

  Creating an optimized production build ...
✓ Compiled successfully in 25.3s
  Running TypeScript ...
Failed to compile.

./app/client/experimental/components/WorkoutSummary.tsx:4:1
Type error: 'React' is declared but its value is never read.

  2 | 'use client'
  3 |
> 4 | import React from 'react'
    | ^
  5 | import {
  6 |   Card,
  7 |   CardContent,
Next.js build worker exited with code: 1 and signal: null
 ELIFECYCLE  Command failed with exit code 1.

❌ Infrastructure Test Failure Details

Log file not found.

❌ Unit Test Failure Details

Log file not found.

❌ Component Test Failure Details

Log file not found.

❌ Visual Test Failure Details

Log file not found.

❌ Performance Test Failure Details

Log file not found.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 54ddc50a31f1dad2a43494b9dc72448d7080508d

@google-labs-jules
Copy link
Contributor

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ❌ failure
Build ❌ failure
Infra Tests ❌ skipped
Unit Tests ❌ skipped
Component Tests ❌ skipped
Perf Tests ❌ skipped
Visual Tests ❌ skipped

❌ Lint Failure Details


> hrm@0.30.0 lint /home/runner/work/hrm/hrm
> eslint app/ components/ constants/ context/ hooks/ lib/ services/ tests/ types/ utils/ server.ts proxy.ts --cache


/home/runner/work/hrm/hrm/app/client/experimental/components/WorkoutSummary.tsx
   13:11  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   18:23  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   42:22  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   43:21  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   44:23  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   45:15  error  Insert `⏎·······`                                                                                                                                                                                                                                                             prettier/prettier
   63:53  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   67:11  error  Replace `·sx={{·bgcolor:·'primary.main',·color:·'primary.contrastText',·p:·2·}}` with `⏎········sx={{·bgcolor:·'primary.main',·color:·'primary.contrastText',·p:·2·}}⏎······`                                                                                                 prettier/prettier
   68:15  error  Replace `·direction="row"·justifyContent="space-between"·alignItems="center"` with `⏎··········direction="row"⏎··········justifyContent="space-between"⏎··········alignItems="center"⏎········`                                                                               prettier/prettier
   70:24  error  Replace `·variant="overline"·sx={{·opacity:·0.8,·letterSpacing:·1·}}` with `⏎··············variant="overline"⏎··············sx={{·opacity:·0.8,·letterSpacing:·1·}}⏎············`                                                                                             prettier/prettier
   73:24  error  Replace `·variant="h6"·fontWeight="bold"·sx={{·display:·'flex',·alignItems:·'center',·gap:·1·}}` with `⏎··············variant="h6"⏎··············fontWeight="bold"⏎··············sx={{·display:·'flex',·alignItems:·'center',·gap:·1·}}⏎············`                         prettier/prettier
   85:35  error  Insert `,`                                                                                                                                                                                                                                                                    prettier/prettier
   89:20  error  Replace `·variant="caption"·sx={{·display:·'block',·mt:·1,·opacity:·0.9·}}` with `⏎··········variant="caption"⏎··········sx={{·display:·'block',·mt:·1,·opacity:·0.9·}}⏎········`                                                                                             prettier/prettier
  104:19  error  Replace `·direction="row"·justifyContent="center"·alignItems="center"·gap={1}·mb={0.5}` with `⏎··············direction="row"⏎··············justifyContent="center"⏎··············alignItems="center"⏎··············gap={1}⏎··············mb={0.5}⏎············`               prettier/prettier
  106:26  error  Replace `·variant="subtitle2"·color="text.secondary"·fontWeight={600}` with `⏎················variant="subtitle2"⏎················color="text.secondary"⏎················fontWeight={600}⏎··············`                                                                     prettier/prettier
  111:42  error  Replace `·unit:·'seconds',·format:·'HH:MM:SS'` with `⏎················unit:·'seconds',⏎················format:·'HH:MM:SS',⏎·············`                                                                                                                                     prettier/prettier
  117:13  error  Replace `·<Stack·direction="row"·justifyContent="center"·alignItems="center"·gap={1}·mb={0.5}` with `<Stack⏎··············direction="row"⏎··············justifyContent="center"⏎··············alignItems="center"⏎··············gap={1}⏎··············mb={0.5}⏎············`  prettier/prettier
  119:26  error  Replace `·variant="subtitle2"·color="text.secondary"·fontWeight={600}` with `⏎················variant="subtitle2"⏎················color="text.secondary"⏎················fontWeight={600}⏎··············`                                                                     prettier/prettier
  138:30  error  Insert `⏎`                                                                                                                                                                                                                                                                    prettier/prettier

✖ 19 problems (19 errors, 0 warnings)
  19 errors and 0 warnings potentially fixable with the `--fix` option.

 ELIFECYCLE  Command failed with exit code 1.

❌ Build Failure Details


> hrm@0.30.0 prebuild /home/runner/work/hrm/hrm
> pnpm run clean


> hrm@0.30.0 clean /home/runner/work/hrm/hrm
> rm -rf .next dist coverage test-results playwright-report *.log *.backup nohup.out diff.txt


> hrm@0.30.0 build /home/runner/work/hrm/hrm
> pnpm run build:server && next build --webpack


> hrm@0.30.0 build:server /home/runner/work/hrm/hrm
> pnpm exec tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json

⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

▲ Next.js 16.1.5 (webpack)
- Environments: .env.local

  Creating an optimized production build ...
✓ Compiled successfully in 25.3s
  Running TypeScript ...
Failed to compile.

./app/client/experimental/components/WorkoutSummary.tsx:4:1
Type error: 'React' is declared but its value is never read.

  2 | 'use client'
  3 |
> 4 | import React from 'react'
    | ^
  5 | import {
  6 |   Card,
  7 |   CardContent,
Next.js build worker exited with code: 1 and signal: null
 ELIFECYCLE  Command failed with exit code 1.

❌ Infrastructure Test Failure Details

Log file not found.

❌ Unit Test Failure Details

Log file not found.

❌ Component Test Failure Details

Log file not found.

❌ Visual Test Failure Details

Log file not found.

❌ Performance Test Failure Details

Log file not found.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 54ddc50a31f1dad2a43494b9dc72448d7080508d

Thanks for the feedback. I've fixed the build and linting issues.

@arii
Copy link
Owner Author

arii commented Feb 2, 2026

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ✅ success
Build ✅ success
Infra Tests ✅ success
Unit Tests ✅ success
Component Tests ✅ success
Perf Tests ✅ success
Visual Tests ❌ failure

❌ Visual Test Failure Details

      - Expected an image 1232px by 205px, received 1232px by 220px. 153407 pixels (ratio 0.57 of all image pixels) are different.
      - waiting 100ms before taking screenshot
      - waiting for getByTestId('workout-summary')
        - locator resolved to <div data-testid="workout-summary" class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation4 MuiCard-root mui-oqorxg">…</div>
      - taking element screenshot
        - disabled all CSS animations
      - waiting for fonts to load...
      - fonts loaded
      - attempting scroll into view action
        - waiting for element to be stable
      - captured a stable screenshot
      - Expected an image 1232px by 205px, received 1232px by 220px. 153407 pixels (ratio 0.57 of all image pixels) are different.


       at lib/visual.ts:52

      50 |   await checkAccessibility(target)
      51 |
    > 52 |   await expect(target).toHaveScreenshot(snapshotName, {
         |                        ^
      53 |     ...SCREENSHOT_OPTIONS,
      54 |     ...options,
      55 |   })
        at takeScreenshot (/home/runner/work/hrm/hrm/tests/playwright/lib/visual.ts:52:24)
        at /home/runner/work/hrm/hrm/tests/playwright/vrt-workout-summary.spec.ts:33:5

    attachment #1: workout-summary-active (image/png) ──────────────────────────────────────────────
    Expected: tests/playwright/vrt-workout-summary.spec.ts-snapshots/workout-summary-active-chromium-linux.png
    Received: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-actual.png
    Diff:     test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-diff.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #2: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-2.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #3: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-3.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #4: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/error-context.md

  1 failed
    [chromium] › tests/playwright/vrt-workout-summary.spec.ts:27:3 › WorkoutSummary Component VRT › active state 
  18 passed (5.6m)
 ELIFECYCLE  Command failed with exit code 1.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 5c0c42dd6168005ee7399182cffbe712f8904e69

@google-labs-jules
Copy link
Contributor

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ✅ success
Build ✅ success
Infra Tests ✅ success
Unit Tests ✅ success
Component Tests ✅ success
Perf Tests ✅ success
Visual Tests ❌ failure

❌ Visual Test Failure Details

      - Expected an image 1232px by 205px, received 1232px by 220px. 153407 pixels (ratio 0.57 of all image pixels) are different.
      - waiting 100ms before taking screenshot
      - waiting for getByTestId('workout-summary')
        - locator resolved to <div data-testid="workout-summary" class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation4 MuiCard-root mui-oqorxg">…</div>
      - taking element screenshot
        - disabled all CSS animations
      - waiting for fonts to load...
      - fonts loaded
      - attempting scroll into view action
        - waiting for element to be stable
      - captured a stable screenshot
      - Expected an image 1232px by 205px, received 1232px by 220px. 153407 pixels (ratio 0.57 of all image pixels) are different.


       at lib/visual.ts:52

      50 |   await checkAccessibility(target)
      51 |
    > 52 |   await expect(target).toHaveScreenshot(snapshotName, {
         |                        ^
      53 |     ...SCREENSHOT_OPTIONS,
      54 |     ...options,
      55 |   })
        at takeScreenshot (/home/runner/work/hrm/hrm/tests/playwright/lib/visual.ts:52:24)
        at /home/runner/work/hrm/hrm/tests/playwright/vrt-workout-summary.spec.ts:33:5

    attachment #1: workout-summary-active (image/png) ──────────────────────────────────────────────
    Expected: tests/playwright/vrt-workout-summary.spec.ts-snapshots/workout-summary-active-chromium-linux.png
    Received: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-actual.png
    Diff:     test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-diff.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #2: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-2.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #3: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-3.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #4: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/error-context.md

  1 failed
    [chromium] › tests/playwright/vrt-workout-summary.spec.ts:27:3 › WorkoutSummary Component VRT › active state 
  18 passed (5.6m)
 ELIFECYCLE  Command failed with exit code 1.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 5c0c42dd6168005ee7399182cffbe712f8904e69

I'm acknowledging the visual regression test failure. I've been unable to update the snapshots due to persistent timeouts in the test environment. However, the UI changes have been manually verified via a screenshot during the frontend verification step and match the expected design.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ✅ success
Build ✅ success
Infra Tests ✅ success
Unit Tests ✅ success
Component Tests ✅ success
Perf Tests ✅ success
Visual Tests ❌ failure

❌ Visual Test Failure Details

      - Expected an image 1232px by 205px, received 1232px by 220px. 153387 pixels (ratio 0.57 of all image pixels) are different.
      - waiting 100ms before taking screenshot
      - waiting for getByTestId('workout-summary')
        - locator resolved to <div data-testid="workout-summary" class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation4 MuiCard-root mui-oqorxg">…</div>
      - taking element screenshot
        - disabled all CSS animations
      - waiting for fonts to load...
      - fonts loaded
      - attempting scroll into view action
        - waiting for element to be stable
      - captured a stable screenshot
      - Expected an image 1232px by 205px, received 1232px by 220px. 153387 pixels (ratio 0.57 of all image pixels) are different.


       at lib/visual.ts:52

      50 |   await checkAccessibility(target)
      51 |
    > 52 |   await expect(target).toHaveScreenshot(snapshotName, {
         |                        ^
      53 |     ...SCREENSHOT_OPTIONS,
      54 |     ...options,
      55 |   })
        at takeScreenshot (/home/runner/work/hrm/hrm/tests/playwright/lib/visual.ts:52:24)
        at /home/runner/work/hrm/hrm/tests/playwright/vrt-workout-summary.spec.ts:33:5

    attachment #1: workout-summary-active (image/png) ──────────────────────────────────────────────
    Expected: tests/playwright/vrt-workout-summary.spec.ts-snapshots/workout-summary-active-chromium-linux.png
    Received: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-actual.png
    Diff:     test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-diff.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #2: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-2.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #3: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-3.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #4: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/error-context.md

  1 failed
    [chromium] › tests/playwright/vrt-workout-summary.spec.ts:27:3 › WorkoutSummary Component VRT › active state 
  18 passed (5.6m)
 ELIFECYCLE  Command failed with exit code 1.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 71b49147b5c87c9d65be777abb7c8a7222b54509

@google-labs-jules
Copy link
Contributor

📋 Quality Gate Results

Check Status
Knip ✅ success
Lint ✅ success
Build ✅ success
Infra Tests ✅ success
Unit Tests ✅ success
Component Tests ✅ success
Perf Tests ✅ success
Visual Tests ❌ failure

❌ Visual Test Failure Details

      - Expected an image 1232px by 205px, received 1232px by 220px. 153387 pixels (ratio 0.57 of all image pixels) are different.
      - waiting 100ms before taking screenshot
      - waiting for getByTestId('workout-summary')
        - locator resolved to <div data-testid="workout-summary" class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation4 MuiCard-root mui-oqorxg">…</div>
      - taking element screenshot
        - disabled all CSS animations
      - waiting for fonts to load...
      - fonts loaded
      - attempting scroll into view action
        - waiting for element to be stable
      - captured a stable screenshot
      - Expected an image 1232px by 205px, received 1232px by 220px. 153387 pixels (ratio 0.57 of all image pixels) are different.


       at lib/visual.ts:52

      50 |   await checkAccessibility(target)
      51 |
    > 52 |   await expect(target).toHaveScreenshot(snapshotName, {
         |                        ^
      53 |     ...SCREENSHOT_OPTIONS,
      54 |     ...options,
      55 |   })
        at takeScreenshot (/home/runner/work/hrm/hrm/tests/playwright/lib/visual.ts:52:24)
        at /home/runner/work/hrm/hrm/tests/playwright/vrt-workout-summary.spec.ts:33:5

    attachment #1: workout-summary-active (image/png) ──────────────────────────────────────────────
    Expected: tests/playwright/vrt-workout-summary.spec.ts-snapshots/workout-summary-active-chromium-linux.png
    Received: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-actual.png
    Diff:     test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/workout-summary-active-diff.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #2: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-2.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #3: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-3.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    attachment #4: screenshot (image/png) ──────────────────────────────────────────────────────────
    test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: test-results/vrt-workout-summary-Workou-48a8b--Component-VRT-active-state-chromium-retry2/error-context.md

  1 failed
    [chromium] › tests/playwright/vrt-workout-summary.spec.ts:27:3 › WorkoutSummary Component VRT › active state 
  18 passed (5.6m)
 ELIFECYCLE  Command failed with exit code 1.

⚠️ Some checks failed. Full logs available in workflow artifacts.


Report generated for commit: 71b49147b5c87c9d65be777abb7c8a7222b54509

I have successfully updated the visual regression test snapshots for the WorkoutSummary component. The tests are now passing with the new card-based design.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

Reviewed commit: 160ec0ac9ce9ba1231eb314050422cecd825efa1

Summary

This PR introduces a significant and positive refactor of the WorkoutSummary component. The visual presentation has been greatly enhanced, and the component now displays more relevant information such as user name and workout date. The integration with Material-UI's theming system is well-executed, leveraging useTheme() and the sx prop extensively, aligning with the DESIGN_GUIDELINES.md.

Strengths

  • Enhanced UI/UX: The component's visual design is a major improvement, providing a more structured and informative summary of workout data.
  • MUI Integration: Excellent use of MUI components (Card, Chip, Stack, Divider, Typography, Box) and the project's theme values, ensuring consistency and adherence to DESIGN_GUIDELINES.md.
  • Readability: The getStatusColor helper function is a good example of extracting logic for clarity and reducing repetition (DRY principle).
  • Responsive Design: The use of direction={{ xs: 'column', sm: 'row' }} in the Stack demonstrates consideration for responsiveness.

Issues

⚠️ Blocking: Insufficient Test Coverage for New Logic

The WorkoutSummary component has undergone a substantial refactor, introducing new logic, props, and complex JSX. While the Visual Regression Test (VRT) snapshot was updated (as indicated by vrt-workout-summary.spec.ts-snapshots in the diff), this primarily verifies visual output. New logical elements, such as the getStatusColor function and the handling of default prop values for userName and date, are not covered by explicit unit tests.

Per DEVELOPMENT.md (Core Principles: Quality & Security First) and TESTING_GUIDELINES.md, critical logic should have dedicated unit tests to ensure correctness and prevent regressions. Relying solely on VRT for a refactor of this magnitude is insufficient.

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Add unit tests for the WorkoutSummary component, specifically covering the getStatusColor logic and default prop behavior.

💡 Important: Misleading Line Count & Refactoring Opportunities

The pull request's context indicated "~0 Lines Changed" and "Net Change: ~0", however, the actual diff shows a net increase of 93 lines of code (133 additions, 40 deletions). While the added features and improved UI justify some increase, CODE_REVIEW_GUIDELINES.md (Section 4: Track Lines of Code) emphasizes paying attention to the net change and looking for refactoring opportunities to reduce codebase size. A significant increase during a refactor should prompt a review for potential over-engineering or opportunities for further consolidation.

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Review the new implementation for opportunities to further consolidate or simplify the JSX/logic, potentially reducing the overall line count without sacrificing functionality or readability. Consider if any sub-components could be extracted for better modularity.

🧐 Nice-to-have: Prop Type Clarity and User Context

The userName and date props now have default values ('Guest User' and new Date()). While practical for ensuring a fallback, the implication of 'Guest User' might suggest a more integrated user context (e.g., from an authentication system or user settings service).

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Consider if userName should always be derived from a global user state or prop-drilled more explicitly rather than relying on a default that might mask missing user data. If date is always intended to be new Date(), the default is fine; otherwise, document its expected source.

Verdict

Request Changes

Reviewed at commit: 160ec0ac9ce9ba1231eb314050422cecd825efa1

@google-labs-jules
Copy link
Contributor

Reviewed commit: 160ec0ac9ce9ba1231eb314050422cecd825efa1

Summary

This PR introduces a significant and positive refactor of the WorkoutSummary component. The visual presentation has been greatly enhanced, and the component now displays more relevant information such as user name and workout date. The integration with Material-UI's theming system is well-executed, leveraging useTheme() and the sx prop extensively, aligning with the DESIGN_GUIDELINES.md.

Strengths

  • Enhanced UI/UX: The component's visual design is a major improvement, providing a more structured and informative summary of workout data.
  • MUI Integration: Excellent use of MUI components (Card, Chip, Stack, Divider, Typography, Box) and the project's theme values, ensuring consistency and adherence to DESIGN_GUIDELINES.md.
  • Readability: The getStatusColor helper function is a good example of extracting logic for clarity and reducing repetition (DRY principle).
  • Responsive Design: The use of direction={{ xs: 'column', sm: 'row' }} in the Stack demonstrates consideration for responsiveness.

Issues

⚠️ Blocking: Insufficient Test Coverage for New Logic

The WorkoutSummary component has undergone a substantial refactor, introducing new logic, props, and complex JSX. While the Visual Regression Test (VRT) snapshot was updated (as indicated by vrt-workout-summary.spec.ts-snapshots in the diff), this primarily verifies visual output. New logical elements, such as the getStatusColor function and the handling of default prop values for userName and date, are not covered by explicit unit tests.

Per DEVELOPMENT.md (Core Principles: Quality & Security First) and TESTING_GUIDELINES.md, critical logic should have dedicated unit tests to ensure correctness and prevent regressions. Relying solely on VRT for a refactor of this magnitude is insufficient.

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Add unit tests for the WorkoutSummary component, specifically covering the getStatusColor logic and default prop behavior.

💡 Important: Misleading Line Count & Refactoring Opportunities

The pull request's context indicated "~0 Lines Changed" and "Net Change: ~0", however, the actual diff shows a net increase of 93 lines of code (133 additions, 40 deletions). While the added features and improved UI justify some increase, CODE_REVIEW_GUIDELINES.md (Section 4: Track Lines of Code) emphasizes paying attention to the net change and looking for refactoring opportunities to reduce codebase size. A significant increase during a refactor should prompt a review for potential over-engineering or opportunities for further consolidation.

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Review the new implementation for opportunities to further consolidate or simplify the JSX/logic, potentially reducing the overall line count without sacrificing functionality or readability. Consider if any sub-components could be extracted for better modularity.

🧐 Nice-to-have: Prop Type Clarity and User Context

The userName and date props now have default values ('Guest User' and new Date()). While practical for ensuring a fallback, the implication of 'Guest User' might suggest a more integrated user context (e.g., from an authentication system or user settings service).

  • File: app/client/experimental/components/WorkoutSummary.tsx
  • Recommendation: Consider if userName should always be derived from a global user state or prop-drilled more explicitly rather than relying on a default that might mask missing user data. If date is always intended to be new Date(), the default is fine; otherwise, document its expected source.

Verdict

Request Changes

Reviewed at commit: 160ec0ac9ce9ba1231eb314050422cecd825efa1

I've addressed the feedback by adding unit tests for WorkoutSummary, refactoring the component to extract a MetricBlock sub-component to reduce complexity and line count, and making userName a required prop with explicit fallback in the parent component. I've also updated the VRT snapshots and ensured all tests/lint/build pass.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

Reviewed commit: 684978fa4c5b85fe9625227e563b074d59b6ff86

Code Review: Refactor WorkoutSummary Component (PR #6226)

This PR introduces a significant refactor of the WorkoutSummary component, transforming it into a more detailed and visually rich display. The changes largely align with the project's design and development guidelines.

Strengths

  • Improved UI/UX: The refactored WorkoutSummary component offers a much more informative and aesthetically pleasing overview of workout sessions, adhering to the principles outlined in docs/DESIGN_GUIDELINES.md.
  • MUI Adherence: The component correctly utilizes Material-UI components, the project's theme (useTheme), and the sx prop for styling, as mandated by docs/DESIGN_GUIDELINES.md and .github/copilot-instructions.md (Component-Driven Precision with MUI).
  • DRY Principle: The introduction of the MetricBlock sub-component effectively reuses display logic for individual metrics (duration, calories), demonstrating adherence to the

Reviewed at commit: 684978fa4c5b85fe9625227e563b074d59b6ff86

@arii arii added enhancement New feature or request testing frontend labels Feb 3, 2026
@google-labs-jules
Copy link
Contributor

Reviewed commit: 684978fa4c5b85fe9625227e563b074d59b6ff86

Code Review: Refactor WorkoutSummary Component (PR #6226)

This PR introduces a significant refactor of the WorkoutSummary component, transforming it into a more detailed and visually rich display. The changes largely align with the project's design and development guidelines.

Strengths

  • Improved UI/UX: The refactored WorkoutSummary component offers a much more informative and aesthetically pleasing overview of workout sessions, adhering to the principles outlined in docs/DESIGN_GUIDELINES.md.
  • MUI Adherence: The component correctly utilizes Material-UI components, the project's theme (useTheme), and the sx prop for styling, as mandated by docs/DESIGN_GUIDELINES.md and .github/copilot-instructions.md (Component-Driven Precision with MUI).
  • DRY Principle: The introduction of the MetricBlock sub-component effectively reuses display logic for individual metrics (duration, calories), demonstrating adherence to the

Reviewed at commit: 684978fa4c5b85fe9625227e563b074d59b6ff86

Thank you for the positive review! I'm glad the refactor meets the design guidelines and improves the overall UI/UX.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

Reviewed commit: 77c3436dcdb3d196ad084010a9096da303e1d55a

Code Review: Refactor WorkoutSummary Component

This PR introduces a substantial refactor of the WorkoutSummary component, significantly enhancing its visual presentation and internal structure. The changes demonstrate a strong adherence to the project's design principles and best practices.

Strengths

  • Improved UI/UX: The component's visual design is greatly improved, utilizing a clear hierarchy, themed colors, and consistent spacing, aligning well with the DESIGN_GUIDELINES.md.
  • MUI Component Usage: Excellent use of Material-UI components (Card, Stack, Chip, Divider, Box, Typography) and the sx prop for styling, ensuring consistency with the project's design system.
  • Modularity & DRY: The introduction of the MetricBlock sub-component is a fantastic example of the Don't Repeat Yourself (DRY) principle, encapsulating common display logic for workout metrics and improving code maintainability.
  • Theme Integration: Proper usage of useTheme() and theme.palette for colors and spacing is evident, reinforcing the global theme integration outlined in DESIGN_GUIDELINES.md.
  • Type Safety: The component definition and props are well-typed, and there are no instances of any type usage, adhering to the strict type safety rules in .github/copilot-instructions.md.
  • Comprehensive Testing: A new unit test file (WorkoutSummary.test.tsx) has been added, providing good coverage for the refactored component's functionality, including prop handling, status-based styling, and conditional rendering. The VRT snapshot update is also expected and confirms visual changes are captured.

Verdict

This PR is a high-quality refactor that delivers significant improvements to the WorkoutSummary component's design and maintainability. The code is clean, well-tested, and follows project standards.

Reviewed at commit: 77c3436dcdb3d196ad084010a9096da303e1d55a

@google-labs-jules
Copy link
Contributor

Reviewed commit: 77c3436dcdb3d196ad084010a9096da303e1d55a

Code Review: Refactor WorkoutSummary Component

This PR introduces a substantial refactor of the WorkoutSummary component, significantly enhancing its visual presentation and internal structure. The changes demonstrate a strong adherence to the project's design principles and best practices.

Strengths

  • Improved UI/UX: The component's visual design is greatly improved, utilizing a clear hierarchy, themed colors, and consistent spacing, aligning well with the DESIGN_GUIDELINES.md.
  • MUI Component Usage: Excellent use of Material-UI components (Card, Stack, Chip, Divider, Box, Typography) and the sx prop for styling, ensuring consistency with the project's design system.
  • Modularity & DRY: The introduction of the MetricBlock sub-component is a fantastic example of the Don't Repeat Yourself (DRY) principle, encapsulating common display logic for workout metrics and improving code maintainability.
  • Theme Integration: Proper usage of useTheme() and theme.palette for colors and spacing is evident, reinforcing the global theme integration outlined in DESIGN_GUIDELINES.md.
  • Type Safety: The component definition and props are well-typed, and there are no instances of any type usage, adhering to the strict type safety rules in .github/copilot-instructions.md.
  • Comprehensive Testing: A new unit test file (WorkoutSummary.test.tsx) has been added, providing good coverage for the refactored component's functionality, including prop handling, status-based styling, and conditional rendering. The VRT snapshot update is also expected and confirms visual changes are captured.

Verdict

This PR is a high-quality refactor that delivers significant improvements to the WorkoutSummary component's design and maintainability. The code is clean, well-tested, and follows project standards.

Reviewed at commit: 77c3436dcdb3d196ad084010a9096da303e1d55a

Thank you for the positive review! I'm glad the refactor and additional tests meet the project standards.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

Reviewed commit: 762a12656fe6f0e9450f66a272bedc8645dbf4b9

Refactor of WorkoutSummary Component

This PR introduces a significant refactor of the WorkoutSummary component, transforming it from a basic display to a more feature-rich and visually appealing summary card. The changes align well with the project's design principles and technical guidelines.

Strengths

  • MUI Adherence: The refactor leverages Material-UI components (Card, Chip, Divider, Stack, Box, Typography) and the project's theme (useTheme, sx prop, theme.palette) extensively, adhering to the "Component-Driven Precision with MUI" guideline in .github/copilot-instructions.md and docs/DESIGN_GUIDELINES.md.
  • Improved Structure and Reusability: The introduction of the MetricBlock sub-component is an excellent example of the DRY (Don't Repeat Yourself) principle, improving code reusability and readability for displaying individual metrics. This aligns with docs/CODE_REVIEW_GUIDELINES.md.
  • Type Safety: The component's props are well-typed, and no any types or unsafe assertions are used, which is critical for maintaining strict type safety as per docs/TYPESCRIPT_PATTERNS.md and .github/copilot-instructions.md.
  • New Unit Tests: A new unit test file, WorkoutSummary.test.tsx, has been added, providing good coverage for component rendering, prop handling, and conditional styling logic. This addresses the "TEST COVERAGE ALERT" mentioned in the task context and ensures the new component behaves as expected.
  • Clearer UI/UX: The new design is much more informative and visually engaging, incorporating user name, formatted date, and distinct status indicators, which directly addresses the intent of a UI/UX improvement.

Issues

No blocking issues found. The increase in lines of code for WorkoutSummary.tsx is justified by the significant UI/UX overhaul and the introduction of a reusable sub-component, which adds functionality and structure rather than just verbosity.

Test Coverage

Test coverage for the WorkoutSummary component is now adequate, with WorkoutSummary.test.tsx covering core rendering and logic. The visual regression test snapshot for vrt-workout-summary.spec.ts has updated as expected due to the UI changes.

Recommendations

  • Date Formatting Consistency: While toLocaleDateString is good, consider centralizing date formatting logic in lib/utils.ts if similar formatting is or will be required across multiple components to ensure consistency. This is a minor frontend-improvement that could be addressed in a follow-up. Currently, it's fine as-is.

Verdict

This PR successfully refactors the WorkoutSummary component, significantly improving its UI and code structure while adhering to project guidelines. The addition of dedicated unit tests is a strong positive.

Reviewed at commit: 762a12656fe6f0e9450f66a272bedc8645dbf4b9

@arii arii added the tested label Feb 3, 2026
@google-labs-jules
Copy link
Contributor

Reviewed commit: 762a12656fe6f0e9450f66a272bedc8645dbf4b9

Refactor of WorkoutSummary Component

This PR introduces a significant refactor of the WorkoutSummary component, transforming it from a basic display to a more feature-rich and visually appealing summary card. The changes align well with the project's design principles and technical guidelines.

Strengths

  • MUI Adherence: The refactor leverages Material-UI components (Card, Chip, Divider, Stack, Box, Typography) and the project's theme (useTheme, sx prop, theme.palette) extensively, adhering to the "Component-Driven Precision with MUI" guideline in .github/copilot-instructions.md and docs/DESIGN_GUIDELINES.md.
  • Improved Structure and Reusability: The introduction of the MetricBlock sub-component is an excellent example of the DRY (Don't Repeat Yourself) principle, improving code reusability and readability for displaying individual metrics. This aligns with docs/CODE_REVIEW_GUIDELINES.md.
  • Type Safety: The component's props are well-typed, and no any types or unsafe assertions are used, which is critical for maintaining strict type safety as per docs/TYPESCRIPT_PATTERNS.md and .github/copilot-instructions.md.
  • New Unit Tests: A new unit test file, WorkoutSummary.test.tsx, has been added, providing good coverage for component rendering, prop handling, and conditional styling logic. This addresses the "TEST COVERAGE ALERT" mentioned in the task context and ensures the new component behaves as expected.
  • Clearer UI/UX: The new design is much more informative and visually engaging, incorporating user name, formatted date, and distinct status indicators, which directly addresses the intent of a UI/UX improvement.

Issues

No blocking issues found. The increase in lines of code for WorkoutSummary.tsx is justified by the significant UI/UX overhaul and the introduction of a reusable sub-component, which adds functionality and structure rather than just verbosity.

Test Coverage

Test coverage for the WorkoutSummary component is now adequate, with WorkoutSummary.test.tsx covering core rendering and logic. The visual regression test snapshot for vrt-workout-summary.spec.ts has updated as expected due to the UI changes.

Recommendations

  • Date Formatting Consistency: While toLocaleDateString is good, consider centralizing date formatting logic in lib/utils.ts if similar formatting is or will be required across multiple components to ensure consistency. This is a minor frontend-improvement that could be addressed in a follow-up. Currently, it's fine as-is.

Verdict

This PR successfully refactors the WorkoutSummary component, significantly improving its UI and code structure while adhering to project guidelines. The addition of dedicated unit tests is a strong positive.

Reviewed at commit: 762a12656fe6f0e9450f66a272bedc8645dbf4b9

Thank you for the thorough review and the positive feedback! I appreciate the recommendation regarding centralizing date formatting; it's a great point for future consistency across the app. Glad the refactor and new tests were helpful.

@arii
Copy link
Owner Author

arii commented Feb 3, 2026

Reviewed commit: 832415a0e439cf2924977e94936e6a429befb399

Refactor of WorkoutSummary Component

This PR introduces a significant and highly beneficial refactor of the WorkoutSummary component, transforming it from a basic display into a well-structured, visually appealing, and informative element. The changes align well with the project's DESIGN_GUIDELINES.md by leveraging Material-UI components, the theme, and the sx prop for consistent styling.

Strengths

  • Enhanced UI/UX: The component's visual design is greatly improved, providing a much richer and more user-friendly summary of workout data. The use of Chip for status and icons for metrics enhances clarity.
  • Modularity and Readability: The introduction of the MetricBlock sub-component is an excellent example of applying the DRY principle from docs/CODE_REVIEW_GUIDELINES.md. It significantly reduces repetition and makes the component's structure easier to understand.
  • Consistent Styling: The extensive use of useTheme() and the sx prop for styling ensures adherence to the project's Material-UI design system, as outlined in docs/DESIGN_GUIDELINES.md and enforced by .github/copilot-instructions.md (Component-Driven Precision with MUI).
  • Improved Type Safety: The component's props are well-defined and typed, ensuring robust usage across the application, in line with docs/TYPESCRIPT_PATTERNS.md (Strict Type Safety).
  • Comprehensive Unit Tests: The addition of tests/unit/app/client/experimental/components/WorkoutSummary.test.tsx is a major plus. It covers various states and props, ensuring the refactored component behaves as expected. This directly addresses the TEST COVERAGE ALERT and significantly improves the quality of the PR.

Issues

No blocking issues were found. The changes are well-implemented and demonstrate a strong understanding of the project's architectural and design principles.

Test Coverage

  • New Unit Tests: Excellent coverage for the refactored component in tests/unit/app/client/experimental/components/WorkoutSummary.test.tsx, including mocking dependencies and testing different states.
  • VRT Snapshots: The Visual Regression Test (VRT) snapshot change in tests/playwright/vrt-workout-summary.spec.ts-snapshots/workout-summary-active-chromium-linux.png is expected and reflects the intentional UI redesign.

Verdict

✅ Verified that the WorkoutSummary component has been successfully refactored, enhancing its design and functionality, and is adequately covered by new unit tests. No regressions or violations of project guidelines were found. Ready for approval.

Reviewed at commit: 832415a0e439cf2924977e94936e6a429befb399

## Description

This submission refactors the `WorkoutSummary` component to a more visually appealing and informative "Card-based Dashboard" using Material UI. It includes a contextual header, visual status indicators, iconography, and improved typography. The parent component has been updated, and the changes have been visually verified.

Fixes #6221

## Change Type: ✨ New feature (non-breaking change adding functionality)

## PR Scope Checklist

_This checklist is mandatory for all PRs._

- [x] **PR has a clear, single purpose:** The title and description of the PR clearly state the purpose of the change.
- [x] **All changes relate to the stated objective:** The code changes should be directly related to the purpose of the PR.
- [x] **No unrelated cleanup or refactoring:** The PR should not contain any changes that are not directly related to the stated objective.
- [x] **Title and description match the actual changes:** The title and description should accurately reflect the changes in the PR.
- [x] **Tests cover the specific change scope:** The tests should be focused on the changes in the PR and should not include unrelated tests.

## Impact Assessment

- [x] Changes are **backward compatible** (or breaking changes are documented)
- [ ] **Tests** are added/updated for new functionality
- [ ] **Documentation** is updated if needed
- [ ] **ADR** is created/updated for significant architectural changes

<details>
<summary>Original PR Body</summary>

This submission refactors the `WorkoutSummary` component to a more visually appealing and informative "Card-based Dashboard" using Material UI, as requested. It includes a contextual header, visual status indicators, iconography, and improved typography. The parent component has been updated, and the changes have been visually verified.

Fixes #6221

---
*PR created automatically by Jules for task [15603091336728052536](https://jules.google.com/task/15603091336728052536) started by @arii*
</details>
@arii arii force-pushed the feat/refactor-workout-summary-card-15603091336728052536 branch from 646c2bb to 7bf495c Compare February 6, 2026 05:28
@arii
Copy link
Owner Author

arii commented Feb 6, 2026

🤖 AI Technical Audit

Deep Code Review

This PR successfully refactors the WorkoutSummary into a modern Card-based UI and introduces utility functions for date formatting. However, there is a critical regression regarding localization and some opportunities to tighten TypeScript definitions.

🚮 ANTI-AI-SLOP DIRECTIVES

  1. OVERLY VERBOSE COMMENTS: The JSDoc comments in WorkoutSummaryProps (e.g., /** Total workout duration in seconds */) are borderline noise. The variable names duration and calories are self-explanatory. Recommendation: Remove comments unless describing edge cases.
  2. CODE RATIO: The MetricBlockProps interface manually re-declares the union type for icon colors ('action' | 'error' | ...). This adds ~10 lines of maintenance burden.
  3. DUPLICATE HOOKS/TYPES: The formatDate utility essentially wraps toLocaleDateString. While DRY is good, the implementation introduces a default parameter that overrides the browser's native locale behavior (see below).
  4. STALE FEATURES: The PR correctly removes the old raw text implementations in SessionDetail and SessionList in favor of the new utility.

📁 File-by-File Analysis

lib/utils.ts (Critical Regression)

Problem: You have hardcoded the default locale to 'en-US'.
export const formatDate = (..., locale: string = 'en-US').

Previously, toLocaleDateString() (used in the files you refactored) defaulted to undefined (the user's browser/system locale). By defaulting to 'en-US', you are forcing US date formats on all international users unless they explicitly pass a locale. This is a regression.

Implementation Sample (Fix):

export const formatDate = (
  date: Date | number,
  options: Intl.DateTimeFormatOptions = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  },
  // Default to undefined to use browser's locale
  locale?: string 
): string => {
  const d = typeof date === 'number' ? new Date(date) : date
  return d.toLocaleDateString(locale, options)
}

app/client/experimental/components/WorkoutSummary.tsx

Problem: Redefining standard MUI types in MetricBlockProps. The iconColor prop manually lists all MUI colors. If MUI updates or if you change the theme, this type might drift.

Implementation Sample (Refactor):

import { SvgIconProps } from '@mui/material'

interface MetricBlockProps {
  // ... other props
  iconColor?: SvgIconProps['color']
}

tests/unit/app/client/experimental/components/WorkoutSummary.test.tsx

Best Practices: The test mocks formatDate and getStatusColor. While this isolates the component, it creates a risk where the integration between the component and the utility (e.g., the locale issue mentioned above) is masked. Since utils.ts is logic-less (pure functions), it is often safer to allow the real implementation to run in component tests, or at least integration tests.

🏛️ Architectural Impact

  • Localization Strategy: The introduction of a central formatDate is good for consistency, but the default value implementation contradicts web best practices for localization.
  • Visual Consistency: The extraction of getStatusColor ensures Chip colors match across the app, which is a good pattern.

🛠️ GitHub Checks & Automation

  • Visual Tests (pr-quality / 🧪 Visual Tests): Snapshots have changed (Binary files ... differ). Please ensure you manually inspect the generated screenshots in the artifacts to verify the UI looks as intended, specifically the alignment of the new Flex/Stack layouts.
  • Squash/Rebase Failure (test_pr_squash_rebase): This check failed. It implies there might be a conflict with the target branch or a dirty history. You may need to rebase your branch on main.

Review automatically published via RepoAuditor.

@arii
Copy link
Owner Author

arii commented Feb 6, 2026

🤖 AI Technical Audit

Code Review for PR #6226

This PR delivers a significant visual upgrade to the WorkoutSummary component. However, there is a critical localization regression in the new utility function and some architectural mixing of UI and business logic concerns.

🛑 ANTI-AI-SLOP DIRECTIVES

  1. OVERLY VERBOSE COMMENTS: In WorkoutSummary.tsx, the JSDoc comments on WorkoutSummaryProps (e.g., /** Total workout duration in seconds */ duration: number) state the obvious. Action: Remove these comments to improve signal-to-noise ratio.
  2. OVER-ENGINEERING / MISPLACED LOGIC: getStatusColor is added to lib/utils.ts. This function returns Material UI specific string literals ('success', 'warning'). Placing UI-specific constants in a generic lib/utils couples your core logic layer to the presentation library.
    • Action: Move getStatusColor directly into WorkoutSummary.tsx or a dedicated ui-utils.ts.
  3. CODE RATIO:
    • Delete getStatusColor from lib/utils.ts (~15 lines).
    • Simplify MetricBlockProps in WorkoutSummary.tsx by inferring types instead of manually listing colors.
  4. STALE FEATURES: Confirmed that the old text-based layout is removed.

📁 File-by-File Analysis

lib/utils.ts

Problem: Localization Regression
The new formatDate utility defaults the locale to 'en-US'. The previous implementation used .toLocaleDateString() (no args), which uses the user's browser/system locale. This change forces US date formats (MM/DD/YYYY) on all users, which is a UX degradation for international users.

Implementation Sample (Fix):

export const formatDate = (
  date: Date | number,
  options: Intl.DateTimeFormatOptions = { ... },
  locale: string | undefined = undefined // undefined uses browser default
): string => {
  const d = typeof date === 'number' ? new Date(date) : date
  return d.toLocaleDateString(locale, options)
}

app/client/experimental/components/WorkoutSummary.tsx

Problem: Redundant Type Definitions
MetricBlockProps manually re-defines valid MUI color strings.

Implementation Sample:

import { SvgIconProps } from '@mui/material';

interface MetricBlockProps {
  // ...
  // Inherit valid colors directly from MUI types
  iconColor?: SvgIconProps['color'];
}

tests/unit/app/client/experimental/components/WorkoutSummary.test.tsx

Observation: The tests mock lib/utils. If you move getStatusColor inside the component file (as suggested above), you will need to update the mock or test the logic directly within the component test.

🛡️ Best Practices

  • Accessibility: Good use of aria-hidden="true" on decorative icons combined with semantic typography.
  • Type Safety: The use of interface is correct, but leverage type inference from libraries (SvgIconProps) to avoid maintenance drift.

🏁 Conclusion

Please address the localization issue in utils.ts and co-locate the UI helper function getStatusColor before merging.

Review automatically published via RepoAuditor.

arii and others added 2 commits February 6, 2026 09:15
…7122)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
…7140)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 6, 2026

🤖 AI Technical Audit

ANTI-AI-SLOP DIRECTIVES

  1. UNRELATED CHANGES (VIOLATION): The file tests/unit/lib/healthCheck.test.ts contains changes to memory usage mocking that are completely unrelated to the UI refactoring of WorkoutSummary. This violates the PR Scope Checklist ("No unrelated cleanup or refactoring").
  2. CODE RATIO: You are adding ~140 lines to WorkoutSummary.tsx and ~25 lines to healthCheck.test.ts. You must remove the changes in healthCheck.test.ts entirely to comply with the scope.
  3. STALE FEATURES: Verified that the old text-based WorkoutSummary implementation is correctly removed.
  4. OVER-ENGINEERING: MetricBlock is defined inside WorkoutSummary.tsx. While clean, it adds 35+ lines for a component used only twice in the same file. Consider if SessionDetail.tsx should also use this new UI, otherwise, it remains an isolated abstraction.

Code Review

General Feedback
The visual refactor of WorkoutSummary significantly improves the user experience. The introduction of formatDate is a good practice to standardize date rendering. However, the inclusion of unrelated backend test changes prevents this from being merged as-is.

tests/unit/lib/healthCheck.test.ts

Problem: Unrelated Scope.
Recommendation: Revert all changes in this file. Submit them in a separate fix or chore PR.
Implementation Sample:

// REMOVE ALL CHANGES IN THIS FILE
// git checkout origin/main -- tests/unit/lib/healthCheck.test.ts

app/client/experimental/components/WorkoutSummary.tsx

Problem: Hardcoded Strings (Localization).
The labels "DURATION", "CALORIES", "HRM Session", and "Status" values are hardcoded. This will make future internationalization difficult.

Best Practice: Use a localization library or at least constants.

Problem: Prop Drilling / Default Values.
userName is passed in, but the default "Guest User" logic resides in the parent ExperimentalAnalyticsPage.tsx. It might be safer to handle the fallback inside the component or a dedicated selector.

lib/utils.ts

Observation: The formatDate function correctly wraps toLocaleDateString. Note that toLocaleDateString takes locales as the first argument, whereas your utility takes it as the third. This is fine, but ensure consistency across the app.

app/client/experimental/components/SessionDetail.tsx

Architectural Opportunity: You updated this file to use formatDate, but it still uses the old plain text UI for the summary. Consider reusing the new WorkoutSummary component here (or at least the MetricBlock logic) to maintain visual consistency across the app between the dashboard and session details.

GitHub Checks

All automated checks passed, including Unit Tests. However, the healthCheck tests passing confirms the unrelated changes are valid code, but they are still procedurally incorrect for this specific PR.

Review automatically published via RepoAuditor.

@arii
Copy link
Owner Author

arii commented Feb 7, 2026

🤖 AI Technical Audit

Principal Engineer Review

🛑 ANTI-AI-SLOP DIRECTIVES

  1. UNRELATED CHANGES: The file tests/unit/lib/healthCheck.test.ts contains changes to checkMemoryUsage logic and mocks that are completely unrelated to the "Refactor WorkoutSummary" scope. These must be removed or moved to a separate PR.
  2. CODE RATIO: In WorkoutSummary.tsx, the getStatusColor function (12 lines) is unnecessarily verbose. It can be replaced with a simple object lookup (3 lines), saving ~9 lines. Additionally, JSDoc comments like "Displays a summary of the current workout session" (3 lines) state the obvious and should be removed.
  3. HYDRATION RISK: The new formatDate utility in lib/utils.ts relies on toLocaleDateString with an implicit (undefined) locale. In a Next.js environment (indicated by 'use client'), this will cause hydration mismatches because the Server (Node) locale often differs from the Client (Browser) locale, or the Timezone difference changes the day.

File-by-File Analysis

lib/utils.ts

Problem: Hydration Mismatch Vulnerability.
The function formatDate defaults locale to undefined. When this runs during SSR, it uses the server's locale (often en-US or C in Docker). On the client, it uses the browser's locale. If the date is rendered text, React will throw a hydration mismatch error.

Implementation Sample (Fix):

// Prefer passing a specific locale from user settings or using a stable format for initial render
export const formatDate = (date: Date | number, options: Intl.DateTimeFormatOptions, locale: string = 'en-US') => {
  // ... implementation
}
// Alternatively, wrap usage in a hook that only formats after mount, though that causes layout shift.

app/client/experimental/components/WorkoutSummary.tsx

Problem: Overly verbose status logic.

Implementation Sample (Refactor):

const STATUS_COLORS: Record<string, 'success' | 'warning' | 'primary' | 'default'> = {
  running: 'success',
  paused: 'warning',
  finished: 'primary',
};

// Usage in component:
// color={STATUS_COLORS[status] || 'default'}

tests/unit/lib/healthCheck.test.ts

Problem: Scope Creep.
This file modifies memory usage mocks. This violates the "No unrelated cleanup" checklist item.

Architectural Impact

  • Component Isolation: The extraction of WorkoutSummary is good, but the dependency on userName (which defaults to 'Guest User' in the parent) suggests the component is becoming more coupled to User context than just Workout context. Ensure userName is actually necessary for a Summary component, or if it belongs in a Page Header.

Automated Checks

  • Unit Tests: Passed, but tests/unit/lib/utils.test.ts might flake on CI servers with different default locales if not explicitly set to 'en-US' in the container.

Review automatically published via RepoAuditor.

…th Check Tests (#7560)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii arii force-pushed the feat/refactor-workout-summary-card-15603091336728052536 branch from 81f4740 to 9267d80 Compare February 10, 2026 16:07
@arii
Copy link
Owner Author

arii commented Feb 10, 2026

🤖 AI Technical Audit

Code Review for PR #6226: Refactor WorkoutSummary Component

Summary

This PR successfully refactors the WorkoutSummary component into a cleaner, card-based UI and introduces a standard date formatting utility. However, there are significant issues regarding client-side hydration consistency, internationalization regressions, and scope creep with unrelated test fixes.

⚠️ ANTI-AI-SLOP DIRECTIVES

  1. UNRELATED CHANGES (STALE FEATURES/SCOPE):
    • File: tests/unit/lib/healthCheck.test.ts
    • Issue: You have modified memory usage mocking logic in a PR titled "Refactor WorkoutSummary". This violates the "No unrelated cleanup" checklist item. These changes should be in a separate fix/test-flakes PR.
  2. OVER-ENGINEERING:
    • File: app/client/experimental/components/WorkoutSummary.tsx
    • Issue: The MetricBlock component is defined with full interface overhead but only used twice within the same file. It adds unnecessary lines (approx 35 lines). Inlining this or using a simple render helper would reduce the file size significantly.
  3. CODE RATIO:
    • Recommendation: Remove the explicit type definition for STATUS_COLORS. TypeScript can infer this strictly with as const, saving ~4 lines of verbose typing.

🚨 Critical Issues

1. Hydration Mismatch Risk (Architectural Impact)

File: app/client/experimental/components/ExperimentalAnalyticsPage.tsx

Problem:
You are passing new Date() to the date prop when no session is active. Since ExperimentalAnalyticsPage is likely pre-rendered on the server (Next.js), the server's new Date() will differ from the client's new Date() during hydration, causing a React hydration mismatch error.

Implementation Sample:

// ❌ BAD: Causes hydration mismatch
date={activeSession ? new Date(activeSession.startTime) : new Date()}

// ✅ GOOD: Handle empty state inside child or use null
date={activeSession ? new Date(activeSession.startTime) : null}
// Then update WorkoutSummary to handle null/undefined date gracefully

2. Internationalization Regression

File: lib/utils.ts

Problem:
The previous implementation used toLocaleDateString() which defaults to the user's browser locale. The new formatDate utility defaults to locale = 'en-US'. This forces US formatting on all users, which is a regression for non-US users.

Implementation Sample:

// lib/utils.ts
export const formatDate = (
  date: Date | number,
  options: Intl.DateTimeFormatOptions = { ... },
  locale: string | undefined = undefined // ⬅️ Allow undefined to use system/browser locale
): string => {
  const d = typeof date === 'number' ? new Date(date) : date
  return d.toLocaleDateString(locale, options)
}

📁 File-by-File Feedback

app/client/experimental/components/WorkoutSummary.tsx

  • Refactor/Cleanup: Remove the explicit MetricBlock component definition to reduce slop. You can achieve the same result with less code.

lib/utils.ts

  • Suggestion: Ensure formatDate accepts undefined for locale to respect the runtime environment's settings.

tests/unit/lib/healthCheck.test.ts

  • Process: Please revert these changes and submit them in a separate PR to maintain a clean git history and adherence to the PR checklist.

Review automatically published via RepoAuditor.

@arii
Copy link
Owner Author

arii commented Feb 10, 2026

🤖 AI Technical Audit

Code Review: Refactor WorkoutSummary Component

🚫 ANTI-AI-SLOP DIRECTIVES

  1. UNRELATED CHANGES (VIOLATION): The file tests/unit/lib/healthCheck.test.ts contains changes to checkMemoryUsage logic and tests that are completely unrelated to the UI refactoring of WorkoutSummary. This violates the "Single Purpose" rule. Action: Remove this file from the PR.
  2. CODE RATIO: By removing the unrelated healthCheck.test.ts changes, you will remove >20 lines of code that do not belong in this feature branch.
  3. VERBOSE COMMENTS: The JSDoc for formatDate in lib/utils.ts states obvious parameter types that TypeScript already handles. Keep it concise.
  4. STALE FEATURES: Correctly identified that the old WorkoutSummary implementation was replaced.

📁 File-by-File Analysis

app/client/experimental/components/ExperimentalAnalyticsPage.tsx

Problem: Prop Instability / Performance.
Passing new Date() as a fallback in the render method creates a new object reference on every render cycle. This forces WorkoutSummary to re-render unnecessarily, even if its other props haven't changed. This is particularly impactful in an analytics dashboard that likely has high-frequency updates (e.g., from CalorieTracker or LiveDuration).

Implementation Sample:

// Better approach: Memoize or handle null in child
const defaultDate = useMemo(() => new Date(), []);
// ...
date={activeSession ? new Date(activeSession.startTime) : defaultDate}

lib/utils.ts

Problem: Hardcoded Locale.
The formatDate utility defaults the locale to 'en-US'. This undermines the browser's ability to use the user's system locale for date formatting, potentially alienating non-US users.

Implementation Sample:

export const formatDate = (
  date: Date | number,
  options: Intl.DateTimeFormatOptions = { ... },
  locale: string | undefined = undefined // Let the browser decide default
): string => {
  // ...
}

app/client/experimental/components/WorkoutSummary.tsx

Problem: Missing Type Key Mapping.
The STATUS_COLORS map is missing an explicit key for 'idle', relying on the fallback || 'default' in the JSX. While functional, it creates a disconnect between the WorkoutSummaryProps['status'] union type and the mapping object.

Suggestion: Add idle: 'default' to STATUS_COLORS to satisfy the record completely or type the Record loosely.

tests/unit/app/client/experimental/components/WorkoutSummary.test.tsx

Problem: Brittle Class Name Testing.
The test checks for specific MUI class names (e.g., MuiChip-colorSuccess). These are internal implementation details of the library and can change between versions. It is better to test for accessibility attributes (like aria-label) or computed styles if absolutely necessary.

🏗 Architectural Impact

  • Utility Centralization: Moving date formatting to lib/utils is a good practice, but ensure this pattern is adopted across the app to avoid mixed usages of toLocaleDateString and the new helper.
  • Component Isolation: The new WorkoutSummary is well-isolated, but the dependency on a hardcoded en-US locale in the utility layer introduces a subtle localization barrier.

🛠 Github Checks

  • Unit Tests: Passed, but the healthCheck tests passed only because they were modified in this PR. They should be moved to a separate fix.
  • Visual Tests: Passed, confirming the UI changes are stable.

Review automatically published via RepoAuditor.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii arii merged commit 5d1589c into leader Feb 11, 2026
40 checks passed
@arii arii deleted the feat/refactor-workout-summary-card-15603091336728052536 branch February 11, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment