Skip to content

Commit cd2fff7

Browse files
chore: wip
1 parent 462d946 commit cd2fff7

File tree

11 files changed

+761
-411
lines changed

11 files changed

+761
-411
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ MEILISEARCH_KEY=masterKey
4040
# FRONTEND_* variables should not contain any sensitive information
4141
FRONTEND_APP_ENV="${APP_ENV}"
4242
FRONTEND_APP_URL="${APP_URL}"
43+
44+
FRONTEND_STRIPE_PUBLIC_KEY=

bun.lockb

2.21 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,5 @@
7474
"storage/framework/libs/components/*",
7575
"storage/framework/views/*",
7676
"storage/framework/server"
77-
],
78-
"devDependencies": {
79-
"@stacksjs/eslint-plugin": "^0.1.3"
80-
}
77+
]
8178
}

resources/stores/payment.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Stripe from 'stripe'
2+
const apiUrl = `http://localhost:3008`
3+
4+
export const usePaymentStore = defineStore('payment', {
5+
state: (): any => {
6+
return {
7+
paymentMethods: [] as Stripe.PaymentMethod[]
8+
}
9+
},
10+
11+
actions: {
12+
async fetchUserPaymentMethods(): Promise<void> {
13+
const response: any = await fetch(`${apiUrl}/stripe/user-payment-methods`, {
14+
method: 'GET',
15+
headers: {
16+
'Content-Type': 'application/json',
17+
'Accept': 'application/json',
18+
},
19+
}).then((res) => res.json())
20+
21+
this.paymentMethods = response.data
22+
},
23+
},
24+
25+
getters: {
26+
getPaymentMethods(state): Stripe.PaymentMethod[] {
27+
return state.paymentMethods
28+
},
29+
},
30+
})
31+
32+
if (import.meta.hot)
33+
import.meta.hot.accept(acceptHMRUpdate(usePaymentStore, import.meta.hot))

resources/views/dashboard/components/billing/payment-method.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { useBillable } from '../../../../functions/billing/payments'
3+
const paymentStore = usePaymentStore()
34
45
const stripeLoading = ref(true)
56
const showStripe = ref(false)
@@ -18,6 +19,10 @@ function cancelPaymentForm() {
1819
showStripe.value = false
1920
stripeLoading.value = true
2021
}
22+
23+
onMounted(async () => {
24+
await paymentStore.fetchUserPaymentMethods()
25+
})
2126
</script>
2227

2328
<template>
@@ -27,15 +32,15 @@ function cancelPaymentForm() {
2732
</h2>
2833

2934
<ul v-if="stripeLoading || !showStripe" role="list" class="grid grid-cols-1 mt-8 gap-6 lg:grid-cols-1 sm:grid-cols-1">
30-
<li class="col-span-1 border rounded-lg bg-white shadow divide-y divide-gray-200">
35+
<li v-for="(method, index) in paymentStore.getPaymentMethods" :key="index" class="col-span-1 border rounded-lg bg-white shadow divide-y divide-gray-200">
3136
<div class="w-full p-4">
3237
<div class="flex space-x-4">
3338
<div class="h-24 w-24">
3439
<img src="/images/logos/mastercard.svg" alt="Mastercard Logo" class="border">
3540
</div>
3641
<h2 class="text-xl text-gray-600">
37-
Mastercard •••• 4242 <br>
38-
<span class="text-xs text-gray-500 italic">Expires 10/30</span>
42+
{{ method.card.brand }} •••• {{ method.card.last4 }} <br>
43+
<span class="text-xs text-gray-500 italic">Expires {{ method.card.exp_month }} / {{ method.card.exp_year }} </span>
3944
</h2>
4045
</div>
4146

storage/framework/.eslintrc-auto-import.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@
414414
"withIndices": true,
415415
"word": true,
416416
"wordBoundary": true,
417-
"wordChar": true
417+
"wordChar": true,
418+
"usePaymentStore": true
418419
}
419420
}

storage/framework/core/components/transition/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script lang="ts" setup>
2+
import Example from './components/Example.vue'
23
import Footer from './components/Footer.vue'
34
import Hero from './components/Hero.vue'
45
import Installation from './components/Installation.vue'
5-
import Example from './components/Example.vue'
66
import { useSEOHeader } from './composables/useSEOHeader'
77
88
useSEOHeader()

