@viur/shop-components 0.0.1-dev.3 → 0.0.1-dev.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.
@@ -0,0 +1,332 @@
1
+ <template>
2
+ <!-- <slot name="form" v-if="mode === 'form'">
3
+ <form @submit.prevent="sendData">
4
+ <h2 class="viur-shop-form-headline headline">Nutzterdaten</h2>
5
+ <div class="viur-shop-form-wrap">
6
+ <sl-input
7
+ name="email"
8
+ v-model="state.formValues['email']"
9
+ placeholder="E-Mail"
10
+ class="viur-shop-form-grid-w-4"
11
+ >
12
+ <label slot="label">E-Mail*</label>
13
+ </sl-input>
14
+ <sl-input
15
+ name="name"
16
+ v-model="state.formValues['lastname']"
17
+ placeholder="Name"
18
+ class="viur-shop-form-grid-w-2"
19
+ >
20
+ <label slot="label">Name*</label>
21
+ </sl-input>
22
+ <sl-input
23
+ name="firstname"
24
+ v-model="state.formValues['firstname']"
25
+ placeholder="Vorname"
26
+ class="viur-shop-form-grid-w-2"
27
+ >
28
+ <label slot="label">Vorname*</label>
29
+ </sl-input>
30
+ </div>
31
+ <div class="viur-shop-form-adress-wrapper">
32
+ <div class="viur-shop-form-adress-column">
33
+ <h2 class="viur-shop-form-headline headline">Lieferadresse</h2>
34
+ <div class="viur-shop-form-wrap">
35
+ <sl-input
36
+ name="street"
37
+ v-model="state.formValues['street']"
38
+ placeholder="Straße"
39
+ class="viur-shop-form-grid-w-3"
40
+ >
41
+ <label slot="label">Strasse *</label>
42
+ </sl-input>
43
+ <sl-input
44
+ name="street"
45
+ v-model="state.formValues['streetnumber']"
46
+ placeholder="Hausnummer"
47
+ type="number"
48
+ >
49
+ <label slot="label">Hausnummer *</label>
50
+ </sl-input>
51
+ <sl-input
52
+ name="street"
53
+ v-model="state.formValues['areacode']"
54
+ placeholder="Postleitzahl"
55
+ class="viur-shop-form-grid-w-2"
56
+ type="number"
57
+ >
58
+ <label slot="label">Postleitzahl *</label>
59
+ </sl-input>
60
+ <sl-input
61
+ name="city"
62
+ v-model="state.formValues['city']"
63
+ placeholder="Stadt"
64
+ class="viur-shop-form-grid-w-2"
65
+ >
66
+ <label slot="label">Stadt*</label>
67
+ </sl-input>
68
+ <sl-input
69
+ name="province"
70
+ v-model="state.formValues['province']"
71
+ placeholder="Bundesland"
72
+ class="viur-shop-form-grid-w-2"
73
+ >
74
+ <label slot="label">Bundesland</label>
75
+ </sl-input>
76
+ </div>
77
+ </div>
78
+
79
+ <sl-checkbox @sl-change="onCustomAdressChange" checked>
80
+ Rechnungsadresse wie Lieferadresse
81
+ </sl-checkbox>
82
+
83
+ <div class="viur-shop-form-adress-column" v-show="state.isCustomAdress">
84
+ <h2 class="viur-shop-form-headline headline">Rechnungsadresse</h2>
85
+ <div class="viur-shop-form-wrap">
86
+ <sl-input
87
+ name="street"
88
+ v-model="state.formValues['billing.street']"
89
+ placeholder="Straße"
90
+ class="viur-shop-form-grid-w-3"
91
+ >
92
+ <label slot="label">Strasse *</label>
93
+ </sl-input>
94
+ <sl-input
95
+ name="street"
96
+ v-model="state.formValues['billing.streetnumber']"
97
+ placeholder="Hausnummer"
98
+ type="number"
99
+ >
100
+ <label slot="label">Hausnummer *</label>
101
+ </sl-input>
102
+ <sl-input
103
+ name="city"
104
+ v-model="state.formValues['billing.areacode']"
105
+ placeholder="Postleitzahl"
106
+ type="number"
107
+ class="viur-shop-form-grid-w-2"
108
+ >
109
+ <label slot="label">Postleitzahl *</label>
110
+ </sl-input>
111
+ <sl-input
112
+ name="city"
113
+ v-model="state.formValues['billing.city']"
114
+ placeholder="Stadt"
115
+ class="viur-shop-form-grid-w-2"
116
+ >
117
+ <label slot="label">Stadt*</label>
118
+ </sl-input>
119
+ <sl-input
120
+ name="province"
121
+ v-model="state.formValues['billing.province']"
122
+ placeholder="Bundesland"
123
+ class="viur-shop-form-grid-w-2"
124
+ >
125
+ <label slot="label">Bundesland</label>
126
+ </sl-input>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ <div class="viur-shop-form-footer">
131
+ <sl-button type="submit"> Zurück </sl-button>
132
+ <sl-button
133
+ :disabled="!state.requiredFieldsFilled"
134
+ type="submit"
135
+ variant="primary"
136
+ >
137
+ Weiter
138
+ </sl-button>
139
+ </div>
140
+ </form>
141
+ </slot> -->
142
+ <!-- <div class="viur-shop-form-wrap"> -->
143
+
144
+ <div>
145
+ <h2 class="viur-shop-form-headline headline">Nutzterdaten</h2>
146
+ <template v-for="item in state.addSkel" :key="item[0]">
147
+ <bone
148
+ :is="getBoneWidget(item[1].type)"
149
+ v-if="item[1].visible && item[1].params.group === 'Customer Info'"
150
+ :name="item[0]"
151
+ :structure="structToDict(state.addSkel)"
152
+ :errors="state.errors[item[0]] ? state.errors[item[0]] : []"
153
+ :skel="state.formValues"
154
+ @change="changeEvent(item[0], $event)"
155
+ class="viur-shop-form-grid-w-2"
156
+ >
157
+ </bone>
158
+ </template>
159
+ </div>
160
+ <div>
161
+ <h2 class="viur-shop-form-headline headline">Lieferadresse</h2>
162
+ <template v-for="item in state.addSkel" :key="item[0]">
163
+ <bone
164
+ :is="getBoneWidget(item[1].type)"
165
+ v-if="item[1].visible && item[1].params.group === 'Customer Address'"
166
+ :name="item[0]"
167
+ :structure="structToDict(state.addSkel)"
168
+ :errors="state.errors[item[0]] ? state.errors[item[0]] : []"
169
+ :skel="state.formValues"
170
+ @change="changeEvent(item[0], $event)"
171
+ >
172
+ </bone>
173
+ </template>
174
+ </div>
175
+ <div v-if="state.isCustomAdress">
176
+ <h2 class="viur-shop-form-headline headline">Rechnungsadresse</h2>
177
+ <template v-for="item in state.addSkel" :key="item[0]">
178
+ <bone
179
+ :is="getBoneWidget(item[1].type)"
180
+ v-if="item[1].visible && item[1].params.group === 'Customer Address'"
181
+ :name="item[0]"
182
+ :structure="structToDict(state.addSkel)"
183
+ :errors="state.errors[item[0]] ? state.errors[item[0]] : []"
184
+ :skel="state.formValues"
185
+ @change="changeEvent(item[0], $event)"
186
+ >
187
+ </bone>
188
+ </template>
189
+ </div>
190
+
191
+ <sl-checkbox @sl-change="onCustomAdressChange" checked>
192
+ Rechnungsadresse wie Lieferadresse
193
+ </sl-checkbox>
194
+
195
+ <!-- </div> -->
196
+ </template>
197
+
198
+ <script setup>
199
+ import { getBoneWidget } from "@viur/vue-utils/bones/edit/index";
200
+
201
+ import { reactive, computed, watch, onBeforeMount } from "vue";
202
+ import { useCartStore } from "../../../stores/cart";
203
+
204
+ const props = defineProps({
205
+ mode: { type: String, default: "form" },
206
+ conditions: { type: Function },
207
+ });
208
+
209
+ const cartStore = useCartStore();
210
+
211
+ const state = reactive({
212
+ formValues: {},
213
+ requiredFieldsFilled: computed(() => {
214
+ if (state.isCustomAdress) {
215
+ return (
216
+ Object.keys(state.formValues).includes("city") &&
217
+ Object.keys(state.formValues).includes("street") &&
218
+ Object.keys(state.formValues).includes("billing.city") &&
219
+ Object.keys(state.formValues).includes("billing.street") &&
220
+ Object.keys(state.formValues).includes("email") &&
221
+ Object.keys(state.formValues).includes("firstname") &&
222
+ Object.keys(state.formValues).includes("lastname")
223
+ );
224
+ }
225
+ if (!state.isCustomAdress) {
226
+ return (
227
+ Object.keys(state.formValues).includes("city") &&
228
+ Object.keys(state.formValues).includes("street") &&
229
+ Object.keys(state.formValues).includes("email") &&
230
+ Object.keys(state.formValues).includes("firstname") &&
231
+ Object.keys(state.formValues).includes("lastname")
232
+ );
233
+ }
234
+ }),
235
+ isCustomAdress: false,
236
+ addSkel: null,
237
+ errors: {},
238
+ });
239
+
240
+ // function updateFormValues(e){
241
+ // state.formValues[e.target.name] = e.target.value
242
+ // }
243
+
244
+ function sendData(e) {
245
+ console.log("sende daten...", state.formValues);
246
+ }
247
+
248
+ function onCustomAdressChange(e) {
249
+ if (e.target.checked) state.isCustomAdress = false;
250
+ if (!e.target.checked) state.isCustomAdress = true;
251
+ }
252
+
253
+ function changeEvent(boneName, ev) {
254
+ for (const [key, value] of Object.entries(ev.value[0])) {
255
+ state.formValues[key] = value;
256
+ }
257
+ }
258
+
259
+ function structToDict(structure) {
260
+ let output = {};
261
+
262
+ structure.forEach((bone) => {
263
+ let boneName = bone[0];
264
+ let boneValues = bone[1];
265
+
266
+ output[boneName] = boneValues;
267
+ });
268
+
269
+ return output;
270
+ }
271
+
272
+ function initBoneNames(structure) {
273
+ let output = [];
274
+
275
+ structure.forEach((bone) => {
276
+ let boneName = bone[0];
277
+
278
+ output.push(boneName);
279
+ });
280
+
281
+ return output;
282
+ }
283
+
284
+ watch(state.formValues, (newValues) => {
285
+ Object.entries(newValues).forEach(([k, v]) => {
286
+ if (v === "") {
287
+ delete state.formValues[k];
288
+ }
289
+ });
290
+ });
291
+
292
+ onBeforeMount(async () => {
293
+ await cartStore.getAdressStructure();
294
+ state.addSkel = cartStore.state.structure.address;
295
+ });
296
+ </script>
297
+
298
+ <style scoped>
299
+
300
+ .viur-shop-form-adress-wrapper {
301
+ display: flex;
302
+ flex-direction: column;
303
+ gap: 1rem;
304
+ width: 100%;
305
+ justify-content: space-around;
306
+ align-items: flex-start;
307
+ }
308
+
309
+ .viur-shop-form-adress-column {
310
+ align-self: flex-start;
311
+ flex-grow: 1;
312
+ }
313
+
314
+ .viur-shop-form-wrap {
315
+ display: grid;
316
+ grid-template-columns: repeat(4, minmax(0, 1fr));
317
+ gap: 0 var(--sl-spacing-medium);
318
+ margin: var(--sl-spacing-large) 0;
319
+ }
320
+
321
+ .viur-shop-form-grid-w-2 {
322
+ grid-column: span 2;
323
+ }
324
+
325
+ .viur-shop-form-grid-w-3 {
326
+ grid-column: span 3;
327
+ }
328
+
329
+ .viur-shop-form-grid-w-4 {
330
+ grid-column: span 4;
331
+ }
332
+ </style>
@@ -0,0 +1,143 @@
1
+ <template>
2
+ <sl-splinner
3
+ v-if="!cartStore.state.carts[cartStore.state.basket]?.items"
4
+ ></sl-splinner>
5
+ <template v-else>
6
+ <div class="form-wrap">
7
+ <sl-select
8
+ v-if="multiAdress"
9
+ multiple
10
+ clearable
11
+ ref="itemSelection"
12
+ @sl-change="onItemSelect"
13
+ @sl-clear="onItemReset"
14
+ :label="'Lieferadresse für: ' + state.selectedItem"
15
+ class="grid-w-4"
16
+ >
17
+ <sl-option
18
+ v-for="item in cartStore.state.carts[cartStore.state.basket]?.items"
19
+ :value="item.key"
20
+ >
21
+ {{ item.shop_name }}</sl-option
22
+ >
23
+ </sl-select>
24
+ <sl-input
25
+ name="street"
26
+ @sl-change="onInput"
27
+ placeholder="Straße"
28
+ class="grid-w-3"
29
+ :disabled="!state.isItemSelected"
30
+ >
31
+ <label slot="label">Strasse *</label>
32
+ </sl-input>
33
+ <sl-input
34
+ name="street"
35
+ @sl-change="onInput"
36
+ placeholder="Hausnummer"
37
+ type="number"
38
+ :disabled="!state.isItemSelected"
39
+ >
40
+ <label slot="label">Hausnummer *</label>
41
+ </sl-input>
42
+ <sl-input
43
+ name="street"
44
+ @sl-change="onInput"
45
+ placeholder="Postleitzahl"
46
+ type="number"
47
+ class="grid-w-2"
48
+ :disabled="!state.isItemSelected"
49
+ >
50
+ <label slot="label">Postleitzahl *</label>
51
+ </sl-input>
52
+ <sl-input
53
+ name="city"
54
+ @sl-change="onInput"
55
+ placeholder="Stadt"
56
+ class="grid-w-2"
57
+ :disabled="!state.isItemSelected"
58
+ >
59
+ <label slot="label">Stadt*</label>
60
+ </sl-input>
61
+ <sl-input
62
+ name="province"
63
+ @sl-change="onInput"
64
+ placeholder="Bundesland"
65
+ class="grid-w-2"
66
+ :disabled="!state.isItemSelected"
67
+ >
68
+ <label slot="label">Bundesland</label>
69
+ </sl-input>
70
+ </div>
71
+ </template>
72
+ </template>
73
+
74
+ <script setup>
75
+ import { onBeforeMount, reactive, ref } from "vue";
76
+ import { useCartStore } from "../../../../stores/cart";
77
+
78
+ const props = defineProps({
79
+ multiAdress: { type: Boolean, default: false },
80
+ items: { type: Array },
81
+ });
82
+
83
+ const emit = defineEmits(["adressInput", "itemSelection"]);
84
+
85
+ const state = reactive({
86
+ selectedItem: null,
87
+ isItemSelected: false,
88
+ items: {},
89
+ });
90
+
91
+ const itemSelection = ref(null);
92
+ const cartStore = useCartStore();
93
+
94
+ function onInput(e) {
95
+ let key = `${[state.selectedItem]}.${[e.target.name]}`;
96
+ emit("adressInput", {
97
+ [`${[state.selectedItem]}.${[e.target.name]}`]: e.target.value,
98
+ });
99
+ }
100
+
101
+ function onItemSelect(e) {
102
+ console.log(e.target.value);
103
+ if (!e.target.value.length) {
104
+ onItemReset();
105
+ return;
106
+ }
107
+ state.selectedItem = e.target.value;
108
+ state.isItemSelected = true;
109
+ }
110
+
111
+ function onItemReset() {
112
+ console.log("clearing...");
113
+ state.selectedItem = null;
114
+ state.isItemSelected = false;
115
+ }
116
+
117
+ onBeforeMount(() => {
118
+ console.log(props.items);
119
+ });
120
+ </script>
121
+
122
+ <style scoped>
123
+ .form-wrap {
124
+ display: grid;
125
+ grid-template-columns: repeat(4, minmax(0, 1fr));
126
+ gap: 0 var(--sl-spacing-medium);
127
+ margin: var(--sl-spacing-large) 0 var(--sl-spacing-x-large) 0;
128
+ padding-bottom: var(--sl-spacing-medium);
129
+ border-bottom: 1px solid var(--sl-color-neutral-400);
130
+ }
131
+
132
+ .grid-w-2 {
133
+ grid-column: span 2;
134
+ }
135
+
136
+ .grid-w-3 {
137
+ grid-column: span 3;
138
+ }
139
+
140
+ .grid-w-4 {
141
+ grid-column: span 4;
142
+ }
143
+ </style>
@@ -0,0 +1,168 @@
1
+ <template>
2
+ <sl-card class="viur-shop-item-card-card">
3
+ <img
4
+ slot="image"
5
+ :src="getImage(item)"
6
+ :alt="item.shop_name"
7
+ loading="lazy"
8
+ class="viur-shop-item-card-image"
9
+ />
10
+ <h3 class="viur-shop-item-card-headline">{{ item.shop_name }}</h3>
11
+ <h4 class="viur-shop-item-card-subline">B 21 x H 6,5 x T 19 cm</h4>
12
+ <div class="viur-shop-item-card-price">{{ item.shop_price_retail }} €</div>
13
+ <div class="viur-shop-item-card-footer" slot="footer">
14
+ <!-- <sl-button-group label="Amount">
15
+ <sl-tooltip content="Remove">
16
+ <sl-icon-button
17
+ variant="primary"
18
+ name="cart-dash"
19
+ label="Remove Amount"
20
+ style="font-size: 2em"
21
+ >
22
+ </sl-icon-button>
23
+ </sl-tooltip>
24
+ <sl-tooltip content="Plus">
25
+ <sl-icon-button
26
+ variant="primary"
27
+ name="cart-plus"
28
+ label="Add Amount"
29
+ style="font-size: 2em"
30
+ >
31
+ </sl-icon-button>
32
+ </sl-tooltip>
33
+ <sl-tooltip content="Add to cart">
34
+ <sl-icon-button
35
+ variant="primary"
36
+ name="cart-check"
37
+ label="Add to cart"
38
+ style="font-size: 2em"
39
+ @click="
40
+ cartStore.addToCart(item.key, cartStore.state.currentCart)
41
+ "
42
+ >
43
+ </sl-icon-button>
44
+ </sl-tooltip>
45
+ </sl-button-group> -->
46
+ <sl-button
47
+ size="small"
48
+ class="viur-shop-item-card-add-to-cart-btn"
49
+ variant="primary"
50
+ title="Add to cart"
51
+ @click.stop="cartStore.addToCart(item.key, cartStore.state.basket)"
52
+ >
53
+ <sl-icon name="bag-plus" slot="prefix"></sl-icon>
54
+
55
+ In den Warenkorb
56
+ </sl-button>
57
+
58
+ <sl-button
59
+ size="small"
60
+ outline
61
+ class="viur-shop-item-card-add-to-favourites-btn"
62
+ variant="primary"
63
+ title="Add to favourites"
64
+ >
65
+ <sl-icon name="heart" slot="prefix"></sl-icon>
66
+ </sl-button>
67
+ </div>
68
+ </sl-card>
69
+ </template>
70
+
71
+ <script setup>
72
+ import { Request } from "@viur/vue-utils";
73
+ import { useCartStore } from "../../../stores/cart";
74
+
75
+ const props = defineProps({
76
+ item: {
77
+ type: Object,
78
+ required: true,
79
+ },
80
+ });
81
+
82
+ const cartStore = useCartStore();
83
+
84
+ function getImage(item) {
85
+ let imageUrl =
86
+ "https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80";
87
+ if (item.dk_artikel.dest.image) {
88
+ return Request.downloadUrlFor(item.dk_artikel.dest.image);
89
+ }
90
+
91
+ return imageUrl;
92
+ }
93
+ </script>
94
+
95
+ <style scoped>
96
+ .viur-shop-item-card-card {
97
+ width: 100%;
98
+
99
+ &::part(header) {
100
+ padding: var(--sl-spacing-medium) 0;
101
+ }
102
+
103
+ &::part(body) {
104
+ padding: var(--sl-spacing-medium) 0;
105
+ }
106
+
107
+ &::part(footer) {
108
+ padding: var(--sl-spacing-medium) 0;
109
+ }
110
+
111
+ &:hover {
112
+ .viur-shop-item-card-add-to-cart-btn {
113
+ opacity: 1;
114
+ }
115
+
116
+ .viur-shop-item-card-headline {
117
+ color: var(--sl-color-primary-500);
118
+ }
119
+
120
+ .viur-shop-item-card-image {
121
+ transform: scale(1.02);
122
+ }
123
+ }
124
+ }
125
+
126
+ .viur-shop-item-card-footer {
127
+ display: flex;
128
+ flex-direction: row;
129
+ align-items: center;
130
+ width: 100%;
131
+ }
132
+
133
+ .viur-shop-item-card-add-to-cart-btn {
134
+ transition: all ease 0.3s;
135
+ margin-right: var(--sl-spacing-medium);
136
+ opacity: 0;
137
+ }
138
+
139
+ .viur-shop-item-card-add-to-favourites-btn {
140
+ margin-left: auto;
141
+ }
142
+
143
+ .viur-shop-item-card-image {
144
+ aspect-ratio: 1;
145
+ object-fit: cover;
146
+ transition: all ease 0.3s;
147
+ }
148
+
149
+ .viur-shop-item-card-headline {
150
+ font-size: 1.1em;
151
+ font-weight: bold;
152
+ color: var(--ignt-basic-color-text);
153
+ margin-bottom: var(--sl-spacing-2x-small);
154
+ transition: all ease 0.3s;
155
+ }
156
+
157
+ .viur-shop-item-card-subline {
158
+ color: var(--ignt-basic-color-text);
159
+ margin-bottom: var(--sl-spacing-2x-small);
160
+ }
161
+
162
+ .viur-shop-item-card-price {
163
+ font-size: 1.1em;
164
+ font-weight: bold;
165
+ color: var(--ignt-basic-color-text);
166
+ margin-left: auto;
167
+ }
168
+ </style>