Skip to content

Commit 34bfe3e

Browse files
feat: Add ACH payment method
1 parent 56cde4f commit 34bfe3e

File tree

16 files changed

+547
-161
lines changed

16 files changed

+547
-161
lines changed

.env.development

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ REACT_APP_MARKETING_BASE_URL=https://about.codecov.io
55
# REACT_APP_STRIPE_KEY=
66
# REACT_APP_LAUNCHDARKLY=
77
# REACT_APP_BAREMETRICS_TOKEN=
8+
REACT_APP_STRIPE_KEY=pk_test_514SJTOGlVGuVgOrkRgh7zxp3tQ7bX4CY6pnxxw6zRZZSoDVtUUjArPKC7oXeeIbJNICTqS7H88FRfwZnWMskPKxo00bAnu2i9I
9+
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_514SJTOGlVGuVgOrkRgh7zxp3tQ7bX4CY6pnxxw6zRZZSoDVtUUjArPKC7oXeeIbJNICTqS7H88FRfwZnWMskPKxo00bAnu2i9I

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.tsx

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,47 @@ import Button from 'ui/Button'
1010
import Icon from 'ui/Icon'
1111

1212
import AddressForm from './AddressForm'
13+
import { cn } from 'shared/utils/cn'
1314

1415
interface AddressCardProps {
16+
isEditMode: boolean
17+
setEditMode: (isEditMode: boolean) => void
1518
subscriptionDetail: z.infer<typeof SubscriptionDetailSchema>
1619
provider: string
1720
owner: string
21+
className?: string
1822
}
1923

