@viur/shop-components 0.0.1-dev.6 → 0.0.1-dev.61

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.
Files changed (131) hide show
  1. package/.editorconfig +16 -0
  2. package/.github/workflows/npm-publish.yml +42 -0
  3. package/.gitmodules +3 -0
  4. package/LICENSE +21 -0
  5. package/README.md +13 -2
  6. package/old/client/HttpClient.js +111 -0
  7. package/old/client/ViURShopClient.js +472 -0
  8. package/old/client/index.js +23 -0
  9. package/old/client/types.js +10 -0
  10. package/old/components/ExampleUsage.vue +95 -0
  11. package/old/components/ShopCart.vue +91 -0
  12. package/old/components/ShopOrderComplete.vue +73 -0
  13. package/old/components/ShopOrderConfirm.vue +311 -0
  14. package/old/components/ShopOrderStepper.vue +352 -0
  15. package/old/components/ShopPaymentProvider.vue +113 -0
  16. package/old/components/ShopShippingMethod.vue +52 -0
  17. package/old/components/ShopSummary.vue +138 -0
  18. package/old/components/ShopUserData.vue +218 -0
  19. package/old/components/cart/CartLeaf.vue +277 -0
  20. package/old/components/cart/CartLeafModel.vue +312 -0
  21. package/old/components/cart/CartNode.vue +26 -0
  22. package/old/components/cart/CartTree.vue +67 -0
  23. package/old/components/cart/CartTreeWrapper.vue +73 -0
  24. package/old/components/cart/CartView.vue +82 -0
  25. package/old/components/cart/Discount.vue +91 -0
  26. package/old/components/generic/loadinghandler.vue +76 -0
  27. package/old/components/paymentProvider/paypalplus.vue +0 -0
  28. package/old/components/paymentProvider/prepayment.vue +0 -0
  29. package/old/components/paymentProvider/unzerPayment.vue +140 -0
  30. package/old/components/simple/ShopUserData.vue +161 -0
  31. package/old/components/simple/SimpleDefaultLayout.vue +116 -0
  32. package/old/components/ui/generic/CardSelector.vue +52 -0
  33. package/old/components/ui/generic/CartList.vue +69 -0
  34. package/old/components/ui/generic/ShippingInfo.vue +56 -0
  35. package/old/components/ui/generic/ShopPriceFormatter.vue +41 -0
  36. package/old/components/ui/generic/alerts/ShopAlert.vue +30 -0
  37. package/old/components/ui/payment/PaymentOption.vue +79 -0
  38. package/old/components/ui/payment/PaymentSelector.vue +158 -0
  39. package/old/components/ui/stepper/StepperItem.vue +90 -0
  40. package/old/components/ui/stepper/StepperTab.vue +161 -0
  41. package/old/components/ui/stepper/StepperTrigger.vue +69 -0
  42. package/old/components/ui/userdata/AddForm.vue +160 -0
  43. package/old/components/ui/userdata/AddressBox.vue +137 -0
  44. package/old/components/ui/userdata/BaseLayout.vue +77 -0
  45. package/old/components/ui/userdata/CustomBooleanBone.vue +58 -0
  46. package/old/components/ui/userdata/CustomSelectBone.vue +91 -0
  47. package/old/components/ui/userdata/CustomStringBone.vue +71 -0
  48. package/old/components/ui/userdata/DefaultLayout.vue +126 -0
  49. package/old/components/ui/userdata/SelectAddress.vue +21 -0
  50. package/old/components/ui/userdata/multi/ActionBar.vue +38 -0
  51. package/old/components/ui/userdata/multi/CartSelection.vue +42 -0
  52. package/old/ignite/.editorconfig +20 -0
  53. package/old/ignite/.github/workflows/ignite.yml +64 -0
  54. package/old/ignite/.github/workflows/node.yml +30 -0
  55. package/old/ignite/.postcssrc.cjs +25 -0
  56. package/old/ignite/CHANGELOG.md +244 -0
  57. package/old/ignite/LICENSE +21 -0
  58. package/old/ignite/README.md +92 -0
  59. package/old/ignite/dist/ignite.css +2019 -0
  60. package/old/ignite/dist/ignite.min.css +4 -0
  61. package/old/ignite/foundation/basic.css +371 -0
  62. package/old/ignite/foundation/color.css +323 -0
  63. package/old/ignite/foundation/config.css +188 -0
  64. package/old/ignite/foundation/grid.css +78 -0
  65. package/old/ignite/foundation/mediaqueries.css +71 -0
  66. package/old/ignite/foundation/reset.css +261 -0
  67. package/old/ignite/ignite.css +29 -0
  68. package/old/ignite/ignite.css.map +1 -0
  69. package/old/ignite/package-lock.json +5530 -0
  70. package/old/ignite/package.json +58 -0
  71. package/old/ignite/shoelace.css +19 -0
  72. package/old/ignite/themes/dark.css +12 -0
  73. package/old/ignite/themes/light.css +11 -0
  74. package/old/ignite/utilities/shoelace.css +537 -0
  75. package/old/ignite/utilities/utilities.css +24 -0
  76. package/old/stores/address.js +122 -0
  77. package/old/stores/cart.js +266 -0
  78. package/old/stores/message.js +21 -0
  79. package/old/stores/order.js +202 -0
  80. package/old/stores/payment.js +79 -0
  81. package/old/stores/shipping.js +78 -0
  82. package/package.json +23 -23
  83. package/src/Shop.vue +212 -0
  84. package/src/ShopOrderStepper.vue +89 -0
  85. package/src/ShopSummary.vue +170 -0
  86. package/src/Steps/ShopCart.vue +60 -0
  87. package/src/Steps/ShopOrderComplete.vue +24 -0
  88. package/src/Steps/ShopOrderConfirm.vue +295 -0
  89. package/src/Steps/ShopPaymentProvider.vue +53 -0
  90. package/src/Steps/ShopShippingMethod.vue +53 -0
  91. package/src/Steps/ShopUserDataGuest.vue +78 -0
  92. package/src/Steps/index.js +15 -0
  93. package/src/components/AddressForm.vue +84 -0
  94. package/src/components/AddressFormLayout.vue +107 -0
  95. package/src/components/CardSelector.vue +68 -0
  96. package/src/components/CartItem.vue +325 -0
  97. package/src/components/CartItemSmall.vue +257 -0
  98. package/src/components/LoadingHandler.vue +76 -0
  99. package/src/components/PaymentOption.vue +78 -0
  100. package/src/components/PaymentProviderUnzer.vue +201 -0
  101. package/src/components/PaymentSelector.vue +55 -0
  102. package/src/components/ShopAlert.vue +30 -0
  103. package/src/components/StepperTab.vue +132 -0
  104. package/src/components/dialogButton.vue +49 -0
  105. package/src/composables/address.js +95 -0
  106. package/src/composables/cart.js +132 -0
  107. package/src/composables/order.js +80 -0
  108. package/src/composables/payment.js +75 -0
  109. package/src/composables/shipping.js +32 -0
  110. package/src/main.js +44 -0
  111. package/src/shop.js +251 -0
  112. package/src/translations/de.js +15 -0
  113. package/src/translations/en.js +5 -0
  114. package/src/utils.js +49 -0
  115. package/vite.config.js +51 -0
  116. package/src/components/cart/CartView.vue +0 -692
  117. package/src/components/cart/ConfirmView.vue +0 -314
  118. package/src/components/order/category/CategoryList.vue +0 -83
  119. package/src/components/order/category/CategoryView.vue +0 -143
  120. package/src/components/order/information/UserInfoMulti.vue +0 -427
  121. package/src/components/order/information/UserInformation.vue +0 -332
  122. package/src/components/order/information/adress/ShippingAdress.vue +0 -143
  123. package/src/components/order/item/ItemCard.vue +0 -168
  124. package/src/components/order/item/ItemView.vue +0 -233
  125. package/src/components/order/process/ExampleUsage.vue +0 -100
  126. package/src/components/order/process/OrderComplete.vue +0 -41
  127. package/src/components/order/process/OrderTabHeader.vue +0 -7
  128. package/src/components/order/process/OrderView.vue +0 -210
  129. package/src/router/index.js +0 -103
  130. package/src/stores/cart.js +0 -111
  131. package/src/views/ViewMissing.vue +0 -20
