Skip to content

feat: Dockside calculator with live result bar and weight-based costs - #121

Merged
paccloud merged 3 commits into
mainfrom
claude/adoring-cerf-nzibk1
Sep 29, 2026
Merged

paccloud merged 3 commits into
mainfrom
claude/adoring-cerf-nzibk1

Conversation

@paccloud

Copy link
Copy Markdown
Owner

Summary

Rebuilds the calculator screen on Dockside, direction A of the three mock-ups (now saved in docs/design-mockups/). It follows #118, which was the accessibility pass.

Dockside is built for people using the app one-handed on a dock or mid-service:

  • Tap tiles replace dropdowns for "What you have" and "What you're making". They are real radio buttons, so arrow keys and screen readers work. Species stays a native select because there are 89 of them. Long product lists show 6 tiles plus "Show all".
  • Big − / + steppers for price, pounds, yield, processing and shipping.
  • A live result bar pinned to the bottom replaces the Calculate button. It always shows the answer for what's on screen, with the parts broken out (Fish + Processing + Shipping) when extra costs are set. Screen readers hear the answer once typing pauses, not on every keystroke.
  • Processing and shipping can each be charged per lb of incoming weight (the starting fish, divided by yield) or outgoing weight (the finished product, added as-is). Both choices are always visible, with a line spelling out what the charge comes to per finished lb.

Math: calcEngine.js gains shippingWeightType and a per-part breakdown, with tests. Shipping defaults to outgoing, so existing results don't change. Because the answer is computed from what's on screen, Save can no longer pair edited inputs with an old result, a bug on main.

Found in browser testing and fixed here (dbdf0bc)

  • Typed amounts could give silently wrong answers. The boxes are text inputs, so $4.50 priced at $0.00/lb, and 1,000 lbs showed "buy 2.4 lbs … makes 1,000 lbs". The new parseAmount (lib/numberInput.js, written test first) accepts $4.50, 1,000, 42%, 100 lbs and 4,50. Anything else marks the box invalid (red border, aria-invalid), and the bar says "Use numbers only". It never counts as 0 or falls back to 100% yield.
  • Controls could hide behind the pinned bar (WCAG 2.4.11). Tabbing to the processing stepper, "Sign in" or the abbreviations toggle could leave them fully covered. The page's scroll-padding-bottom now tracks the bar's height, and it's removed when you leave the calculator.

Commits

  • bdf7dd0 docs: save the three mock-ups and the visual board
  • ea16d1e feat: Dockside calculator with processing and shipping weight basis
  • dbdf0bc fix: read typed amounts safely and keep focus clear of the result bar

Test plan

  • npm run lint: 0 errors (the same 2 warnings as main)
  • npm test: 2298 passed, including new calcEngine weight-basis/breakdown tests and 25 parseAmount cases. Two files don't load in the sandbox (bcrypt, exceljs not installed); they run in CI.
  • npm run build passes
  • Browser (Playwright/Chromium, API mocked with the production /api/fish-data shape):
    • Answers: $4.50 at 42% = $10.71; with $1 processing on incoming weight $13.10 (outgoing $11.71); with $0.50 shipping on outgoing $12.21 or incoming $12.90; 100 lbs at 42% = 238.1 lbs; the Low/Average presets and steppers update it live.
    • Typed input: $4.50 → $10.71; 1,000 lbs → 2381.0; 42% works; abc or 4x2 → no answer, box marked.
    • Signed in (session simulated): after editing the yield, Save sent the current yield 50 with result 9.00 (= 4.50 ÷ 50%). "Saved!" clears as soon as anything changes.
    • Keyboard: arrow keys move within tile groups with a 3px focus ring, and no Tab stop is hidden behind the bar.
    • Layout: 390px and 320px phones have no sideways scroll, every control is at least 44×44, and the last card clears the bar.
    • Other paths: species with no "Round" (Dungeness Crab) or with a single starting form (Norwegian Farmed Salmon); help tooltips still work while the fieldset is disabled.
    • axe-core (WCAG 2.2 AA): clean in light and dark, phone and desktop, empty and filled.
  • On a real phone with the Inter font (the sandbox uses a fallback font)
  • Save against the real API (only the request payload was checked)

