Skip to content

Commit 42671c3

Browse files
chore: wip
1 parent 85206ba commit 42671c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3239
-5264
lines changed
Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,54 @@
1-
<script setup lang="ts">
2-
import { useBillable } from '../../../functions/billing/payments'
1+
<script>
2+
export const plan = {} // { subscription: { type, description, unit_price }, providerSubscription: { current_period_end } }
33

4-
const paymentStore = usePaymentStore()
4+
function convertUnixTimestampToDate(timestamp) {
5+
if (!timestamp) return ''
6+
const date = new Date(timestamp * 1000)
7+
return date.toLocaleDateString()
8+
}
59

6-
const { convertUnixTimestampToDate, editPlan } = useBillable()
10+
const subscriptionType = plan.subscription?.type
11+
? plan.subscription.type.charAt(0).toUpperCase() + plan.subscription.type.slice(1)
12+
: ''
713

8-
async function cancelPlan() {
9-
await paymentStore.cancelPlan()
10-
11-
await paymentStore.fetchUserActivePlan()
12-
}
13-
14-
const subscriptionType = computed(() => {
15-
const type = paymentStore.getCurrentPlan.subscription.type
16-
17-
return type.charAt(0).toUpperCase() + type.slice(1)
18-
})
19-
20-
const nextPayment = computed(() => {
21-
return convertUnixTimestampToDate(paymentStore.getCurrentPlan.providerSubscription.current_period_end)
22-
})
23-
24-
const unitPrice = computed(() => {
25-
return paymentStore.getCurrentPlan.subscription.unit_price / 100
26-
})
14+
const nextPayment = convertUnixTimestampToDate(plan.providerSubscription?.current_period_end)
15+
const unitPrice = plan.subscription?.unit_price ? (plan.subscription.unit_price / 100).toFixed(2) : '0.00'
2716
</script>
2817

29-
<template>
30-
<div class="w-full">
31-
<h2 class="text-lg text-gray-900 font-medium">
32-
Plan Details
33-
</h2>
34-
35-
<div class="pt-8">
36-
<p class="text-gray-700 font-bold">
37-
{{ subscriptionType }} Plan
38-
</p>
18+
<div class="w-full">
19+
<h2 class="text-lg text-gray-900 font-medium">
20+
Plan Details
21+
</h2>
3922

40-
<p class="pt-2 text-sm text-gray-500 font-normal italic">
41-
{{ paymentStore.getCurrentPlan.subscription.description }}
42-
</p>
23+
<div class="pt-8">
24+
<p class="text-gray-700 font-bold">
25+
{{ subscriptionType }} Plan
26+
</p>
4327

44-
<p class="pt-4 text-sm text-gray-700 font-semibold">
45-
Next payment of ${{ unitPrice }} occurs on {{ nextPayment }}
46-
</p>
47-
</div>
28+
<p class="pt-2 text-sm text-gray-500 font-normal italic">
29+
{{ plan.subscription?.description || '' }}
30+
</p>
4831

49-
<div class="mt-8 flex">
50-
<button
51-
type="button"
52-
class="rounded-md bg-white px-2.5 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50"
53-
@click="cancelPlan"
54-
>
55-
Cancel Plan
56-
</button>
32+
<p class="pt-4 text-sm text-gray-700 font-semibold">
33+
Next payment of ${{ unitPrice }} occurs on {{ nextPayment }}
34+
</p>
35+
</div>
5736

58-
<button
59-
type="button"
60-
class="ml-4 rounded-md bg-blue-600 px-2.5 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-blue-gray-500 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 focus-visible:outline"
61-
@click="editPlan"
62-
>
63-
Change Plan
64-
</button>
65-
</div>
37+
<div class="mt-8 flex">
38+
<button
39+
type="button"
40+
class="rounded-md bg-white px-2.5 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50"
41+
data-action="cancel-plan"
42+
>
43+
Cancel Plan
44+
</button>
45+
46+
<button
47+
type="button"
48+
class="ml-4 rounded-md bg-blue-600 px-2.5 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-blue-gray-500 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 focus-visible:outline"
49+
data-action="change-plan"
50+
>
51+
Change Plan
52+
</button>
6653
</div>
67-
</template>
54+
</div>
Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,29 @@
1-
<script setup lang="ts">
2-
const props = defineProps<{
3-
brand: string
4-
width?: number
5-
}>()
1+
<script>
2+
export const brand = ''
3+
export const width = 4
64

