Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
suejung-sentry committed Jan 24, 2025
1 parent b9ff2e2 commit fb74dde
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 49 deletions.
28 changes: 12 additions & 16 deletions src/pages/PlanPage/PlanPage.jsx → src/pages/PlanPage/PlanPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import config from 'config'
import { SentryRoute } from 'sentry'

import { useAccountDetails } from 'services/account'
import { Provider } from 'shared/api/helpers'
import { Theme, useThemeContext } from 'shared/ThemeContext'
import A from 'ui/A'
import { Alert } from 'ui/Alert'
Expand All @@ -19,10 +20,8 @@ import PlanBreadcrumb from './PlanBreadcrumb'
import { PlanPageDataQueryOpts } from './queries/PlanPageDataQueryOpts'
import Tabs from './Tabs'


import { StripeAppearance } from '../../stripe'


const CancelPlanPage = lazy(() => import('./subRoutes/CancelPlanPage'))
const CurrentOrgPlan = lazy(() => import('./subRoutes/CurrentOrgPlan'))
const InvoicesPage = lazy(() => import('./subRoutes/InvoicesPage'))
Expand All @@ -40,8 +39,13 @@ const Loader = () => (
</div>
)

interface URLParams {
owner: string
provider: Provider
}

function PlanPage() {
const { owner, provider } = useParams()
const { owner, provider } = useParams<URLParams>()
const { data: ownerData } = useSuspenseQueryV5(
PlanPageDataQueryOpts({ owner, provider })
)
Expand All @@ -56,15 +60,8 @@ function PlanPage() {
if (config.IS_SELF_HOSTED || !ownerData?.isCurrentUserPartOfOrg) {
return <Redirect to={`/${provider}/${owner}`} />
}

const isAwaitingVerification =
const hasUnverifiedPaymentMethods =
accountDetails?.unverifiedPaymentMethods?.length
// const isAwaitingFirstPaymentMethodVerification =
// !accountDetails?.subscriptionDetail?.defaultPaymentMethod &&
// isAwaitingVerification

// const hasSuccessfulDefaultPaymentMethod =
// accountDetails?.subscriptionDetail?.defaultPaymentMethod

return (
<div className="flex flex-col gap-4">
Expand All @@ -80,7 +77,7 @@ function PlanPage() {
>
<PlanProvider>
<PlanBreadcrumb />
{isAwaitingVerification ? (
{hasUnverifiedPaymentMethods ? (
<UnverifiedPaymentMethodAlert
url={
accountDetails?.unverifiedPaymentMethods?.[0]
Expand Down Expand Up @@ -117,10 +114,7 @@ function PlanPage() {
)
}

export default PlanPage

// eslint-disable-next-line react/prop-types
const UnverifiedPaymentMethodAlert = ({ url }) => {
const UnverifiedPaymentMethodAlert = ({ url }: { url?: string }) => {
return (
<>
<Alert variant={'warning'}>
Expand All @@ -142,3 +136,5 @@ const UnverifiedPaymentMethodAlert = ({ url }) => {
</>
)
}

export default PlanPage
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ function PaymentCard({ accountDetails, provider, owner }) {
const subscriptionDetail = accountDetails?.subscriptionDetail
const card = subscriptionDetail?.defaultPaymentMethod?.card
const usBankAccount = subscriptionDetail?.defaultPaymentMethod?.usBankAccount
// const isAwaitingDelayedPaymentMethodVerification = true

let nextBillingDisplayDate = null
if (!subscriptionDetail?.cancelAtPeriodEnd) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ const PaymentMethodForm = ({
mutate: updatePaymentMethod,
isLoading,
error,
reset,
} = useUpdatePaymentMethod({
provider,
owner,
name,
email,
address: stripeAddress(billingDetails) || undefined,
})

async function submit(e: React.FormEvent) {
e.preventDefault()

Expand All @@ -67,6 +69,8 @@ const PaymentMethodForm = ({
})
}

const showError = error && !reset

return (
<form onSubmit={submit} aria-label="form">
<div className={cs('flex flex-col gap-3')}>
Expand All @@ -83,7 +87,7 @@ const PaymentMethodForm = ({
}}
/>
<p className="mt-1 text-ds-primary-red">
{error ? getErrorMessage(error) : null}
{showError ? getErrorMessage(error) : null}
</p>
<div className="mb-8 mt-4 flex gap-1">
<Button
Expand Down
23 changes: 8 additions & 15 deletions src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentOrgPlan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,22 @@ function CurrentOrgPlan() {
})
)

const isAwaitingVerification =
accountDetails?.unverifiedPaymentMethods?.length
const isAwaitingFirstPaymentMethodVerification =
// awaitingInitialPaymentMethodVerification is true if the
// customer needs to verify a delayed notification payment method
// like ACH for their first subscription
const awaitingInitialPaymentMethodVerification =
!accountDetails?.subscriptionDetail?.defaultPaymentMethod &&
isAwaitingVerification
accountDetails?.unverifiedPaymentMethods?.length

const scheduledPhase = accountDetails?.scheduleDetail?.scheduledPhase
// customer is delinquent until their first payment method is verified
const isDelinquent =
accountDetails?.delinquent && !isAwaitingFirstPaymentMethodVerification
accountDetails?.delinquent && !awaitingInitialPaymentMethodVerification
const scheduleStart = scheduledPhase
? getScheduleStart(scheduledPhase)
: undefined

const shouldRenderBillingDetails =
!isAwaitingFirstPaymentMethodVerification &&
!awaitingInitialPaymentMethodVerification &&
((accountDetails?.planProvider !== 'github' &&
!accountDetails?.rootOrganization) ||
accountDetails?.usesInvoice)
Expand All @@ -64,21 +64,14 @@ function CurrentOrgPlan() {

const account = enterpriseDetails?.owner?.account

const hasSuccessfulDefaultPaymentMethod =
accountDetails?.subscriptionDetail?.defaultPaymentMethod

const hideSuccessBanner = isAwaitingVerification
? hasSuccessfulDefaultPaymentMethod
: true

return (
<div className="w-full lg:w-4/5">
{planUpdatedNotification.isCancellation ? (
<InfoAlertCancellation
subscriptionDetail={accountDetails?.subscriptionDetail}
/>
) : null}
{hideSuccessBanner ? <InfoMessageStripeCallback /> : null}
<InfoMessageStripeCallback accountDetails={accountDetails} />
{isDelinquent ? <DelinquentAlert /> : null}
{planData?.plan ? (
<div className="flex flex-col gap-4 sm:mr-4 sm:flex-initial md:w-2/3 lg:w-3/4">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import qs from 'qs'
import { useLocation } from 'react-router-dom'
import { z } from 'zod'

import Message from 'old_ui/Message'
import { AccountDetailsSchema } from 'services/account'

// Stripe redirects to this page with ?success or ?cancel in the URL
// this component takes care of rendering a message if it is successful
function InfoMessageStripeCallback() {
function InfoMessageStripeCallback({
accountDetails,
}: {
accountDetails?: z.infer<typeof AccountDetailsSchema>
}) {
const urlParams = qs.parse(useLocation().search, {
ignoreQueryPrefix: true,
})
const isAwaitingVerification =
accountDetails?.unverifiedPaymentMethods?.length

if ('success' in urlParams)
if ('success' in urlParams && !isAwaitingVerification)
return (
<div className="col-start-1 col-end-13 mb-4">
<Message variant="success">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useParams } from 'react-router-dom'

Expand All @@ -23,6 +23,7 @@ import { useUpgradeControls } from './hooks'
import PlanTypeOptions from './PlanTypeOptions'
import UpdateBlurb from './UpdateBlurb/UpdateBlurb'
import UpdateButton from './UpdateButton'
import UpgradeFormModal from './UpgradeFormModal'

type URLParams = {
provider: Provider
Expand All @@ -45,6 +46,9 @@ function UpgradeForm({ selectedPlan, setSelectedPlan }: UpgradeFormProps) {
const { data: plans } = useAvailablePlans({ provider, owner })
const { data: planData } = usePlanData({ owner, provider })
const { upgradePlan } = useUpgradeControls()
const [showModal, setShowModal] = useState(false)
const [formData, setFormData] = useState<UpgradeFormFields>()
const [isUpgrading, setIsUpgrading] = useState(false)
const isSentryUpgrade = canApplySentryUpgrade({
isEnterprisePlan: planData?.plan?.isEnterprisePlan,
plans,
Expand Down Expand Up @@ -90,22 +94,20 @@ function UpgradeForm({ selectedPlan, setSelectedPlan }: UpgradeFormProps) {
trigger('seats')
}, [newPlan, trigger])

const onSubmit = handleSubmit((data) => {
if (accountDetails?.unverifiedPaymentMethods?.length) {
setFormData(data)
setShowModal(true)
} else {
setIsUpgrading(true)
upgradePlan(data)
}
})

return (
<form
className="flex flex-col gap-6 border p-4 text-ds-gray-default md:w-2/3"
onSubmit={handleSubmit((data) => {
if (accountDetails?.unverifiedPaymentMethods?.length) {
if (
window.confirm(
'You have a payment method awaiting verification. Are you sure you want to proceed with upgrading your plan? This will cancel the existing action.'
)
) {
upgradePlan(data)
}
} else {
upgradePlan(data)
}
})}
onSubmit={onSubmit}
>
<div className="flex flex-col gap-1">
<h3 className="font-semibold">Organization</h3>
Expand All @@ -131,6 +133,21 @@ function UpgradeForm({ selectedPlan, setSelectedPlan }: UpgradeFormProps) {
nextBillingDate={getNextBillingDate(accountDetails)!}
/>
<UpdateButton isValid={isValid} newPlan={newPlan} seats={seats} />
{showModal && formData && (
<UpgradeFormModal
isOpen={showModal}
onClose={() => setShowModal(false)}
onConfirm={() => {
setIsUpgrading(true)
upgradePlan(formData)
}}
url={
accountDetails?.unverifiedPaymentMethods?.[0]
?.hostedVerificationLink || ''
}
isUpgrading={isUpgrading}
/>
)}
</form>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import A from 'ui/A'
import Button from 'ui/Button'
import Icon from 'ui/Icon'
import Modal from 'ui/Modal'

interface UpgradeModalProps {
isOpen: boolean
onClose: () => void
onConfirm: () => void
url: string
isUpgrading?: boolean
}

const UpgradeFormModal = ({
isOpen,
onClose,
onConfirm,
url,
isUpgrading = false,
}: UpgradeModalProps) => (
<Modal
isOpen={isOpen}
onClose={onClose}
title={
<p className="flex items-center gap-2 text-base">
<Icon
name="exclamationTriangle"
size="sm"
className="fill-ds-primary-yellow"
/>
Incomplete Plan Upgrade
</p>
}
body={
<div className="flex flex-col gap-4">
<div>
You have an incomplete plan upgrade that is awaiting payment
verification{' '}
<A
href={url}
isExternal
hook={'verify-payment-method'}
to={undefined}
>
here
</A>
.
</div>
<p>
Are you sure you wish to abandon the pending upgrade and start a new
one?
</p>
</div>
}
footer={
<div className="flex gap-2">
<Button hook="cancel-upgrade" onClick={onClose} disabled={isUpgrading}>
Cancel
</Button>
<Button
hook="confirm-upgrade"
variant="primary"
onClick={onConfirm}
disabled={isUpgrading}
>
{isUpgrading ? 'Processing...' : 'Yes, Start New Upgrade'}
</Button>
</div>
}
/>
)

export default UpgradeFormModal

0 comments on commit fb74dde

Please sign in to comment.