Not in this PR

  • The design is not derived from Grace Communications, namanet.org, NFFC or localcatch.org. Those sites were blocked from the build environment.
  • Save still records only cost, yield and result, not processing or shipping (unchanged from main).
  • Still open from docs/DESIGN_SYSTEM.md: the calculator is unusable offline if /api/fish-data fails, and Footer.jsx/InstallPrompt.jsx are unused.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ErLEY8gicR3Wg7Q1yXAVaC


Generated by Claude Code

Adds three self-contained HTML mock-ups (A Dockside, B Market Board,
C Clear Water) and the visual board comparing them, so they survive
beyond the session that made them. No direction is chosen yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErLEY8gicR3Wg7Q1yXAVaC
Rebuilds the calculator on the chosen Dockside mock-up (direction A):
tap tiles for what you have and what you're making, +/- steppers for
every number, and a live result bar pinned to the bottom instead of a
Calculate button.

Processing and shipping can each be charged per lb of incoming weight
(the starting fish, spread over the finished pounds) or outgoing weight
(the finished product). Both choices are always visible, with a line
showing what the charge comes to per finished lb, and the result bar
breaks the total into fish, processing and shipping.

The math now comes from calcEngine, extended with shippingWeightType
(default outgoing, so earlier results are unchanged) and a per-part
breakdown, test first. Because the result is computed live from what is
on screen, a saved calculation can no longer pair new inputs with an
old result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErLEY8gicR3Wg7Q1yXAVaC
The Dockside number boxes are text inputs, so parseFloat got common
entries silently wrong: "$4.50" priced at $0.00/lb, and "1,000" lbs
became "buy 2.4 lbs ... makes 1,000 lbs".

- Add parseAmount (lib/numberInput.js, test first): accepts "$4.50",
  "1,000", "42%", "100 lbs" and a decimal comma ("4,50"); returns NaN
  for anything else instead of guessing.
- Text that isn't a number marks its box invalid (red border,
  aria-invalid) and the result bar says to use numbers, rather than
  counting it as 0 or falling back to 100% yield.
- Steppers, hints, the saved payload and the weight-mode sentence all
  use the parsed values.
- Set scroll-padding-bottom to the pinned bar's height while the
  calculator is shown, so tabbed-to controls are never hidden behind it
  (WCAG 2.4.11). Removed again when leaving the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ErLEY8gicR3Wg7Q1yXAVaC
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
fish-cost-calculator Ready Ready Preview Sep 29, 2026 12:55pm UTC

@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: cfe5b7b0-f40d-4747-af36-c9ee26d005f7

📥 Commits

Reviewing files that changed from the base of the PR and between 7fb428a and dbdf0bc.

📒 Files selected for processing (11)
  • app/src/components/Calculator.jsx
  • app/src/lib/calcEngine.js
  • app/src/lib/calcEngine.test.js
  • app/src/lib/numberInput.js
  • app/src/lib/numberInput.test.js
  • docs/DESIGN_SYSTEM.md
  • docs/design-mockups/README.md
  • docs/design-mockups/mockup-a-dockside.html
  • docs/design-mockups/mockup-b-market-board.html
  • docs/design-mockups/mockup-c-clear-water.html
  • docs/design-mockups/visual-board.html

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T12:58:07.395152Z dbdf0bc PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@paccloud
paccloud merged commit 2cee318 into main Sep 29, 2026
6 checks passed
paccloud pushed a commit that referenced this pull request Sep 29, 2026
Resolve against the Dockside calculator (#121): keep main's live result
bar and re-apply this PR's fixes on top of it. Bundled reference yields
get from/to so the forms list offline, the API only replaces them when it
sends usable conversions, and a yield at or below 0 or above 100 shows
'Enter a yield above 0 and up to 100%' instead of a price (0 used to fall
back to 100%).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PnPh61Aps5neY87hh1pu9T

This branch was successfully deployed

1 active deployment
Preview — dbdf0bc0 Deployed Sep 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants