@@ -16,7 +16,7 @@ import {
1616 useProgramCount , useProgram , useCreateProgram ,
1717 useAssignProgramAdmin , useAddMember , useMemberBalance ,
1818} from "@/hooks/useRewardsProgram" ;
19- import { CONTRACTS , REWARDS_PROGRAM_ABI , MemberRoleLabels , MemberRoleEnum } from "@/config/contracts" ;
19+ import { CONTRACTS , REWARDS_PROGRAM_ABI , MemberRoleLabels , MemberRoleEnum , MemberTypeLabels } from "@/config/contracts" ;
2020import { fromBytes8 , fromBytes12 , shortenAddress , formatFula , isValidAddress , formatContractError } from "@/lib/utils" ;
2121import { OnChainDisclaimer } from "@/components/common/OnChainDisclaimer" ;
2222import { QRCodeDisplay } from "@/components/common/QRCodeDisplay" ;
@@ -73,6 +73,9 @@ function MemberRow({ programId, wallet }: { programId: number; wallet: `0x${stri
7373 size = "small"
7474 />
7575 </ TableCell >
76+ < TableCell >
77+ < Chip label = { MemberTypeLabels [ Number ( member . memberType ) ] || "Free" } size = "small" variant = "outlined" />
78+ </ TableCell >
7679 < TableCell > { shortenAddress ( member . parent ) } </ TableCell >
7780 < TableCell >
7881 { balance ? `${ formatFula ( balance [ 0 ] ) } / ${ formatFula ( balance [ 1 ] ) } / ${ formatFula ( balance [ 2 ] ) } ` : "-" }
@@ -104,7 +107,9 @@ function ProgramDetail({ programId }: { programId: number }) {
104107 const [ mWallet , setMWallet ] = useState ( "" ) ;
105108 const [ mMemberId , setMMemberId ] = useState ( "" ) ;
106109 const [ mRole , setMRole ] = useState ( 1 ) ;
110+ const [ paMemberType , setPaMemberType ] = useState ( 0 ) ;
107111 const [ paDisclaimer , setPaDisclaimer ] = useState ( false ) ;
112+ const [ mMemberType , setMMemberType ] = useState ( 0 ) ;
108113 const [ mDisclaimer , setMDisclaimer ] = useState ( false ) ;
109114
110115 const canAddMembers = isAdmin || role === MemberRoleEnum . ProgramAdmin || role === MemberRoleEnum . TeamLeader ;
@@ -115,14 +120,14 @@ function ProgramDetail({ programId }: { programId: number }) {
115120 // Reset and close dialogs on success
116121 useEffect ( ( ) => {
117122 if ( isSuccessPA ) {
118- const t = setTimeout ( ( ) => { setOpenPA ( false ) ; setPaWallet ( "" ) ; setPaMemberId ( "" ) ; setPaDisclaimer ( false ) ; } , 1500 ) ;
123+ const t = setTimeout ( ( ) => { setOpenPA ( false ) ; setPaWallet ( "" ) ; setPaMemberId ( "" ) ; setPaMemberType ( 0 ) ; setPaDisclaimer ( false ) ; } , 1500 ) ;
119124 return ( ) => clearTimeout ( t ) ;
120125 }
121126 } , [ isSuccessPA ] ) ;
122127
123128 useEffect ( ( ) => {
124129 if ( isSuccessM ) {
125- const t = setTimeout ( ( ) => { setOpenMember ( false ) ; setMWallet ( "" ) ; setMMemberId ( "" ) ; setMRole ( 1 ) ; setMDisclaimer ( false ) ; } , 1500 ) ;
130+ const t = setTimeout ( ( ) => { setOpenMember ( false ) ; setMWallet ( "" ) ; setMMemberId ( "" ) ; setMRole ( 1 ) ; setMMemberType ( 0 ) ; setMDisclaimer ( false ) ; } , 1500 ) ;
126131 return ( ) => clearTimeout ( t ) ;
127132 }
128133 } , [ isSuccessM ] ) ;
@@ -193,6 +198,7 @@ function ProgramDetail({ programId }: { programId: number }) {
193198 < TableCell > Member ID</ TableCell >
194199 < TableCell > Wallet</ TableCell >
195200 < TableCell > Role</ TableCell >
201+ < TableCell > Type</ TableCell >
196202 < TableCell > Parent</ TableCell >
197203 < TableCell > Balance (FULA)</ TableCell >
198204 < TableCell > Status</ TableCell >
@@ -201,7 +207,7 @@ function ProgramDetail({ programId }: { programId: number }) {
201207 </ TableHead >
202208 < TableBody >
203209 < TableRow >
204- < TableCell colSpan = { 7 } align = "center" >
210+ < TableCell colSpan = { 8 } align = "center" >
205211 < Typography variant = "body2" color = "text.secondary" >
206212 Search for members on the Members page by their Member ID.
207213 </ Typography >
@@ -221,14 +227,22 @@ function ProgramDetail({ programId }: { programId: number }) {
221227 error = { ! ! paWallet && ! paWalletValid } helperText = { paWallet && ! paWalletValid ? "Invalid wallet address" : "Leave empty to create walletless member" } />
222228 < TextField label = "Member ID" value = { paMemberId } onChange = { ( e ) => setPaMemberId ( e . target . value ) }
223229 fullWidth margin = "normal" inputProps = { { maxLength : 12 } } />
230+ < FormControl fullWidth margin = "normal" >
231+ < InputLabel > Member Type</ InputLabel >
232+ < Select value = { paMemberType } onChange = { ( e ) => setPaMemberType ( Number ( e . target . value ) ) } label = "Member Type" >
233+ { Object . entries ( MemberTypeLabels ) . map ( ( [ k , v ] ) => (
234+ < MenuItem key = { k } value = { Number ( k ) } > { v } </ MenuItem >
235+ ) ) }
236+ </ Select >
237+ </ FormControl >
224238 { errorPA && < Alert severity = "error" sx = { { mt : 2 } } > { formatContractError ( errorPA ) } </ Alert > }
225239 { isSuccessPA && < Alert severity = "success" sx = { { mt : 2 } } > Program Admin assigned!</ Alert > }
226240 < OnChainDisclaimer accepted = { paDisclaimer } onChange = { setPaDisclaimer } />
227241 </ DialogContent >
228242 < DialogActions >
229243 < Button onClick = { ( ) => setOpenPA ( false ) } > Cancel</ Button >
230244 < Button variant = "contained"
231- onClick = { ( ) => assignProgramAdmin ( programId , ( paWallet || "0x0000000000000000000000000000000000000000" ) as `0x${string } `, paMemberId ) }
245+ onClick = { ( ) => assignProgramAdmin ( programId , ( paWallet || "0x0000000000000000000000000000000000000000" ) as `0x${string } `, paMemberId , "0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${ string } ` , paMemberType ) }
232246 disabled = { isPendingPA || isConfirmingPA || ! paMemberId || ! paDisclaimer || ( ! ! paWallet && ! paWalletValid ) } >
233247 { isPendingPA || isConfirmingPA ? < CircularProgress size = { 20 } /> : "Assign" }
234248 </ Button >
@@ -257,14 +271,22 @@ function ProgramDetail({ programId }: { programId: number }) {
257271 ) }
258272 </ Select >
259273 </ FormControl >
274+ < FormControl fullWidth margin = "normal" >
275+ < InputLabel > Member Type</ InputLabel >
276+ < Select value = { mMemberType } onChange = { ( e ) => setMMemberType ( Number ( e . target . value ) ) } label = "Member Type" >
277+ { Object . entries ( MemberTypeLabels ) . map ( ( [ k , v ] ) => (
278+ < MenuItem key = { k } value = { Number ( k ) } > { v } </ MenuItem >
279+ ) ) }
280+ </ Select >
281+ </ FormControl >
260282 { errorM && < Alert severity = "error" sx = { { mt : 2 } } > { formatContractError ( errorM ) } </ Alert > }
261283 { isSuccessM && < Alert severity = "success" sx = { { mt : 2 } } > Member added!</ Alert > }
262284 < OnChainDisclaimer accepted = { mDisclaimer } onChange = { setMDisclaimer } />
263285 </ DialogContent >
264286 < DialogActions >
265287 < Button onClick = { ( ) => setOpenMember ( false ) } > Cancel</ Button >
266288 < Button variant = "contained"
267- onClick = { ( ) => addMember ( programId , ( mWallet || "0x0000000000000000000000000000000000000000" ) as `0x${string } `, mMemberId , mRole ) }
289+ onClick = { ( ) => addMember ( programId , ( mWallet || "0x0000000000000000000000000000000000000000" ) as `0x${string } `, mMemberId , mRole , "0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${ string } ` , mMemberType ) }
268290 disabled = { isPendingM || isConfirmingM || ! mMemberId || ! mDisclaimer || ( ! ! mWallet && ! mWalletValid ) } >
269291 { isPendingM || isConfirmingM ? < CircularProgress size = { 20 } /> : "Add" }
270292 </ Button >
0 commit comments