Add Superfluid Campaign GoodWidget - #130
Add Superfluid Campaign GoodWidget#130goodbounties-nanoclaw-agent[bot] wants to merge 12 commits into
Conversation
Implements the widget from #129 (plan for #127): a reusable GoodWidget presenting the Superfluid Ecosystem Rewards campaign — header, two reward-pool action sections (GoodDollar actions, ecosystem funding actions), a leaderboard view, and the campaign FAQ, against a static mock dataset for this phase. - New packages/superfluid-campaign-widget: presentational components, widgetRuntimeContract, mock dataset, and the element/register web component bridge (mirrors the streaming-widget bridge pattern). - Adds a disconnected-state "Connect wallet" CTA in the content view, gated on useWallet().isConnected, matching the #127 acceptance criteria. - Adds Accordion and ProgressBar to packages/ui (reusable, used by the FAQ and pool-progress sections). - Adds an additive initialTab prop to citizen-claim-widget and an additive initialView prop to SuperfluidCampaignWidget, so Storybook/QA fixtures and deep links can land directly on a given view. - Adds Storybook coverage under examples/storybook: a manual injected- wallet showcase story, four QA fixture stories (disconnected/connected x content/leaderboard) using the existing custodial-wallet fixture pattern from citizen-claim-widget, and a doc page that explicitly flags two known gaps for this phase (activity icon glyph registry, live leaderboard search/pagination). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot could not run the full agentic suite for this review because it was automatically requested on a bot-authored pull request. Request a review from Copilot under Reviewers to retry with the full agentic suite. Improved support for bot-authored pull requests is coming soon.
Adds a new “Superfluid campaign” widget package and introduces shared UI primitives needed to render campaign progress and FAQ content, while extending CitizenClaimWidget to support deep-linking into a specific tab.
Changes:
- Export new
ProgressBarandAccordioncomponents from@goodwidget/ui. - Add
@goodwidget/superfluid-campaign-widgetpackage (runtime contract, mock data, widget UI, custom element + registration, tsup build config). - Add
initialTabsupport toCitizenClaimWidgetto open the embedded widget directly on Claim/Invite tabs.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ui/src/index.ts | Exposes new UI primitives (ProgressBar, Accordion) from the UI package entrypoint. |
| packages/ui/src/components/ProgressBar.tsx | Implements labeled progress bar used by campaign pools/leaderboard summary. |
| packages/ui/src/components/Accordion.tsx | Implements shared accordion primitive used for Superfluid FAQ. |
| packages/superfluid-campaign-widget/tsup.config.ts | Adds build configuration for the new widget package (esm/cjs + dts). |
| packages/superfluid-campaign-widget/tsconfig.json | Adds local TS config + workspace path aliases for development. |
| packages/superfluid-campaign-widget/tsconfig.build.json | Adds build-only TS config used by tsup. |
| packages/superfluid-campaign-widget/src/widgetRuntimeContract.ts | Defines the public runtime contract types/constants for the widget. |
| packages/superfluid-campaign-widget/src/mockData.ts | Provides static mock data fixtures for content + leaderboard + FAQ. |
| packages/superfluid-campaign-widget/src/index.ts | Exports public types/constants/mock data and the widget component. |
| packages/superfluid-campaign-widget/src/element.ts | Wraps the widget as a Custom Element via createMiniAppElement. |
| packages/superfluid-campaign-widget/src/register.ts | Registers a default custom element tag and auto-registers on import. |
| packages/superfluid-campaign-widget/src/components/* | Implements campaign header, reward pools, leaderboard views, FAQ wrapper, and icon rendering. |
| packages/superfluid-campaign-widget/src/SuperfluidCampaignWidget.tsx | Composes the full campaign runtime, view routing, and CTA handling including embedded CitizenClaimWidget. |
| packages/superfluid-campaign-widget/package.json | Declares the new package, build outputs, and exports map. |
| packages/citizen-claim-widget/src/widgetRuntimeContract.ts | Adds CitizenClaimTab and initialTab to the widget props contract. |
| packages/citizen-claim-widget/src/CitizenClaimWidget.tsx | Wires initialTab into internal tab state. |
| examples/storybook/src/stories/superfluid-campaign-widget/* | Adds showcase + QA stories/docs for the new widget. |
| examples/storybook/src/stories/helpers/superfluidCampaignWidgetStories.tsx | Adds helper shells/fixtures to render connected/disconnected states. |
| examples/storybook/package.json | Adds the new widget package as a Storybook dependency. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
| if (embeddedClaimTab) { | ||
| return ( | ||
| <YStack gap="$3" width="100%"> | ||
| <CitizenClaimWidget environment={citizenClaimEnvironment} initialTab={embeddedClaimTab} /> |
| <AccordionHeader isOpen={isOpen} onPress={() => toggleItem(item.id)}> | ||
| <Text flex={1}>{item.title}</Text> | ||
| <Icon | ||
| name="chevron-down" | ||
| size="sm" | ||
| color="muted" | ||
| style={{ | ||
| transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)', | ||
| transition: 'transform 150ms ease', | ||
| }} | ||
| /> | ||
| </AccordionHeader> | ||
| {isOpen && <AccordionContent>{item.content}</AccordionContent>} |
| <YStack width="100%" gap="$1"> | ||
| {label && ( | ||
| <XStack justifyContent="space-between" alignItems="center"> | ||
| <Text variant="label">{label}</Text> | ||
| <Text variant="caption">{Math.round(percentage)}%</Text> | ||
| </XStack> | ||
| )} | ||
| <ProgressTrack> | ||
| <ProgressFill variant={variant} width={`${percentage}%`} /> | ||
| </ProgressTrack> | ||
| </YStack> |
| export function register(tagName: string = DEFAULT_TAG_NAME): string { | ||
| if (!customElements.get(tagName)) { | ||
| customElements.define(tagName, SuperfluidCampaignWidgetElement) | ||
| } | ||
| return tagName | ||
| } | ||
|
|
||
| register() |
| const ACTIVITY_ICON_NAME_FALLBACK: Record<CampaignActionMockData['activity'], IconName> = { | ||
| 'claim-ubi': 'check', | ||
| 'invite-users': 'user', | ||
| 'flow-state-vote': 'arrow-up', | ||
| 'flow-state-funding': 'arrows-left-right', | ||
| 'gardens-donation': 'wallet', | ||
| 'gardens-funding': 'refresh', | ||
| } |
| @@ -0,0 +1,59 @@ | |||
| import React from 'react' | |||
| import { Text } from './Text' | |||
| import { XStack, YStack } from '../components-test/Stacks' | |||
| import type { ReactNode } from 'react' | ||
| import { Icon } from './Icon' | ||
| import { Text } from './Text' | ||
| import { XStack, YStack } from '../components-test/Stacks' |
|
@copilot address issues found in review. Also why aren't there any tests and screenshots of the widget? |
…, provider passthrough, add Playwright tests Co-authored-by: sirpy <671095+sirpy@users.noreply.github.com>
All review issues addressed in commit
|
|
@L03TJ3 "components-test imports — Accordion.tsx and ProgressBar.tsx now import XStack/YStack directly from tamagui (same as Card.ts)." |
…e compaction - Add prominent "Claim SUP rewards" CTA opening claim.superfluid.org in a new tab, per Meri's change request. - Add useAirdropStatus hook that fetches the connected wallet's live status from the Superfluid airdrop worker endpoint on connect/load/address-change, with loading and error states. Adds an airdropStatusAdapter DI seam (mirrors the ai-credits-widget adapterFactory convention) so Storybook/ Playwright fixtures stay deterministic instead of hitting the live network. - Mobile compaction pass: FAQ restructured into one collapsible section wrapping per-question accordion toggles, ProgressBar gains hidePercentageOnMobile to drop the redundant percentage where the bar already communicates it, ActionCard description truncates to one line on mobile, CampaignHeader title sized down on small viewports. - Extend the Playwright spec with the new CTA/airdrop-status states and regenerate all baseline screenshots (scw-01..13) against the updated UI. Leaderboard split (606/614) and campaign-level SUP totals remain blocked on cms.superfluid.pro connection registration (task #20). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@sirpy Nothing directly on the components. they are still re-exported from the UI package without any changes. In this PR, it really does not change anything if it imports from tamagui or from the local file 'Stacks.ts' The only change based on our last conversation was made in the provider: https://github.com/GoodDollar/GoodWidget/blob/main/packages/core/src/provider.tsx I have a bounty in preparation for doing a sweep of all the UI components and resolving 'align with design system' so that we can move away from components vs components-test. |
- Apply compactButtonProps sizing to every Button across the widget - Fix mobile copy wrapping in ActionCard/CampaignHeader body text - Restructure ActionCard layout (icon/copy/points-pill/CTA column) - Reclassify Text tone usage (secondary/soft) per design system - Swap activity icons to design reference via new @goodwidget/ui ActivityIcons re-export of @tamagui/lucide-icons (keeps the direct lucide-icons dependency out of the widget package itself) - Move "Connect wallet" CTA to the header's top-right slot - Extend the Storybook react-native-svg web shim with named Svg plus Path/Line/Rect/Polygon/Polyline/Ellipse passthroughs, needed because @tamagui/lucide-icons' barrel export pulls in every icon module during the web build, not just the ones actually imported - Regenerate all 13 Playwright baseline screenshots
Implements the widget from #129 (plan for #127): a reusable GoodWidget presenting the Superfluid Ecosystem Rewards campaign — header, two reward-pool action sections (GoodDollar actions, ecosystem funding actions), a leaderboard view, and the campaign FAQ, against a static mock dataset for this phase. - New packages/superfluid-campaign-widget: presentational components, widgetRuntimeContract, mock dataset, and the element/register web component bridge (mirrors the streaming-widget bridge pattern). - Adds a disconnected-state "Connect wallet" CTA in the content view, gated on useWallet().isConnected, matching the #127 acceptance criteria. - Adds Accordion and ProgressBar to packages/ui (reusable, used by the FAQ and pool-progress sections). - Adds an additive initialTab prop to citizen-claim-widget and an additive initialView prop to SuperfluidCampaignWidget, so Storybook/QA fixtures and deep links can land directly on a given view. - Adds Storybook coverage under examples/storybook: a manual injected- wallet showcase story, four QA fixture stories (disconnected/connected x content/leaderboard) using the existing custodial-wallet fixture pattern from citizen-claim-widget, and a doc page that explicitly flags two known gaps for this phase (activity icon glyph registry, live leaderboard search/pagination). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…, provider passthrough, add Playwright tests Co-authored-by: sirpy <671095+sirpy@users.noreply.github.com>
…e compaction - Add prominent "Claim SUP rewards" CTA opening claim.superfluid.org in a new tab, per Meri's change request. - Add useAirdropStatus hook that fetches the connected wallet's live status from the Superfluid airdrop worker endpoint on connect/load/address-change, with loading and error states. Adds an airdropStatusAdapter DI seam (mirrors the ai-credits-widget adapterFactory convention) so Storybook/ Playwright fixtures stay deterministic instead of hitting the live network. - Mobile compaction pass: FAQ restructured into one collapsible section wrapping per-question accordion toggles, ProgressBar gains hidePercentageOnMobile to drop the redundant percentage where the bar already communicates it, ActionCard description truncates to one line on mobile, CampaignHeader title sized down on small viewports. - Extend the Playwright spec with the new CTA/airdrop-status states and regenerate all baseline screenshots (scw-01..13) against the updated UI. Leaderboard split (606/614) and campaign-level SUP totals remain blocked on cms.superfluid.pro connection registration (task #20). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Apply compactButtonProps sizing to every Button across the widget - Fix mobile copy wrapping in ActionCard/CampaignHeader body text - Restructure ActionCard layout (icon/copy/points-pill/CTA column) - Reclassify Text tone usage (secondary/soft) per design system - Swap activity icons to design reference via new @goodwidget/ui ActivityIcons re-export of @tamagui/lucide-icons (keeps the direct lucide-icons dependency out of the widget package itself) - Move "Connect wallet" CTA to the header's top-right slot - Extend the Storybook react-native-svg web shim with named Svg plus Path/Line/Rect/Polygon/Polyline/Ellipse passthroughs, needed because @tamagui/lucide-icons' barrel export pulls in every icon module during the web build, not just the ones actually imported - Regenerate all 13 Playwright baseline screenshots
98699ea to
a4040c6
Compare
…ar/GoodWidget into feat/superfluid-campaign-widget
…erfluid-campaign-widget
Summary
Implements the Superfluid Ecosystem Rewards campaign widget planned in #129, for parent feature #127.
packages/superfluid-campaign-widget: header, two reward-pool action sections (GoodDollar actions, ecosystem funding actions), a leaderboard view, and the campaign FAQ, rendered against a static mock dataset for this phase.useWallet().isConnected, per [Feature]: Add Superfluid Campaign GoodWidget #127 acceptance criteria.AccordionandProgressBaradded topackages/ui(used by the FAQ and pool-progress sections; assessed as generic enough to belong in the shared package rather than the widget itself).initialTabprop oncitizen-claim-widgetand additiveinitialViewprop onSuperfluidCampaignWidget, so Storybook/QA fixtures and deep links can land directly on a given view.element.ts/register.tsweb-component bridge, mirroring the existingstreaming-widgetpattern.examples/storybook: a manual injected-wallet showcase story, four QA fixture stories (disconnected/connected x content/leaderboard) using the existing custodial-wallet fixture pattern fromcitizen-claim-widget, and a doc page.Known gaps flagged for follow-up (not silently worked around)
ACTIVITY_ICON_MAP's exact icon names aren't yet in@goodwidget/ui's Icon registry; the closest already-registered glyphs are substituted until the registry is extended.Test plan
pnpm build(turbo) succeeds across all packages/appseslintclean on all new/changed files in this PR's scopetsc --noEmitclean on all new/changed files in this PR's scopepnpm storybook)🤖 Generated with Claude Code