storage/framework/core/components/transition/src/components/Example.vue

Lines changed: 84 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,81 @@
11
<script setup lang="ts">
2-
import { ref, computed } from 'vue'
3-
import { useCopyCode } from '../composables/useCopyCode'
4-
5-
import {
6-
TransitionRoot,
7-
TransitionChild,
8-
Dialog,
9-
DialogPanel,
10-
DialogTitle,
11-
} from '@headlessui/vue'
12-
13-
type TransitionClass = {
14-
enter: string
15-
enterFrom: string
16-
enterTo: string
17-
leave: string
18-
leaveFrom: string
19-
leaveTo: string
20-
}
21-
22-
const transitionList = ref<string[]>([
23-
'fade',
24-
'slideInRight',
25-
'slideInDown',
26-
'pop'
27-
])
28-
29-
const showCheckIcon = ref(false)
30-
const currentTransition = ref(transitionList.value[0])
31-
const isOpen = ref(false)
32-
33-
const transitionClass = computed<TransitionClass>(() => {
34-
35-
if (currentTransition.value === 'slideInRight') {
36-
return {
37-
enter: 'transition-transform transition-opacity duration-500 ease-out',
38-
enterFrom: 'opacity-0 translate-x-full',
39-
enterTo: 'opacity-100 translate-x-0',
40-
leave: 'transition-transform transition-opacity duration-500 ease-out',
41-
leaveFrom: 'opacity-100 translate-x-0',
42-
leaveTo: 'opacity-0 translate-x-full',
43-
}
44-
}
45-
46-
if (currentTransition.value === 'slideInDown') {
47-
return {
48-
enter: 'transition-transform transition-opacity duration-500 ease-out',
49-
enterFrom: 'opacity-0 -translate-y-full',
50-
enterTo: 'opacity-100 translate-y-0',
51-
leave: 'transition-transform transition-opacity duration-500 ease-out',
52-
leaveFrom: 'opacity-100 translate-y-0',
53-
leaveTo: 'opacity-0 -translate-y-full',
54-
}
2+
import {
3+
Dialog,
4+
DialogPanel,
5+
DialogTitle,
6+
TransitionChild,
7+
TransitionRoot,
8+
} from '@headlessui/vue'
9+
import { computed, ref } from 'vue'
10+
11+
import { useCopyCode } from '../composables/useCopyCode'
12+
13+
interface TransitionClass {
14+
enter: string
15+
enterFrom: string
16+
enterTo: string
17+
leave: string
18+
leaveFrom: string
19+
leaveTo: string
20+
}
21+
22+
const transitionList = ref<string[]>([
23+
'fade',
24+
'slideInRight',
25+
'slideInDown',
26+
'pop',
27+
])
28+
29+
const showCheckIcon = ref(false)
30+
const currentTransition = ref(transitionList.value[0])
31+
const isOpen = ref(false)
32+
33+
const transitionClass = computed<TransitionClass>(() => {
34+
if (currentTransition.value === 'slideInRight') {
35+
return {
36+
enter: 'transition-transform transition-opacity duration-500 ease-out',
37+
enterFrom: 'opacity-0 translate-x-full',
38+
enterTo: 'opacity-100 translate-x-0',
39+
leave: 'transition-transform transition-opacity duration-500 ease-out',
40+
leaveFrom: 'opacity-100 translate-x-0',
41+
leaveTo: 'opacity-0 translate-x-full',
5542
}
43+
}
5644
57-
if (currentTransition.value === 'pop') {
58-
return {
59-
enter: 'transition-transform duration-300',
60-
enterFrom: 'transform scale-0',
61-
enterTo: 'transform scale-100',
62-
leave: 'transition-transform duration-300',
63-
leaveFrom: 'transform scale-100',
64-
leaveTo: 'transform scale-0',
65-
}
45+
if (currentTransition.value === 'slideInDown') {
46+
return {
47+
enter: 'transition-transform transition-opacity duration-500 ease-out',
48+
enterFrom: 'opacity-0 -translate-y-full',
49+
enterTo: 'opacity-100 translate-y-0',
50+
leave: 'transition-transform transition-opacity duration-500 ease-out',
51+
leaveFrom: 'opacity-100 translate-y-0',
52+
leaveTo: 'opacity-0 -translate-y-full',
6653
}
54+
}
6755
56+
if (currentTransition.value === 'pop') {
6857
return {
69-
enter: 'transition-opacity duration-300',
70-
enterFrom: 'opacity-0',
71-
enterTo: 'opacity-100',
72-
leave: 'transition-opacity duration-300',
73-
leaveFrom: 'opacity-100',
74-
leaveTo: 'opacity-0',
58+
enter: 'transition-transform duration-300',
59+
enterFrom: 'transform scale-0',
60+
enterTo: 'transform scale-100',
61+
leave: 'transition-transform duration-300',
62+
leaveFrom: 'transform scale-100',
63+
leaveTo: 'transform scale-0',
7564
}
76-
})
65+
}
7766
78-
const renderedCode = computed(() => {
79-
return `
67+
return {
68+
enter: 'transition-opacity duration-300',
69+
enterFrom: 'opacity-0',
70+
enterTo: 'opacity-100',
71+
leave: 'transition-opacity duration-300',
72+
leaveFrom: 'opacity-100',
73+
leaveTo: 'opacity-0',
74+
}
75+
})
76+
77+
const renderedCode = computed(() => {
78+
return `
8079
<TransitionRoot appear :show="isOpen">
8180
<Dialog :open="isOpen" @close="setIsOpen" class="relative z-50">
8281
<div class="fixed inset-0 bg-black/30" aria-hidden="true" />
@@ -104,20 +103,20 @@
104103
</Dialog>
105104
</TransitionRoot>
106105
`
107-
})
106+
})
108107
109-
function setIsOpen(value: boolean) {
110-
isOpen.value = value
111-
}
108+
function setIsOpen(value: boolean) {
109+
isOpen.value = value
110+
}
112111
113-
function handleClick(trans: string) {
114-
setIsOpen(true)
115-
currentTransition.value = trans
116-
}
112+
function handleClick(trans: string) {
113+
setIsOpen(true)
114+
currentTransition.value = trans
115+
}
117116
118-
async function handleCopyCode() {
119-
await useCopyCode({ code: renderedCode.value, checkIconRef: showCheckIcon })
120-
}
117+
async function handleCopyCode() {
118+
await useCopyCode({ code: renderedCode.value, checkIconRef: showCheckIcon })
119+
}
121120
</script>
122121

123122
<template>
@@ -162,17 +161,14 @@
162161
</div>
163162

164163
<div class="flex flex-col gap-4">
165-
166164
<TransitionRoot
167165
appear
168166
:show="isOpen"
169167
>
170-
<Dialog :open="isOpen" @close="setIsOpen" class="relative z-50">
168+
<Dialog :open="isOpen" class="relative z-50" @close="setIsOpen">
171169
<div class="fixed inset-0 bg-black/30" aria-hidden="true" />
172170

173-
174-
<div class="fixed inset-0 flex w-screen items-center justify-center p-4">
175-
171+
<div class="fixed inset-0 w-screen flex items-center justify-center p-4">
176172
<TransitionChild
177173
:enter="transitionClass.enter"
178174
:enter-from="transitionClass.enterFrom"
@@ -181,7 +177,7 @@
181177
:leave-from="transitionClass.leaveFrom"
182178
:leave-to="transitionClass.leaveTo"
183179
>
184-
<DialogPanel class="w-full max-w-sm rounded bg-white p-5">
180+
<DialogPanel class="max-w-sm w-full rounded bg-white p-5">
185181
<DialogTitle>Complete your order</DialogTitle>
186182

187183
<div class="mt-4">

storage/framework/core/payments/src/drivers/stripe.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ export const paymentIntent: PaymentIntent = (() => {
2020
return await client.paymentIntents.create(params)
2121
}
2222

23-
async function retrieve(stripeId: string) {
23+
async function retrieve(stripeId: string): Promise<Stripe.Response<Stripe.PaymentIntent>> {
2424
return await client.paymentIntents.retrieve(stripeId)
2525
}
2626

2727
async function update(stripeId: string, params: Stripe.PaymentIntentCreateParams) {
2828
return await client.paymentIntents.update(stripeId, params)
2929
}
3030

31-
async function cancel(stripeId: string) {
31+
async function cancel(stripeId: string): Promise<Stripe.Response<Stripe.PaymentIntent>> {
3232
return await client.paymentIntents.cancel(stripeId)
3333
}
3434

0 commit comments

Comments
 (0)