feat(apps): AI Credits analytics data widget - #179
Draft
goodbounties-nanoclaw-agent[bot] wants to merge 21 commits into
Draft
feat(apps): AI Credits analytics data widget#179goodbounties-nanoclaw-agent[bot] wants to merge 21 commits into
goodbounties-nanoclaw-agent[bot] wants to merge 21 commits into
Conversation
Adds a reusable Scorecard component to packages/ui — a single-metric KPI card with label, formatted value, optional trend indicator, and bare/card variants. Implements #139's compact/decimal/none formatting modes via a shared formatMetricValue utility, and a golden-ratio modular typography scale (base 24px, ratio 1.618, 12px floor) across sm/md/lg sizes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- formatMetricValue: fix a rounding-boundary bug where a scaled value could round up to the next unit's threshold without promoting (e.g. 999_950 -> "1000.0K" instead of "1.0M"); guard non-finite input (NaN/Infinity) with a "--" fallback shared by all consumers; note the intentional en-US locale. - Scorecard: set both testID and data-testid so React Native test tooling and web DOM queries both work; mark the trend arrow SVG as decorative (accessible=false / aria-hidden) since adjacent text already conveys direction; give resolveThemeColor a visible fallback and dev warning instead of silently rendering an empty fill; type its theme param via ReturnType<typeof useTheme> instead of an unsafe double cast. - package.json: move react-native-svg to peerDependencies (kept in devDependencies for local build/test) to avoid native-module duplication for consumers. - Storybook story + smoke test: render all 5 mock-data rows in both the bare and card variants with per-row testIDs, and assert all 10 are visible so the test matches what it claims to cover. Co-Authored-By: Claude <noreply@anthropic.com>
…ing pass
- formatMetricValue: whole numbers below the compact threshold render
without decimals ("47", not "47.0").
- Scorecard card variant: vertically centers content regardless of
whether a trend row is present.
- Value text uses $color instead of $primary; prefix/suffix render at
fontWeight 400 in $placeholderColor, subordinate to the value.
- Card variant elevation now uses a lightness-overlay + top highlight
instead of a hard border, scoped to Scorecard's <Card> call site so
the shared Card primitive is untouched.
- Spacing (label-to-value gap, value-to-trend gap, card padding) now
derives from the same golden-ratio constants as the type scale.
- Bump the Scorecard smoke test's viewport height to fit the taller
card layout without clipping the screenshot.
Co-Authored-By: Claude <noreply@anthropic.com>
Second consumer (PieDonutChart, and the 3 charts after it) needs the same theme-token-to-raw-color resolution Scorecard already does privately. Extracted to packages/ui/src/utils/resolveThemeColor.ts rather than duplicating a 5th time, mirroring how formatMetricValue was shared. Scorecard.tsx is untouched — it already shipped under a prior issue and migrating it is out of this task's scope. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Generalizes FundingDistributionChart's SVG arc technique into a themeable packages/ui primitive: computed ring geometry supports innerRadius from 0 (filled pie) to a thin donut, sort/maxSlices "Other" aggregation, legend with percentages, empty/stress states, and onSegmentPress. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vertical/horizontal categorical bar chart with nice-number axis ticks, zero-baseline-aware single-edge-rounded bars, graceful long-label truncation, and sub-pixel-safe rendering for large category counts. Follows Scorecard/PieDonutChart conventions (createComponent, theme color resolution, golden-ratio type scale). Also adds a Text primitive to the Storybook react-native-svg web shim — needed because BarChart is the first chart to render labels inside the SVG (for pixel-precise axis alignment) rather than via Tamagui Text, and the shim never had to support that primitive before. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Time-series line/area chart with linear/monotone/step interpolation, optional area-fill gradient, reference lines, multi-series with an optional secondary y-axis, null-gap handling (connectNulls), and adaptive x-axis label thinning/truncation for dense datasets, mirroring BarChart's established truncateLabelToWidth pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Shared CHART_FONT_FAMILY constant applied to every SVG <Text> in BarChart and LineAreaChart, matching the default preset's sans-serif typography stack instead of the browser's default serif fallback (react-native-svg's Text isn't part of Tamagui's styling system, same reason resolveThemeColor exists for fill/stroke). - PieDonutChart's Default story now shows the spec default (innerRadius 0.6, donut with center metric) instead of overriding it to a flat pie; the pie mode moves to its own PurePie story. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
centerContentMaxWidth was derived from ringRadius * (1 - innerRadius), which shrinks as the hole grows instead of growing with it — ringRadius is the stroke's centerline, not the hole radius. Compute the actual hole radius (ringRadius - strokeWidth / 2) and size the available square off that instead. Also default the center value's own formatting to 0 decimals (450K, not 450.0K) so typical aggregated totals fit the hole at the component's default size. Co-Authored-By: Claude <noreply@anthropic.com>
Pure-Tamagui data table with typed columns, sorting, striping, sticky header, and horizontal/vertical scroll. Applies the design-hierarchy rules from the Pie/Bar/Line fix round: muted $placeholderColor headers (bold weight kept per spec's own rule 4) vs full-contrast $color data values. Co-Authored-By: Claude <noreply@anthropic.com>
formatMetricValue's compact formatter always applied toFixed(decimals) to the scaled value, even when it landed on a whole unit (892000 -> "892.0K" instead of "892K"). Mirrors the same whole-number check already used in the below-threshold branch. Affects BarChart/LineAreaChart axis labels and DataTable cells. Also backfills missing Playwright screenshot coverage requested in QA: Pie/Donut empty + stress, Bar empty, Line/Area step/multi-series/gap/empty/ single-point, DataTable empty/null-cells/card variant. Co-Authored-By: Claude <noreply@anthropic.com>
…pped elements Several new QA-round screenshots (Pie/Donut, Bar, Line/Area empty states, Line/Area step/single-point, DataTable empty/nulls) used element-level locator screenshots instead of the established screenshotStory() full-iframe helper, producing tightly-cropped composites inconsistent with the rest of the suite. DataTable/Default now uses a taller viewport (1800px) so the card variant, previously captured as a separate cropped shot, renders within the same full-page capture as the bare table. Co-Authored-By: Claude <noreply@anthropic.com>
examples/react-web's local web shim for react-native-svg never got the Text/Defs/LinearGradient/Stop passthroughs that examples/storybook's copy already has. BarChart and LineAreaChart import these directly from react-native-svg, which resolves to this shim in the web build, so example-react-web#build failed at "Text" is not exported by reactNativeSvg.tsx — and since all 3 PR #148 Vercel preview checks share this turbo build task, all 3 were failing on it. Mirrors the existing storybook shim's implementation exactly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
examples/html/src/shims/reactNativeSvg.tsx had the identical gap already fixed in examples/react-web (missing Text/Defs/LinearGradient/Stop), which was the next failure turbo hit on the shared example-html#build task once the react-web build was unblocked. apps/superfluid-campaign-web and apps/ai-credits-web each keep their own differently-structured shim (src/reactNativeSvgWeb.tsx, aliased directly in vite.config.ts rather than living under a shims/ folder) with a wider pre-existing gap: also missing G, needed since PieDonutChart. Added G/Text/Defs/LinearGradient/Stop to both, following each file's own per-element-typed function style rather than the shims/ copies' createPassthroughSvgPrimitive factory. Full `pnpm build` across the monorepo now succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…nt stories Add an explicit-render Controllable story to each analytics component (BarChart, PieDonutChart, LineAreaChart, DataTable, Scorecard), leaving Default fixed/static with a comment noting Controls are inert there by design, matching the Stepper/Card convention. Root cause of the reported inertness: any argType-covered prop absent from a story's args object renders as a non-functional "Set boolean/ string/number" placeholder button in Storybook's live Controls panel instead of a working control, until clicked once to initialize a default. Every argType-covered prop across all 5 components now has an explicit default in Controllable's args, matched to each component's own real internal default value, so every control renders live and interactive on first load. Co-Authored-By: Claude <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
New standalone read-only Vite/React app (@goodwidget/ai-credits-analytics-web) visualizing AntSeed AI Credits activity: G$ volume, credit usage, and unique wallet counts, sourced from the AntSeed Analytics Worker with a local demo fallback. Ported from GoodDollar/data-team's reference dashboard, composed entirely from existing @goodwidget/ui chart primitives (Scorecard, LineAreaChart, BarChart, DataTable). No wallet connection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
…s-web Vercel token/project-id secret naming confirmed by Laurence; job/environment naming scoped to this new workflow only per the same confirmation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
goodbounties-nanoclaw-agent
Bot
force-pushed
the
feat/ai-credits-analytics-web
branch
from
August 21, 2026 15:37
11fd95f to
613fe8c
Compare
…o a reusable GoodData widget package Moves connector/config, fetch/validate/normalize/refresh, and dashboard composition logic out of apps/gooddata-analytics-web into packages/gooddata-widget, with a dashboard registry (mirroring the manifest.ts pattern) and connector registry so future dashboards can be added without copy-pasting a new app. apps/gooddata-analytics-web is now a thin host: mount/config + deploy entry point only, with an SPA rewrite so direct navigation and refresh work on dashboard subpaths. Adds Storybook QA fixtures for the widget's loading/live/demo/live-unavailable/ empty states and a Playwright spec with baseline screenshots, matching the existing GoodWidget test convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> On-Behalf-Of: BountyCoder[onecli] (yaskkeryodtdijpv)
goodbounties-nanoclaw-agent
Bot
force-pushed
the
feat/ai-credits-analytics-web
branch
from
August 21, 2026 15:40
613fe8c to
9f2aad6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #178 (plan sub-issue for #176 — AI Credits analytics data widget).
Summary
apps/ai-credits-analytics-web(Vite + React +TamaguiProvider), following theapps/ai-credits-web/apps/superfluid-campaign-webscaffold pattern. No wallet connection anywhere.@goodwidget/uichart components:Scorecard,LineAreaChart,BarChart), and a paginated daily-summary table (DataTable+ an app-localPaginatedDataTablewrapper, sinceDataTablehas no built-in paging).src/lib/analyticsApi.ts,analyticsConversions.ts,generateDemoData.ts,src/hooks/useAnalyticsData.ts) is an internal module inside the app, not a separate package, per plan. Ported fromGoodDollar/data-team's reference dashboard (projects/antseed-analytics/dashboard/app.js): live-fetch-with-demo-fallback state machine, manual Live/Demo toggle (stays clickable even when live is unavailable — shows an inline "not yet deployed" message instead of disabling), 5-minute auto-refresh, and a refresh button that POSTs then re-fetches.Number().packages/uicomponents were needed — all 5 analytics chart components already cover this issue's requirements.Out of scope (per Bounty Lead sign-off on the plan)
ai-credits-web/superfluid-campaign-webdeploy workflows' generic job/environment naming is not touched here — tracked as a separate follow-up..github/workflows/deploy-ai-credits-analytics-web.yml) is drafted and committed locally but intentionally not included in this PR pending Laurence confirming the Vercel project/secret specifics for this app — will be pushed as a follow-up commit once confirmed.Testing
pnpm turbo run build --filter=@goodwidget/ai-credits-analytics-web— passes.pnpm turbo run lint --filter=@goodwidget/ai-credits-analytics-web— passes.apps/ai-credits-analytics-web/tests/dashboard.spec.ts(desktop/Chromium project) — 6/6 passing, covering: live data render, demo fallback, toggling to Live while unavailable (inline message, toggle stays clickable), refresh loading state, empty state, and table pagination.Human-reviewer checklist
antseed-integrationPR [Plan] Build packages/savings-widget: SDK integration, UI mapping, and execution checklist #19 link from the "live unavailable" copy (replaced with generic "not yet deployed" text) is correct.PaginatedDataTablewrapper (vs. promoting pagination intopackages/ui'sDataTable) is the right call for now.deploy-ai-credits-analytics-web.yml(committed locally, not in this PR) once Laurence confirms Vercel project/secret specifics, before it's pushed.