@lilaquadrat/design-core 0.1.0
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/README.md +236 -0
- package/html/index.html +25 -0
- package/html/index.mail.html +15 -0
- package/html/index.server.html +29 -0
- package/package.json +148 -0
- package/src/client-entry.ts +28 -0
- package/src/components/partials/action.partial.vue +30 -0
- package/src/components/partials/client-only.partial.vue +11 -0
- package/src/components/partials/error.partial.vue +73 -0
- package/src/components/partials/main-components.partial.vue +167 -0
- package/src/components/partials/mediadetection.partial.vue +71 -0
- package/src/components/partials/qrcode.partial.vue +35 -0
- package/src/customs.ts +12 -0
- package/src/env.d.ts +1 -0
- package/src/functions/PaymenyProviderFactory.ts +27 -0
- package/src/functions/lila-dom.ts +100 -0
- package/src/functions/shopify.provider.ts +378 -0
- package/src/functions/stripe.provider.ts +181 -0
- package/src/globals.d.ts +19 -0
- package/src/index.ts +47 -0
- package/src/interfaces/AppState.interface.ts +4 -0
- package/src/interfaces/EditorConfiguration.interface.ts +15 -0
- package/src/interfaces/EventDeclaration.interface.ts +19 -0
- package/src/interfaces/FrontendConfig.interface.ts +42 -0
- package/src/interfaces/GenericEvents.interface.ts +6 -0
- package/src/interfaces/GenericState.interface.ts +5 -0
- package/src/interfaces/IconsPartial.ts +9 -0
- package/src/interfaces/IdTokenExtended.interface.ts +7 -0
- package/src/interfaces/ModuleBaseProps.interface.ts +8 -0
- package/src/interfaces/PaymentProvider.interface.ts +13 -0
- package/src/libs/ActionNotice.ts +235 -0
- package/src/libs/Models.class.ts +482 -0
- package/src/main.ts +84 -0
- package/src/mixins/createCookieString.ts +78 -0
- package/src/mixins/createModelDeclaration.ts +29 -0
- package/src/mixins/createRouter.ts +30 -0
- package/src/mixins/date.ts +23 -0
- package/src/mixins/formatSize.ts +12 -0
- package/src/mixins/getAnchor.ts +14 -0
- package/src/mixins/getRoutes.ts +50 -0
- package/src/mixins/hasSlotContent.ts +32 -0
- package/src/mixins/hooks.ts +104 -0
- package/src/mixins/loadComponents.ts +107 -0
- package/src/mixins/logger.ts +32 -0
- package/src/mixins/replaceVariables.ts +19 -0
- package/src/mixins/scroll.ts +83 -0
- package/src/models/Address.model.ts +24 -0
- package/src/models/Contact.model.ts +22 -0
- package/src/models.ts +2 -0
- package/src/plugins/auth.ts +121 -0
- package/src/plugins/currency.ts +26 -0
- package/src/plugins/events.ts +156 -0
- package/src/plugins/filters.ts +43 -0
- package/src/plugins/inview.ts +351 -0
- package/src/plugins/replacer.ts +18 -0
- package/src/plugins/resize.ts +128 -0
- package/src/plugins/signupFlow.ts +89 -0
- package/src/plugins/traceable.ts +53 -0
- package/src/plugins/translations.ts +29 -0
- package/src/plugins/youtube.ts +80 -0
- package/src/routes.ts +132 -0
- package/src/server-entry.ts +113 -0
- package/src/stores/calls.store.ts +33 -0
- package/src/stores/cart.store.ts +186 -0
- package/src/stores/content.store.ts +83 -0
- package/src/stores/editor.store.ts +27 -0
- package/src/stores/files.store.ts +166 -0
- package/src/stores/main.store.ts +184 -0
- package/src/stores/user.store.ts +124 -0
- package/src/translations/de.ts +138 -0
- package/src/views/content.view.vue +219 -0
- package/src/views/download.view.vue +143 -0
- package/src/views/editor.view.vue +243 -0
- package/src/views/login.view.vue +82 -0
- package/src/views/signup-account.view.vue +64 -0
- package/tooling/cypress/config.ts +80 -0
- package/tooling/cypress/generate-manifest.js +5 -0
- package/tooling/cypress/manifest-utils.mjs +40 -0
- package/tooling/cypress/run-parallel.mjs +77 -0
- package/tooling/cypress/support/commands.ts +436 -0
- package/tooling/cypress/support/e2e.ts +17 -0
- package/tooling/eslint.config.js +223 -0
- package/tooling/preview.plugin.ts +134 -0
- package/tooling/ssr-test/index.mjs +391 -0
- package/tooling/stylelint.config.mjs +24 -0
- package/tooling/vite.ts +246 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
export default class ShopifyGraphQLAPI {
|
|
2
|
+
|
|
3
|
+
private shop: string;
|
|
4
|
+
private accessToken: string;
|
|
5
|
+
private apiVersion: string;
|
|
6
|
+
|
|
7
|
+
productCache: Record<string, any> = {};
|
|
8
|
+
|
|
9
|
+
constructor (shop: string, accessToken: string, apiVersion: string = '2024-04') {
|
|
10
|
+
this.shop = shop;
|
|
11
|
+
this.accessToken = accessToken;
|
|
12
|
+
this.apiVersion = apiVersion;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private async makeGraphQLRequest (query: string, variables?: object): Promise<any> {
|
|
16
|
+
|
|
17
|
+
const url = `https://${this.shop}/api/${this.apiVersion}/graphql.json`;
|
|
18
|
+
const headers = {
|
|
19
|
+
'X-Shopify-Storefront-Access-Token': this.accessToken,
|
|
20
|
+
'Content-Type' : 'application/json',
|
|
21
|
+
};
|
|
22
|
+
const body = JSON.stringify({ query, variables });
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers,
|
|
26
|
+
body,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`GraphQL Error: ${response.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await response.json();
|
|
34
|
+
|
|
35
|
+
if (result.errors) {
|
|
36
|
+
throw new Error(`GraphQL Error: ${JSON.stringify(result.errors)}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result.data;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Fetch a product by ID
|
|
43
|
+
public async getProduct (productId: string): Promise<any> {
|
|
44
|
+
|
|
45
|
+
if(this.productCache[productId]) return Promise.resolve(this.productCache[productId]);
|
|
46
|
+
|
|
47
|
+
const query = `
|
|
48
|
+
query GetProduct($id: ID!) {
|
|
49
|
+
product(id: $id) {
|
|
50
|
+
id
|
|
51
|
+
title
|
|
52
|
+
description
|
|
53
|
+
variants(first: 10) {
|
|
54
|
+
edges {
|
|
55
|
+
node {
|
|
56
|
+
id
|
|
57
|
+
title
|
|
58
|
+
price {
|
|
59
|
+
amount
|
|
60
|
+
currencyCode
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
images(first: 1) {
|
|
66
|
+
edges {
|
|
67
|
+
node {
|
|
68
|
+
id
|
|
69
|
+
src: url
|
|
70
|
+
altText
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
const variables = { id: `gid://shopify/Product/${productId}` };
|
|
78
|
+
const product = await this.makeGraphQLRequest(query, variables);
|
|
79
|
+
|
|
80
|
+
console.log(product);
|
|
81
|
+
|
|
82
|
+
// const cleanedProduct = this.transformProduct(product);
|
|
83
|
+
const cleanedProduct = {
|
|
84
|
+
name : product.product.title,
|
|
85
|
+
id : product.product.id,
|
|
86
|
+
variantId: product.product.variants.edges[0].node.id,
|
|
87
|
+
price : {
|
|
88
|
+
amount : +product.product.variants.edges[0].node.price.amount,
|
|
89
|
+
currency: product.product.variants.edges[0].node.price.currencyCode
|
|
90
|
+
},
|
|
91
|
+
description: product.product.description
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if(product.product.images.edges[0]) {
|
|
95
|
+
|
|
96
|
+
cleanedProduct.image = product.product.images.edges[0].node.src;
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.productCache[productId] = cleanedProduct;
|
|
101
|
+
|
|
102
|
+
return cleanedProduct;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Create an empty cart
|
|
107
|
+
public async getCart (attributes: {key: string, value: string}[]): Promise<any> {
|
|
108
|
+
const mutation = `
|
|
109
|
+
mutation CreateEmptyCart($attributes: [AttributeInput!]) {
|
|
110
|
+
cartCreate(input: { attributes: $attributes }) {
|
|
111
|
+
cart {
|
|
112
|
+
id
|
|
113
|
+
checkoutUrl
|
|
114
|
+
attributes {
|
|
115
|
+
key
|
|
116
|
+
value
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
userErrors {
|
|
120
|
+
field
|
|
121
|
+
message
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
const cart = await this.makeGraphQLRequest(mutation, {attributes});
|
|
127
|
+
|
|
128
|
+
return cart.cartCreate.cart;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Get a cart by ID
|
|
132
|
+
public async getCartWithProducts (cartId: string): Promise<any> {
|
|
133
|
+
const query = `
|
|
134
|
+
query GetCart($cartId: ID!) {
|
|
135
|
+
cart(id: $cartId) {
|
|
136
|
+
id
|
|
137
|
+
checkoutUrl
|
|
138
|
+
attributes {
|
|
139
|
+
key
|
|
140
|
+
value
|
|
141
|
+
}
|
|
142
|
+
lines(first: 50) {
|
|
143
|
+
edges {
|
|
144
|
+
node {
|
|
145
|
+
id
|
|
146
|
+
quantity
|
|
147
|
+
merchandise {
|
|
148
|
+
... on ProductVariant {
|
|
149
|
+
id
|
|
150
|
+
title
|
|
151
|
+
product {
|
|
152
|
+
id
|
|
153
|
+
title
|
|
154
|
+
description
|
|
155
|
+
images(first: 1) {
|
|
156
|
+
edges {
|
|
157
|
+
node {
|
|
158
|
+
id
|
|
159
|
+
src: url
|
|
160
|
+
altText
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
price {
|
|
166
|
+
amount
|
|
167
|
+
currencyCode
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
const variables = { cartId };
|
|
178
|
+
const cart = await this.makeGraphQLRequest(query, variables);
|
|
179
|
+
|
|
180
|
+
if(!cart.cart) {
|
|
181
|
+
console.log('no cart');
|
|
182
|
+
throw new Error('CART_NOT_FOUND');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return this.transformProducts(cart.cart.lines.edges);
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public async addToCart (cartId: string, product: any, quantity: number): Promise<any> {
|
|
190
|
+
const mutation = `
|
|
191
|
+
mutation AddProductToCart($cartId: ID!, $lines: [CartLineInput!]!) {
|
|
192
|
+
cartLinesAdd(cartId: $cartId, lines: $lines) {
|
|
193
|
+
cart {
|
|
194
|
+
id
|
|
195
|
+
checkoutUrl
|
|
196
|
+
lines(first: 10) {
|
|
197
|
+
edges {
|
|
198
|
+
node {
|
|
199
|
+
id
|
|
200
|
+
quantity
|
|
201
|
+
merchandise {
|
|
202
|
+
... on ProductVariant {
|
|
203
|
+
id
|
|
204
|
+
title
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
userErrors {
|
|
212
|
+
field
|
|
213
|
+
message
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
`;
|
|
218
|
+
const variables = {
|
|
219
|
+
cartId,
|
|
220
|
+
lines: [
|
|
221
|
+
{
|
|
222
|
+
merchandiseId: product.variantId,
|
|
223
|
+
quantity,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
const cartLinesAdd = await this.makeGraphQLRequest(mutation, variables);
|
|
228
|
+
|
|
229
|
+
product.lineId = cartLinesAdd.cartLinesAdd.cart.lines.edges[0].node.id;
|
|
230
|
+
|
|
231
|
+
return product;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Remove product from the cart
|
|
235
|
+
public async removeFromCart (cartId: string, cartProduct: any): Promise<any> {
|
|
236
|
+
const mutation = `
|
|
237
|
+
mutation RemoveCartLine($cartId: ID!, $lineIds: [ID!]!) {
|
|
238
|
+
cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
|
|
239
|
+
cart {
|
|
240
|
+
id
|
|
241
|
+
checkoutUrl
|
|
242
|
+
lines(first: 10) {
|
|
243
|
+
edges {
|
|
244
|
+
node {
|
|
245
|
+
id
|
|
246
|
+
quantity
|
|
247
|
+
merchandise {
|
|
248
|
+
... on ProductVariant {
|
|
249
|
+
id
|
|
250
|
+
title
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
userErrors {
|
|
258
|
+
field
|
|
259
|
+
message
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
`;
|
|
264
|
+
const variables = {
|
|
265
|
+
cartId,
|
|
266
|
+
lineIds: [cartProduct.lineId], // List of line IDs to remove
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
return this.makeGraphQLRequest(mutation, variables);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public async updateQuantity (cartId: string, cartProduct: any, quantity: number): Promise<any> {
|
|
273
|
+
const mutation = `
|
|
274
|
+
mutation UpdateCartLineQuantity($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
|
|
275
|
+
cartLinesUpdate(cartId: $cartId, lines: $lines) {
|
|
276
|
+
cart {
|
|
277
|
+
id
|
|
278
|
+
checkoutUrl
|
|
279
|
+
lines(first: 10) {
|
|
280
|
+
edges {
|
|
281
|
+
node {
|
|
282
|
+
id
|
|
283
|
+
quantity
|
|
284
|
+
merchandise {
|
|
285
|
+
... on ProductVariant {
|
|
286
|
+
id
|
|
287
|
+
title
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
userErrors {
|
|
295
|
+
field
|
|
296
|
+
message
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
`;
|
|
301
|
+
const variables = {
|
|
302
|
+
cartId,
|
|
303
|
+
lines: [
|
|
304
|
+
{
|
|
305
|
+
id: cartProduct.lineId, // The line item ID to update
|
|
306
|
+
quantity,
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return this.makeGraphQLRequest(mutation, variables);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
public async updateCartAttributes (cartId: string, attributes: { key: string; value: string }[]): Promise<any> {
|
|
315
|
+
const mutation = `
|
|
316
|
+
mutation UpdateCartAttributes($cartId: ID!, $attributes: [AttributeInput!]!) {
|
|
317
|
+
cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {
|
|
318
|
+
cart {
|
|
319
|
+
id
|
|
320
|
+
checkoutUrl
|
|
321
|
+
attributes {
|
|
322
|
+
key
|
|
323
|
+
value
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
userErrors {
|
|
327
|
+
field
|
|
328
|
+
message
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
`;
|
|
333
|
+
const variables = { cartId, attributes };
|
|
334
|
+
|
|
335
|
+
console.log(variables);
|
|
336
|
+
|
|
337
|
+
const cart = await this.makeGraphQLRequest(mutation, variables);
|
|
338
|
+
|
|
339
|
+
if (cart.cartAttributesUpdate.userErrors.length > 0) {
|
|
340
|
+
console.error('Errors:', cart.cartAttributesUpdate.userErrors);
|
|
341
|
+
throw new Error('Failed to update cart attributes');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return cart.cartAttributesUpdate.cart;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
transformProducts (products: any[]) {
|
|
348
|
+
|
|
349
|
+
return products.map((edge) => {
|
|
350
|
+
|
|
351
|
+
const transformedProduct = {
|
|
352
|
+
lineId : edge.node.id,
|
|
353
|
+
variantId : edge.node.merchandise.id,
|
|
354
|
+
quantity : edge.node.quantity,
|
|
355
|
+
name : edge.node.merchandise.product.title,
|
|
356
|
+
id : edge.node.merchandise.product.id,
|
|
357
|
+
description: edge.node.merchandise.product.description,
|
|
358
|
+
price : {
|
|
359
|
+
amount : +edge.node.merchandise.price.amount,
|
|
360
|
+
currency: edge.node.merchandise.price.currencyCode,
|
|
361
|
+
},
|
|
362
|
+
currency: edge.node.merchandise.price.currencyCode,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
console.log(edge.node);
|
|
366
|
+
|
|
367
|
+
if(edge.node.merchandise.product.images.edges[0]) {
|
|
368
|
+
|
|
369
|
+
transformedProduct.image = edge.node.merchandise.product.images.edges[0].node.src;
|
|
370
|
+
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return transformedProduct;
|
|
374
|
+
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
}
|
|
378
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type PaymentProvider from '../interfaces/PaymentProvider.interface';
|
|
2
|
+
import useCartStore from '../stores/cart.store';
|
|
3
|
+
import useMainStore from '../stores/main.store';
|
|
4
|
+
import StudioSDK from '@lilaquadrat/sdk';
|
|
5
|
+
|
|
6
|
+
export default class StripePaymentProvider implements PaymentProvider {
|
|
7
|
+
|
|
8
|
+
async getCart (attributes: Record<string, string>): Promise<{ id: string; attributes: Record<string, string> }> {
|
|
9
|
+
|
|
10
|
+
const { apiConfig } = useMainStore();
|
|
11
|
+
const sdk = new StudioSDK(apiConfig)
|
|
12
|
+
|
|
13
|
+
console.log('StripePaymentProvider.getCart', attributes);
|
|
14
|
+
|
|
15
|
+
const cart = await sdk.public.carts.create({attributes});
|
|
16
|
+
|
|
17
|
+
return { id: cart.data._id, attributes: attributes || {} };
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async updateCartAttributes (cartId: string, attributes?: Record<string, string>): Promise<any> {
|
|
22
|
+
|
|
23
|
+
const { apiConfig } = useMainStore();
|
|
24
|
+
const sdk = new StudioSDK(apiConfig)
|
|
25
|
+
const { products } = useCartStore();
|
|
26
|
+
const updateCart: {items?: {_id: string, quantity: number}[], attributes: Record<string, string>} = {
|
|
27
|
+
items : [],
|
|
28
|
+
attributes: {}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
products.forEach((item: any) => {
|
|
32
|
+
|
|
33
|
+
updateCart.items?.push({_id: item._id, quantity: item.quantity});
|
|
34
|
+
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if(attributes) {
|
|
38
|
+
|
|
39
|
+
Object.keys(attributes).forEach((attribute) => {
|
|
40
|
+
updateCart.attributes[attribute] = attributes[attribute];
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const updatedCart = await sdk.public.carts.update(cartId, updateCart);
|
|
46
|
+
|
|
47
|
+
console.log('StripePaymentProvider.updateCartAttributes', updateCart);
|
|
48
|
+
return Promise.resolve(updatedCart);
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getCartWithProducts (cartId: string) {
|
|
53
|
+
|
|
54
|
+
const { apiConfig } = useMainStore();
|
|
55
|
+
const sdk = new StudioSDK(apiConfig)
|
|
56
|
+
|
|
57
|
+
console.log('StripePaymentProvider.getCartWithProducts');
|
|
58
|
+
|
|
59
|
+
const cart = await sdk.public.carts.getById(cartId);
|
|
60
|
+
|
|
61
|
+
if(!cart.data) throw new Error('NO_CART_FOUND');
|
|
62
|
+
|
|
63
|
+
return cart.data.items || [];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getProduct (productId: string): Promise<any> {
|
|
67
|
+
|
|
68
|
+
console.log('StripePaymentProvider.getProduct', productId);
|
|
69
|
+
|
|
70
|
+
const { apiConfig } = useMainStore();
|
|
71
|
+
const sdk = new StudioSDK(apiConfig)
|
|
72
|
+
const product = await sdk.public.carts.getProduct(productId);
|
|
73
|
+
|
|
74
|
+
return product.data;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async addToCart (cartId: string, product: any, amount: number): Promise<any> {
|
|
78
|
+
|
|
79
|
+
const { apiConfig } = useMainStore();
|
|
80
|
+
const sdk = new StudioSDK(apiConfig)
|
|
81
|
+
const { products } = useCartStore();
|
|
82
|
+
const updateCart: {items?: {_id: string, quantity: number}[]} = {
|
|
83
|
+
items: [],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
console.log('StripePaymentProvider.addToCart', cartId, product, amount);
|
|
87
|
+
|
|
88
|
+
const itemInCart = products.find((item: any) => item._id === product._id);
|
|
89
|
+
|
|
90
|
+
if(itemInCart) {
|
|
91
|
+
|
|
92
|
+
itemInCart.quantity = itemInCart.quantity + amount;
|
|
93
|
+
|
|
94
|
+
} else {
|
|
95
|
+
|
|
96
|
+
updateCart.items?.push({
|
|
97
|
+
_id : product._id,
|
|
98
|
+
quantity: amount
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
products.forEach((item: any) => {
|
|
104
|
+
|
|
105
|
+
updateCart.items?.push({_id: item._id, quantity: item.quantity});
|
|
106
|
+
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const updatedCart = await sdk.public.carts.update(cartId, updateCart);
|
|
110
|
+
const addedItem = updatedCart.data.items.find((item: any) => item.id === product.id);
|
|
111
|
+
|
|
112
|
+
return addedItem
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async removeFromCart (cartId: string, product: any): Promise<any> {
|
|
117
|
+
|
|
118
|
+
const { apiConfig } = useMainStore();
|
|
119
|
+
const sdk = new StudioSDK(apiConfig)
|
|
120
|
+
const { products } = useCartStore();
|
|
121
|
+
const updateCart: {items?: {_id: string, quantity: number}[]} = {
|
|
122
|
+
items: []
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
products.forEach((item) => {
|
|
126
|
+
|
|
127
|
+
if(item._id === product._id) return;
|
|
128
|
+
updateCart.items?.push({_id: item._id, quantity: item.quantity});
|
|
129
|
+
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if(updateCart.items?.length === 0) {
|
|
133
|
+
delete updateCart.items;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
await sdk.public.carts.update(cartId, updateCart);
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async updateQuantity (cartId: string, cartProduct: any, amount: number): Promise<any> {
|
|
141
|
+
|
|
142
|
+
const { apiConfig } = useMainStore();
|
|
143
|
+
const sdk = new StudioSDK(apiConfig)
|
|
144
|
+
const { products } = useCartStore();
|
|
145
|
+
const updateCart: {items?: {_id: string, quantity: number}[]} = {
|
|
146
|
+
items: []
|
|
147
|
+
};
|
|
148
|
+
const itemInCart = products.find((item) => item._id === cartProduct._id);
|
|
149
|
+
|
|
150
|
+
itemInCart.quantity = amount;
|
|
151
|
+
|
|
152
|
+
products.forEach((item) => {
|
|
153
|
+
updateCart.items?.push({_id: item._id, quantity: item.quantity});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await sdk.public.carts.update(cartId, updateCart);
|
|
157
|
+
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async finalize (cartId: string): Promise<{checkoutUrl: string}> {
|
|
161
|
+
|
|
162
|
+
const { apiConfig } = useMainStore();
|
|
163
|
+
const sdk = new StudioSDK(apiConfig)
|
|
164
|
+
const repsonse = await sdk.public.carts.finalize(cartId);
|
|
165
|
+
|
|
166
|
+
return repsonse.data;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async getFinishedCart (cartId: string): Promise<any> {
|
|
170
|
+
|
|
171
|
+
const { apiConfig } = useMainStore();
|
|
172
|
+
const sdk = new StudioSDK(apiConfig)
|
|
173
|
+
const cart = await sdk.public.carts.getFinishedById(cartId);
|
|
174
|
+
|
|
175
|
+
if(!cart.data) throw new Error('NO_CART_FOUND');
|
|
176
|
+
|
|
177
|
+
return cart.data;
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
}
|
package/src/globals.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { StateTree } from 'pinia';
|
|
2
|
+
import type FrontendConfigInterface from './interfaces/FrontendConfig.interface';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
|
|
6
|
+
interface Window {
|
|
7
|
+
onYouTubeIframeAPIReady: () => void
|
|
8
|
+
__INITIAL_STATE__?: Record<string, StateTree>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const __FRONTEND_CONFIG__: FrontendConfigInterface;
|
|
12
|
+
const __TARGET__: string;
|
|
13
|
+
/**
|
|
14
|
+
* true only in the shareable static gallery build (yarn build:preview)
|
|
15
|
+
*/
|
|
16
|
+
const __PREVIEW__: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { };
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lilaquadrat/design-core
|
|
3
|
+
*
|
|
4
|
+
* The framework half of a STUDIO design. Everything that is not the design
|
|
5
|
+
* itself lives here: app bootstrap, router, stores, plugins, models and the
|
|
6
|
+
* shared build tooling.
|
|
7
|
+
*
|
|
8
|
+
* This barrel carries the bootstrap surface only. Everything else is reached
|
|
9
|
+
* through its own subpath, mirroring the layout a design used to have:
|
|
10
|
+
*
|
|
11
|
+
* import useMainStore from '@lilaquadrat/design-core/stores/main.store';
|
|
12
|
+
* import { useInview } from '@lilaquadrat/design-core/plugins/inview';
|
|
13
|
+
* import useDate from '@lilaquadrat/design-core/mixins/date';
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// app bootstrap
|
|
17
|
+
export { getAppInstance, type AppComponents } from './main';
|
|
18
|
+
export { createClientEntry } from './client-entry';
|
|
19
|
+
export { render } from './server-entry';
|
|
20
|
+
|
|
21
|
+
// routing
|
|
22
|
+
export { dynamicRoutes, editorRoutes, createPreviewRoutes } from './routes';
|
|
23
|
+
export { default as getRoutes, type RouteSets } from './mixins/getRoutes';
|
|
24
|
+
export { default as createRouter } from './mixins/createRouter';
|
|
25
|
+
export { default as hooks } from './mixins/hooks';
|
|
26
|
+
export { smartScrollBehavior } from './mixins/scroll';
|
|
27
|
+
|
|
28
|
+
// component registries
|
|
29
|
+
export {
|
|
30
|
+
loadViaGlob,
|
|
31
|
+
loadViaDeclaration,
|
|
32
|
+
loadViaDeclarationSync,
|
|
33
|
+
getAvailableModules,
|
|
34
|
+
createModulesArray,
|
|
35
|
+
} from './mixins/loadComponents';
|
|
36
|
+
|
|
37
|
+
// i18n
|
|
38
|
+
export { default as i18n, t, addMessages } from './plugins/translations';
|
|
39
|
+
|
|
40
|
+
// framework contracts
|
|
41
|
+
export type { default as FrontendConfig } from './interfaces/FrontendConfig.interface';
|
|
42
|
+
export type { default as ModuleBaseProps } from './interfaces/ModuleBaseProps.interface';
|
|
43
|
+
export type { default as IconsPartial } from './interfaces/IconsPartial';
|
|
44
|
+
export type { default as EditorConfiguration } from './interfaces/EditorConfiguration.interface';
|
|
45
|
+
export type { default as PaymentProvider } from './interfaces/PaymentProvider.interface';
|
|
46
|
+
|
|
47
|
+
export { default as logger } from './mixins/logger';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface EditorTitleDescription {
|
|
2
|
+
short?: string
|
|
3
|
+
full?: string
|
|
4
|
+
}
|
|
5
|
+
export default interface EditorConfiguration {
|
|
6
|
+
|
|
7
|
+
editorUrl?: string
|
|
8
|
+
breakpointTablet?: string
|
|
9
|
+
breakpointDesktop?: string
|
|
10
|
+
breakpointWide?: string
|
|
11
|
+
preloadImages?: boolean
|
|
12
|
+
title?: EditorTitleDescription
|
|
13
|
+
description?: EditorTitleDescription
|
|
14
|
+
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default interface EventDeclaration {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
confirmRequired?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* the event is async and we need to show a animation on execute
|
|
8
|
+
*/
|
|
9
|
+
operation?: boolean;
|
|
10
|
+
feedback?: {
|
|
11
|
+
pending?: string;
|
|
12
|
+
resolved?: string;
|
|
13
|
+
rejected?: string;
|
|
14
|
+
};
|
|
15
|
+
additionalData?: {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Auth0ClientOptions } from '@auth0/auth0-spa-js';
|
|
2
|
+
import type StudioSDK from '@lilaquadrat/sdk';
|
|
3
|
+
|
|
4
|
+
export default interface FrontendConfig {
|
|
5
|
+
|
|
6
|
+
auth0Options?: Auth0ClientOptions
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* for identification at the backend
|
|
10
|
+
*/
|
|
11
|
+
name: string
|
|
12
|
+
|
|
13
|
+
company: string
|
|
14
|
+
project: string
|
|
15
|
+
|
|
16
|
+
api: {
|
|
17
|
+
mode: StudioSDK['mode']
|
|
18
|
+
customEndpoints?: StudioSDK['customEndpoints']
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
cdn: {
|
|
22
|
+
public: string
|
|
23
|
+
secure: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
payment?: {
|
|
27
|
+
type?: 'internal' | 'shopify' | 'stripe',
|
|
28
|
+
options?: Record<string, string>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* base path for loading files
|
|
33
|
+
*/
|
|
34
|
+
base?: string
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* indicates that this project is dynamic. e.g. an app or an website with at least one dynamic part
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
dynamic?: boolean
|
|
41
|
+
|
|
42
|
+
}
|