diff --git a/packages/ui/src/components/billing/ModrinthServersPurchaseModal.vue b/packages/ui/src/components/billing/ModrinthServersPurchaseModal.vue index 9690f036ce..bbc816afed 100644 --- a/packages/ui/src/components/billing/ModrinthServersPurchaseModal.vue +++ b/packages/ui/src/components/billing/ModrinthServersPurchaseModal.vue @@ -10,7 +10,7 @@ import { } from '@modrinth/assets' import { useQueryClient } from '@tanstack/vue-query' import type Stripe from 'stripe' -import { computed, nextTick, ref, useTemplateRef, watch } from 'vue' +import { computed, nextTick, ref, toRef, useTemplateRef, watch } from 'vue' import { injectNotificationManager } from '#ui/providers/web-notifications.ts' @@ -94,8 +94,8 @@ const { noPaymentRequired, } = useStripe( props.publishableKey, - props.customer, - props.paymentMethods, + toRef(props, 'customer'), + toRef(props, 'paymentMethods'), props.currency, selectedPlan, selectedInterval, @@ -116,6 +116,10 @@ const steps: Step[] = props.planStage ? (['plan', 'region', 'payment', 'review'] as Step[]) : (['region', 'payment', 'review'] as Step[]) +const isUpgrade = computed(() => !!props.existingSubscription) +const skipRegionStep = computed(() => isUpgrade.value && !customServer.value) +const visibleSteps = computed(() => steps.filter((s) => !(s === 'region' && skipRegionStep.value))) + const titles: Record = { plan: defineMessage({ id: 'servers.purchase.step.plan.title', defaultMessage: 'Plan' }), region: defineMessage({ id: 'servers.purchase.step.region.title', defaultMessage: 'Region' }), @@ -146,17 +150,24 @@ const currentPing = computed(() => { const currentStep = ref() -const currentStepIndex = computed(() => (currentStep.value ? steps.indexOf(currentStep.value) : -1)) +const currentStepIndex = computed(() => + currentStep.value ? visibleSteps.value.indexOf(currentStep.value) : -1, +) const previousStep = computed(() => { - const step = currentStep.value ? steps[steps.indexOf(currentStep.value) - 1] : undefined + if (!currentStep.value) return undefined + const idx = visibleSteps.value.indexOf(currentStep.value) + let step = idx > 0 ? visibleSteps.value[idx - 1] : undefined if (step === 'payment' && skipPaymentMethods.value && primaryPaymentMethodId.value) { - return 'region' + const paymentIdx = visibleSteps.value.indexOf('payment') + step = paymentIdx > 0 ? visibleSteps.value[paymentIdx - 1] : undefined } return step }) -const nextStep = computed(() => - currentStep.value ? steps[steps.indexOf(currentStep.value) + 1] : undefined, -) +const nextStep = computed(() => { + if (!currentStep.value) return undefined + const idx = visibleSteps.value.indexOf(currentStep.value) + return idx >= 0 ? visibleSteps.value[idx + 1] : undefined +}) const canProceed = computed(() => { switch (currentStep.value) { @@ -195,12 +206,14 @@ async function beforeProceed(step: string) { await initializeStripe() if (primaryPaymentMethodId.value && skipPaymentMethods.value) { - const paymentMethod = await props.paymentMethods.find( + const paymentMethod = props.paymentMethods.find( (x) => x.id === primaryPaymentMethodId.value, ) - await selectPaymentMethod(paymentMethod) - await setStep('review', true) - return false + if (paymentMethod) { + await selectPaymentMethod(paymentMethod) + await setStep('review', true) + return false + } } return true case 'review': @@ -261,11 +274,25 @@ async function setStep(step: Step | undefined, skipValidation = false) { } } -watch(selectedPlan, () => { - if (currentStep.value === 'plan') { - customServer.value = !selectedPlan.value - } -}) +watch( + selectedPlan, + () => { + if (currentStep.value === 'plan') { + customServer.value = !selectedPlan.value + } + }, + { flush: 'sync' }, +) + +watch( + () => props.existingSubscription, + (sub) => { + if (sub?.metadata?.type === 'pyro' && sub.metadata.region) { + selectedRegion.value = sub.metadata.region + } + }, + { immediate: true }, +) const defaultPlan = computed(() => { return ( @@ -295,7 +322,9 @@ function begin( customServer.value = !selectedPlan.value selectedPaymentMethod.value = undefined const skipPlanStep = props.planStage && plan !== undefined - currentStep.value = skipPlanStep ? (steps[1] ?? steps[0]) : steps[0] + currentStep.value = skipPlanStep + ? (visibleSteps.value[1] ?? visibleSteps.value[0]) + : visibleSteps.value[0] skipPaymentMethods.value = true projectId.value = project modal.value?.show() @@ -339,7 +368,7 @@ function goToBreadcrumbStep(id: string) {