@mixd-id/web-scaffold 0.2.240706 → 0.2.250801010

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 (220) hide show
  1. package/docs/components/Dashboard.md +56 -0
  2. package/log.txt +7 -0
  3. package/package.json +27 -19
  4. package/src/components/404.vue +61 -0
  5. package/src/components/AccountIcon.vue +19 -0
  6. package/src/components/Ahref.vue +1 -1
  7. package/src/components/Alert.vue +4 -13
  8. package/src/components/ArrayList.vue +49 -0
  9. package/src/components/Article.vue +24 -30
  10. package/src/components/Button.vue +83 -169
  11. package/src/components/Card.vue +257 -0
  12. package/src/components/Carousel.vue +61 -60
  13. package/src/components/Cart.vue +192 -0
  14. package/src/components/CartIcon.vue +89 -0
  15. package/src/components/ChartBar.vue +2 -3
  16. package/src/components/Checkbox.vue +20 -11
  17. package/src/components/Checkout.vue +373 -0
  18. package/src/components/CheckoutDelivery.vue +267 -0
  19. package/src/components/CodeEditor.vue +5 -16
  20. package/src/components/CollapsiblePanel.vue +70 -0
  21. package/src/components/ColorPicker.vue +12 -5
  22. package/src/components/ColorPicker2.vue +41 -19
  23. package/src/components/ColorPicker3.vue +100 -0
  24. package/src/components/Confirm.vue +9 -7
  25. package/src/components/ContextMenu.vue +122 -206
  26. package/src/components/ContextMenuItem.vue +53 -0
  27. package/src/components/Dashboard.vue +243 -0
  28. package/src/components/Dashboard2.vue +118 -0
  29. package/src/components/DashboardComponentSelector.vue +96 -0
  30. package/src/components/DashboardConfigs.vue +202 -0
  31. package/src/components/Datepicker.vue +102 -41
  32. package/src/components/DayTimeRange.vue +3 -2
  33. package/src/components/Dropdown.vue +7 -4
  34. package/src/components/Flex.vue +14 -40
  35. package/src/components/GHeatMaps.vue +2 -2
  36. package/src/components/Grid.vue +6 -6
  37. package/src/components/HTMLEditor.vue +27 -14
  38. package/src/components/Image.vue +62 -108
  39. package/src/components/ImagePreview.vue +14 -4
  40. package/src/components/ImageUploader.vue +114 -0
  41. package/src/components/ImportModal.vue +3 -3
  42. package/src/components/Link.vue +62 -6
  43. package/src/components/List.vue +528 -403
  44. package/src/components/ListContextMenu.vue +88 -0
  45. package/src/components/ListItem.vue +6 -4
  46. package/src/components/ListPage1.vue +14 -15
  47. package/src/components/ListView.vue +5 -6
  48. package/src/components/ListViewSettings.vue +2 -2
  49. package/src/components/LogViewerItem.vue +1 -1
  50. package/src/components/MarkdownEdit.vue +128 -0
  51. package/src/components/MarkdownPreview.vue +102 -0
  52. package/src/components/MenuItem1.vue +36 -0
  53. package/src/components/Modal.vue +95 -43
  54. package/src/components/MultiDropdown.vue +124 -0
  55. package/src/components/MultilineText.vue +1 -4
  56. package/src/components/OTPField.vue +40 -26
  57. package/src/components/ObjectTree.vue +1 -1
  58. package/src/components/PageBuilder.vue +3 -3
  59. package/src/components/Paragraph.vue +1 -2
  60. package/src/components/PresetSelectorFilterItem.vue +107 -95
  61. package/src/components/Radio.vue +1 -1
  62. package/src/components/SearchModal.vue +153 -0
  63. package/src/components/Slider.vue +1 -1
  64. package/src/components/Svg.vue +1 -1
  65. package/src/components/SvgEditor.vue +173 -0
  66. package/src/components/Switch.vue +4 -5
  67. package/src/components/Table.vue +2 -2
  68. package/src/components/TableView.vue +2 -3
  69. package/src/components/TableViewHead.vue +2 -2
  70. package/src/components/Tabs.vue +1 -1
  71. package/src/components/Testimonial.vue +2 -2
  72. package/src/components/Text.vue +7 -22
  73. package/src/components/TextEditor.vue +3 -3
  74. package/src/components/TextWithTag.vue +61 -30
  75. package/src/components/Textarea.vue +16 -22
  76. package/src/components/Textbox.vue +9 -19
  77. package/src/components/Timepicker.vue +25 -15
  78. package/src/components/Toast.vue +5 -3
  79. package/src/components/TreeMenu.vue +122 -0
  80. package/src/components/TreeView.vue +15 -10
  81. package/src/components/TreeView2.vue +38 -0
  82. package/src/components/TreeViewItem.vue +58 -29
  83. package/src/components/TreeViewItem2.vue +55 -0
  84. package/src/components/Uploader.vue +45 -0
  85. package/src/components/Video.vue +119 -0
  86. package/src/components/VirtualGrid.vue +24 -7
  87. package/src/components/VirtualTable.vue +363 -128
  88. package/src/configs/dashboard/data-table.js +9 -0
  89. package/src/configs/web-page-builder.js +118 -0
  90. package/src/directives/intersect.js +26 -0
  91. package/src/hooks/device.js +14 -0
  92. package/src/index.js +62 -107
  93. package/src/mixin/component.js +151 -67
  94. package/src/themes/default/index.js +118 -159
  95. package/src/utils/dashboard.js +22 -962
  96. package/src/utils/helpers.cjs +635 -0
  97. package/src/utils/helpers.js +91 -60
  98. package/src/utils/helpers.mjs +245 -12
  99. package/src/utils/importer.js +22 -3
  100. package/src/utils/list.mjs +1509 -0
  101. package/src/utils/preset-selector.cjs +1455 -0
  102. package/src/utils/preset-selector.js +489 -95
  103. package/src/utils/preset-selector.mjs +59 -20
  104. package/src/utils/queue.js +63 -0
  105. package/src/utils/web.mjs +120 -0
  106. package/src/utils/wss.js +38 -36
  107. package/src/utils/wss.mjs +24 -19
  108. package/src/widgets/AhrefSetting.vue +16 -13
  109. package/src/widgets/ArticleSetting.vue +15 -27
  110. package/src/widgets/BackgroundColorSetting.vue +153 -0
  111. package/src/widgets/BorderColorSetting.vue +57 -0
  112. package/src/widgets/BotEditor/BotEditorActions.vue +3 -2
  113. package/src/widgets/BotEditor/BotEditorSettings.vue +21 -0
  114. package/src/widgets/BotEditor.vue +35 -15
  115. package/src/widgets/ButtonSetting.vue +12 -13
  116. package/src/widgets/CarouselSetting.vue +33 -45
  117. package/src/widgets/CartSetting.vue +46 -0
  118. package/src/widgets/CheckoutSetting.vue +46 -0
  119. package/src/widgets/CollapsiblePanelSetting.vue +46 -0
  120. package/src/widgets/ColumnSelector.vue +29 -5
  121. package/src/widgets/ComponentSetting.vue +1 -1
  122. package/src/widgets/ComponentSetting2.vue +145 -236
  123. package/src/widgets/ComponentSetting3.vue +1 -1
  124. package/src/widgets/ContactForm.vue +3 -3
  125. package/src/widgets/ContactFormSetting.vue +41 -30
  126. package/src/widgets/Dashboard/BarChart.vue +47 -11
  127. package/src/widgets/Dashboard/BarChartSetting.vue +1 -1
  128. package/src/widgets/Dashboard/DataTable.vue +125 -0
  129. package/src/widgets/Dashboard/DataTableSetting.vue +243 -0
  130. package/src/widgets/Dashboard/DatasourceSelector.vue +1 -1
  131. package/src/widgets/Dashboard/Doughnut.vue +49 -7
  132. package/src/widgets/Dashboard/DoughnutSetting.vue +2 -2
  133. package/src/widgets/Dashboard/Metric.vue +78 -19
  134. package/src/widgets/Dashboard/MetricSetting.vue +81 -28
  135. package/src/widgets/Dashboard/Pie.vue +55 -6
  136. package/src/widgets/Dashboard/PieSetting.vue +1 -1
  137. package/src/widgets/Dashboard/PolarArea.vue +49 -7
  138. package/src/widgets/Dashboard/PolarAreaSetting.vue +1 -1
  139. package/src/widgets/Dashboard/SharingModal.vue +4 -5
  140. package/src/widgets/Dashboard/ViewSelector.vue +2 -2
  141. package/src/widgets/Dashboard/VirtualTableSetting.vue +121 -184
  142. package/src/widgets/{Dashboard.vue → Dashboard0.vue} +426 -343
  143. package/src/widgets/EmbeddedVideoSetting.vue +7 -5
  144. package/src/widgets/FAQ.vue +16 -3
  145. package/src/widgets/FAQSetting.vue +53 -47
  146. package/src/widgets/FeatureList.vue +3 -0
  147. package/src/widgets/FeatureListSetting.vue +112 -102
  148. package/src/widgets/FlexSetting.vue +83 -106
  149. package/src/widgets/GridSetting.vue +71 -196
  150. package/src/widgets/Header2.vue +34 -71
  151. package/src/widgets/Header2Setting.vue +95 -179
  152. package/src/widgets/HeaderSetting.vue +16 -18
  153. package/src/widgets/IconListSetting.vue +69 -65
  154. package/src/widgets/ImageSetting.vue +33 -60
  155. package/src/widgets/LinkSetting.vue +60 -37
  156. package/src/widgets/LinkSettingModal.vue +173 -0
  157. package/src/widgets/LogViewer.vue +1 -1
  158. package/src/widgets/MarginSetting.vue +2 -2
  159. package/src/widgets/MenuEditor.vue +1 -1
  160. package/src/widgets/MenuItem1Setting.vue +78 -0
  161. package/src/widgets/ModalSetting.vue +42 -44
  162. package/src/widgets/MultiValueSetting.vue +2 -2
  163. package/src/widgets/MultiValueSetting2.vue +78 -45
  164. package/src/widgets/OGSettingModal.vue +103 -0
  165. package/src/widgets/PaddingSetting.vue +2 -2
  166. package/src/widgets/ParagraphSetting.vue +16 -13
  167. package/src/widgets/PositionSetting.vue +209 -0
  168. package/src/widgets/PresetBar.vue +359 -210
  169. package/src/widgets/PresetBarPivot.vue +31 -19
  170. package/src/widgets/PresetSelector.vue +29 -17
  171. package/src/widgets/SearchModalSetting.vue +70 -0
  172. package/src/widgets/Share.vue +1 -2
  173. package/src/widgets/ShareSetting.vue +67 -60
  174. package/src/widgets/StyleSetting.vue +365 -150
  175. package/src/widgets/TestimonialSetting.vue +97 -88
  176. package/src/widgets/TextBlockSetting.vue +16 -13
  177. package/src/widgets/UserActionBuilder/UserActionConsole.vue +30 -10
  178. package/src/widgets/UserActionBuilder/UserActionOutput.vue +2 -2
  179. package/src/widgets/UserActionBuilder/UserActionOutputReply.vue +64 -87
  180. package/src/widgets/UserActionBuilder/UserActionProps.vue +3 -3
  181. package/src/widgets/UserActionBuilder.vue +4 -16
  182. package/src/widgets/WebComponentSelector.vue +15 -11
  183. package/src/widgets/WebLayoutSelector.vue +41 -270
  184. package/src/widgets/WebPageBuilder.vue +1019 -707
  185. package/src/widgets/WebPageBuilder2.vue +7 -7
  186. package/src/widgets/WebPageBuilder4/ButtonSetting.vue +0 -8
  187. package/src/widgets/WebPageBuilder4/CarouselSetting.vue +63 -7
  188. package/src/widgets/WebPageBuilder4/FlexAlignSetting.vue +3 -3
  189. package/src/widgets/WebPageBuilder4/FlexSetting.vue +1 -10
  190. package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +2 -2
  191. package/src/widgets/WebPageBuilder4/PropertySetting.vue +0 -7
  192. package/src/widgets/WebPageBuilder4/WebPageComponentSelector.vue +1 -7
  193. package/src/widgets/WebPageBuilder4.vue +289 -575
  194. package/src/widgets/WebPageSelector.vue +1 -1
  195. package/src/widgets/YoutubeVideoSetting.vue +16 -13
  196. package/tailwind.config.js +3 -35
  197. package/docs/schema/user-action.json +0 -266
  198. package/src/App.vue +0 -25
  199. package/src/components/SearchButton.vue +0 -57
  200. package/src/entry-client.js +0 -27
  201. package/src/entry-server.js +0 -73
  202. package/src/events/event.js +0 -2
  203. package/src/main.js +0 -29
  204. package/src/mixin/website.js +0 -121
  205. package/src/router.js +0 -57
  206. package/src/widgets/MobileMenu.vue +0 -182
  207. package/src/widgets/WebPageBuilder4/ActionSetting.vue +0 -158
  208. package/src/widgets/WebPageBuilder4/ColorSetting.vue +0 -63
  209. package/src/widgets/WebPageBuilder4/DataSetting.vue +0 -92
  210. package/src/widgets/WebPageBuilder4/FontSizeSetting.vue +0 -76
  211. package/src/widgets/WebPageBuilder4/LinkSetting.vue +0 -68
  212. package/src/widgets/WebPageBuilder4/MobileMenuSetting.vue +0 -106
  213. package/src/widgets/WebPageBuilder4/Setting.vue +0 -73
  214. package/src/widgets/WebPageBuilder4/StyleSetting.vue +0 -77
  215. package/src/widgets/WebPageBuilder4/SvgSetting.vue +0 -207
  216. package/src/widgets/WebPageBuilder4/TextTransformSetting.vue +0 -70
  217. package/src/widgets/WebPageBuilder4/WebPageDataEdit.vue +0 -121
  218. package/test.json +0 -22
  219. /package/src/widgets/{Header1.vue → Header0.vue} +0 -0
  220. /package/src/widgets/{Header1Setting.vue → Header0Setting.vue} +0 -0
@@ -0,0 +1,373 @@
1
+ <template>
2
+ <div :class="$style.el">
3
+
4
+ <div v-if="order === 'loading'" class="flex justify-center items-center min-h-[80vh]">
5
+ Loading...
6
+ </div>
7
+
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>
21
+ </div>
22
+
23
+ <div v-else class="flex flex-col md:flex-row md:gap-8 min-h-[100vh]">
24
+
25
+ <div class="flex-1 flex flex-col gap-5">
26
+
27
+ <div class="p-5">
28
+ <h3>Checkout</h3>
29
+ </div>
30
+
31
+ <div v-if="order.customerId">
32
+ <div class="px-5">
33
+ <small class="text-text-400">Customer</small>
34
+ </div>
35
+ <div class="bg-base-300 flex flex-col p-5 py-3">
36
+ <strong>{{ order.customerName }}</strong>
37
+ <label>{{ order.mobileNumber }}</label>
38
+ <small>{{ order.email }}</small>
39
+ </div>
40
+ </div>
41
+
42
+ <div v-else>
43
+ <div class="px-5 flex flex-row gap-2">
44
+ <small class="flex-1 text-text-400">Customer</small>
45
+ </div>
46
+ <div class="mt-1 bg-base-300 flex flex-col gap-3 p-5 py-3">
47
+ <div>
48
+ <small>Name</small>
49
+ <Textbox v-model="order.customerName" />
50
+ </div>
51
+ <div>
52
+ <small>Mobile Number</small>
53
+ <Textbox v-model="order.mobileNumber" maxlength="20" />
54
+ </div>
55
+ <div>
56
+ <small>Email</small>
57
+ <Textbox v-model="order.email" maxlength="50" />
58
+ </div>
59
+ </div>
60
+ </div>
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-300" />
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
+
79
+ <div>
80
+ <div class="px-5 flex flex-row gap-2">
81
+ <small class="text-text-400 flex-1">Delivery Address</small>
82
+ <button type="button" class="text-primary text-sm"
83
+ @click="$router.push({ query:$route.query, hash:'#select-delivery' })">
84
+ Choose Address
85
+ </button>
86
+ </div>
87
+ <div class="bg-base-300 flex flex-col gap-5 p-5 py-3 mt-1">
88
+
89
+ <div class="flex flex-col gap-1">
90
+ <small>{{ order.deliveryType }}</small>
91
+ <strong>{{ order.deliveryContactName }}</strong>
92
+ <p>{{ order.deliveryAddress }}</p>
93
+ <p>
94
+ {{ order.deliveryProvinceName }}
95
+ -
96
+ {{ order.deliveryCityName}}
97
+ </p>
98
+ <p>
99
+ {{ order.deliveryDistrictName }}
100
+ -
101
+ {{ order.deliverySubdistrictName }}
102
+ -
103
+ {{ order.deliveryPostalCode }}
104
+ </p>
105
+ </div>
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
+
131
+ </div>
132
+ </div>
133
+
134
+ <div>
135
+ <div class="px-5 flex flex-row gap-2">
136
+ <small class="text-text-400">Payment</small>
137
+ </div>
138
+ <div class="bg-base-300 p-5 py-3 grid md:grid-cols-2 gap-3">
139
+
140
+ <Radio v-for="paymentType of paymentTypes"
141
+ :class="`${$style.paymentType}${paymentType.id === order.paymentTypeId ? ' ' + $style.paymentTypeSelected : ''}`"
142
+ v-model.number="order.paymentTypeId"
143
+ :value="paymentType.id">
144
+ {{ paymentType.name }}
145
+ </Radio>
146
+
147
+ </div>
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
+
174
+ </div>
175
+
176
+ <div class="flex md:hidden p-5 py-3 bg-base-300 flex-row sticky bottom-0 border-t-[1px] border-border-50">
177
+ <div v-if="order?.total > 0" class="flex flex-col flex-1 leading-3">
178
+ <small>Total</small>
179
+ <h5>Rp. {{ order.total.toLocaleString() }}</h5>
180
+ </div>
181
+ <div v-else class="flex-1"></div>
182
+ <Button ref="paymentBtn"
183
+ class="px-8 font-bold"
184
+ :state="canPayment ? 1 : -1"
185
+ @click="payment">
186
+ Payment
187
+ </Button>
188
+ </div>
189
+
190
+ <div class="hidden md:flex flex-col w-[300px]">
191
+
192
+ <div class="flex flex-row gap-2 px-3">
193
+ <small class="text-text-400 flex-1">Summary</small>
194
+ </div>
195
+ <div class="bg-base-300 min-h-[200px]">
196
+
197
+ </div>
198
+
199
+ </div>
200
+
201
+ </div>
202
+
203
+ <Modal hash="#select-delivery"
204
+ width="400"
205
+ height="640"
206
+ :dismissable="true">
207
+ <template #default="{ context }">
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>
215
+ </div>
216
+
217
+ <CheckoutDelivery class="flex-1"
218
+ :api-url="apiUrl"
219
+ ref="checkoutDelivery"
220
+ :items="deliveryAddresses"
221
+ @apply="setDelivery" />
222
+ </div>
223
+ </template>
224
+ </Modal>
225
+
226
+ </div>
227
+ </template>
228
+
229
+ <script>
230
+
231
+ import axios from "axios";
232
+ import CheckoutDelivery from "./CheckoutDelivery.vue";
233
+
234
+ export default {
235
+
236
+ components: {CheckoutDelivery},
237
+
238
+ inject: [ 'toast' ],
239
+
240
+ computed: {
241
+
242
+ canPayment(){
243
+ return this.apiUrl &&
244
+ this.order
245
+ },
246
+
247
+ courierPackages(){
248
+ const courier = (this.couriers ?? [])
249
+ .find(_ => _.id === this.order.deliveryCourierId)
250
+
251
+ return courier?.packages
252
+ }
253
+
254
+ },
255
+
256
+ props: {
257
+
258
+ apiUrl: {
259
+ type: String,
260
+ required: true
261
+ },
262
+
263
+ items: Array
264
+
265
+ },
266
+
267
+ methods: {
268
+
269
+ load(uid){
270
+ this.order = 'loading'
271
+ axios.get(import.meta.env.VITE_API_HOST + this.apiUrl, {
272
+ params: {
273
+ uid
274
+ }
275
+ })
276
+ .then(res => {
277
+ this.order = res.data.order
278
+ this.deliveryAddresses = res.data.deliveryAddresses
279
+ this.paymentTypes = res.data.paymentTypes
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))
295
+ },
296
+
297
+ payment(){
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:'' })
313
+ }
314
+
315
+ },
316
+
317
+ data(){
318
+ return {
319
+ order: null,
320
+ paymentTypes: null,
321
+ deliveryAddresses: null,
322
+
323
+ couriers: null
324
+ }
325
+ },
326
+
327
+ mounted() {
328
+ if(this.$editMode.value > 0){
329
+ this.order = {}
330
+ }
331
+ },
332
+
333
+ watch: {
334
+
335
+ '$route.query.uid': {
336
+ immediate: true,
337
+ handler(uid){
338
+ if(uid){
339
+ this.load(uid)
340
+ }
341
+ }
342
+ },
343
+
344
+ 'order.deliveryAddress': {
345
+ immediate: true,
346
+ handler(deliveryAddress){
347
+ if(deliveryAddress){
348
+ this.loadCouriers()
349
+ }
350
+ }
351
+ }
352
+
353
+ }
354
+
355
+ }
356
+
357
+ </script>
358
+
359
+ <style module>
360
+
361
+ .el{
362
+ @apply max-w-[900px] mx-auto;
363
+ }
364
+
365
+ .paymentType{
366
+ @apply rounded-lg;
367
+ @apply p-2 text-sm;
368
+ }
369
+ .paymentTypeSelected{
370
+ @apply border-primary;
371
+ }
372
+
373
+ </style>
@@ -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-border-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>
@@ -1,10 +1,9 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
- <div class="flex flex-row bg-text-50 p-2">
4
- <div class="flex-1">&nbsp;</div>
5
- </div>
6
- <code v-html="modelValue" contenteditable="true" spellcheck="false"
7
- @paste="onPaste"></code>
3
+ <code contenteditable="true" spellcheck="false"
4
+ @paste="onPaste">
5
+ {{ modelValue }}
6
+ </code>
8
7
  </div>
9
8
  </template>
10
9
 
@@ -20,19 +19,9 @@ export default{
20
19
 
21
20
  methods: {
22
21
 
23
- beautify(){
24
- const html = JSON.parse(JSON.stringify(this.modelValue, null, 2))
25
- this.$emit('update:modelValue', html)
26
- },
27
-
28
22
  onPaste(e) {
29
23
  e.preventDefault()
30
-
31
24
  let text = (e.clipboardData || window.clipboardData).getData("text");
32
- const el = document.createElement('div')
33
- el.innerHTML = text
34
- text = el.innerText
35
-
36
25
  this.$emit('update:modelValue', text)
37
26
  }
38
27
 
@@ -45,7 +34,7 @@ export default{
45
34
  <style module>
46
35
 
47
36
  .comp{
48
- @apply border-text-50 border-[1px] rounded-lg overflow-hidden flex flex-col;
37
+ @apply border-[1px] border-border-200 bg-base-300 rounded-lg flex flex-col overflow-hidden;
49
38
  }
50
39
 
51
40
  .comp code{