@viur/shop-components 0.0.1-dev.2

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,83 @@
1
+ <template>
2
+ <RouterLink :to="{ name: 'CategoryView', params: { identifier: 'dk' } }"
3
+ v-for="item in list"
4
+ :key="item"
5
+ class="item-link"
6
+ >
7
+ <sl-card class="item">
8
+ <img
9
+ slot="image"
10
+ src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
11
+ alt="A kitten."
12
+ class="item-img"
13
+ />
14
+ <h2 class="item-headline"> {{ item }}</h2>
15
+ <div class="fake-link">Alle anzeigen &raquo;</div>
16
+
17
+ </sl-card>
18
+ </RouterLink>
19
+ </template>
20
+
21
+ <script setup>
22
+ import { onBeforeMount } from "vue";
23
+ import ItemCard from "../item/ItemCard.vue";
24
+ import { useCartStore } from "../../../stores/cart";
25
+
26
+ const cartStore = useCartStore();
27
+ const props = defineProps({
28
+ list: { type: Array, required: true },
29
+ });
30
+
31
+ onBeforeMount(async () => {
32
+ // cartStore.init();
33
+ });
34
+ </script>
35
+
36
+ <style scoped>
37
+
38
+ .item-link{
39
+ display: flex;
40
+ flex-direction: column;
41
+ width: 100%;
42
+
43
+ &:hover{
44
+ .fake-link{
45
+ text-decoration: underline;
46
+ }
47
+
48
+ .item-img{
49
+ transform: scale(1.02);
50
+ }
51
+ }
52
+ }
53
+
54
+ .item{
55
+ width: 100%;
56
+
57
+ &::part(header){
58
+ padding: var(--sl-spacing-medium) 0;
59
+ }
60
+
61
+ &::part(body){
62
+ padding: var(--sl-spacing-medium) 0;
63
+ }
64
+
65
+ &::part(footer){
66
+ padding: var(--sl-spacing-medium) 0;
67
+ }
68
+ }
69
+
70
+ .item-headline{
71
+ font-size: 1.4em;
72
+ margin-bottom: var(--sl-spacing-medium);
73
+ color: var(--ignt-basic-color-text);
74
+ }
75
+
76
+ .item-img{
77
+ aspect-ratio: 1;
78
+ object-fit: cover;
79
+ transition: all ease .3s;
80
+ }
81
+
82
+
83
+ </style>
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div class="item-list">
3
+ <router-link
4
+ v-for="item in state.skellist"
5
+ :key="item.shop_name"
6
+ :to="{ name: 'itemView', params: { item: item.key } }"
7
+ >
8
+ <ItemCard :item="item"> </ItemCard>
9
+ </router-link>
10
+ </div>
11
+
12
+ <sl-button
13
+ @click="loadMore"
14
+ :loading="state.loading"
15
+ :disabled="state.isLastItem"
16
+ >
17
+ Mehr anzeigen
18
+ </sl-button>
19
+ </template>
20
+
21
+ <script setup>
22
+ import { onMounted, reactive, computed } from "vue";
23
+ import { useCartStore } from "../../../stores/cart";
24
+ import { useRoute } from "vue-router";
25
+ import { Request, ListRequest } from "@viur/vue-utils";
26
+ // import { ViURShopClient } from "@viur/viur-shop-client";
27
+
28
+ // component imports
29
+ import ItemCard from "../item/ItemCard.vue";
30
+
31
+ const route = useRoute();
32
+
33
+ const cartStore = useCartStore();
34
+
35
+ const state = reactive({
36
+ skellist: [],
37
+ loading: true,
38
+ currentCursor: "",
39
+ isLastItem: false,
40
+ itemCount: 99,
41
+ itemType: computed(() => route.params.identifier),
42
+ });
43
+
44
+ const categoryList = ListRequest("categorystore", {
45
+ module: "variante",
46
+ params: { type: state.itemType, limit: state.itemCount },
47
+ });
48
+
49
+ function listItems() {
50
+ let params = {
51
+ limit: state.itemCount,
52
+ cursor: state.currentCursor,
53
+ type: state.itemType,
54
+ };
55
+
56
+ state.loading = true;
57
+
58
+ Request.get("/json/variante/list", { dataObj: params }).then(async (resp) => {
59
+ let data = await resp.json();
60
+
61
+ if (data.cursor !== state.currentCursor && !state.isLastItem) {
62
+ state.currentCursor = data.cursor;
63
+ state.skellist.push(...data.skellist);
64
+ state.loading = false;
65
+ } else if (data.cursor === state.currentCursor) {
66
+ state.isLastItem = true;
67
+ state.loading = false;
68
+ }
69
+
70
+ console.log("hier", data);
71
+ });
72
+ }
73
+
74
+ async function loadMore() {
75
+ state.loading = true;
76
+ await categoryList.next();
77
+
78
+ if (state.skellist.length < categoryList.state.skellist.length) {
79
+ state.skellist = categoryList.state.skellist;
80
+ state.loading = false;
81
+ } else {
82
+ state.loading = false;
83
+ state.isLastItem = true;
84
+ }
85
+ }
86
+
87
+ onMounted(async () => {
88
+ await categoryList.fetch(true);
89
+ state.skellist = categoryList.state.skellist;
90
+ state.loading = false;
91
+
92
+ // await cartStore.init();
93
+ });
94
+ </script>
95
+
96
+ <style scoped>
97
+ .item-list {
98
+ display: grid;
99
+ width: 100%;
100
+ grid-gap: var(--sl-spacing-medium);
101
+ grid-template-columns: repeat(4, 1fr);
102
+ }
103
+ </style>
@@ -0,0 +1,182 @@
1
+ <template>
2
+ <sl-card class="card">
3
+ <img
4
+ slot="image"
5
+ :src="getImage(item)"
6
+ :alt="item.shop_name"
7
+ class="card-image"
8
+ />
9
+ <h3 class="card-headline"> {{ item.shop_name }}</h3>
10
+ <h4 class="card-subline">B 21 x H 6,5 x T 19 cm</h4>
11
+ <div class="price">
12
+ {{ item.shop_price_retail }} €
13
+ </div>
14
+ <div class="card-footer" slot="footer">
15
+ <!-- <sl-button-group label="Amount">
16
+ <sl-tooltip content="Remove">
17
+ <sl-icon-button
18
+ variant="primary"
19
+ name="cart-dash"
20
+ label="Remove Amount"
21
+ style="font-size: 2em"
22
+ >
23
+ </sl-icon-button>
24
+ </sl-tooltip>
25
+ <sl-tooltip content="Plus">
26
+ <sl-icon-button
27
+ variant="primary"
28
+ name="cart-plus"
29
+ label="Add Amount"
30
+ style="font-size: 2em"
31
+ >
32
+ </sl-icon-button>
33
+ </sl-tooltip>
34
+ <sl-tooltip content="Add to cart">
35
+ <sl-icon-button
36
+ variant="primary"
37
+ name="cart-check"
38
+ label="Add to cart"
39
+ style="font-size: 2em"
40
+ @click="
41
+ cartStore.addToCart(item.key, cartStore.state.currentCart)
42
+ "
43
+ >
44
+ </sl-icon-button>
45
+ </sl-tooltip>
46
+ </sl-button-group> -->
47
+ <sl-button
48
+ size="small"
49
+ class="add-to-cart-btn"
50
+ variant="primary"
51
+ title="Add to cart"
52
+ @click.stop="cartStore.addToCart(item.key, cartStore.state.currentCart)"
53
+ >
54
+ <sl-icon name="bag-plus"
55
+ slot="prefix"
56
+ ></sl-icon>
57
+
58
+ In den Warenkorb
59
+ </sl-button>
60
+
61
+ <sl-button
62
+ size="small"
63
+ outline
64
+ class="add-to-favourites-btn"
65
+ variant="primary"
66
+ title="Add to favourites"
67
+ >
68
+ <sl-icon name="heart"
69
+ slot="prefix"
70
+ ></sl-icon>
71
+ </sl-button>
72
+
73
+
74
+ </div>
75
+ </sl-card>
76
+ </template>
77
+
78
+ <script>
79
+ import {Request} from "@viur/vue-utils";
80
+
81
+ export default {
82
+ props: {
83
+ item: {
84
+ type: Object,
85
+ required: true
86
+ }
87
+ },
88
+ setup(props, context) {
89
+
90
+ function getImage(item) {
91
+ let imageUrl =
92
+ "https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80";
93
+ if (item.dk_artikel.dest.image) {
94
+ return Request.downloadUrlFor(item.dk_artikel.dest.image);
95
+ }
96
+
97
+ return imageUrl;
98
+ }
99
+
100
+ return {
101
+ props,
102
+ getImage
103
+ }
104
+ }
105
+ }
106
+ </script>
107
+
108
+ <style scoped>
109
+ .card {
110
+ width: 100%;
111
+
112
+ &::part(header){
113
+ padding: var(--sl-spacing-medium) 0;
114
+ }
115
+
116
+ &::part(body){
117
+ padding: var(--sl-spacing-medium) 0;
118
+ }
119
+
120
+ &::part(footer){
121
+ padding: var(--sl-spacing-medium) 0;
122
+ }
123
+
124
+ &:hover{
125
+ .add-to-cart-btn{
126
+ opacity: 1;
127
+ }
128
+
129
+ .card-headline{
130
+ color: var(--sl-color-primary-500)
131
+ }
132
+
133
+ .card-image{
134
+ transform: scale(1.02);
135
+ }
136
+ }
137
+ }
138
+
139
+ .card-footer{
140
+ display: flex;
141
+ flex-direction: row;
142
+ align-items: center;
143
+ width: 100%;
144
+ }
145
+
146
+ .add-to-cart-btn{
147
+ transition: all ease .3s;
148
+ margin-right: var(--sl-spacing-medium);
149
+ opacity: 0;
150
+ }
151
+
152
+ .add-to-favourites-btn{
153
+ margin-left: auto;
154
+ }
155
+
156
+
157
+ .card-image {
158
+ aspect-ratio: 1;
159
+ object-fit: cover;
160
+ transition: all ease .3s;
161
+ }
162
+
163
+ .card-headline{
164
+ font-size: 1.1em;
165
+ font-weight: bold;
166
+ color: var(--ignt-basic-color-text);
167
+ margin-bottom: var(--sl-spacing-2x-small);
168
+ transition: all ease .3s;
169
+ }
170
+
171
+ .card-subline{
172
+ color: var(--ignt-basic-color-text);
173
+ margin-bottom: var(--sl-spacing-2x-small);
174
+ }
175
+
176
+ .price{
177
+ font-size: 1.1em;
178
+ font-weight: bold;
179
+ color: var(--ignt-basic-color-text);
180
+ margin-left: auto;
181
+ }
182
+ </style>
@@ -0,0 +1,233 @@
1
+ <template>
2
+ <div class="wrap">
3
+ <div class="image-wrap">
4
+ <sl-carousel class="carousel-thumbnails" navigation loop>
5
+ <sl-carousel-item>
6
+ <img
7
+ :alt="state.item.shop_name"
8
+ :src="getImage(state.item)"
9
+ />
10
+ </sl-carousel-item>
11
+ </sl-carousel>
12
+
13
+ <div class="thumbnails">
14
+ <div class="thumbnails__scroller">
15
+ <img :alt="state.item.shop_name"
16
+ class="thumbnails__image active"
17
+ :src="getImage(state.item)" />
18
+ </div>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="info-wrap">
23
+ <h1 class="headline">{{ state.item.shop_name }}</h1>
24
+ <h2 class="subline">B 21 x H 6,5 x T 19 cm</h2>
25
+
26
+ <div class="price">
27
+ {{ state.item.shop_price_retail }} €
28
+ </div>
29
+
30
+ <div class="paragraph">
31
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
32
+ nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
33
+ sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
34
+ Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
35
+ amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
36
+ eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
37
+ At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
38
+ gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
39
+ </div>
40
+
41
+ <div class="btn-wrap">
42
+ <sl-button
43
+ size="small"
44
+ class="add-to-cart-btn"
45
+ variant="primary"
46
+ title="Add to cart"
47
+ @click.stop="cartStore.addToCart(item.key, cartStore.state.currentCart)"
48
+ >
49
+ <sl-icon name="bag-plus"
50
+ slot="prefix"
51
+ ></sl-icon>
52
+
53
+ In den Warenkorb
54
+ </sl-button>
55
+
56
+ <sl-button
57
+ size="small"
58
+ outline
59
+ class="add-to-favourites-btn"
60
+ variant="primary"
61
+ title="Add to favourites"
62
+ >
63
+ <sl-icon name="heart"
64
+ slot="prefix"
65
+ ></sl-icon>
66
+ Auf die Wunschliste
67
+ </sl-button>
68
+ </div>
69
+ </div>
70
+
71
+ </div>
72
+ <br>
73
+ <h1 class="headline">Ähnliche Artikel</h1>
74
+ <div class="item-grid">
75
+ <ItemCard :item="state.item">
76
+ </ItemCard>
77
+
78
+ </div>
79
+
80
+ </template>
81
+
82
+ <script setup>
83
+ import { computed, onBeforeMount, reactive } from "vue";
84
+ import { Request } from "@viur/vue-utils";
85
+ import { useRoute } from "vue-router";
86
+ // component imports
87
+ import ItemCard from "../item/ItemCard.vue";
88
+ import '@viur/shoelace/dist/components/carousel/carousel.js';
89
+
90
+ const route = useRoute();
91
+
92
+ const state = reactive({
93
+ item: {},
94
+ });
95
+
96
+ function getImage(item) {
97
+ console.log("hier", item.dk_artikel);
98
+ let imageUrl =
99
+ "https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80";
100
+ if (item?.dk_artikel.dest.image) {
101
+ return Request.downloadUrlFor(item.dk_artikel.dest.image);
102
+ }
103
+
104
+ return imageUrl;
105
+ }
106
+
107
+ onBeforeMount(async () => {
108
+ Request.get(`/json/variante/view/${route.params.item}`).then(async (resp) => {
109
+ let data = await resp.json();
110
+
111
+ state.item = data.values;
112
+ });
113
+ });
114
+ </script>
115
+
116
+ <style scoped>
117
+ .wrap{
118
+ display: grid;
119
+ grid-template-columns: 45% minmax(0 ,1fr);
120
+ }
121
+
122
+ .info-wrap{
123
+ padding: var(--sl-spacing-x-large);
124
+ }
125
+
126
+ .image-wrap{
127
+ display: flex;
128
+ flex-direction: column;
129
+ }
130
+
131
+ sl-carousel{
132
+ aspect-ratio: 1;
133
+ background-color: var(--sl-color-neutral-200);
134
+
135
+ &::part(base){
136
+ display: flex;
137
+ gap: 0;
138
+ }
139
+
140
+ &::part(scroll-container){
141
+ border-radius: 0;
142
+ }
143
+
144
+ &::part(navigation-button){
145
+ position: absolute;
146
+ background-color: color-mix(in hsl, var(--sl-color-neutral-0) 85%, transparent);
147
+ color: var(--app-primary-color);
148
+ border-radius: 0;
149
+ transition: all ease.3s;
150
+ opacity: 0;
151
+ }
152
+
153
+ &::part(navigation-button--previous){
154
+ left: 0;
155
+ }
156
+
157
+ &::part(navigation-button--next){
158
+ right: 0;
159
+ }
160
+
161
+ &:hover{
162
+ &::part(navigation-button){
163
+ opacity: 1;
164
+ }
165
+ }
166
+ }
167
+ .thumbnails {
168
+ display: flex;
169
+ justify-content: start;
170
+ margin-top: vaR(--sl-spacing-medium)
171
+ }
172
+
173
+ .thumbnails__scroller {
174
+ display: flex;
175
+ gap: var(--sl-spacing-small);
176
+ overflow-x: auto;
177
+ scrollbar-width: none;
178
+ scroll-behavior: smooth;
179
+ scroll-padding: var(--sl-spacing-small);
180
+ }
181
+
182
+ .thumbnails__scroller::-webkit-scrollbar {
183
+ display: none;
184
+ }
185
+
186
+ .thumbnails__image {
187
+ width: 64px;
188
+ height: 64px;
189
+ object-fit: cover;
190
+
191
+ opacity: 0.3;
192
+ will-change: opacity;
193
+ transition: 250ms opacity;
194
+
195
+ cursor: pointer;
196
+ }
197
+
198
+ .thumbnails__image.active {
199
+ opacity: 1;
200
+ }
201
+
202
+ .headline{
203
+ margin-bottom: var(--sl-spacing-small);
204
+ }
205
+
206
+ .subline{
207
+ margin-bottom: var(--sl-spacing-small);
208
+ }
209
+
210
+ .price{
211
+ font-size: 1.4em;
212
+ margin-bottom: var(--sl-spacing-small);
213
+ }
214
+
215
+ .paragraph{
216
+ margin-bottom: var(--sl-spacing-x-large);
217
+ }
218
+
219
+ .btn-wrap{
220
+ display: flex;
221
+ flex-direction: column;
222
+
223
+ sl-button{
224
+ margin-bottom: var(--sl-spacing-x-small);
225
+ }
226
+ }
227
+
228
+ .item-grid{
229
+ display: grid;
230
+ grid-template-columns: repeat(4, minmax(0, 1fr));
231
+ grid-gap: var(--sl-spacing-medium);
232
+ }
233
+ </style>
package/src/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + Vue</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.js"></script>
12
+ </body>
13
+ </html>
package/src/index.js ADDED
@@ -0,0 +1,4 @@
1
+ //import CategoryList from "./components/order/category/CategoryList.vue";
2
+ import createRouterInstance from "./router";
3
+
4
+ export { createRouterInstance };
package/src/main.js ADDED
@@ -0,0 +1,9 @@
1
+ import { createPinia } from "pinia";
2
+ import { createApp } from "vue";
3
+ import App from "./App.vue";
4
+
5
+ const pinia = createPinia();
6
+ const app = createApp(App)
7
+ app.use(pinia)
8
+
9
+ app.mount("#app");