Skip to content

[GoodBounty]: Finalize GovernanceWidget functionality membership lifecycle, runtime QA, and UI/UX structure #80

Description

@L03TJ3

Summary

PR #77 now has a contract-backed GovernanceWidget foundation, but its membership lifecycle still presents a misleading “restake to rejoin” action. In the current GoodDaoHouses contract, an active member may call unstake(), which returns their G$ and removes their member record; that wallet then becomes a new/non-member and may join again.
A revoked member is deliberately out of scope: the contract has no reactivation route, so this task must not invent one.

Finalize the active-member unstake and no-member onboarding flow, complete the remaining runtime boundaries and contract-edge validation, and make the resulting Storybook/Playwright evidence trustworthy for human review.

After all functionality is done, the UI structure should be aligned with figma design reference (only structuring pages of the widget, header-bar etc):
https://www.figma.com/design/xsk5EiF6CvStA9mtdbA9OR/GoodWidget-Library?node-id=2311-3&t=n8jj6CUBsjyvJ2Je-1

Contributor task

Make sure to start your work as branch-out from: copilot/plan-wire-governancewidget-to-gooddaohouses

Scope checks

Membership lifecycle

  • Replace the existing restake/rejoin action with an active-member unstake() action.
    • Use the actual GoodDaoHouses unstake() call, wait for a successful receipt, and show wallet-confirmation, submitted, confirmed, rejected, and reverted states.
    • Respect the contract lock: unstaking is allowed only after member.updatedAt + termDuration. Show an accurate disabled/explanatory state before that time; never report success before the receipt.
    • After confirmation and refreshed reads, route the wallet to the existing no-member onboarding flow.
  • A wallet whose member record has status: None can use normal onboarding: Citizenship is available; Alignment remains available only when getHoaEligibility(account).isEligible is true.
  • Keep pending Alignment as a pending state. For Revoked, remove the misleading rejoin/restake CTA and show a concise non-actionable status. Do not implement reactivation, committee actions, or an “unrevoke” workaround.

Runtime correctness and maintainability

  • Refactor useGovernanceAdapter into a small composition hook. Separate membership/onboarding and unstake actions, voting state/actions, and funding refresh into meaningful widget-local modules/hooks. Do not create forwarding-only files or move contract calls into UI components.
  • Match vote-window rules before enabling a ballot: the voter and provisional HoA recipients must have joined before the vote start. Use the contract snapshot when it exists; otherwise filter the active HoA provisional list so the widget never submits a recipient the contract will reject.
  • Keep the cumulative funding total inclusive of stopped streams, but only present it as actively streaming when at least one stream has a non-zero current flow rate.

Tests, evidence, and comments

  • Add real-adapter integration tests using mocked viem RPC and Superfluid subgraph responses. Static injected adapter state is useful for visual QA but is not sufficient proof of runtime wiring.
  • Cover: no-member onboarding, eligible/ineligible HoA selection, successful and reverted/rejected registration and unstake receipts, lock-period handling, both-house voting eligibility, Citizen GoodID-root duplicate checks, join-time recipient filtering, 10,000-bps validation, and funding active/stopped/empty/failed states.
  • Keep Storybook runtime states for disconnected, loading, onboarding, pending, active, no eligible HoA, upcoming/open/already-voted/executed vote, funding unavailable, unsupported chain, unstake lock/confirmation/failure, revoked, and friendly error states.
  • Update current Playwright screenshots under tests/widgets/governance-widget/test-results/ when the UI changes; test output should represent the latest states.
  • Update comments in files touched by this work when they become inaccurate. Prefer clear component/function names and JSX structure over comments such as “CTA button” or “field rows.” Keep short comments only where they preserve a non-obvious protocol decision, for example: Citizen voting uses a GoodID root; a vote snapshot excludes members joined after the voting window starts; or stopped streams still contribute to the cumulative received total.

Scope boundaries

In scope

  • The GovernanceWidget lifecycle and runtime code, stories, tests, and generated widget test evidence.
  • Existing GoodDaoHouses read/write interface only, including unstake().
  • Focused comment corrections in files changed for this bounty.

Out of scope

  • Any GoodProtocol contract change, deployment, registry administration, committee UI, or member reactivation/unrevoke mechanism.
    if something is found to be missing from the contract it should be raised as comment in the pull-request.
  • Changing shared packages/ui, packages/core, or packages/embed APIs.
  • New dashboard metrics, project-allocation funding breakdowns, or a detailed voting-page redesign.

Starting points

  • packages/governance-widget/src/adapter.ts — split orchestration; replace restake flow; preserve widget-local boundaries.
  • packages/governance-widget/src/sdks/contracts.ts — verified #299 ABI, record mapping, receipt and address helpers.
  • packages/governance-widget/src/sdks/contractReads.ts — membership, schedule, vote, and FlowSplitter reads.
  • packages/governance-widget/src/sdks/transactions.ts — add/use the unstake() transaction path and receipt handling.
  • packages/governance-widget/src/sdks/funding.ts — cumulative funding aggregation and active-flow metadata.
  • packages/governance-widget/src/GovernanceWidget.tsx — truthful active, pending, revoked, and no-member surfaces; no contract calls here.
  • examples/storybook/src/stories/governance-widget/GovernanceRuntime.stories.tsx — deterministic visual states.
  • tests/widgets/governance-widget/adapter-logic.spec.ts and runtime.spec.ts — extend real-adapter and UI-flow coverage.
  • governance-widget-first-pass-verdict.md — concise review context and previously verified commands.

Definition of Done + how to test

Definition of Done

  • An eligible active member can unstake only when the contract lock permits it; confirmed unstaking returns widget state to no-member onboarding.
  • No-member onboarding, HoA registry gating, pending Alignment, and revoked states are accurate and do not offer an unsupported reactivation path.
  • Registration, unstaking, and voting wait for receipts and clearly represent submitted, rejected, reverted, and confirmed outcomes.
  • Runtime vote recipients and voter eligibility match the GoodDaoHouses vote-start/snapshot rules; submitted allocations are valid addresses totaling exactly 10,000 bps.
  • Funding displays the cumulative received total correctly and distinguishes stopped historical streams from active streaming.
  • useGovernanceAdapter is a composition boundary, with no new monolith or trivial helper-file fragmentation.
  • Mocked-RPC/subgraph tests prove the runtime adapter flows listed above; Storybook and Playwright evidence cover the expected visible states.
  • Comments changed by this work explain non-obvious protocol constraints or decisions, not obvious UI structure; comments unrelated to the changed code are preserved.
  • The PR description mirrors this checklist, links [Feature]: Build functionality into GovernanceWidget #75/[PLAN] Wire GovernanceWidget functionality to GoodDaoHouses #76/Wire GovernanceWidget runtime to GoodDaoHouses #77, includes desktop and mobile evidence, and documents any unrelated root-lint failure.

How to test

pnpm install
pnpm build
pnpm --filter @goodwidget/governance-widget lint
pnpm lint
pnpm test:demo tests/widgets/governance-widget

pnpm lint currently has unrelated root failures. Do not fix other packages for this bounty; record the exact failures in the PR handoff. Run Storybook locally and manually verify the changed active, no-member, pending, revoked, voting, funding, and transaction states at mobile and desktop widths.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions