1- " use client" ;
1+ ' use client' ;
22
3- import { useState , useCallback } from "react" ;
4- import type { TransactionSummaryItem } from "../components/ui/ConfirmTransactionDialog" ;
3+ import { useQueryClient } from '@tanstack/react-query' ;
4+ import { useContractMutation } from './useContractMutation' ;
5+ import { useConfirmation } from './useConfirmation' ; // Existing hook
56
6- interface ConfirmedMutationOptions < TVariables > {
7- /** Build the summary rows from the mutation variables. */
8- buildSummary ?: ( variables : TVariables ) => TransactionSummaryItem [ ] ;
9- /** Dialog title. */
10- title ?: string ;
11- /** Dialog description / warning text. */
12- description ?: string ;
13- /** Label for the confirm button. */
14- confirmLabel ?: string ;
7+ interface ConfirmedMutationOptions < TData , TVariables > {
8+ operation : string ;
9+ buildTx : ( variables : TVariables ) => Promise < string > ;
10+ signTx : ( xdr : string ) => Promise < string > ;
11+ submitTx : ( signedXdr : string ) => Promise < { hash : string } > ;
12+ queryKeys : string [ ] ; // Queries to invalidate on success
13+ onSuccess ?: ( data : TData , variables : TVariables ) => void ;
1514}
1615
17- /**
18- * Wraps any async mutation with a confirmation dialog flow.
19- *
20- * Usage:
21- * ```tsx
22- * const { dialogProps, trigger, isLoading } = useConfirmedMutation(
23- * (vars) => approveLoanMutation.mutateAsync(vars),
24- * {
25- * title: "Approve Loan",
26- * buildSummary: (vars) => [
27- * { label: "Loan ID", value: String(vars.loanId) },
28- * { label: "Amount", value: `${vars.amount} USDC` },
29- * ],
30- * },
31- * );
32- *
33- * // Render the dialog using dialogProps, trigger on button click:
34- * <button onClick={() => trigger(variables)}>Approve</button>
35- * <ConfirmTransactionDialog {...dialogProps} />
36- * ```
37- */
38- export function useConfirmedMutation < TVariables > (
39- action : ( variables : TVariables ) => Promise < unknown > ,
40- options : ConfirmedMutationOptions < TVariables > = { } ,
16+ export function useConfirmedMutation < TData = unknown , TVariables = unknown > (
17+ options : ConfirmedMutationOptions < TData , TVariables >
4118) {
42- const [ isOpen , setIsOpen ] = useState ( false ) ;
43- const [ isLoading , setIsLoading ] = useState ( false ) ;
44- const [ pendingVariables , setPendingVariables ] = useState < TVariables | null > ( null ) ;
45- const [ summary , setSummary ] = useState < TransactionSummaryItem [ ] > ( [ ] ) ;
19+ const queryClient = useQueryClient ( ) ;
20+ const { confirm } = useConfirmation ( ) ; // Existing confirmation hook
4621
47- const trigger = useCallback (
48- ( variables : TVariables ) => {
49- setPendingVariables ( variables ) ;
50- setSummary ( options . buildSummary ? options . buildSummary ( variables ) : [ ] ) ;
51- setIsOpen ( true ) ;
22+ const mutation = useContractMutation ( {
23+ ... options ,
24+ confirmTx : async ( hash : string ) => {
25+ // Use existing confirmation hook with unified timeout
26+ return confirm ( hash , { timeout : 30000 , pollingInterval : 2000 } ) ;
5227 } ,
53- [ options ] ,
54- ) ;
55-
56- const handleConfirm = useCallback ( async ( ) => {
57- if ( pendingVariables === null ) return ;
58- setIsLoading ( true ) ;
59- try {
60- await action ( pendingVariables ) ;
61- } finally {
62- setIsLoading ( false ) ;
63- setIsOpen ( false ) ;
64- setPendingVariables ( null ) ;
65- }
66- } , [ action , pendingVariables ] ) ;
67-
68- const handleClose = useCallback ( ( ) => {
69- if ( isLoading ) return ; // block dismiss while tx is in-flight
70- setIsOpen ( false ) ;
71- setPendingVariables ( null ) ;
72- } , [ isLoading ] ) ;
73-
74- return {
75- /** Spread onto <ConfirmTransactionDialog> */
76- dialogProps : {
77- isOpen,
78- onClose : handleClose ,
79- onConfirm : handleConfirm ,
80- title : options . title ,
81- description : options . description ,
82- confirmLabel : options . confirmLabel ,
83- summary,
84- isLoading,
28+ onSuccess : ( data , variables ) => {
29+ // Invalidate relevant queries
30+ options . queryKeys . forEach ( ( key ) => {
31+ queryClient . invalidateQueries ( { queryKey : [ key ] } ) ;
32+ } ) ;
33+ options . onSuccess ?.( data , variables ) ;
8534 } ,
86- /** Call with mutation variables to open the dialog */
87- trigger,
88- isLoading,
89- } ;
90- }
35+ } ) ;
36+
37+ return mutation ;
38+ }
0 commit comments