@mixd-id/web-scaffold 0.1.240411024 → 0.1.240411025
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/package.json
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="$style.el">
|
|
3
3
|
|
|
4
|
-
<div v-if="
|
|
4
|
+
<div v-if="order === 'loading'" class="flex justify-center items-center min-h-[80vh]">
|
|
5
5
|
Loading...
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
|
-
<div v-else-if="
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
<div v-else-if="order instanceof Error"
|
|
9
|
+
class="flex flex-col gap-4 justify-center items-center min-h-[80vh] p-8">
|
|
10
|
+
<slot name="error" :error="order">
|
|
11
|
+
<component v-if="items"
|
|
12
|
+
v-for="component in items"
|
|
13
|
+
:is="component"
|
|
14
|
+
:key="component"
|
|
15
|
+
:="component" />
|
|
16
|
+
<div v-else class="flex flex-col gap-3 items-center justify-center">
|
|
17
|
+
<h1>Error</h1>
|
|
18
|
+
<p class="max-w-[480px]">{{ order.message }}</p>
|
|
19
|
+
</div>
|
|
20
|
+
</slot>
|
|
14
21
|
</div>
|
|
15
22
|
|
|
16
23
|
<div v-else class="flex flex-col md:flex-row md:gap-8 min-h-[100vh]">
|
|
17
24
|
|
|
18
25
|
<div class="flex-1 flex flex-col gap-5">
|
|
26
|
+
|
|
27
|
+
<div class="p-5">
|
|
28
|
+
<h3>Checkout</h3>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
19
31
|
<div v-if="order.customerId">
|
|
20
32
|
<div class="px-5">
|
|
21
33
|
<small class="text-text-400">Customer</small>
|
|
@@ -28,10 +40,10 @@
|
|
|
28
40
|
</div>
|
|
29
41
|
|
|
30
42
|
<div v-else>
|
|
31
|
-
<div class="px-5">
|
|
32
|
-
<small class="text-text-400">Customer</small>
|
|
43
|
+
<div class="px-5 flex flex-row gap-2">
|
|
44
|
+
<small class="flex-1 text-text-400">Customer</small>
|
|
33
45
|
</div>
|
|
34
|
-
<div class="bg-base-300 flex flex-col gap-3 p-5 py-3">
|
|
46
|
+
<div class="mt-1 bg-base-300 flex flex-col gap-3 p-5 py-3">
|
|
35
47
|
<div>
|
|
36
48
|
<small>Name</small>
|
|
37
49
|
<Textbox v-model="order.customerName" />
|
|
@@ -47,17 +59,36 @@
|
|
|
47
59
|
</div>
|
|
48
60
|
</div>
|
|
49
61
|
|
|
62
|
+
<div>
|
|
63
|
+
<div class="px-5">
|
|
64
|
+
<small class="text-text-400">Products</small>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div class="mt-1 p-5 bg-base-300 flex flex-col gap-3">
|
|
68
|
+
<div v-for="item in order.items" class="flex flex-row gap-3">
|
|
69
|
+
<Image :src="item.imageSrc" class="w-[60px] aspect-square rounded-lg bg-base-50" />
|
|
70
|
+
<div class="flex-1 flex flex-col gap1">
|
|
71
|
+
<small>{{ item.code }}</small>
|
|
72
|
+
<strong>{{ item.name }}</strong>
|
|
73
|
+
<label>{{ item.qty }}x {{ item.price.toLocaleString() }}</label>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
50
79
|
<div>
|
|
51
80
|
<div class="px-5 flex flex-row gap-2">
|
|
52
|
-
<small class="text-text-400 flex-1">Delivery</small>
|
|
81
|
+
<small class="text-text-400 flex-1">Delivery Address</small>
|
|
53
82
|
<button type="button" class="text-primary text-sm"
|
|
54
|
-
@click="$
|
|
83
|
+
@click="$router.push({ query:$route.query, hash:'#select-delivery' })">
|
|
55
84
|
Choose Address
|
|
56
85
|
</button>
|
|
57
86
|
</div>
|
|
58
|
-
<div class="bg-base-300 flex flex-col p-5 py-3">
|
|
87
|
+
<div class="bg-base-300 flex flex-col gap-5 p-5 py-3 mt-1">
|
|
59
88
|
|
|
60
|
-
<div
|
|
89
|
+
<div class="flex flex-col gap-1">
|
|
90
|
+
<small>{{ order.deliveryType }}</small>
|
|
91
|
+
<strong>{{ order.deliveryContactName }}</strong>
|
|
61
92
|
<p>{{ order.deliveryAddress }}</p>
|
|
62
93
|
<p>
|
|
63
94
|
{{ order.deliveryProvinceName }}
|
|
@@ -73,6 +104,30 @@
|
|
|
73
104
|
</p>
|
|
74
105
|
</div>
|
|
75
106
|
|
|
107
|
+
<div class="h-[1px] bg-text-50"></div>
|
|
108
|
+
|
|
109
|
+
<div class="grid grid-cols-2 gap-3">
|
|
110
|
+
<div>
|
|
111
|
+
<small>Courier</small>
|
|
112
|
+
<Dropdown v-model.number="order.deliveryCourierId">
|
|
113
|
+
<option disabled selected>Select Courier</option>
|
|
114
|
+
<option v-for="courier in couriers" :value="courier.id">
|
|
115
|
+
{{ courier.name }}
|
|
116
|
+
</option>
|
|
117
|
+
</Dropdown>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<div>
|
|
121
|
+
<small>Package</small>
|
|
122
|
+
<Dropdown v-model.number="order.deliveryPackageId">
|
|
123
|
+
<option disabled selected>Select Package</option>
|
|
124
|
+
<option v-for="obj in courierPackages" :value="obj.id">
|
|
125
|
+
{{ obj.name }}
|
|
126
|
+
</option>
|
|
127
|
+
</Dropdown>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
76
131
|
</div>
|
|
77
132
|
</div>
|
|
78
133
|
|
|
@@ -80,18 +135,42 @@
|
|
|
80
135
|
<div class="px-5 flex flex-row gap-2">
|
|
81
136
|
<small class="text-text-400">Payment</small>
|
|
82
137
|
</div>
|
|
83
|
-
<div class="bg-base-300 p-5 py-3 grid grid-cols-2 gap-3">
|
|
138
|
+
<div class="bg-base-300 p-5 py-3 grid md:grid-cols-2 gap-3">
|
|
84
139
|
|
|
85
140
|
<Radio v-for="paymentType of paymentTypes"
|
|
86
141
|
:class="`${$style.paymentType}${paymentType.id === order.paymentTypeId ? ' ' + $style.paymentTypeSelected : ''}`"
|
|
87
142
|
v-model.number="order.paymentTypeId"
|
|
88
|
-
:value="paymentType.id"
|
|
89
|
-
:custom="true">
|
|
143
|
+
:value="paymentType.id">
|
|
90
144
|
{{ paymentType.name }}
|
|
91
145
|
</Radio>
|
|
92
146
|
|
|
93
147
|
</div>
|
|
94
148
|
</div>
|
|
149
|
+
|
|
150
|
+
<div>
|
|
151
|
+
<div class="px-5 flex flex-row gap-2">
|
|
152
|
+
<small class="text-text-400">Summary</small>
|
|
153
|
+
</div>
|
|
154
|
+
<div class="bg-base-300 mt-1 p-5 flex flex-col gap-3">
|
|
155
|
+
|
|
156
|
+
<div class="flex flex-row gap-2">
|
|
157
|
+
<label class="flex-1">Total Products</label>
|
|
158
|
+
<strong>{{ (order.subTotal ?? 0).toLocaleString() }}</strong>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div class="flex flex-row gap-2">
|
|
162
|
+
<label class="flex-1">Discount</label>
|
|
163
|
+
<strong>{{ (order.discountAmount ?? 0).toLocaleString() }}</strong>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="flex flex-row gap-2">
|
|
167
|
+
<label class="flex-1">Delivery Charge</label>
|
|
168
|
+
<strong>{{ (order.deliveryCharge ?? 0).toLocaleString() }}</strong>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
95
174
|
</div>
|
|
96
175
|
|
|
97
176
|
<div class="flex md:hidden p-5 py-3 bg-base-300 flex-row sticky bottom-0 border-t-[1px] border-text-50">
|
|
@@ -101,7 +180,7 @@
|
|
|
101
180
|
</div>
|
|
102
181
|
<div v-else class="flex-1"></div>
|
|
103
182
|
<Button ref="paymentBtn"
|
|
104
|
-
class="px-
|
|
183
|
+
class="px-8 font-bold"
|
|
105
184
|
:state="canPayment ? 1 : -1"
|
|
106
185
|
@click="payment">
|
|
107
186
|
Payment
|
|
@@ -121,37 +200,25 @@
|
|
|
121
200
|
|
|
122
201
|
</div>
|
|
123
202
|
|
|
124
|
-
<Modal
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<div class="absolute top-0 right-0 p-2">
|
|
129
|
-
<button type="button" class="p-2" @click="$refs.deliveryAddress.close()">
|
|
130
|
-
<svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
|
|
131
|
-
<path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
|
|
132
|
-
</svg>
|
|
133
|
-
</button>
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
136
|
-
</template>
|
|
137
|
-
|
|
203
|
+
<Modal hash="#select-delivery"
|
|
204
|
+
width="400"
|
|
205
|
+
height="640"
|
|
206
|
+
:dismissable="true">
|
|
138
207
|
<template #default="{ context }">
|
|
139
|
-
<div class="flex-1
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
208
|
+
<div class="flex-1 flex flex-col">
|
|
209
|
+
<div class="absolute top-0 right-0">
|
|
210
|
+
<button type="button"
|
|
211
|
+
class="p-5"
|
|
212
|
+
@click="$router.replace({ query:$route.query, hash:'' })">
|
|
213
|
+
<svg width="19" height="19" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
|
|
214
|
+
</button>
|
|
143
215
|
</div>
|
|
144
216
|
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
</template>
|
|
151
|
-
|
|
152
|
-
<template v-slot:foot>
|
|
153
|
-
<div class="p-5">
|
|
154
|
-
|
|
217
|
+
<CheckoutDelivery class="flex-1"
|
|
218
|
+
:api-url="apiUrl"
|
|
219
|
+
ref="checkoutDelivery"
|
|
220
|
+
:items="deliveryAddresses"
|
|
221
|
+
@apply="setDelivery" />
|
|
155
222
|
</div>
|
|
156
223
|
</template>
|
|
157
224
|
</Modal>
|
|
@@ -162,28 +229,45 @@
|
|
|
162
229
|
<script>
|
|
163
230
|
|
|
164
231
|
import axios from "axios";
|
|
232
|
+
import CheckoutDelivery from "./CheckoutDelivery.vue";
|
|
165
233
|
|
|
166
234
|
export default {
|
|
167
235
|
|
|
236
|
+
components: {CheckoutDelivery},
|
|
237
|
+
|
|
238
|
+
inject: [ 'toast' ],
|
|
239
|
+
|
|
168
240
|
computed: {
|
|
169
241
|
|
|
170
242
|
canPayment(){
|
|
171
243
|
return this.apiUrl &&
|
|
172
244
|
this.order
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
courierPackages(){
|
|
248
|
+
const courier = (this.couriers ?? [])
|
|
249
|
+
.find(_ => _.id === this.order.deliveryCourierId)
|
|
250
|
+
|
|
251
|
+
return courier?.packages
|
|
173
252
|
}
|
|
174
253
|
|
|
175
254
|
},
|
|
176
255
|
|
|
177
256
|
props: {
|
|
178
257
|
|
|
179
|
-
apiUrl:
|
|
258
|
+
apiUrl: {
|
|
259
|
+
type: String,
|
|
260
|
+
required: true
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
items: Array
|
|
180
264
|
|
|
181
265
|
},
|
|
182
266
|
|
|
183
267
|
methods: {
|
|
184
268
|
|
|
185
269
|
load(uid){
|
|
186
|
-
this.
|
|
270
|
+
this.order = 'loading'
|
|
187
271
|
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
188
272
|
params: {
|
|
189
273
|
uid
|
|
@@ -193,16 +277,39 @@ export default {
|
|
|
193
277
|
this.order = res.data.order
|
|
194
278
|
this.deliveryAddresses = res.data.deliveryAddresses
|
|
195
279
|
this.paymentTypes = res.data.paymentTypes
|
|
196
|
-
this.readyState = 1
|
|
197
|
-
})
|
|
198
|
-
.catch(err => {
|
|
199
|
-
this.readyState = -1
|
|
200
|
-
this.error = err
|
|
201
280
|
})
|
|
281
|
+
.catch(err => this.order = err)
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
loadCouriers(){
|
|
285
|
+
if(!this.apiUrl)
|
|
286
|
+
return console.warn('Unable to load couriers, apiUrl not set')
|
|
287
|
+
|
|
288
|
+
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
289
|
+
params: {
|
|
290
|
+
_action: 'load-couriers'
|
|
291
|
+
}
|
|
292
|
+
})
|
|
293
|
+
.then(res => this.couriers = res.data)
|
|
294
|
+
.catch(err => this.toast(err))
|
|
202
295
|
},
|
|
203
296
|
|
|
204
297
|
payment(){
|
|
205
298
|
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
update(){
|
|
302
|
+
axios.post(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
303
|
+
_action: 'update',
|
|
304
|
+
order: this.order
|
|
305
|
+
})
|
|
306
|
+
.then(res => Object.assign(this.order, res.data))
|
|
307
|
+
.catch(err => this.toast(err))
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
setDelivery(address){
|
|
311
|
+
Object.assign(this.order, address)
|
|
312
|
+
this.$router.replace({ query:this.$route.query, hash:'' })
|
|
206
313
|
}
|
|
207
314
|
|
|
208
315
|
},
|
|
@@ -212,14 +319,14 @@ export default {
|
|
|
212
319
|
order: null,
|
|
213
320
|
paymentTypes: null,
|
|
214
321
|
deliveryAddresses: null,
|
|
215
|
-
|
|
216
|
-
|
|
322
|
+
|
|
323
|
+
couriers: null
|
|
217
324
|
}
|
|
218
325
|
},
|
|
219
326
|
|
|
220
327
|
mounted() {
|
|
221
328
|
if(this.$editMode.value > 0){
|
|
222
|
-
this.
|
|
329
|
+
this.order = {}
|
|
223
330
|
}
|
|
224
331
|
},
|
|
225
332
|
|
|
@@ -232,6 +339,15 @@ export default {
|
|
|
232
339
|
this.load(uid)
|
|
233
340
|
}
|
|
234
341
|
}
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
'order.deliveryAddress': {
|
|
345
|
+
immediate: true,
|
|
346
|
+
handler(deliveryAddress){
|
|
347
|
+
if(deliveryAddress){
|
|
348
|
+
this.loadCouriers()
|
|
349
|
+
}
|
|
350
|
+
}
|
|
235
351
|
}
|
|
236
352
|
|
|
237
353
|
}
|
|
@@ -247,7 +363,7 @@ export default {
|
|
|
247
363
|
}
|
|
248
364
|
|
|
249
365
|
.paymentType{
|
|
250
|
-
@apply
|
|
366
|
+
@apply rounded-lg;
|
|
251
367
|
@apply p-2 text-sm;
|
|
252
368
|
}
|
|
253
369
|
.paymentTypeSelected{
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex-1 flex flex-col">
|
|
3
|
+
|
|
4
|
+
<div class="p-5">
|
|
5
|
+
<h3>Select Delivery</h3>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<div v-if="!newItem" class="flex flex-col divide-y divide-text-50">
|
|
9
|
+
<div v-for="item in items"
|
|
10
|
+
class="p-5 py-3 flex flex-col cursor-pointer"
|
|
11
|
+
@click="apply(item)">
|
|
12
|
+
<small>{{ item.deliveryType }}</small>
|
|
13
|
+
<strong>{{ item.deliveryContactName }}</strong>
|
|
14
|
+
<p>{{ item.deliveryAddress }}</p>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<button type="button" class="p-6 text-primary" @click="addNew">
|
|
18
|
+
New Address
|
|
19
|
+
</button>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div v-else class="flex-1 flex flex-col gap-5">
|
|
23
|
+
|
|
24
|
+
<div class="flex-1 overflow-y-auto flex flex-col gap-5 p-5">
|
|
25
|
+
<div>
|
|
26
|
+
<small>Type</small>
|
|
27
|
+
<Dropdown v-model="newItem.deliveryType">
|
|
28
|
+
<option>Home</option>
|
|
29
|
+
<option>Office</option>
|
|
30
|
+
</Dropdown>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div>
|
|
34
|
+
<small>Contact Name</small>
|
|
35
|
+
<Textbox v-model="newItem.deliveryContactName" />
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div>
|
|
39
|
+
<small>Address</small>
|
|
40
|
+
<Textarea v-model="newItem.deliveryAddress" rows="3" />
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div>
|
|
44
|
+
<small>Province</small>
|
|
45
|
+
<Dropdown v-model="newItem.deliveryProvinceName">
|
|
46
|
+
<option disabled selected>Choose Province</option>
|
|
47
|
+
<option v-for="province in provinces" :value="province.name">
|
|
48
|
+
{{ province.name }}
|
|
49
|
+
</option>
|
|
50
|
+
</Dropdown>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div>
|
|
54
|
+
<small>City</small>
|
|
55
|
+
<Dropdown v-model="newItem.deliveryCityName">
|
|
56
|
+
<option disabled selected>Choose City</option>
|
|
57
|
+
<option v-for="city in cities" :value="city.name">
|
|
58
|
+
{{ city.name }}
|
|
59
|
+
</option>
|
|
60
|
+
</Dropdown>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div>
|
|
64
|
+
<small>District</small>
|
|
65
|
+
<Dropdown v-model="newItem.deliveryDistrictName">
|
|
66
|
+
<option disabled selected>Choose District</option>
|
|
67
|
+
<option v-for="district in districts" :value="district.name">
|
|
68
|
+
{{ district.name }}
|
|
69
|
+
</option>
|
|
70
|
+
</Dropdown>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div>
|
|
74
|
+
<small>Sub District</small>
|
|
75
|
+
<Dropdown v-model="newItem.deliverySubDistrictName"
|
|
76
|
+
@change="setPostalCode(newItem.deliverySubDistrictName)">
|
|
77
|
+
<option disabled selected>Choose Sub District</option>
|
|
78
|
+
<option v-for="subDistrict in subDistricts" :value="subDistrict.name">
|
|
79
|
+
{{ subDistrict.name }}
|
|
80
|
+
</option>
|
|
81
|
+
</Dropdown>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div>
|
|
85
|
+
<small>Postal Code</small>
|
|
86
|
+
<Textbox v-model="newItem.deliveryPostalCode" />
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div class="p-5">
|
|
91
|
+
<Button class="w-full"
|
|
92
|
+
:state="canSave ? 1 : -1"
|
|
93
|
+
@click="apply(newItem)">Set Address</Button>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
100
|
+
|
|
101
|
+
<script>
|
|
102
|
+
|
|
103
|
+
import axios from "axios";
|
|
104
|
+
|
|
105
|
+
export default{
|
|
106
|
+
|
|
107
|
+
emits: [ 'apply' ],
|
|
108
|
+
|
|
109
|
+
computed: {
|
|
110
|
+
|
|
111
|
+
canSave(){
|
|
112
|
+
return this.newItem &&
|
|
113
|
+
this.newItem.deliveryType &&
|
|
114
|
+
this.newItem.deliveryContactName &&
|
|
115
|
+
this.newItem.deliveryAddress &&
|
|
116
|
+
this.newItem.deliveryProvinceName &&
|
|
117
|
+
this.newItem.deliveryCityName &&
|
|
118
|
+
this.newItem.deliveryDistrictName &&
|
|
119
|
+
this.newItem.deliverySubDistrictName &&
|
|
120
|
+
this.newItem.deliveryPostalCode
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
props: {
|
|
126
|
+
|
|
127
|
+
apiUrl: {
|
|
128
|
+
type: String,
|
|
129
|
+
required: true
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
items: Array
|
|
133
|
+
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
data(){
|
|
137
|
+
return {
|
|
138
|
+
newItem: null,
|
|
139
|
+
|
|
140
|
+
provinces: null,
|
|
141
|
+
cities: null,
|
|
142
|
+
districts: null,
|
|
143
|
+
subDistricts: null
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
methods: {
|
|
148
|
+
|
|
149
|
+
addNew(){
|
|
150
|
+
this.newItem = {}
|
|
151
|
+
this.loadProvinces()
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
apply(item){
|
|
155
|
+
this.$emit('apply', JSON.parse(JSON.stringify(item)))
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
loadProvinces(){
|
|
159
|
+
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
160
|
+
params: {
|
|
161
|
+
_action: 'load-provinces'
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
.then(res => {
|
|
165
|
+
this.provinces = res.data
|
|
166
|
+
})
|
|
167
|
+
.catch(err => {
|
|
168
|
+
console.error(err)
|
|
169
|
+
})
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
loadCities(){
|
|
173
|
+
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
174
|
+
params: {
|
|
175
|
+
_action: 'load-cities',
|
|
176
|
+
province: this.newItem.deliveryProvinceName
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
.then(res => {
|
|
180
|
+
this.cities = res.data
|
|
181
|
+
})
|
|
182
|
+
.catch(err => {
|
|
183
|
+
console.error(err)
|
|
184
|
+
})
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
loadDistricts(){
|
|
188
|
+
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
189
|
+
params: {
|
|
190
|
+
_action: 'load-districts',
|
|
191
|
+
province: this.newItem.deliveryProvinceName,
|
|
192
|
+
city: this.newItem.deliveryCityName
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
.then(res => {
|
|
196
|
+
this.districts = res.data
|
|
197
|
+
})
|
|
198
|
+
.catch(err => {
|
|
199
|
+
console.error(err)
|
|
200
|
+
})
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
loadSubDistricts(){
|
|
204
|
+
axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
|
|
205
|
+
params: {
|
|
206
|
+
_action: 'load-sub-districts',
|
|
207
|
+
province: this.newItem.deliveryProvinceName,
|
|
208
|
+
city: this.newItem.deliveryCityName,
|
|
209
|
+
district: this.newItem.deliveryDistrictName
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
.then(res => {
|
|
213
|
+
this.subDistricts = res.data
|
|
214
|
+
})
|
|
215
|
+
.catch(err => {
|
|
216
|
+
console.error(err)
|
|
217
|
+
})
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
setPostalCode(subDistrictName){
|
|
221
|
+
const subDistrict = (this.subDistricts ?? []).find(item => item.name === subDistrictName)
|
|
222
|
+
this.newItem.deliveryPostalCode = subDistrict?.postalCode ?? ''
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
watch: {
|
|
228
|
+
|
|
229
|
+
'newItem.deliveryProvinceName': {
|
|
230
|
+
immediate: true,
|
|
231
|
+
handler(to){
|
|
232
|
+
if(to)
|
|
233
|
+
this.loadCities()
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
'newItem.deliveryCityName': {
|
|
238
|
+
immediate: true,
|
|
239
|
+
handler(to){
|
|
240
|
+
if(to)
|
|
241
|
+
this.loadDistricts()
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
'newItem.deliveryDistrictName': {
|
|
246
|
+
immediate: true,
|
|
247
|
+
handler(to){
|
|
248
|
+
if(to)
|
|
249
|
+
this.loadSubDistricts()
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
</script>
|
|
260
|
+
|
|
261
|
+
<style module>
|
|
262
|
+
|
|
263
|
+
.comp{
|
|
264
|
+
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
</style>
|
package/src/components/Modal.vue
CHANGED
|
@@ -404,6 +404,7 @@ html[data-theme='dark'] .overlay{
|
|
|
404
404
|
@media screen and (max-width: 640px){
|
|
405
405
|
|
|
406
406
|
.modal {
|
|
407
|
+
width: 100% !important;
|
|
407
408
|
max-height: 90vh;
|
|
408
409
|
}
|
|
409
410
|
|
|
@@ -429,11 +430,5 @@ html[data-theme='dark'] .overlay{
|
|
|
429
430
|
|
|
430
431
|
}
|
|
431
432
|
|
|
432
|
-
@media screen and (min-width: 640px) {
|
|
433
|
-
|
|
434
|
-
.modal {
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
}
|
|
438
433
|
|
|
439
434
|
</style>
|