Skip to content

LF-5302: Build presentational components for the Profitability widget#4183

Open
litefarm-pr-bot wants to merge 1 commit into
integrationfrom
LF-5302-build-presentational-components-for-the-profitability-widget
Open

LF-5302: Build presentational components for the Profitability widget#4183
litefarm-pr-bot wants to merge 1 commit into
integrationfrom
LF-5302-build-presentational-components-for-the-profitability-widget

Conversation

@litefarm-pr-bot
Copy link
Copy Markdown
Collaborator

@litefarm-pr-bot litefarm-pr-bot commented May 25, 2026

Description

The Profitability home widget is a substantial composition: a hero KPI card with a trend, three secondary KPI cards, a More data / Less data expand toggle, a two-column bars region, an entity table with Crops/Animals/All tabs, an empty-state CTA banner, and a skeleton. None of those parts exist anywhere in the codebase today, and writing them inline in the smart container would produce one ~600-line file that no one can review or visually tune. This PR ships them as seven independent, prop-driven, Storybook-testable presentational components in a new components/ProfitabilityWidget/ directory.

Each component takes its labels and currency as plain props rather than calling useTranslation itself, which keeps every component fully driveable from Storybook with no Redux store and no i18n session. The new profitability translation namespace lives at public/locales/en/profitability.json and is registered in i18n.js so the upcoming container can resolve useTranslation('profitability') without further config; the namespace's DATE_RANGE.YEAR_LABEL key is reserved for the container PR's DateRangeDropdown wrapper, which depends on the previously-extended DateRangeSelector and is intentionally not in this PR. A single styles.module.scss carries the per-variant colour tokens from Figma so every component pulls from the same palette; constants.ts exports the EntityTab and KpiVariant enums alongside TOP_EXPENSE_CATEGORIES_COUNT and FARM_GENERAL_ROW_ID.

The convention worth carrying forward: keep presentational components in this widget pure of i18n and Redux. When localised strings are needed, accept them as props (either a labels shape, or individual label / ctaLabel strings), so the same component can be rendered both from the live container and from a Storybook story without context. The smart container will own the useTranslation call and pass the resolved strings down.

Jira: https://lite-farm.atlassian.net/browse/LF-5302

Type of change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Passes test case
  • UI components visually reviewed on desktop view
  • UI components visually reviewed on mobile view
  • Other (please explain): NODE_OPTIONS=--max_old_space_size=3000 pnpm exec tsc --noEmit from packages/webapp passes with no errors. The existing webapp Vitest suite is unaffected (no source code paths that previous tests exercise were modified beyond appending a new namespace to the i18n ns array). Storybook stories were added for each component but were not rendered locally — the visual review should happen via pnpm storybook against the new Components/ProfitabilityWidget/* story tree, and the full widget composition will be visually reviewable when the smart container lands.

Checklist:

  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • The precommit and linting ran successfully
  • I have added or updated language tags for text that's part of the UI
  • I have ordered translation keys alphabetically (optional: run pnpm i18n to help with this)
  • I have added the GNU General Public License to all new files

Adds the seven prop-driven, Storybook-testable presentational components
that compose the upcoming Profitability home widget: KpiCard (with four
colour-variant tokens and an optional hero-size trend slot), KpiSection
(hero card on top of a 3-column compact row), RevenueExpenseBars (two
columns of labelled MUI LinearProgress bars), EntityProfitTable (a
TableV2 driven by a Crops/Animals/All StateTab), ExpandableSection (a
blue-bordered More data / Less data toggle that mirrors the Additional
Nutrients pattern from ProductDetails), EmptyTransactionsBanner (the
green CTA banner shown when a range has zero transactions), and
ProfitabilityWidgetSkeleton (matching the widget layout with neutral-50
placeholder rectangles).

Each component takes its labels and currency as plain props rather than
calling i18n itself, which keeps every component fully driveable from
Storybook with no Redux store or i18n session required. A new
profitability translation namespace is added to public/locales/en and
registered in i18n.js so the container PR (which lands the
useTranslation('profitability') consumer) can pick it up without further
config; the namespace's DATE_RANGE.YEAR_LABEL key is reserved for that
PR's DateRangeDropdown wrapper. constants.ts exports the EntityTab and
KpiVariant enums alongside TOP_EXPENSE_CATEGORIES_COUNT and
FARM_GENERAL_ROW_ID; a single styles.module.scss carries the colour
tokens from Figma so every component pulls from the same palette.

One Storybook story per component (no play functions, just visual
scaffolds), plus a small expanded-state composition story for KpiCard
to exercise all four variants at once.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@litefarm-pr-bot litefarm-pr-bot requested review from a team as code owners May 25, 2026 16:41
@litefarm-pr-bot litefarm-pr-bot requested review from kathyavini and removed request for a team May 25, 2026 16:41
@kathyavini kathyavini self-assigned this May 25, 2026
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