7-
const defaultProps = {
8-
width: 4,
9-
}
5+
function getLogoSrc(cardBrand) {
6+
if (!cardBrand) return ''
107

11-
const { brand, width = defaultProps.width } = props
12-
13-
const logoSrc = computed(() => {
14-
if (!props.brand)
15-
return ''
16-
17-
switch (props.brand.toLowerCase()) {
18-
case 'visa':
19-
return '/images/logos/visa.png'
20-
case 'mastercard':
21-
case 'mc':
22-
return '/images/logos/mastercard.svg'
23-
case 'jcb':
24-
return '/images/logos/jcb.svg'
25-
case 'amex':
26-
case 'american express':
27-
return '/images/logos/amex.jpg'
28-
default:
29-
return '/images/logos/default-card.svg' // Path to a default card image if brand is unrecognized
8+
switch (cardBrand.toLowerCase()) {
9+
case 'visa':
10+
return '/images/logos/visa.png'
11+
case 'mastercard':
12+
case 'mc':
13+
return '/images/logos/mastercard.svg'
14+
case 'jcb':
15+
return '/images/logos/jcb.svg'
16+
case 'amex':
17+
case 'american express':
18+
return '/images/logos/amex.jpg'
19+
default:
20+
return '/images/logos/default-card.svg'
21+
}
3022
}
31-
})
23+
24+
const logoSrc = getLogoSrc(brand)
3225
</script>
3326

34-
<template>
35-
<div :style="`width: ${width}rem`">
36-
<img :src="logoSrc" :alt="`${brand} Logo`">
37-
</div>
38-
</template>
27+
<div style="width: {{ width }}rem">
28+
<img src="{{ logoSrc }}" alt="{{ brand }} Logo">
29+
</div>
Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,31 @@
1-
<script setup lang="ts">
2-
import { useBillable } from '../../../functions/billing/payments'
3-
4-
const emit = defineEmits(['cancelPaymentMethodAddition'])
5-
const { loadCardForm, handleAddPaymentMethod } = useBillable()
6-
const paymentStore = usePaymentStore()
7-
8-
const element = ref(null as any)
9-
let clientSecret: string
10-
11-
onMounted(async () => {
12-
clientSecret = await paymentStore.fetchSetupIntent(1)
13-
14-
element.value = await loadCardForm(clientSecret)
15-
})
16-
17-
async function addPaymentMethod() {
18-
await handleAddPaymentMethod(clientSecret, element.value)
19-
20-
await paymentStore.fetchUserPaymentMethods(1)
21-
await paymentStore.fetchDefaultPaymentMethod(1)
22-
23-
emit('cancelPaymentMethodAddition')
24-
}
1+
<script>
2+
export const clientSecret = ''
253
</script>
264

27-
<template>
28-
<div>
29-
<form
30-
id="card-form"
31-
class="mt-8 border border-gray-200 p-8"
32-
>
33-
<div id="link-authentication-element" />
34-
<div id="card-element" />
35-
36-
<div class="mt-6 flex space-x-2">
37-
<button type="button" class="w-full rounded bg-indigo-600 px-2 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline" @click="addPaymentMethod">
38-
Save Payment Method
39-
</button>
40-
41-
<button type="button" class="w-full rounded bg-white px-2 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50" @click="emit('cancelPaymentMethodAddition')">
42-
Cancel
43-
</button>
44-
</div>
45-
</form>
46-
</div>
47-
</template>
5+
<div>
6+
<form
7+
id="card-form"
8+
class="mt-8 border border-gray-200 p-8"
9+
>
10+
<div id="link-authentication-element"></div>
11+
<div id="card-element"></div>
12+
13+
<div class="mt-6 flex space-x-2">
14+
<button
15+
type="button"
16+
class="w-full rounded bg-indigo-600 px-2 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline"
17+
data-action="save-payment-method"
18+
>
19+
Save Payment Method
20+
</button>
21+
22+
<button
23+
type="button"
24+
class="w-full rounded bg-white px-2 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50"
25+
data-action="cancel"
26+
>
27+
Cancel
28+
</button>
29+
</div>
30+
</form>
31+
</div>
Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,25 @@
1-
<script setup lang="ts">
2-
import { useBillable } from '../../../functions/billing/payments'
1+
<script>
2+
export const product = {} // { name, unit_price }
3+
export const paymentIntent = ''
34

4-
import PaymentForm from './PaymentForm.vue'
5-
6-
interface Props {
7-
product: number,
8-
paymentIntent: string,
9-
}
10-
11-
const props = defineProps<Props>()
12-
13-
const paymentStore = usePaymentStore()
14-
15-
const { isEmpty } = useBillable()
16-
17-
const productId = computed(() => {
18-
return props.product || 1
19-
})
20-
21-
const unitPrice = computed(() => {
22-
return `$${(paymentStore.getProduct.unit_price / 100).toFixed(2)}`
23-
})
24-
25-
onMounted(async () => {
26-
await paymentStore.fetchProduct(productId.value)
27-
})
5+
const unitPrice = product.unit_price ? `$${(product.unit_price / 100).toFixed(2)}` : '$0.00'
286
</script>
297

30-
<template>
31-
<div v-if="!isEmpty(paymentStore.getProduct)" class="flex border border-gray-200 rounded-md p-4 space-x-2">
8+
@if(product.name)
9+
<div class="flex border border-gray-200 rounded-md p-4 space-x-2">
3210
<ul role="list" class="w-1/3 text-sm text-gray-900 font-medium divide-y divide-gray-200">
3311
<li class="items-ce flex space-x-4">
3412
<img src="https://tailwindui.com/plus/img/ecommerce-images/checkout-page-04-product-01.jpg" alt="Moss green canvas compact backpack with double top zipper, zipper front pouch, and matching carry handle and backpack straps." class="size-20 flex-none border rounded-md object-cover">
3513
<div class="mt-2 flex-auto space-y-1">
36-
<h3>{{ paymentStore.getProduct.name }}</h3>
14+
<h3>{{ product.name }}</h3>
3715
<p class="flex-none text-sm font-medium">
38-
{{ unitPrice || '$00.00' }}
16+
{{ unitPrice }}
3917
</p>
4018
</div>
4119
</li>
4220
</ul>
43-
<PaymentForm :paymentIntent="props.paymentIntent" :product-id="1" :price="unitPrice" class="w-2/3" />
21+
<div class="w-2/3">
22+
{{ paymentFormSlot }}
23+
</div>
4424
</div>
45-
</template>
25+
@endif
Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,30 @@
1-
<script setup lang="ts">
2-
import { useBillable } from '../../../functions/billing/payments'
3-
4-
interface Props {
5-
productId: number
6-
price: string,
7-
paymentIntent: string,
8-
}
9-
10-
const props = defineProps<Props>()
11-
12-
const emit = defineEmits(['cancelPayment'])
13-
const { loadPaymentForm, handlePayment } = useBillable()
14-
const paymentStore = usePaymentStore()
15-
16-
const element = ref(null as any)
17-
18-
onMounted(async () => {
19-
element.value = await loadPaymentForm(props.paymentIntent)
20-
})
21-
22-
async function pay() {
23-
await paymentStore.storeTransaction(1, props.productId)
24-
25-
await handlePayment(element.value)
26-
27-
emit('cancelPayment')
28-
}
1+
<script>
2+
export const productId = 1
3+
export const price = '$0.00'
4+
export const paymentIntent = ''
295
</script>
306

31-
<template>
32-
<div>
33-
<form
34-
id="payment-form"
35-
>
36-
<div id="link-authentication-element" />
37-
<div id="payment-element" />
38-
39-
<div class="mt-6 flex space-x-2">
40-
<button type="button" class="w-full rounded bg-indigo-600 px-2 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline" @click="pay">
41-
Pay {{ props.price }}
42-
</button>
43-
44-
<button type="button" class="w-full rounded bg-white px-2 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50" @click="emit('cancelPayment')">
45-
Cancel
46-
</button>
47-
</div>
48-
</form>
49-
</div>
50-
</template>
7+
<div>
8+
<form id="payment-form">
9+
<div id="link-authentication-element"></div>
10+
<div id="payment-element"></div>
11+
12+
<div class="mt-6 flex space-x-2">
13+
<button
14+
type="button"
15+
class="w-full rounded bg-indigo-600 px-2 py-1.5 text-sm text-white font-semibold shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline"
16+
data-action="pay"
17+
>
18+
Pay {{ price }}
19+
</button>
20+
21+
<button
22+
type="button"
23+
class="w-full rounded bg-white px-2 py-1.5 text-sm text-gray-900 font-semibold shadow-sm ring-1 ring-gray-300 ring-inset hover:bg-gray-50"
24+
data-action="cancel"
25+
>
26+
Cancel
27+
</button>
28+
</div>
29+
</form>
30+
</div>

0 commit comments

Comments
 (0)