@@ -0,0 +1,312 @@
1
+ <template>
2
+ <!-- Debugging -->
3
+ <!-- <pre>{{ modelValue.leaf.article.dest.key }}</pre>
4
+
5
+ <pre>{{ modelValue }}</pre> -->
6
+
7
+ <sl-dialog no-header ref="confirm" @sl-hide="resetItem">
8
+ <p>Möchten Sie den Artikel wirklich aus dem Warenkorb entfernen?</p>
9
+ <sl-bar>
10
+ <sl-button
11
+ slot="left"
12
+ variant="danger"
13
+ @click="confirm.hide()"
14
+ size="medium"
15
+ >
16
+ Abbrechen
17
+ </sl-button>
18
+ <sl-button
19
+ slot="right"
20
+ variant="success"
21
+ @click="onConfirm"
22
+ size="medium"
23
+ >
24
+ Aus Warenkorb entfernen
25
+ </sl-button>
26
+ </sl-bar>
27
+ </sl-dialog>
28
+
29
+ <div v-if="!modelValue"></div>
30
+ <sl-card horizontal class="viur-shop-cart-leaf" v-else>
31
+ <img
32
+ class="viur-shop-cart-leaf-image"
33
+ slot="image"
34
+ :src="
35
+ getImage(
36
+ modelValue?.shop_image
37
+ ? modelValue.shop_image
38
+ : undefined,
39
+ )
40
+ "
41
+ />
42
+ <h4
43
+ class="viur-shop-cart-leaf-headline headline"
44
+ v-html="modelValue.article.dest.shop_name"
45
+ ></h4>
46
+ <h5 class="viur-shop-cart-leaf-artno">
47
+ {{ modelValue.article.dest.shop_art_no_or_gtin }}
48
+ </h5>
49
+ <div
50
+ class="viur-shop-cart-leaf-description"
51
+ v-html="modelValue.article.dest.shop_description"
52
+ ></div>
53
+ <div class="viur-shop-cart-leaf-quantity">
54
+ <sl-input
55
+ class="viur-shop-cart-leaf-value viur-shop-cart-leaf-value--quantity"
56
+ type="number"
57
+ label="Anzahl"
58
+ placeholder="Number"
59
+ min="0"
60
+ :value="modelValue.quantity"
61
+ @sl-change="updateItem"
62
+ :disabled="cartStore.state.freeze"
63
+ ref="itemCount"
64
+ >
65
+ </sl-input>
66
+ </div>
67
+ <div class="viur-shop-cart-leaf-unitprice">
68
+ <div class="viur-shop-cart-leaf-label">Stückpreis</div>
69
+ <sl-format-number
70
+ class="viur-shop-cart-leaf-value viur-shop-cart-leaf-value--unitprice"
71
+ lang="de"
72
+ type="currency"
73
+ currency="EUR"
74
+ :value="modelValue.shop_price_retail"
75
+ >
76
+ </sl-format-number>
77
+ </div>
78
+
79
+ <div class="viur-shop-cart-leaf-actions">
80
+ <!-- <sl-button
81
+ size="small"
82
+ outline
83
+ class="viur-shop-cart-leaf-add-to-favourites-btn"
84
+ variant="primary"
85
+ title="Add to favourites"
86
+ >
87
+ <sl-icon name="heart" slot="prefix"></sl-icon>
88
+ </sl-button> -->
89
+ <sl-button
90
+ size="small"
91
+ outline
92
+ class="viur-shop-cart-leaf-delete-btn"
93
+ variant="primary"
94
+ title="Remove from cart"
95
+ @click="confirm.show()"
96
+ v-if="!cartStore.state.freeze"
97
+ >
98
+ <sl-icon name="trash" slot="prefix"></sl-icon>
99
+ </sl-button>
100
+ </div>
101
+
102
+ <div class="viur-shop-cart-leaf-price">
103
+ <div class="viur-shop-cart-leaf-label">Gesamtpreis</div>
104
+ <sl-format-number
105
+ class="viur-shop-cart-leaf-value viur-shop-cart-leaf-value--price"
106
+ lang="de"
107
+ type="currency"
108
+ currency="EUR"
109
+ :value="modelValue.shop_price_retail * modelValue.quantity"
110
+ >
111
+ </sl-format-number>
112
+ </div>
113
+ <!-- TODO: Some customer needs an availability indicator ("in stock" etc.) here -->
114
+ </sl-card>
115
+ </template>
116
+
117
+ <script setup>
118
+ import { computed, onBeforeMount, reactive, ref } from "vue";
119
+ import { Request } from "@viur/vue-utils";
120
+ import { useCartStore } from "../../stores/cart";
121
+ import { useDebounceFn } from "@vueuse/core";
122
+ // import ShopPriceFormatter from "../ui/generic/ShopPriceFormatter.vue";
123
+
124
+ const props = defineProps(["modelValue"]);
125
+ const emit = defineEmits(["update:modelValue"]);
126
+
127
+ const cartStore = useCartStore();
128
+ const confirm = ref(null);
129
+ const isConfirmed = ref(false);
130
+ const itemCount = ref(null);
131
+
132
+ function getImage(image) {
133
+ if (image !== undefined) return Request.downloadUrlFor(image);
134
+
135
+ return cartStore.state.placeholder;
136
+ }
137
+
138
+ const updateItem = useDebounceFn(
139
+ (ev) => {
140
+ console.log(ev);
141
+ let newEvent = { ...props.modelValue };
142
+
143
+ newEvent.quantity = ev.target.value;
144
+
145
+ console.log("update", newEvent.quantity);
146
+ if (newEvent.quantity < 1) {
147
+ confirm.value.show();
148
+ } else {
149
+ emit("update:modelValue", newEvent);
150
+ }
151
+ },
152
+ 1500,
153
+ { maxWait: 5000 },
154
+ );
155
+
156
+ function removeItem() {
157
+ let newEvent = { ...props.modelValue };
158
+ newEvent.quantity = 0;
159
+ emit("update:modelValue", newEvent);
160
+ }
161
+
162
+ function resetItem() {
163
+ if (!isConfirmed.value) {
164
+ itemCount.value.value = props.modelValue.quantity;
165
+ }
166
+ }
167
+
168
+ async function onConfirm() {
169
+ isConfirmed.value = true;
170
+ removeItem();
171
+ confirm.value.hide();
172
+ }
173
+ </script>
174
+
175
+ <style scoped>
176
+ @layer foundation.shop {
177
+ .viur-shop-cart-leaf {
178
+ --shop-leaf-label-color: var(--ignt-color-primary);
179
+ --shop-leaf-label-font-weight: 600;
180
+ --shop-leaf-label-font-size: 1em;
181
+ --shop-leaf-price-font-size: 1em;
182
+ --shop-leaf-headline-font-size: 1.3em;
183
+
184
+ margin-bottom: var(--ignt-spacing-x-large);
185
+
186
+ &::part(base) {
187
+ display: flex;
188
+ position: relative;
189
+ }
190
+
191
+ &::part(header) {
192
+ border-bottom: none;
193
+ padding-top: 0;
194
+ padding-right: 0;
195
+ }
196
+
197
+ &::part(image) {
198
+ aspect-ratio: 1;
199
+ }
200
+
201
+ &::part(body) {
202
+ display: grid;
203
+ grid-template-columns: repeat(5, minmax(0, 1fr));
204
+ gap: var(--sl-spacing-medium);
205
+ padding: var(--sl-spacing-large);
206
+ height: 100%;
207
+ }
208
+
209
+ &::part(group) {
210
+ padding: 0;
211
+ }
212
+
213
+ @media (max-width: 600px) {
214
+ &::part(body) {
215
+ grid-template-columns: repeat(2, minmax(0, 1fr));
216
+ gap: var(--sl-spacing-medium);
217
+ padding: var(--sl-spacing-large);
218
+ height: 100%;
219
+ }
220
+
221
+ &::part(image) {
222
+ border-radius: var(--border-radius);
223
+ align-self: baseline;
224
+ }
225
+ }
226
+ }
227
+
228
+ .viur-shop-cart-leaf-image {
229
+ aspect-ratio: 1;
230
+ }
231
+
232
+ .viur-shop-cart-leaf-headline {
233
+ grid-column: 1 / span 4;
234
+ order: -2;
235
+ margin: 0;
236
+ font-size: var(--shop-leaf-headline-font-size);
237
+
238
+ @media (max-width: 600px) {
239
+ grid-column: 1 / span 2;
240
+ }
241
+ }
242
+
243
+ .viur-shop-cart-leaf-artno {
244
+ grid-column: 1 / span 5;
245
+ margin: 0;
246
+
247
+ @media (max-width: 600px) {
248
+ grid-column: 1 / span 2;
249
+ }
250
+ }
251
+
252
+ .viur-shop-cart-leaf-actions {
253
+ display: flex;
254
+ justify-content: start;
255
+ gap: var(--sl-spacing-x-small);
256
+
257
+ @media (min-width: 600px) {
258
+ grid-column: 5 / span 1;
259
+ order: -1;
260
+ justify-content: end;
261
+ align-items: end;
262
+ }
263
+ }
264
+
265
+ .viur-shop-cart-leaf-description {
266
+ grid-column: 1 / span 5;
267
+ margin-bottom: var(--ignt-spacing-small);
268
+ display: -webkit-box;
269
+ -webkit-line-clamp: 3;
270
+ -webkit-box-orient: vertical;
271
+ overflow: hidden;
272
+
273
+ &:deep(*) {
274
+ margin: 0;
275
+ }
276
+
277
+ @media (max-width: 600px) {
278
+ grid-column: span 2;
279
+ }
280
+
281
+ @media (max-width: 500px) {
282
+ display: none;
283
+ }
284
+ }
285
+
286
+ .viur-shop-cart-leaf-price {
287
+ align-self: flex-end;
288
+ text-align: right;
289
+ font-size: var(--shop-leaf-price-font-size);
290
+ }
291
+
292
+ .viur-shop-cart-leaf-quantity {
293
+ align-self: flex-end;
294
+ }
295
+
296
+ .viur-shop-cart-leaf-unitprice {
297
+ align-self: flex-end;
298
+
299
+ @media (max-width: 600px) {
300
+ text-align: right;
301
+ }
302
+ }
303
+
304
+ .viur-shop-cart-leaf-label,
305
+ .viur-shop-cart-leaf-value--quantity::part(form-control-label) {
306
+ color: var(--shop-leaf-label-color);
307
+ font-weight: var(--shop-leaf-label-font-weight);
308
+ font-size: var(--shop-leaf-label-font-size);
309
+ margin-bottom: var(--ignt-spacing-x-small);
310
+ }
311
+ }
312
+ </style>
@@ -0,0 +1,26 @@
1
+ <template>
2
+
3
+ <sl-details v-if="node.children" :summary="node.name">
4
+ <slot></slot>
5
+ </sl-details>
6
+
7
+ <h1 class="viur-shop-cart-headline" v-else>
8
+ {{ node.name }}
9
+ </h1>
10
+ </template>
11
+
12
+ <script setup>
13
+ import { computed, reactive } from "vue";
14
+ import CartLeaf from "./CartLeaf.vue";
15
+ const props = defineProps({
16
+ node: { type: Object, required: true },
17
+ });
18
+
19
+ const state = reactive({});
20
+ </script>
21
+
22
+ <style scoped>
23
+ .viur-shop-cart-headline {
24
+ font-size: 2rem;
25
+ }
26
+ </style>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <CartTreeWrapper :tree="state.tree" @update:modelValue="handleChange">
3
+ </CartTreeWrapper>
4
+
5
+ <sl-button
6
+ @click="
7
+ cartStore.addNode(
8
+ cartStore.state.basket.key,
9
+ (cartType = 'basket'),
10
+ )
11
+ "
12
+ >addbutton</sl-button
13
+ >
14
+ </template>
15
+ <script setup>
16
+ import { reactive, watch, computed } from "vue";
17
+ import CartTreeWrapper from "./CartTreeWrapper.vue";
18
+ import { useCartStore } from "../../stores/cart";
19
+
20
+ const cartStore = useCartStore();
21
+
22
+ const props = defineProps({
23
+ modelValue: { type: Array, required: true },
24
+ });
25
+
26
+ const emits = defineEmits(["update:modelValue"]);
27
+
28
+ const arrayToTree = (arr, parent = null) =>
29
+ arr
30
+ .filter((item) => item.parententry === parent)
31
+ .map((child) => ({ ...child, children: arrayToTree(arr, child.key) }));
32
+
33
+ const state = reactive({
34
+ loading: computed(() => {
35
+ return props.modelValue ? false : true;
36
+ }),
37
+ tree: computed(() => {
38
+ // ! NOTE: it is very important to unpack the prop (copy the array) at this point to avoid prop mutation!!!
39
+ let temp = props.modelValue ? arrayToTree([...props.modelValue]) : [""];
40
+
41
+ return temp[0];
42
+ }),
43
+ });
44
+
45
+ function handleChange(e) {
46
+ // ! NOTE: it is very important to unpack the prop (copy the array) at this point to avoid prop mutation!!!
47
+ let temp = [...props.modelValue];
48
+
49
+ temp.forEach((item, index) => {
50
+ if (item.key === e.key) {
51
+ if (e.quantity < 1) {
52
+ temp.splice(index, 1);
53
+ } else {
54
+ temp[index] = e;
55
+ }
56
+ }
57
+ });
58
+
59
+ emits("update:modelValue", temp);
60
+ }
61
+
62
+ // watch(() => props.modelValue,
63
+ // (oldVal, newVal) => {
64
+ // if(oldVal === )
65
+ // }
66
+ // );
67
+ </script>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <div v-if="state.loading">keine Einträge im Warenkorb</div>
3
+
4
+ <template v-else-if="tree.is_root_node">
5
+ <template v-for="child in tree.children" :key="child.key">
6
+ <CartLeafModel
7
+ :modelValue="child"
8
+ v-if="child.skel_type === 'leaf'"
9
+ @update:modelValue="handleChange"
10
+ />
11
+
12
+ <CartNode
13
+ :node="child"
14
+ v-else-if="child.children.length && child?.skel_type === 'node'"
15
+ >
16
+ <template v-for="item in child.children" :key="item.key">
17
+ <CartLeafModel
18
+ :modelValue="item"
19
+ v-if="item.skel_type === 'leaf'"
20
+ @update:modelValue="handleChange"
21
+ >
22
+ </CartLeafModel>
23
+ <CartTreeWrapper
24
+ :tree="item"
25
+ @update:modelValue="handleChange"
26
+ v-else
27
+ >
28
+ </CartTreeWrapper>
29
+ </template>
30
+ </CartNode>
31
+ </template>
32
+ </template>
33
+
34
+ <CartNode :node="tree" v-else-if="tree.skel_type === 'node'">
35
+ <template v-for="item in tree.children" :key="item.key">
36
+ <CartLeafModel
37
+ :modelValue="item"
38
+ @update:modelValue="handleChange"
39
+ v-if="item.skel_type === 'leaf'"
40
+ >
41
+ </CartLeafModel>
42
+ <CartTreeWrapper :tree="item" @update:modelValue="handleChange" v-else>
43
+ </CartTreeWrapper>
44
+ </template>
45
+ </CartNode>
46
+ </template>
47
+
48
+ <script setup>
49
+ import { reactive, watch, computed } from "vue";
50
+ import CartLeafModel from "./CartLeafModel.vue";
51
+ import CartNode from "./CartNode.vue";
52
+
53
+ const props = defineProps({
54
+ tree: { type: Object },
55
+ });
56
+
57
+ const emits = defineEmits(["update:modelValue"]);
58
+
59
+ const state = reactive({
60
+ loading: computed(() => {
61
+ if (props.tree) {
62
+ return false;
63
+ }
64
+ return true;
65
+ }),
66
+ });
67
+
68
+ function handleChange(e) {
69
+ emits("update:modelValue", e);
70
+ }
71
+
72
+ watch(() => {});
73
+ </script>
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <div v-if="state.loading">keine Einträge im Warenkorb</div>
3
+ <template v-else>
4
+ <div
5
+ class="viur-shop-cart-node"
6
+ v-for="entry in modelValue"
7
+ :key="entry.key"
8
+ >
9
+ <CartLeafModel
10
+ :modelValue="entry"
11
+ v-if="entry.skel_type === 'leaf'"
12
+ @update:modelValue="handleChange"
13
+ />
14
+ </div>
15
+ <shop-summary v-if="standalone">
16
+ <template #custom v-if="customComponent">
17
+ <component :is="customComponent"></component>
18
+ </template>
19
+ </shop-summary>
20
+ </template>
21
+ </template>
22
+ <script setup>
23
+ import { reactive, computed } from "vue";
24
+ import CartLeafModel from "./CartLeafModel.vue";
25
+ import { useCartStore } from "../../stores/cart";
26
+ import ShopSummary from "../ShopSummary.vue";
27
+
28
+ const props = defineProps({
29
+ modelValue: { type: Array, required: true },
30
+ standalone: { type: Boolean, default: true },
31
+ customComponent: { default: null },
32
+ });
33
+
34
+ const emits = defineEmits(["update:modelValue"]);
35
+
36
+ const cartStore = useCartStore();
37
+
38
+ const state = reactive({
39
+ loading: computed(() => {
40
+ return props.modelValue.length ? false : true;
41
+ }),
42
+ });
43
+
44
+ async function handleChange(e) {
45
+ // ! NOTE: it is very important to unpack the prop (copy the array) at this point to avoid prop mutation!!!
46
+ let temp = [...props.modelValue];
47
+
48
+ temp.forEach(async (item, index) => {
49
+ if (item.key === e.key) {
50
+ if (item.quantity === e.quantity) {
51
+ return; //return if value has no changes so if value is 0 or remove button is clicked no request will be fired
52
+ }
53
+ if (e.quantity < 1) {
54
+ await cartStore.removeItem(e.article.dest.key, e.parententry);
55
+ temp.splice(index, 1);
56
+ } else {
57
+ await cartStore.updateItem(
58
+ e.article.dest.key,
59
+ e.parententry,
60
+ e.quantity,
61
+ );
62
+ temp[index] = e;
63
+ }
64
+ }
65
+ });
66
+
67
+ emits("update:modelValue", temp);
68
+ }
69
+
70
+ // watch(() => props.modelValue,
71
+ // (oldVal, newVal) => {
72
+ // if(oldVal === )
73
+ // }
74
+ // );
75
+ </script>
76
+
77
+ <style scoped>
78
+ .viur-shop-cart-node {
79
+ display: flex;
80
+ flex-direction: column;
81
+ }
82
+ </style>
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <div>
3
+
4
+ <span>Haben Sie noch ein Gutschein?</span><br>
5
+ <span v-if="!cartStore.state.basket.discount">Es befindet sich noch kein Gutschein im Warenkorb.</span>
6
+ <sl-button-group>
7
+ <sl-input placeholder="Rabatt Code" ref="codeInput">
8
+
9
+ </sl-input>
10
+ <sl-button @click="addDiscountCode">Einlösen</sl-button>
11
+ </sl-button-group>
12
+ <sl-alert ref="errorMessageContainer">
13
+ <sl-icon slot="icon" name="info-circle"></sl-icon>
14
+ {{ state.errorMessage }}
15
+ </sl-alert>
16
+ </div>
17
+ <div>
18
+ <div v-if="cartStore.state.basket.discount">
19
+ <!--Todo bessere texte und translations??-->
20
+ <div v-if="cartStore.state.basket.discount.dest.discount_type==='absolute'">
21
+ <span>
22
+ Sie haben einen Rabattcode im Wert von {{ cartStore.state.basket.discount.dest.absolute }} € eingegeben
23
+ </span>
24
+ <sl-icon-button name="x-lg" label="Löschen" @click="removeDiscountCode"></sl-icon-button>
25
+ </div>
26
+ <div v-if="cartStore.state.basket.discount.dest.discount_type==='percentage'">
27
+ <span>
28
+ Sie haben einen Rabattcode im Wert von {{ cartStore.state.basket.discount.dest.percentage }} % eingegeben
29
+ </span>
30
+ <sl-icon-button name="x-lg" label="Löschen" @click="removeDiscountCode"></sl-icon-button>
31
+ </div>
32
+
33
+ </div>
34
+ </div>
35
+ <sl-spinner v-show="state.isFetching"></sl-spinner>
36
+
37
+ </template>
38
+ <script setup>
39
+ import {useCartStore} from "../../stores/cart";
40
+ import {computed, reactive, ref} from "vue";
41
+
42
+ const cartStore = useCartStore();
43
+ const codeInput = ref(null);
44
+ const errorMessageContainer = ref(null);
45
+ const state = reactive({
46
+ errorMessage: "",
47
+ isFetching: false,
48
+ });
49
+
50
+ async function addDiscountCode() {
51
+ errorMessageContainer.value.hide();
52
+ const discountCode = codeInput.value.value;
53
+ if (!discountCode) {
54
+ errorMessageContainer.value.show();
55
+ state.errorMessage = "Es wurde kein Rabattcode eingegeben";
56
+ return
57
+ }
58
+ state.isFetching = true;
59
+ console.log("festch", state.isFetching)
60
+ cartStore.addDiscount(discountCode).then((res) => {
61
+ cartStore.init();//TODO muss man alles neuladen ??
62
+ state.isFetching = false;
63
+
64
+ }).catch((e) => {
65
+ console.error("Cant add key");
66
+ state.isFetching = false;
67
+ })
68
+
69
+ }
70
+
71
+ async function removeDiscountCode() {
72
+
73
+ errorMessageContainer.value.hide();
74
+ state.isFetching = true;
75
+ console.log("code ", cartStore.state.basket.discount.dest.key)
76
+ cartStore.removeDiscount(cartStore.state.basket.discount.dest.key).then((res) => {
77
+ cartStore.init();//TODO muss man alles neuladen ??
78
+ state.isFetching = false;
79
+
80
+ }).catch((e) => {
81
+ console.error("Cant remove key");
82
+ state.isFetching = false;
83
+ })
84
+
85
+ }
86
+ </script>
87
+
88
+
89
+ <style scoped>
90
+
91
+ </style>