@@ -10,14 +10,17 @@ import {
1010import { Outlet } from '@tanstack/react-router' ;
1111import { styles } from '../styles' ;
1212import { useFrontier } from '~/react/contexts/FrontierContext' ;
13- import { useCallback , useEffect , useState } from 'react' ;
13+ import { useCallback , useEffect } from 'react' ;
1414import billingStyles from './billing.module.css' ;
1515import {
16- V1Beta1CheckoutSetupBody ,
17- V1Beta1Invoice
18- } from '~/src' ;
19- import { BillingAccount } from '@raystack/proton/frontier' ;
20- // import { converBillingAddressToString } from '~/react/utils';
16+ BillingAccount ,
17+ ListInvoicesRequestSchema ,
18+ FrontierServiceQueries ,
19+ CreateCheckoutRequestSchema
20+ } from '@raystack/proton/frontier' ;
21+ import { useQuery as useConnectQuery } from '@connectrpc/connect-query' ;
22+ import { create } from '@bufbuild/protobuf' ;
23+ import { useMutation } from '~hooks' ;
2124import Invoices from './invoices' ;
2225import qs from 'query-string' ;
2326
@@ -84,13 +87,12 @@ const BillingDetails = ({
8487 isAllowed,
8588 disabled = false
8689} : BillingDetailsProps ) => {
87- // const addressStr = converBillingAddressToString(billingAccount?.address);
8890 const btnText =
8991 billingAccount ?. email || billingAccount ?. name ? 'Update' : 'Add details' ;
9092 const isButtonDisabled = isLoading || disabled ;
9193 return (
9294 < div className = { billingStyles . detailsBox } >
93- < Flex align = "center" justify = "between" style = { { width : '100%' } } >
95+ < Flex align = "center" justify = "between" width = "full" >
9496 < Text className = { billingStyles . detailsBoxHeading } > Billing Details</ Text >
9597 { isAllowed ? (
9698 < Tooltip
@@ -131,7 +133,6 @@ export default function Billing() {
131133 const {
132134 billingAccount,
133135 isBillingAccountLoading,
134- client,
135136 config,
136137 activeSubscription,
137138 isActiveSubscriptionLoading,
@@ -140,83 +141,91 @@ export default function Billing() {
140141 isOrganizationKycLoading
141142 } = useFrontier ( ) ;
142143
143- const [ invoices , setInvoices ] = useState < V1Beta1Invoice [ ] > ( [ ] ) ;
144- const [ isInvoicesLoading , setIsInvoicesLoading ] = useState ( false ) ;
145144 const { isAllowed, isFetching } = useBillingPermission ( ) ;
146145
147- const fetchInvoices = useCallback (
148- async ( organizationId : string , billingId : string ) => {
149- setIsInvoicesLoading ( true ) ;
150- try {
151- const resp = await client ?. frontierServiceListInvoices (
152- organizationId ,
153- billingId ,
154- { nonzero_amount_only : true }
155- ) ;
156- const newInvoices = resp ?. data ?. invoices || [ ] ;
157- setInvoices ( newInvoices ) ;
158- } catch ( err ) {
159- console . error ( err ) ;
160- } finally {
161- setIsInvoicesLoading ( false ) ;
162- }
163- } ,
164- [ client ]
146+ const {
147+ data : invoices = [ ] ,
148+ isLoading : isInvoicesLoading ,
149+ error : invoicesError
150+ } = useConnectQuery (
151+ FrontierServiceQueries . listInvoices ,
152+ create ( ListInvoicesRequestSchema , {
153+ orgId : billingAccount ?. orgId || '' ,
154+ billingId : billingAccount ?. id || '' ,
155+ nonzeroAmountOnly : true
156+ } ) ,
157+ {
158+ enabled : ! ! billingAccount ?. id && ! ! billingAccount ?. orgId ,
159+ select : data => data ?. invoices || [ ]
160+ }
165161 ) ;
166162
167163 useEffect ( ( ) => {
168- if ( billingAccount ?. id && billingAccount ?. orgId ) {
169- fetchInvoices ( billingAccount ?. orgId , billingAccount ?. id ) ;
164+ if ( invoicesError ) {
165+ toast . error ( 'Failed to load invoices' , {
166+ description : invoicesError ?. message
167+ } ) ;
168+ }
169+ } , [ invoicesError ] ) ;
170+
171+ const { mutateAsync : createCheckoutMutation } = useMutation (
172+ FrontierServiceQueries . createCheckout ,
173+ {
174+ onError : ( err : Error ) => {
175+ console . error ( err ) ;
176+ toast . error ( 'Something went wrong' , {
177+ description : err ?. message
178+ } ) ;
179+ }
170180 }
171- } , [ billingAccount ?. id , billingAccount ?. orgId , client , fetchInvoices ] ) ;
181+ ) ;
172182
173183 const onAddDetailsClick = useCallback ( async ( ) => {
174184 const orgId = billingAccount ?. orgId || '' ;
175185 const billingAccountId = billingAccount ?. id || '' ;
176- if ( billingAccountId && orgId ) {
177- try {
178- const query = qs . stringify (
179- {
180- details : btoa (
181- qs . stringify ( {
182- billing_id : billingAccount ?. id ,
183- organization_id : billingAccount ?. orgId ,
184- type : 'billing'
185- } )
186- ) ,
187- checkout_id : '{{.CheckoutID}}'
188- } ,
189- { encode : false }
190- ) ;
191- const cancel_url = `${ config ?. billing ?. cancelUrl } ?${ query } ` ;
192- const success_url = `${ config ?. billing ?. successUrl } ?${ query } ` ;
186+ if ( ! billingAccountId || ! orgId ) return ;
193187
194- const setup_body : V1Beta1CheckoutSetupBody = {
195- customer_portal : true
196- } ;
188+ try {
189+ const query = qs . stringify (
190+ {
191+ details : btoa (
192+ qs . stringify ( {
193+ billing_id : billingAccount ?. id ,
194+ organization_id : billingAccount ?. orgId ,
195+ type : 'billing'
196+ } )
197+ ) ,
198+ checkout_id : '{{.CheckoutID}}'
199+ } ,
200+ { encode : false }
201+ ) ;
202+ const cancel_url = `${ config ?. billing ?. cancelUrl } ?${ query } ` ;
203+ const success_url = `${ config ?. billing ?. successUrl } ?${ query } ` ;
197204
198- const resp = await client ?. frontierServiceCreateCheckout (
199- billingAccount ?. orgId || '' ,
200- billingAccount ?. id || '' ,
201- {
202- cancel_url,
203- success_url,
204- setup_body
205+ const resp = await createCheckoutMutation (
206+ create ( CreateCheckoutRequestSchema , {
207+ orgId : billingAccount ?. orgId || '' ,
208+ billingId : billingAccount ?. id || '' ,
209+ cancelUrl : cancel_url ,
210+ successUrl : success_url ,
211+ setupBody : {
212+ paymentMethod : false ,
213+ customerPortal : true
205214 }
206- ) ;
207- const checkout_url = resp ?. data ?. checkout_session ?. checkout_url ;
208- if ( checkout_url ) {
209- window . location . href = checkout_url ;
210- }
211- } catch ( err ) {
212- console . error ( err ) ;
213- toast . error ( 'Something went wrong' ) ;
215+ } )
216+ ) ;
217+ const checkoutUrl = resp ?. checkoutSession ?. checkoutUrl ;
218+ if ( checkoutUrl ) {
219+ window . location . href = checkoutUrl ;
214220 }
221+ } catch ( err ) {
222+ console . error ( err ) ;
223+ toast . error ( 'Something went wrong' ) ;
215224 }
216225 } , [
217226 billingAccount ?. id ,
218227 billingAccount ?. orgId ,
219- client ,
228+ createCheckoutMutation ,
220229 config ?. billing ?. cancelUrl ,
221230 config ?. billing ?. successUrl
222231 ] ) ;
@@ -231,7 +240,7 @@ export default function Billing() {
231240 const isOrganizationKycCompleted = organizationKyc ?. status === true ;
232241
233242 return (
234- < Flex direction = "column" style = { { width : '100%' } } >
243+ < Flex direction = "column" width = "full" >
235244 < Flex style = { styles . header } >
236245 < Text size = "large" > Billing</ Text >
237246 </ Flex >
0 commit comments