Files
AstralRinth/packages/ui/src/components/billing/AddPaymentMethod.vue
Cal H. 2aabcf36ee refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs

* fix: prettier frontend

* feat: config changes

* fix: lint issues

* fix: lint

* fix: type imports

* fix: cyclical import issue

* fix: lockfile

* fix: missing dep

* fix: switch to tabs

* fix: continue switch to tabs

* fix: rustfmt parity

* fix: moderation lint issue

* fix: lint issues

* fix: ui intl

* fix: lint issues

* Revert "fix: rustfmt parity"

This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711.

* feat: revert last rs
2025-08-14 20:48:38 +00:00

106 lines
2.3 KiB
Vue

<script setup lang="ts">
import { createStripeElements } from '@modrinth/utils'
import { loadStripe, type Stripe as StripsJs, type StripeElements } from '@stripe/stripe-js'
import { ref } from 'vue'
import ModalLoadingIndicator from '../modal/ModalLoadingIndicator.vue'
const emit = defineEmits<{
(e: 'startLoading' | 'stopLoading'): void
}>()
export type SetupIntentResponse = {
client_secret: string
}
export type AddPaymentMethodProps = {
publishableKey: string
createSetupIntent: () => Promise<SetupIntentResponse>
returnUrl: string
onError: (error: Error) => void
}
const props = defineProps<AddPaymentMethodProps>()
const elementsLoaded = ref<0 | 1 | 2>(0)
const stripe = ref<StripsJs>()
const elements = ref<StripeElements>()
const error = ref(false)
function handleError(error: Error) {
props.onError(error)
error.value = true
}
async function reload(paymentMethods: Stripe.PaymentMethod[]) {
try {
elementsLoaded.value = 0
error.value = false
const result = await props.createSetupIntent()
stripe.value = await loadStripe(props.publishableKey)
const {
elements: newElements,
addressElement,
paymentElement,
} = createStripeElements(stripe.value, paymentMethods, {
clientSecret: result.client_secret,
})
elements.value = newElements
paymentElement.on('ready', () => {
elementsLoaded.value += 1
})
addressElement.on('ready', () => {
elementsLoaded.value += 1
})
} catch (err) {
handleError(err)
}
}
async function submit(): Promise<boolean> {
emit('startLoading')
const result = await stripe.value.confirmSetup({
elements: elements.value,
confirmParams: {
return_url: props.returnUrl,
},
})
console.log(result)
const { error } = result
emit('stopLoading')
if (error && error.type !== 'validation_error') {
handleError(error.message)
return false
} else if (!error) {
return true
}
}
defineExpose({
reload,
submit,
})
</script>
<template>
<div class="min-h-[16rem] flex flex-col gap-2 justify-center items-center">
<div v-show="elementsLoaded < 2">
<ModalLoadingIndicator :error="error">
Loading...
<template #error> Error loading Stripe payment UI. </template>
</ModalLoadingIndicator>
</div>
<div class="w-full">
<div id="address-element"></div>
<div id="payment-element" class="mt-4"></div>
</div>
</div>
</template>