2024
function AddressCard({
25+
isEditMode,
26+
setEditMode,
2127
subscriptionDetail,
2228
provider,
2329
owner,
30+
className,
2431
}: AddressCardProps) {
25-
const [isFormOpen, setIsFormOpen] = useState(false)
2632
const billingDetails =
2733
subscriptionDetail?.defaultPaymentMethod?.billingDetails
2834

35+
const isAddressSameAsPrimary = true // TODO
36+
2937
return (
30-
<div className="flex flex-col gap-2 border-t p-4">
31-
{isFormOpen && (
38+
<div className={cn('flex gap-2', className)}>
39+
{isEditMode && (
3240
<AddressForm
3341
name={billingDetails?.name || ''}
3442
address={billingDetails?.address}
3543
provider={provider}
3644
owner={owner}
37-
closeForm={() => setIsFormOpen(false)}
45+
closeForm={() => setEditMode(false)}
3846
/>
3947
)}
40-
{!isFormOpen && (
48+
{!isEditMode && (
4149
<>
42-
<div className="flex justify-between">
43-
<h4 className="font-semibold">Cardholder name</h4>
44-
<A
45-
variant="semibold"
46-
onClick={() => setIsFormOpen(true)}
47-
hook="edit-address"
48-
isExternal={false}
49-
to={undefined}
50-
>
51-
Edit <Icon name="chevronRight" size="sm" variant="solid" />
52-
</A>
53-
</div>
5450
<BillingInner
5551
billingDetails={billingDetails}
56-
setIsFormOpen={setIsFormOpen}
52+
setEditMode={setEditMode}
53+
isAddressSameAsPrimary={isAddressSameAsPrimary}
5754
/>
5855
</>
5956
)}
@@ -63,27 +60,36 @@ function AddressCard({
6360

6461
interface BillingInnerProps {
6562
billingDetails?: z.infer<typeof BillingDetailsSchema>
66-
setIsFormOpen: (val: boolean) => void
63+
setEditMode: (val: boolean) => void
64+
isAddressSameAsPrimary: boolean
6765
}
6866

69-
function BillingInner({ billingDetails, setIsFormOpen }: BillingInnerProps) {
67+
function BillingInner({
68+
billingDetails,
69+
setEditMode,
70+
isAddressSameAsPrimary,
71+
}: BillingInnerProps) {
7072
if (billingDetails) {
7173
return (
7274
<div>
73-
<p>{`${billingDetails.name ?? 'N/A'}`}</p>
74-
<br />
7575
<h4 className="mb-2 font-semibold">Billing address</h4>
76-
<p>{`${billingDetails.address?.line1 ?? ''} ${
77-
billingDetails.address?.line2 ?? ''
78-
}`}</p>
79-
<p>
80-
{billingDetails.address?.city
81-
? `${billingDetails.address?.city}, `
82-
: ''}
83-
{`${billingDetails.address?.state ?? ''} ${
84-
billingDetails.address?.postalCode ?? ''
85-
}`}
86-
</p>
76+
{isAddressSameAsPrimary ? (
77+
<p>Same as primary address</p>
78+
) : (
79+
<>
80+
<p>{`${billingDetails.address?.line1 ?? ''} ${
81+
billingDetails.address?.line2 ?? ''
82+
}`}</p>
83+
<p>
84+
{billingDetails.address?.city
85+
? `${billingDetails.address?.city}, `
86+
: ''}
87+
{`${billingDetails.address?.state ?? ''} ${
88+
billingDetails.address?.postalCode ?? ''
89+
}`}
90+
</p>
91+
</>
92+
)}
8793
</div>
8894
)
8995
}
@@ -98,7 +104,7 @@ function BillingInner({ billingDetails, setIsFormOpen }: BillingInnerProps) {
98104
<Button
99105
hook="open-modal"
100106
variant="primary"
101-
onClick={() => setIsFormOpen(true)}
107+
onClick={() => setEditMode(true)}
102108
to={undefined}
103109
disabled={false}
104110
>

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function AddressForm({
105105
disabled={isLoading}
106106
to={undefined}
107107
>
108-
Update
108+
Save
109109
</Button>
110110
<Button
111111
type="button"

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.tsx

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import { useParams } from 'react-router-dom'
22

33
import { useAccountDetails } from 'services/account'
44

5-
import AddressCard from './Address/AddressCard'
65
import EmailAddress from './EmailAddress'
7-
import PaymentCard from './PaymentCard'
6+
import PaymentMethod from './PaymentMethod'
7+
import Button from 'ui/Button'
8+
import { useState } from 'react'
9+
import A from 'ui/A'
10+
import EditablePaymentMethod from './EditablePaymentMethod'
811

912
interface URLParams {
1013
provider: string
@@ -18,34 +21,82 @@ function BillingDetails() {
1821
owner,
1922
})
2023
const subscriptionDetail = accountDetails?.subscriptionDetail
24+
const [isEditMode, setEditMode] = useState(false)
25+
26+
const isAdmin = true // TODO
2127

2228
if (!subscriptionDetail) {
2329
return null
2430
}
2531

32+
console.log('iseditmode', isEditMode)
33+
2634
return (
2735
<div className="flex flex-col border">
28-
<h3 className="p-4 font-semibold">Billing details</h3>
29-
<EmailAddress />
30-
<PaymentCard
31-
// @ts-expect-error - TODO fix this once we update PaymentCard to TS
32-
subscriptionDetail={subscriptionDetail}
33-
provider={provider}
34-
owner={owner}
35-
/>
36-
<AddressCard
37-
subscriptionDetail={subscriptionDetail}
38-
provider={provider}
39-
owner={owner}
40-
/>
41-
{subscriptionDetail.taxIds.length > 0 ? (
42-
<div className="flex flex-col gap-2 p-4">
43-
<h4 className="font-semibold">Tax ID</h4>
44-
{subscriptionDetail.taxIds.map((val, index) => (
45-
<p key={index}>{val?.value}</p>
46-
))}
36+
<div className="grid grid-cols-[1fr_auto] items-center gap-4 p-4">
37+
<div>
38+
<h3 className="font-semibold">Billing details</h3>
39+
<p className="pt-1 text-xs text-ds-gray-octonary">
40+
You can modify your billing details. To update your tax IDs, please{' '}
41+
{/* @ts-expect-error ignore until we can convert A component to ts */}
42+
<A to={{ pageName: 'support' }} variant="link">
43+
contact support
44+
</A>
45+
</p>
4746
</div>
48-
) : null}
47+
{!isEditMode ? (
48+
<Button
49+
hook="button"
50+
onClick={() => setEditMode(true)}
51+
variant="default"
52+
disabled={!isAdmin}
53+
>
54+
Edit payment
55+
</Button>
56+
) : (
57+
<Button
58+
hook="button"
59+
onClick={() => setEditMode(false)}
60+
variant="danger"
61+
disabled={!isAdmin}
62+
>
63+
Cancel edit
64+
</Button>
65+
)}
66+
</div>
67+
{isEditMode ? (
68+
<EditablePaymentMethod />
69+
) : (
70+
<>
71+
<EmailAddress />
72+
<PaymentMethod
73+
heading="Primary Payment Method"
74+
isPrimary={true}
75+
isEditMode={isEditMode}
76+
setEditMode={setEditMode}
77+
subscriptionDetail={subscriptionDetail}
78+
provider={provider}
79+
owner={owner}
80+
/>
81+
<PaymentMethod
82+
heading="Secondary Payment Method"
83+
isPrimary={false}
84+
isEditMode={isEditMode}
85+
setEditMode={setEditMode}
86+
subscriptionDetail={subscriptionDetail}
87+
provider={provider}
88+
owner={owner}
89+
/>
90+
{subscriptionDetail?.taxIds?.length ? (
91+
<div className="flex flex-col gap-2 p-4">
92+
<h4 className="font-semibold">Tax ID</h4>
93+
{subscriptionDetail?.taxIds?.map((val, index) => (
94+
<p key={index}>{val?.value}</p>
95+
))}
96+
</div>
97+
) : null}
98+
</>
99+
)}
49100
</div>
50101
)
51102
}

0 commit comments

Comments
 (0)