fix(web): fetch real group members from contract using groupId#223
Open
mvanhorn wants to merge 1 commit into
Open
fix(web): fetch real group members from contract using groupId#223mvanhorn wants to merge 1 commit into
mvanhorn wants to merge 1 commit into
Conversation
GroupMembers accepted a `groupId` prop but never used it; it rendered a
hardcoded array of 8 fake members. Real members from the savings contract
were never displayed.
Changes:
- Calls `useSavingsContract().getMembersByGroup(groupId)` inside an effect.
- Maps the contract Member shape (address, joinOrder, joinTimestamp,
status, totalContributed, hasReceivedPayout) to the existing render
surface. join_timestamp (u64 unix seconds, BigInt) is formatted as a
'Mmm YYYY' string.
- Maps contract MemberStatus to the existing badge variants:
Active -> pending
PaidCurrentRound -> paid
Overdue -> overdue
Defaulted -> overdue
ReceivedPayout -> received
- Determines 'isYou' by comparing each member address to publicKey from
useWallet().
- Adds a skeleton loading state while fetching.
- Adds an empty state when no members are returned, and an error state
when the contract call fails.
- Adds 'use client' (the component is now stateful and uses hooks).
MemberStatusBadge variants are unchanged per the issue notes.
Closes BlockHaven-Labs#49
|
@mvanhorn is attempting to deploy a commit to the aminubabafatima8-gmailcom's projects Team on Vercel. A member of the Team first needs to authorize it. |
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.
Summary
GroupMembersaccepted agroupIdprop but never read it; it rendered a hardcoded array of 8 fake members at the top ofapps/web/components/group-members.tsx. Real members from the savings contract were never displayed. This PR replaces the hardcoded array with a contract fetch viauseSavingsContract().getMembersByGroup(groupId), mapped onto the existing render surface.Closes #49
Why this matters
The component is wired into a group detail page that already passes the right
groupId, so users opening a group's "Members" tab were seeing eight invented Stellar addresses regardless of which group they were looking at. The contract already exposesget_members(groupId)throughuseSavingsContract; the hook just wasn't being called. This is exactly the scenario the issue describes as the bug, and the fix is to wire the existing hook to the existing prop.Approach
The component is now a client component (
"use client"is required because it usesuseEffect,useState, and the wallet/contract hooks). The fetch runs inside auseEffectkeyed on[canFetch, groupId, getMembersByGroup, publicKey]. Updates happen intry/catch/finallycallbacks of an async IIFE so the effect body itself does not synchronously callsetState(react-hooks/set-state-in-effectis enforced and was the only new lint error in the first iteration).Contract members map to the existing render shape with three small adapters. Addresses are truncated to
XXXX...XXXXfor display, the position number comes fromjoinOrder, andjoinTimestamp(au64of unix seconds, BigInt) is formatted asMmm YYYYviatoLocaleDateString. Contract status maps to the existing badge variants:Active->pending,PaidCurrentRound->paid,Overdue->overdue,Defaulted->overdue(closest at-risk match),ReceivedPayout->received. TheisYouflag is derived by comparing each member's fulladdressagainstpublicKeyfromuseWallet().MemberStatusBadgeitself is unchanged per the issue notes.The component renders a skeleton row stack while fetching (matches
dashboard-stats.tsx), an empty-state message when no members come back, and an inline error message if the contract call rejects.Acceptance criteria (issue body)
const members = [...]array removed"use client"addeduseSavingsContract().getMembersByGroup(groupId)called inside auseEffectisYouderived frompublicKey === member.addressjoinTimestamp(u64) formatted as a readable date stringVerification
npx tsc --noEmitis clean for the changed file.npx eslint components/group-members.tsxis clean; the previously reportedreact-hooks/set-state-in-effectviolation is gone after moving updates into the async callback. Pre-existing lint problems elsewhere in the repo (for exampledashboard-stats.tsxanduseUserGroups.ts) are untouched.Notes
Contract
MemberStatus.Defaultedhas no direct existing badge variant; it is mapped tooverduebecause both communicate an at-risk state. Happy to add a dedicateddefaultedvariant in a follow-up if preferred.