@@ -31,9 +31,12 @@ import {
3131} from '@hypha-platform/core/client' ;
3232import { useScrollToErrors } from '../../hooks' ;
3333import { useDbTokens } from '../../hooks/use-db-tokens' ;
34+ import { useDbSpaces } from '../../hooks' ;
3435import { formatCurrencyValue } from '@hypha-platform/ui-utils' ;
3536import { Loader2 } from 'lucide-react' ;
3637import { formatUnits } from 'viem' ;
38+ import { RecipientField } from '../../agreements/plugins/components/common/recipient-field' ;
39+ import { useEffect } from 'react' ;
3740
3841type PurchasableToken = {
3942 id : number ;
@@ -55,6 +58,8 @@ const buySpaceTokensSchema = z.object({
5558 . refine ( ( v ) => parseFloat ( v ) > 0 , {
5659 message : 'Amount must be greater than 0' ,
5760 } ) ,
61+ buyerAddress : z . string ( ) . optional ( ) ,
62+ paymentRecipient : z . string ( ) . optional ( ) ,
5863} ) ;
5964
6065type FormValues = z . infer < typeof buySpaceTokensSchema > ;
@@ -170,6 +175,8 @@ export const PeopleBuySpaceTokens = ({
170175 defaultValues : {
171176 tokenAddress : '' ,
172177 amount : '' ,
178+ buyerAddress : person ?. address ?? '' ,
179+ paymentRecipient : '' ,
173180 } ,
174181 } ) ;
175182
@@ -229,6 +236,35 @@ export const PeopleBuySpaceTokens = ({
229236 formatUnits ( sale . salePricePerToken , sale . paymentTokenDecimals ) ,
230237 ) ;
231238 } , [ sale ] ) ;
239+ const { spaces } = useDbSpaces ( {
240+ parentOnly : false ,
241+ } ) ;
242+ const buyerMembers = useMemo (
243+ ( ) => ( person ?. address ? [ person ] : [ ] ) ,
244+ [ person ] ,
245+ ) ;
246+ const recipientSpaces = useMemo (
247+ ( ) =>
248+ spaces ?. filter (
249+ ( space ) =>
250+ sale ?. executor &&
251+ space . address ?. toLowerCase ( ) === sale . executor . toLowerCase ( ) ,
252+ ) ?? [ ] ,
253+ [ sale ?. executor , spaces ] ,
254+ ) ;
255+
256+ useEffect ( ( ) => {
257+ if ( buyerAddress || person ?. address ) {
258+ form . setValue ( 'buyerAddress' , buyerAddress ?? person ?. address ?? '' , {
259+ shouldDirty : false ,
260+ } ) ;
261+ }
262+ if ( sale ?. executor ) {
263+ form . setValue ( 'paymentRecipient' , sale . executor , {
264+ shouldDirty : false ,
265+ } ) ;
266+ }
267+ } , [ buyerAddress , person ?. address , sale ?. executor , form ] ) ;
232268
233269 const handleApprove = async ( ) => {
234270 form . clearErrors ( 'root' ) ;
@@ -386,7 +422,7 @@ export const PeopleBuySpaceTokens = ({
386422 </ div >
387423 </ div >
388424
389- { selectedToken && ! isNaN ( parsedAmount ) && parsedAmount > 0 && (
425+ { selectedToken && ! isNaN ( parsedAmount ) && parsedAmount > 0 && sale && (
390426 < div className = "text-sm text-neutral-11" >
391427 < div >
392428 Price:{ ' ' }
@@ -405,68 +441,6 @@ export const PeopleBuySpaceTokens = ({
405441 < div >
406442 Remaining in sale: < strong > { remainingForSale } </ strong >
407443 </ div >
408- < div >
409- Buyer eligibility:{ ' ' }
410- < strong >
411- { sale ?. canPurchase ? 'Eligible' : 'Not eligible for this sale' }
412- </ strong >
413- </ div >
414- < div >
415- Purchase mode:{ ' ' }
416- < strong > { sale ?. purchaseEligibilityMode ?? '-' } </ strong >
417- </ div >
418- < div >
419- Allowance:{ ' ' }
420- < strong >
421- { sale
422- ? `${ formatCurrencyValue (
423- Number (
424- formatUnits ( sale . allowance , sale . paymentTokenDecimals ) ,
425- ) ,
426- ) } ${ paymentTokenMeta ?. symbol ?? '' } `
427- : '-' }
428- </ strong >
429- </ div >
430- < div >
431- Balance:{ ' ' }
432- < strong >
433- { sale
434- ? `${ formatCurrencyValue (
435- Number (
436- formatUnits ( sale . balance , sale . paymentTokenDecimals ) ,
437- ) ,
438- ) } ${ paymentTokenMeta ?. symbol ?? '' } `
439- : '-' }
440- </ strong >
441- </ div >
442- < div >
443- Payment token treasury recipient:{ ' ' }
444- < strong className = "break-all" > { sale ?. executor ?? '-' } </ strong >
445- </ div >
446- < div >
447- Wallet used for tx:{ ' ' }
448- < strong className = "break-all" >
449- { buyerAddress ?? person ?. address ?? '-' }
450- </ strong >
451- </ div >
452- { needsApproval && (
453- < div >
454- < strong > Approval required before buying.</ strong >
455- </ div >
456- ) }
457- { ! hasEnoughBalance && (
458- < div >
459- < strong > Insufficient payment token balance.</ strong >
460- </ div >
461- ) }
462- { ( approveError || buyError ) && (
463- < div >
464- < strong >
465- { ( approveError || buyError ) ?. message ??
466- 'Transaction failed. Please retry.' }
467- </ strong >
468- </ div >
469- ) }
470444 </ div >
471445 ) }
472446
@@ -494,45 +468,26 @@ export const PeopleBuySpaceTokens = ({
494468
495469 < Separator />
496470
497- { /* Token sent to (buyer) */ }
498- < div className = "flex flex-col gap-2" >
499- < span className = "text-2 text-neutral-11" > Token sent to</ span >
500- < div className = "flex items-center gap-2 p-2 rounded-md bg-neutral-2 border border-neutral-6" >
501- < span className = "text-2 text-neutral-11 font-medium truncate" >
502- { person ?. name
503- ? `${ person . name } ${ person . surname ? ` ${ person . surname } ` : '' } `
504- : person ?. address ?? '—' }
505- </ span >
506- { ( buyerAddress || person ?. address ) && (
507- < span className = "text-1 text-neutral-10 truncate" >
508- { buyerAddress ?? person ?. address }
509- </ span >
510- ) }
511- </ div >
512- </ div >
471+ < RecipientField
472+ label = { `${ selectedToken ?. symbol ?? 'Token' } sent to` }
473+ members = { buyerMembers }
474+ defaultRecipientType = "member"
475+ readOnly = { true }
476+ showTabs = { false }
477+ name = "buyerAddress"
478+ />
513479
514480 < Separator />
515481
516- { /* Payment sent to (space treasury) */ }
517- < div className = "flex flex-col gap-2" >
518- < span className = "text-2 text-neutral-11" > Payment sent to</ span >
519- < div className = "flex items-center gap-2 p-2 rounded-md bg-neutral-2 border border-neutral-6" >
520- { selectedToken ? (
521- < div className = "flex flex-col" >
522- < span className = "text-2 text-neutral-11 font-medium" >
523- { selectedToken . name } Space Treasury
524- </ span >
525- < span className = "text-1 text-neutral-10 break-all" >
526- { sale ?. executor ?? 'Loading...' }
527- </ span >
528- </ div >
529- ) : (
530- < span className = "text-2 text-neutral-10 italic" >
531- Select a token to see the treasury address
532- </ span >
533- ) }
534- </ div >
535- </ div >
482+ < RecipientField
483+ label = { `${ paymentTokenMeta ?. symbol ?? 'Payment' } paid to` }
484+ members = { [ ] }
485+ spaces = { recipientSpaces }
486+ defaultRecipientType = "space"
487+ readOnly = { true }
488+ showTabs = { false }
489+ name = "paymentRecipient"
490+ />
536491
537492 < Separator />
538493
@@ -594,6 +549,12 @@ export const PeopleBuySpaceTokens = ({
594549 { form . formState . errors . root . message }
595550 </ div >
596551 ) }
552+ { ( approveError || buyError ) && (
553+ < div className = "text-2 text-foreground" >
554+ { ( approveError || buyError ) ?. message ??
555+ 'Transaction failed. Please retry.' }
556+ </ div >
557+ ) }
597558 </ form >
598559 </ Form >
599560 ) ;
0 commit comments