diff --git a/apps/frontend/src/error.vue b/apps/frontend/src/error.vue index 8b28f35ea6..c431787539 100644 --- a/apps/frontend/src/error.vue +++ b/apps/frontend/src/error.vue @@ -77,6 +77,9 @@ const errorMessages = computed( const route = useRoute(); +// TODO: REMOVE BEFORE MERGE +console.log(props.error); + watch(route, () => { console.log(route); }); diff --git a/apps/frontend/src/pages/settings/billing/index.vue b/apps/frontend/src/pages/settings/billing/index.vue index 517a41c995..9200e93940 100644 --- a/apps/frontend/src/pages/settings/billing/index.vue +++ b/apps/frontend/src/pages/settings/billing/index.vue @@ -353,6 +353,21 @@ Upgrade + + + + + Change billing interval + + + midasCharge.value?.subscription_interval === "yearly" ? "monthly" : "yearly", ); +async function showPyroIntervalChange(subscription) { + currentSubscription.value = subscription; + currentSubRenewalDate.value = getPyroCharge(subscription).due; + currentProduct.value = getPyroProduct(subscription); + + upgradeProducts.value = [currentProduct.value]; + upgradeProducts.value.metadata = { type: "pyro" }; + + await nextTick(); + pyroIntervalModal.value.show(); +} + async function switchMidasInterval(interval) { changingInterval.value = true; startLoading(); @@ -941,6 +993,7 @@ const getProductPrice = (product, interval) => { const modalCancel = ref(null); const pyroPurchaseModal = ref(); +const pyroIntervalModal = ref(); const currentSubscription = ref(null); const currentProduct = ref(null); const upgradeProducts = ref([]); diff --git a/packages/ui/src/components/billing/PurchaseModal.vue b/packages/ui/src/components/billing/PurchaseModal.vue index 7b216b9a6d..e04fe3d66e 100644 --- a/packages/ui/src/components/billing/PurchaseModal.vue +++ b/packages/ui/src/components/billing/PurchaseModal.vue @@ -2,7 +2,8 @@ - Subscribe to Modrinth+! + Change billing interval + Subscribe to Modrinth+! Upgrade server plan Subscribe to Modrinth Servers! @@ -11,11 +12,11 @@ - + Configure @@ -25,8 +26,8 @@ {{ productType === 'pyro' ? 'Billing' : 'Plan' }} @@ -37,8 +38,8 @@ Payment @@ -46,17 +47,14 @@ Review - + Configure your server @@ -182,10 +180,7 @@ - + Choose billing interval @@ -249,9 +244,7 @@ - + - + + + Billing interval change + + + Current interval: {{ props.existingSubscription?.interval }} + + + + New interval: {{ selectedPlan }} + + Server details @@ -429,7 +430,7 @@ - + Cancel @@ -454,40 +455,21 @@ - - + + Back - + Select - - { - purchaseModalStep = mutatedProduct.metadata.type === 'pyro' && !projectId ? 1 : 0 - loadingPaymentMethodModal = 0 - paymentLoading = false - } - " - > + + Back @@ -495,11 +477,7 @@ Continue - + Cancel @@ -511,7 +489,7 @@ @click="submitPayment" > - Subscribe + {{ props.intervalChangeOnly ? 'Change Interval' : 'Subscribe' }} @@ -639,10 +617,40 @@ const props = defineProps({ required: false, default: null, }, + intervalChangeOnly: { + type: Boolean, + default: false, + }, }) const productType = computed(() => (props.customServer ? 'pyro' : props.product.metadata.type)) +const isConfigStep = computed( + () => + productType.value === 'pyro' && + !props.projectId && + !props.intervalChangeOnly && + purchaseModalStep.value === 0, +) + +const isBillingStep = computed( + () => + purchaseModalStep.value === + (props.intervalChangeOnly ? 0 : productType.value === 'pyro' && !props.projectId ? 1 : 0), +) + +const isPaymentStep = computed( + () => + purchaseModalStep.value === + (props.intervalChangeOnly ? 1 : productType.value === 'pyro' && !props.projectId ? 2 : 1), +) + +const isReviewStep = computed( + () => + purchaseModalStep.value === + (props.intervalChangeOnly ? 2 : productType.value === 'pyro' && !props.projectId ? 3 : 2), +) + const messages = defineMessages({ paymentMethodCardDisplay: { id: 'omorphia.component.purchase_modal.payment_method_card_display', @@ -749,6 +757,10 @@ const customServerConfig = reactive({ }) const updateCustomServerProduct = () => { + if (!props.product || !Array.isArray(props.product)) { + return + } + customMatchingProduct.value = props.product.find( (product) => product.metadata.ram === customServerConfig.ram, ) @@ -789,6 +801,10 @@ const updateCustomServerStock = async () => { } function updateRamValues() { + if (!props.product || !Array.isArray(props.product)) { + return + } + const ramValues = props.product.map((product) => product.metadata.ram / 1024) customMinRam.value = Math.min(...ramValues) customMaxRam.value = Math.max(...ramValues) @@ -868,10 +884,19 @@ const sharedCpus = computed(() => { return (mutatedProduct.value?.metadata?.cpu ?? 0) / 2 }) +const isSameInterval = computed(() => { + return ( + props.intervalChangeOnly && + props.existingSubscription && + selectedPlan.value === props.existingSubscription.interval + ) +}) + function nextStep() { if ( mutatedProduct.value.metadata.type === 'pyro' && !props.projectId && + !props.intervalChangeOnly && purchaseModalStep.value === 0 ) { purchaseModalStep.value = 1 @@ -891,13 +916,19 @@ async function beginPurchaseFlow(skip = false) { paymentLoading.value = true await refreshPayment(null, primaryPaymentMethodId.value) paymentLoading.value = false - purchaseModalStep.value = - mutatedProduct.value.metadata.type === 'pyro' && !props.projectId ? 3 : 2 + purchaseModalStep.value = props.intervalChangeOnly + ? 2 + : mutatedProduct.value.metadata.type === 'pyro' && !props.projectId + ? 3 + : 2 } else { try { loadingPaymentMethodModal.value = 0 - purchaseModalStep.value = - mutatedProduct.value.metadata.type === 'pyro' && !props.projectId ? 2 : 1 + purchaseModalStep.value = props.intervalChangeOnly + ? 1 + : mutatedProduct.value.metadata.type === 'pyro' && !props.projectId + ? 2 + : 1 await nextTick() @@ -955,8 +986,11 @@ async function validatePayment() { loadingPaymentMethodModal.value = 0 confirmationToken.value = await createConfirmationToken() - purchaseModalStep.value = - mutatedProduct.value.metadata.type === 'pyro' && !props.projectId ? 3 : 2 + purchaseModalStep.value = props.intervalChangeOnly + ? 2 + : mutatedProduct.value.metadata.type === 'pyro' && !props.projectId + ? 3 + : 2 paymentLoading.value = false } @@ -1006,7 +1040,7 @@ async function refreshPayment(confirmationId, paymentMethodId) { }, ) - if (!paymentIntentId.value) { + if (result.payment_intent_id && !paymentIntentId.value) { paymentIntentId.value = result.payment_intent_id clientSecret.value = result.client_secret }
Configure your server
Choose billing interval
Billing interval change
Server details