@monkeyplus/payscope 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/database.mjs +1 -1
- package/dist/_chunks/db.d.mts +13 -5
- package/dist/_chunks/taxes.mjs +214 -0
- package/dist/server/db.mjs +10 -0
- package/dist/server/router.d.mts +8 -5
- package/dist/server/router.mjs +19 -218
- package/dist/server/taxes.d.mts +131 -0
- package/dist/server/taxes.mjs +2 -0
- package/package.json +1 -1
- package/storefront/cart/ShoppinCart.vue +3 -12
- package/storefront/cart/ShoppinCartItem.vue +13 -11
- package/storefront/checkout/App.vue +1 -1
- package/storefront/checkout/AppCart.vue +31 -24
- package/storefront/checkout/AppCartTotals.vue +19 -15
- package/storefront/checkout/pages/Auth.vue +8 -0
- package/storefront/checkout/pages/Basic/BasicBillingForm.vue +95 -0
- package/storefront/checkout/pages/Basic/BasicCustomerForm.vue +188 -0
- package/storefront/checkout/pages/Basic/BasicShippingForm.vue +93 -0
- package/storefront/checkout/pages/Basic/BasicSummary.vue +63 -0
- package/storefront/checkout/pages/Basic.vue +82 -0
- package/storefront/checkout/pages/Pay/Pay.vue +3 -50
- package/storefront/checkout/pages/Pay/PayForms.vue +55 -0
- package/storefront/checkout/pages/Payment/Payment.vue +1 -1
- package/storefront/checkout/router.ts +49 -39
- package/storefront/product/AddProduct.vue +87 -103
- package/storefront/product/composables.ts +0 -0
- package/storefront/stores.ts +26 -4
|
@@ -1,34 +1,13 @@
|
|
|
1
1
|
<!-- eslint-disable ts/ban-ts-comment -->
|
|
2
2
|
<script lang="ts" setup>
|
|
3
3
|
import type { ProductStore, ProductStoreStocks } from '@monkeyplus/e-schema/models';
|
|
4
|
-
import { useEventBus } from '@vueuse/core';
|
|
4
|
+
import { useAsyncState, useEventBus } from '@vueuse/core';
|
|
5
5
|
import { ofetch } from 'ofetch';
|
|
6
6
|
import { computed, inject, onMounted, reactive, ref } from 'vue';
|
|
7
7
|
import { useCartStore } from '../stores.ts';
|
|
8
8
|
import AddProductNumber from './AddProductNumber.vue';
|
|
9
|
-
// import { useCrud, useShoppingCart, useTheProduct } from '../../helpers';
|
|
10
|
-
// import { EButton, InputNumber } from '../shared/exports';
|
|
11
9
|
import AddProductVariant from './AddProductVariant.vue';
|
|
12
|
-
|
|
13
|
-
// to: {
|
|
14
|
-
// type: String,
|
|
15
|
-
// },
|
|
16
|
-
// omitStock: {
|
|
17
|
-
// type: Boolean,
|
|
18
|
-
// default: false,
|
|
19
|
-
// },
|
|
20
|
-
// hideWhistlist: {
|
|
21
|
-
// type: Boolean,
|
|
22
|
-
// default: false,
|
|
23
|
-
// },
|
|
24
|
-
// maxQuantity: {
|
|
25
|
-
// type: Number,
|
|
26
|
-
// },
|
|
27
|
-
// messageMax: {
|
|
28
|
-
// type: String,
|
|
29
|
-
// },
|
|
30
|
-
// product:
|
|
31
|
-
// });
|
|
10
|
+
|
|
32
11
|
const props = defineProps<{
|
|
33
12
|
to?: string
|
|
34
13
|
omitStock?: boolean
|
|
@@ -41,8 +20,6 @@ const emit = defineEmits(['stock']);
|
|
|
41
20
|
|
|
42
21
|
const { product } = props;
|
|
43
22
|
|
|
44
|
-
// const product = useTheProduct();
|
|
45
|
-
// const { store } = useShoppingCart();
|
|
46
23
|
const settings = reactive({
|
|
47
24
|
omitStock: props.omitStock || product.noVariants,
|
|
48
25
|
hideWhistlist: props.hideWhistlist,
|
|
@@ -52,19 +29,9 @@ type Selections = Record<string, string>;
|
|
|
52
29
|
|
|
53
30
|
const busImages = useEventBus('busGalleryImages');
|
|
54
31
|
const busCart = useEventBus('busCart');
|
|
55
|
-
// const { crud: CrudCart } = useCrud('cart');
|
|
56
32
|
const cartStore = useCartStore();
|
|
57
|
-
const
|
|
58
|
-
const { options, variants, id, uid, price, sku } = product;
|
|
59
|
-
|
|
60
|
-
// const { state, uid: userId, user } = useIdentify();
|
|
61
|
-
|
|
62
|
-
// const {} = useCustomer();
|
|
63
|
-
// const whislist = useCrud('account/wishlist');
|
|
64
|
-
|
|
65
|
-
// const addToCart = ()=>{
|
|
33
|
+
const { options, variants, id, price, sku } = product;
|
|
66
34
|
|
|
67
|
-
// }
|
|
68
35
|
const firstVariant = variants[0];
|
|
69
36
|
const initValues = firstVariant.selectedOptions.reduce((acc, current) => {
|
|
70
37
|
return {
|
|
@@ -75,28 +42,23 @@ const initValues = firstVariant.selectedOptions.reduce((acc, current) => {
|
|
|
75
42
|
|
|
76
43
|
const quantity = ref(1);
|
|
77
44
|
const selections = ref<Selections>(initValues);
|
|
78
|
-
const stock = ref({} as ProductStoreStocks);
|
|
79
|
-
// Initial images
|
|
80
45
|
busImages.emit(selections.value);
|
|
81
46
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
}
|
|
47
|
+
const { state: stock, isLoading: loading, executeImmediate: verifyStock } = useAsyncState(async () => {
|
|
48
|
+
// loading.value = true;
|
|
49
|
+
const stocks = await ofetch<ProductStoreStocks>(`/storefront/cache/products/${product.id}/stock`);
|
|
50
|
+
// stock.value = stocks;
|
|
51
|
+
emit('stock', stocks);
|
|
52
|
+
return stocks;
|
|
53
|
+
}, {} as ProductStoreStocks, {
|
|
54
|
+
immediate: false,
|
|
55
|
+
onError(e) {
|
|
56
|
+
console.error(e);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
96
59
|
|
|
97
60
|
if (!settings.omitStock)
|
|
98
61
|
verifyStock();
|
|
99
|
-
// console.log(selections.value);
|
|
100
62
|
|
|
101
63
|
const selected = computed(() => {
|
|
102
64
|
return variants.find((variant) => {
|
|
@@ -105,46 +67,46 @@ const selected = computed(() => {
|
|
|
105
67
|
return variant.selectedOptions.every(el => selections.value[el.name] === el.value);
|
|
106
68
|
});
|
|
107
69
|
});
|
|
108
|
-
const loadingAdd = ref(false);
|
|
109
70
|
const loadingWhislist = ref(false);
|
|
110
71
|
|
|
72
|
+
const alertModal = reactive({
|
|
73
|
+
isOpen: false,
|
|
74
|
+
title: '',
|
|
75
|
+
description: '',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
function showAlert(title: string, description: string) {
|
|
79
|
+
alertModal.title = title;
|
|
80
|
+
alertModal.description = description;
|
|
81
|
+
alertModal.isOpen = true;
|
|
82
|
+
}
|
|
83
|
+
|
|
111
84
|
const addToCartOmit = inject('addToCartOmit', (_id: any, _selected: any, _items: any) => true);
|
|
112
85
|
// const verify
|
|
113
86
|
async function addToCart(): Promise<void> {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (!addToCartOmit(`${id}:${selected.value?.id}`, selected.value, cartStore.items)) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
// console.log(selected.value);
|
|
121
|
-
if (!settings.omitStock) {
|
|
122
|
-
const r = await ofetch(`/storefront/cache/products/${encodeURIComponent(`${uid! || product.id}`)}/verify?selectedOptions=${JSON.stringify(selected.value?.selectedOptions || {})}`, {
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
if (!r.ok)
|
|
126
|
-
return alert('Sin stock disponible');
|
|
127
|
-
}
|
|
128
|
-
const el = await cartStore.addToCart({
|
|
129
|
-
id: `${id}:${selected.value?.id}`,
|
|
130
|
-
quantity: quantity.value,
|
|
131
|
-
});
|
|
132
|
-
busCart.emit({
|
|
133
|
-
action: 'create',
|
|
134
|
-
payload: { ...el, product },
|
|
135
|
-
});
|
|
87
|
+
if (!addToCartOmit(`${id}:${selected.value?.id}`, selected.value, cartStore.items)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
136
90
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
91
|
+
const el = await cartStore.addToCart({
|
|
92
|
+
id: `${id}:${selected.value?.id}`,
|
|
93
|
+
quantity: quantity.value,
|
|
94
|
+
});
|
|
95
|
+
if (el.error && el.error === 'stock') {
|
|
96
|
+
showAlert('Aviso', 'Sin stock disponible');
|
|
97
|
+
return;
|
|
141
98
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
99
|
+
busCart.emit({
|
|
100
|
+
action: 'create',
|
|
101
|
+
payload: { ...el, product },
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!props.to) {
|
|
105
|
+
cartStore.open = true;
|
|
106
|
+
// console.log({ cartStore });
|
|
145
107
|
}
|
|
146
|
-
|
|
147
|
-
|
|
108
|
+
else {
|
|
109
|
+
location.href = `${props.to}${props.to.includes('?') ? '&' : '?'}items=${el?.lineItems?.length}`;
|
|
148
110
|
}
|
|
149
111
|
}
|
|
150
112
|
async function addToWhislist() {
|
|
@@ -211,9 +173,6 @@ const isMax = computed(() => {
|
|
|
211
173
|
return false;
|
|
212
174
|
return quantity.value > props.maxQuantity;
|
|
213
175
|
});
|
|
214
|
-
// const disabledSelect = computed(() => {
|
|
215
|
-
// return !variantStock.item || !selected || loadingAdd;
|
|
216
|
-
// });
|
|
217
176
|
</script>
|
|
218
177
|
|
|
219
178
|
<template>
|
|
@@ -228,7 +187,6 @@ const isMax = computed(() => {
|
|
|
228
187
|
</div>
|
|
229
188
|
</div>
|
|
230
189
|
<teleport v-if="teleports.price" to="#price">
|
|
231
|
-
<!-- {{ selected?. }} -->
|
|
232
190
|
{{ thePrice }}
|
|
233
191
|
</teleport>
|
|
234
192
|
<div v-if="!product.noVariants" class="mb-2 space-y-1">
|
|
@@ -257,40 +215,29 @@ const isMax = computed(() => {
|
|
|
257
215
|
</div>
|
|
258
216
|
</div>
|
|
259
217
|
<div class=" space-y-3">
|
|
260
|
-
<!-- <el-input-number
|
|
261
|
-
v-model="quantity"
|
|
262
|
-
:min="1"
|
|
263
|
-
:max="8"
|
|
264
|
-
size="medium"
|
|
265
|
-
class="w-32"
|
|
266
|
-
/> -->
|
|
267
218
|
<div class="p-1px">
|
|
268
219
|
<AddProductNumber v-model="quantity" :min="1" :max="variantStock.itemStock" size="large" class="w-[8rem]" />
|
|
269
220
|
</div>
|
|
270
221
|
<UButton
|
|
271
|
-
|
|
272
|
-
:
|
|
273
|
-
:loading="loadingAdd"
|
|
222
|
+
:disabled="!variantStock.item || !selected || cartStore.loadingAdd || isMax"
|
|
223
|
+
:loading="cartStore.loadingAdd"
|
|
274
224
|
icon="i-bytesize-cart"
|
|
275
225
|
size="xl"
|
|
276
226
|
block
|
|
277
227
|
@click="addToCart"
|
|
278
228
|
>
|
|
279
|
-
<!-- <i-bytesize-cart class="relative -left-3 text-xl dark:text-white" /> -->
|
|
280
229
|
<span class="text-white font-medium uppercase "> {{ !variantStock.item ? 'Sin existencias' : 'Agregar al carrito' }} </span>
|
|
281
230
|
</UButton>
|
|
282
231
|
<div v-if="!settings.hideWhistlist">
|
|
283
232
|
<UButton
|
|
284
|
-
:disabled=" !selected || loadingAdd || loadingWhislist "
|
|
233
|
+
:disabled=" !selected || cartStore.loadingAdd || loadingWhislist "
|
|
285
234
|
:loading="loadingWhislist"
|
|
286
235
|
icon="i-mdi-heart-outline"
|
|
287
236
|
size="lg"
|
|
288
237
|
variant="subtle"
|
|
289
238
|
@click="addToWhislist"
|
|
290
239
|
>
|
|
291
|
-
<!-- <i-mdi-heart-outline class="relative -left-3 text-xl" /> -->
|
|
292
240
|
<span class=" font-medium uppercase"> Añadir a deseos
|
|
293
|
-
<!-- {{ state.isAuth }} -->
|
|
294
241
|
</span>
|
|
295
242
|
</UButton>
|
|
296
243
|
</div>
|
|
@@ -299,5 +246,42 @@ const isMax = computed(() => {
|
|
|
299
246
|
{{ messageMax }}
|
|
300
247
|
</div>
|
|
301
248
|
<slot :id="id" :quantity="quantity" :sku="sku" />
|
|
249
|
+
|
|
250
|
+
<UModal v-model:open="alertModal.isOpen">
|
|
251
|
+
<template #content>
|
|
252
|
+
<div class="p-6 flex flex-col items-center text-center">
|
|
253
|
+
<div class="relative flex items-center justify-center mb-8 mt-4">
|
|
254
|
+
<!-- Anillos pulsantes en color Rojo/Rosa -->
|
|
255
|
+
<div class="absolute inset-0 rounded-full bg-rose-500/20 animate-ping" style="animation-duration: 2.5s;" />
|
|
256
|
+
<div class="absolute inset-[-1.5rem] rounded-full bg-rose-500/10 animate-pulse" style="animation-duration: 3s;" />
|
|
257
|
+
|
|
258
|
+
<!-- Icono central -->
|
|
259
|
+
<div class="relative z-10 w-24 h-24 bg-gradient-to-br from-rose-400 to-rose-600 rounded-full flex items-center justify-center shadow-lg shadow-rose-500/30">
|
|
260
|
+
<i-mdi-close-circle class="text-white text-5xl" />
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
<span class="text-xs font-bold px-4 py-1.5 bg-rose-50 text-rose-600 border border-rose-100 rounded-full uppercase tracking-wider mb-3">
|
|
265
|
+
Aviso
|
|
266
|
+
</span>
|
|
267
|
+
|
|
268
|
+
<h2 class="text-2xl font-bold text-gray-800 tracking-tight mb-2">
|
|
269
|
+
{{ alertModal.title }}
|
|
270
|
+
</h2>
|
|
271
|
+
<p class="text-sm text-gray-500 max-w-sm mx-auto mb-6 leading-relaxed">
|
|
272
|
+
{{ alertModal.description }}
|
|
273
|
+
</p>
|
|
274
|
+
|
|
275
|
+
<div class="pt-4 w-full">
|
|
276
|
+
<button
|
|
277
|
+
class="w-full bg-gradient-to-r from-slate-800 to-slate-900 hover:from-slate-900 hover:to-slate-950 text-white font-bold px-8 py-3.5 rounded-xl uppercase tracking-wider text-xs shadow-md hover:shadow-lg transition-all duration-300 transform hover:-translate-y-0.5 active:translate-y-0"
|
|
278
|
+
@click="alertModal.isOpen = false"
|
|
279
|
+
>
|
|
280
|
+
Cerrar
|
|
281
|
+
</button>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</template>
|
|
285
|
+
</UModal>
|
|
302
286
|
</div>
|
|
303
287
|
</template>
|
|
File without changes
|
package/storefront/stores.ts
CHANGED
|
@@ -3,10 +3,13 @@ import { ofetch } from 'ofetch';
|
|
|
3
3
|
import { createPinia, defineStore } from 'pinia';
|
|
4
4
|
import { type App, computed, ref } from 'vue';
|
|
5
5
|
|
|
6
|
-
if (!(window as any)?.sharedPinia) {
|
|
6
|
+
if (typeof window !== 'undefined' && !(window as any)?.sharedPinia) {
|
|
7
7
|
(window as any).sharedPinia = createPinia();
|
|
8
8
|
}
|
|
9
9
|
export function registerPinia(app: App) {
|
|
10
|
+
if (typeof window === 'undefined') {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
10
13
|
app.use((window as any).sharedPinia);
|
|
11
14
|
}
|
|
12
15
|
export const useCartStore = defineStore('cart', () => {
|
|
@@ -15,8 +18,26 @@ export const useCartStore = defineStore('cart', () => {
|
|
|
15
18
|
return r.lineItems as any[];
|
|
16
19
|
}, [] as any[]);
|
|
17
20
|
|
|
21
|
+
interface ProductAdd {
|
|
22
|
+
|
|
23
|
+
id: any
|
|
24
|
+
quantity: number
|
|
25
|
+
verifyStock?: boolean
|
|
26
|
+
selectedOptions?: any
|
|
27
|
+
|
|
28
|
+
}
|
|
18
29
|
const { executeImmediate: addToCart, isLoading: loadingAdd } = useAsyncState(
|
|
19
|
-
async (body:
|
|
30
|
+
async (body: ProductAdd) => {
|
|
31
|
+
if (body.verifyStock) {
|
|
32
|
+
const stock = await ofetch(`/storefront/cache/products/${encodeURIComponent(`${body.id}`)}/verify?selectedOptions=${JSON.stringify(body.selectedOptions)}`, {
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!stock.ok) {
|
|
36
|
+
return {
|
|
37
|
+
error: 'stock',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
20
41
|
const r = await ofetch('/storefront/cart', {
|
|
21
42
|
method: 'POST',
|
|
22
43
|
body,
|
|
@@ -33,16 +54,17 @@ export const useCartStore = defineStore('cart', () => {
|
|
|
33
54
|
const total = computed(() => {
|
|
34
55
|
return items.value.reduce((acc: number, item: any) => acc + (item.variant?.price * item.quantity), 0).toFixed(2);
|
|
35
56
|
});
|
|
36
|
-
const
|
|
57
|
+
const open = ref(false);
|
|
37
58
|
const loading = computed(() => {
|
|
38
59
|
return loadingInit.value || loadingAdd.value;
|
|
39
60
|
});
|
|
40
61
|
return {
|
|
41
62
|
addToCart,
|
|
42
63
|
items,
|
|
43
|
-
|
|
64
|
+
open,
|
|
44
65
|
total,
|
|
45
66
|
loading,
|
|
67
|
+
loadingAdd,
|
|
46
68
|
};
|
|
47
69
|
});
|
|
48
70
|
|