139 lines
3.6 KiB
Vue
139 lines
3.6 KiB
Vue
<template>
|
|
<div
|
|
v-if="field.type === 'payment'"
|
|
class="px-4"
|
|
>
|
|
<EditorSectionHeader
|
|
icon="i-heroicons-credit-card-20-solid"
|
|
title="Payment"
|
|
/>
|
|
|
|
<select-input
|
|
name="currency"
|
|
label="Currency"
|
|
:options="currencyList"
|
|
:form="field"
|
|
:required="true"
|
|
:searchable="true"
|
|
:disabled="stripeAccounts.length === 0"
|
|
/>
|
|
<text-input
|
|
name="amount"
|
|
label="Amount"
|
|
native-type="number"
|
|
:form="field"
|
|
:required="true"
|
|
:disabled="stripeAccounts.length === 0"
|
|
/>
|
|
<div v-if="stripeAccounts.length > 0">
|
|
<select-input
|
|
name="stripe_account_id"
|
|
label="Stripe Account"
|
|
:options="stripeAccounts"
|
|
:form="field"
|
|
:required="true"
|
|
/>
|
|
<p class="mt-4 text-sm text-center text-bold">
|
|
OR
|
|
</p>
|
|
</div>
|
|
<UButton
|
|
class="mt-4"
|
|
icon="i-heroicons-arrow-right"
|
|
block
|
|
trailing
|
|
:loading="stripeLoading"
|
|
@click.prevent="connectStripe"
|
|
>
|
|
Connect Stripe Account
|
|
</UButton>
|
|
<p class="text-sm text-gray-500 mt-3">
|
|
<a
|
|
target="#"
|
|
class="text-gray-500 cursor-pointer text-sm"
|
|
@click.prevent="crisp.openHelpdeskArticle('how-to-collect-payment-svig30')"
|
|
>
|
|
<Icon
|
|
name="heroicons:information-circle-16-solid"
|
|
class="h-3 w-3 mt-1"
|
|
/>
|
|
Learn how to accept payments
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import EditorSectionHeader from '~/components/open/forms/components/form-components/EditorSectionHeader.vue'
|
|
import stripeCurrencies from "~/data/stripe_currencies.json"
|
|
import { useWindowMessage, WindowMessageTypes } from '~/composables/useWindowMessage'
|
|
|
|
const props = defineProps({
|
|
field: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
})
|
|
|
|
const crisp = useCrisp()
|
|
const providersStore = useOAuthProvidersStore()
|
|
const stripeLoading = ref(false)
|
|
|
|
// Setup window message listener for Stripe connection
|
|
const { listen, cleanup } = useWindowMessage()
|
|
|
|
onMounted(async () => {
|
|
await providersStore.fetchOAuthProviders()
|
|
|
|
if(props.field?.currency === undefined || props.field?.currency === null) {
|
|
props.field.currency = 'USD'
|
|
}
|
|
if(props.field?.amount === undefined || props.field?.amount === null) {
|
|
props.field.amount = 10
|
|
}
|
|
|
|
// Auto-select first Stripe account if none is selected
|
|
if (!props.field.stripe_account_id && stripeAccounts.value.length > 0) {
|
|
props.field.stripe_account_id = stripeAccounts.value[0].value
|
|
}
|
|
|
|
// Listen for Stripe connection message
|
|
listen(async () => {
|
|
await providersStore.fetchOAuthProviders()
|
|
// Auto-select first Stripe account after refresh if one isn't already selected (or maybe always select the newest? for now, first)
|
|
if (stripeAccounts.value.length > 0) {
|
|
props.field.stripe_account_id = stripeAccounts.value[0].value
|
|
}
|
|
useAlert().success('Stripe accounts updated.')
|
|
}, {
|
|
useMessageChannel: false,
|
|
acknowledge: false
|
|
}, `${WindowMessageTypes.OAUTH_PROVIDER_CONNECTED}:stripe`)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
// Cleanup listener (optional, as useWindowMessage handles it)
|
|
cleanup()
|
|
})
|
|
|
|
const stripeAccounts = computed(() => providersStore.getAll.filter((item) => item.provider === 'stripe').map((item) => ({
|
|
name: item.name + (item.email ? ' (' + item.email + ')' : ''),
|
|
value: item.id
|
|
})))
|
|
|
|
const currencyList = computed(() => {
|
|
return stripeCurrencies.map((item) => ({
|
|
name: item.name,
|
|
value: item.code
|
|
}))
|
|
})
|
|
|
|
|
|
const connectStripe = () => {
|
|
stripeLoading.value = true
|
|
providersStore.connect('stripe', false, true, true)
|
|
setTimeout(() => {
|
|
stripeLoading.value = false
|
|
}, 10000)
|
|
}
|
|
</script> |