@subiz/widget-v4 4.0.59 → 4.0.64

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 (152) hide show
  1. package/assets/img/caret.svg +1 -0
  2. package/assets/img/done_green.svg +4 -0
  3. package/assets/img/empty_1.svg +11 -0
  4. package/assets/img/ghn.svg +17 -0
  5. package/assets/img/ghtk.svg +18 -0
  6. package/assets/img/home.svg +1 -0
  7. package/assets/img/info.svg +1 -0
  8. package/assets/img/loader.svg +1 -0
  9. package/assets/img/map-pin.svg +1 -0
  10. package/assets/img/not_found_search.png +0 -0
  11. package/assets/img/package.svg +5 -0
  12. package/assets/img/package_fade.svg +1 -0
  13. package/assets/img/phone.svg +1 -0
  14. package/assets/img/search.svg +1 -0
  15. package/assets/img/shop.svg +1 -0
  16. package/assets/img/shop_faded.svg +1 -0
  17. package/assets/img/user.svg +1 -0
  18. package/assets/img/x.svg +5 -0
  19. package/assets/less/chatbox.less +35 -0
  20. package/assets/less/dropdown_select.less +130 -0
  21. package/assets/less/form.less +7 -20
  22. package/assets/less/order.less +489 -0
  23. package/assets/less/rating.less +3 -8
  24. package/babel.config.js +2 -4
  25. package/compiled_src/bot.js +7 -1
  26. package/compiled_src/chatbox/DropdownSelect.js +248 -0
  27. package/compiled_src/chatbox/Event.js +4 -2
  28. package/compiled_src/chatbox/Events.js +1 -0
  29. package/compiled_src/chatbox/Order.js +285 -0
  30. package/compiled_src/chatbox/OrderAttachments.js +2 -1
  31. package/compiled_src/chatbox/TextMessage.js +9 -2
  32. package/compiled_src/chatbox/Widget.js +44 -3
  33. package/compiled_src/chatbox/main.js +2 -1
  34. package/compiled_src/chatbox/spinner.js +1 -1
  35. package/compiled_src/chatbox/time.js +3 -1
  36. package/compiled_src/common.js +40 -1
  37. package/compiled_src/contact/contact.js +1 -3
  38. package/compiled_src/order/address_picker.js +249 -0
  39. package/compiled_src/order/icon.js +62 -0
  40. package/compiled_src/order/index.js +113 -0
  41. package/compiled_src/order/order.js +1234 -0
  42. package/compiled_src/plugin.js +9 -42
  43. package/compiled_src/popup/popup.js +2 -2
  44. package/compiled_src/store/api.js +20 -0
  45. package/compiled_src/store/store.js +42 -0
  46. package/compiled_src/util/common.js +36 -2
  47. package/dist/0b82fa7e5c3b07b40a44.png +1 -0
  48. package/dist/0f4af006e38ee8b93633.png +1 -0
  49. package/dist/{74.js → 132.js} +2322 -279
  50. package/dist/178.js +341 -174
  51. package/dist/17ee31b89ac.132.js +1 -0
  52. package/dist/17ee31b89ac.178.js +1 -0
  53. package/dist/17ee31b89ac.213.js +1 -0
  54. package/dist/17ee31b89ac.335.js +1 -0
  55. package/dist/17ee31b89ac.362.js +1 -0
  56. package/dist/17ee31b89ac.441.js +1 -0
  57. package/dist/17ee31b89ac.605.js +1 -0
  58. package/dist/17ee31b89ac.678.js +1 -0
  59. package/dist/17ee31b89ac.782.js +1 -0
  60. package/dist/17ee31b89ac.app.js +1 -0
  61. package/dist/{17d939953e0.index.html → 17ee31b89ac.index.html} +3 -18
  62. package/dist/{17d939953e0.library.html → 17ee31b89ac.library.html} +3 -18
  63. package/dist/17ee31b89ac.library.js +1 -0
  64. package/dist/{17d939953e0.preview.html → 17ee31b89ac.preview.html} +1 -1
  65. package/dist/17ee31b89ac.preview.js +1 -0
  66. package/dist/17ee31b89ac.screenshoot.js +1 -0
  67. package/dist/1ea1c6cd21d25176810c.png +1 -0
  68. package/dist/213.js +35 -70
  69. package/dist/292d42404e1b03398f61.png +1 -0
  70. package/dist/312d376370831b7bea83.png +1 -0
  71. package/dist/313d1bfc1cf776d1aefe.png +1 -0
  72. package/dist/335.js +411 -0
  73. package/dist/362.js +71 -21
  74. package/dist/441.js +70 -44
  75. package/dist/4aa58bb7a66bb44975aa.png +1 -0
  76. package/dist/56ce063bc6c81adb7322.png +1 -0
  77. package/dist/605.js +1 -64
  78. package/dist/678.js +70 -20
  79. package/dist/6a411166ef5cc79e0714.png +1 -0
  80. package/dist/6faf403782fefacc1649.png +1 -0
  81. package/dist/782.js +118 -21
  82. package/dist/79dca33c68fab79c067f.png +1 -0
  83. package/dist/82da1578fa84f9debaeb.png +1 -0
  84. package/dist/8b8e0f0824743974b282.png +1 -0
  85. package/dist/8d551390d81e39130a3c.png +1 -0
  86. package/dist/9fc61b9479877ebdb6c7.png +1 -0
  87. package/dist/HASH +1 -1
  88. package/dist/a165d31dcb3dc90f1057.png +1 -0
  89. package/dist/a98d4a5698812c4426b3.png +1 -0
  90. package/dist/assets/img/caret.998eb8f.svg +1 -0
  91. package/dist/assets/img/done_green.b817fd4.svg +4 -0
  92. package/dist/assets/img/empty_1.0b98af0.svg +11 -0
  93. package/dist/assets/img/ghn.070f8e3.svg +17 -0
  94. package/dist/assets/img/ghtk.326eac1.svg +18 -0
  95. package/dist/assets/img/info.ebce7ea.svg +1 -0
  96. package/dist/assets/img/loader.37000a7.svg +1 -0
  97. package/dist/assets/img/not_found_search.2ddb8d1.png +0 -0
  98. package/dist/assets/img/package.8d37d0f.svg +5 -0
  99. package/dist/assets/img/package_fade.763c001.svg +1 -0
  100. package/dist/assets/img/search.f9705ff.svg +1 -0
  101. package/dist/assets/img/shop.f7dc7d8.svg +1 -0
  102. package/dist/assets/img/shop_faded.df7845a.svg +1 -0
  103. package/dist/assets/img/x.26fdfa3.svg +5 -0
  104. package/dist/c41606bf9d1b604e46d5.png +1 -0
  105. package/dist/ce1f7450ce6c1aacd330.png +1 -0
  106. package/dist/cf8c01e88f4770a6e3e5.png +1 -0
  107. package/dist/dfbcfeab1d5622a737e2.png +1 -0
  108. package/dist/e4893ed8c2f7b8329919.png +1 -0
  109. package/dist/ec2ab4eb4ef73d186186.png +1 -0
  110. package/dist/screenshoot.html +1 -1
  111. package/dist/screenshoot.js +211 -48
  112. package/index.html +3 -18
  113. package/order.html +32 -0
  114. package/package.json +14 -15
  115. package/src/bot.js +2 -1
  116. package/src/chatbox/DropdownSelect.js +229 -0
  117. package/src/chatbox/Event.js +2 -2
  118. package/src/chatbox/Events.js +43 -42
  119. package/src/chatbox/Order.js +232 -0
  120. package/src/chatbox/OrderAttachments.js +2 -1
  121. package/src/chatbox/TextMessage.js +21 -12
  122. package/src/chatbox/Widget.js +34 -4
  123. package/src/chatbox/main.js +2 -2
  124. package/src/chatbox/spinner.js +1 -1
  125. package/src/chatbox/time.js +1 -1
  126. package/src/common.js +52 -8
  127. package/src/contact/contact.js +1 -1
  128. package/src/order/address_picker.js +235 -0
  129. package/src/order/icon.js +32 -0
  130. package/src/order/index.js +86 -0
  131. package/src/order/order.js +1157 -0
  132. package/src/order/scratch +211 -0
  133. package/src/plugin.js +7 -52
  134. package/src/popup/popup.js +2 -2
  135. package/src/store/api.js +26 -1
  136. package/src/store/store.js +46 -9
  137. package/src/util/common.js +48 -2
  138. package/webpack.dev.js +2 -0
  139. package/dist/17d939953e0.178.js +0 -1
  140. package/dist/17d939953e0.213.js +0 -1
  141. package/dist/17d939953e0.362.js +0 -1
  142. package/dist/17d939953e0.441.js +0 -1
  143. package/dist/17d939953e0.605.js +0 -1
  144. package/dist/17d939953e0.619.js +0 -1
  145. package/dist/17d939953e0.678.js +0 -1
  146. package/dist/17d939953e0.74.js +0 -1
  147. package/dist/17d939953e0.782.js +0 -1
  148. package/dist/17d939953e0.app.js +0 -1
  149. package/dist/17d939953e0.library.js +0 -1
  150. package/dist/17d939953e0.preview.js +0 -1
  151. package/dist/17d939953e0.screenshoot.js +0 -1
  152. package/dist/619.js +0 -777
@@ -0,0 +1,211 @@
1
+ renderShipping(order) {
2
+ let editmode = false
3
+ if (!order.status || order.status == 'new') {
4
+ editmode = !order.user_confirmation
5
+ }
6
+
7
+ let user = store.matchUser()
8
+ if (editmode) {
9
+ let addresses = store.matchShippingAddresses()
10
+
11
+ let $addrs = sb.map(addresses, (addr) => {
12
+ let fulladdr = [addr.street, addr.ward, addr.district, addr.region, addr.country].filter((a) => a).join(', ')
13
+ let cls = 'order__card'
14
+ if (this.state.shipping_address === addr.id) cls += ' order__card__active'
15
+ let $phone = null
16
+ if (addr.phone) {
17
+ $phone = (
18
+ <div style='margin-bottom:5px !important; '>
19
+ <img class='order_ship_icon' src={require('../../assets/img/phone.svg')} /> {addr.phone}
20
+ </div>
21
+ )
22
+ }
23
+ return (
24
+ <div class={cls}>
25
+ <div style='width: 100% !important;'>
26
+ <div class='radio'>
27
+ <input
28
+ type='radio'
29
+ id={'shipping_addr.' + addr.id}
30
+ onInput={(e) => this.onChangeShippingAddress(addr.id)}
31
+ name='shipping_address'
32
+ checked={this.state.shipping_address === addr.id}
33
+ />
34
+ <label class='radio--label ml-2' for={'shipping_addr.' + addr.id}>
35
+ Giao hàng tới <b>{addr.fullname}</b>
36
+ </label>
37
+ <div class='radio--check'>
38
+ <div class='inside'></div>
39
+ </div>
40
+ </div>
41
+ <div class='muted mt-1' style='margin-left: 30px !important;'>
42
+ {$phone}
43
+ <div>
44
+ <img class='order_ship_icon' src={require('../../assets/img/home.svg')} /> {fulladdr}
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ )
50
+ })
51
+
52
+ let provinces = sb.map(this.state.provinces, (province) => ({id: province.id, name: province.province}))
53
+ let districts = sb.map(this.state.districts, (district) => ({id: district.id, name: district.district}))
54
+ let wards = sb.map(this.state.wards, (ward) => ({id: ward.id, name: ward.ward}))
55
+ let cls = 'order__card'
56
+ let $new = null
57
+ if (this.state.shipping_address === 'new') {
58
+ cls += ' order__card__active'
59
+ $new = (
60
+ <div style='margin-left: 0px !important;'>
61
+ <div class='d-flex'>
62
+ <div class='mr-2' style='flex: 1 !important;'>
63
+ <div class='order_form_label'>{this.props.t('fullname')}</div>
64
+ <input type='text' class='form-control' onInput={this.onChangeFullname} value={this.state.fullname} />
65
+ </div>
66
+ <div class='ml-2' style='flex: 1 !important;'>
67
+ <div class='order_form_label'>{this.props.t('phone')}</div>
68
+ <input type='text' class='form-control' onInput={this.onChangePhone} value={this.state.phone} />
69
+ </div>
70
+ </div>
71
+
72
+ <div class='' style='width: 100% !important'>
73
+ <div class='order_form_label'>{this.props.t('address')}</div>
74
+ <input type='text' class='form-control' onInput={this.onChangeAddress} value={this.state.address} />
75
+ </div>
76
+
77
+ <div>
78
+ <div class='order_form_label'>{this.props.t('province')}</div>
79
+ <DropdownSelect
80
+ width='180'
81
+ has_search
82
+ loading={this.state.loadProvince}
83
+ full
84
+ items={provinces}
85
+ selected={this.state.selectedProvince}
86
+ onSelect={this.onSelectProvince}
87
+ />
88
+ </div>
89
+ <div>
90
+ <div class='order_form_label'>{this.props.t('district')}</div>
91
+ <DropdownSelect
92
+ width='180'
93
+ full
94
+ selected={this.state.selectedDistrict}
95
+ has_search
96
+ onSelect={this.onSelectDistrict}
97
+ loading={this.state.loadDistrict}
98
+ items={districts}
99
+ />
100
+ </div>
101
+
102
+ <div class='order_form_label'>{this.props.t('ward')}</div>
103
+ <DropdownSelect
104
+ width='180'
105
+ selected={this.state.selectedWard}
106
+ full
107
+ has_search
108
+ onSelect={this.onSelectWard}
109
+ loading={this.state.loadWard}
110
+ items={wards}
111
+ />
112
+ </div>
113
+ )
114
+ }
115
+
116
+ $addrs.push(
117
+ <div class={cls}>
118
+ <div style='width: 100% !important;'>
119
+ <div class='radio'>
120
+ <input
121
+ type='radio'
122
+ name='shipping_address'
123
+ id={'shipping_addr.new'}
124
+ onInput={(e) => this.onChangeShippingAddress('new')}
125
+ checked={this.state.shipping_address === 'new'}
126
+ />
127
+ <label class='radio--label ml-2' for={'shipping_addr.new'}>
128
+ <b>Giao hàng tới địa chỉ khác</b>
129
+ </label>
130
+ <div class='radio--check'>
131
+ <div class='inside'></div>
132
+ </div>
133
+ </div>
134
+ {$new}
135
+ </div>
136
+ </div>,
137
+ )
138
+
139
+ let shopcls = 'order__card'
140
+ let $shop = null
141
+ if (this.state.shipping_address === 'shop') {
142
+ shopcls += ' order__card__active'
143
+ $shop = (
144
+ <div>
145
+ <div class='d-flex'>
146
+ <div class='mr-2' style='flex: 3 !important;'>
147
+ <div class='order_form_label'>{this.props.t('fullname')}</div>
148
+ <input type='text' class='form-control' onInput={this.onChangeFullname} value={this.state.fullname} />
149
+ </div>
150
+ <div class='ml-2' style='flex: 2 !important;'>
151
+ <div class='order_form_label'>{this.props.t('phones')}</div>
152
+ <input type='text' class='form-control' onInput={this.onChangePhone} value={this.state.phone} />
153
+ </div>
154
+ </div>
155
+ <div>
156
+ <div class='order_form_label'>{this.props.t('email')}</div>
157
+ <input type='text' class='form-control' onInput={this.onChangeEmail} value={this.state.email} />
158
+ </div>
159
+ </div>
160
+ )
161
+ }
162
+
163
+ $addrs.unshift(
164
+ <div class={shopcls}>
165
+ <div style='width: 100% !important;'>
166
+ <div class='radio'>
167
+ <input
168
+ type='radio'
169
+ name='shipping_address'
170
+ id={'shipping_addr.shop'}
171
+ onInput={(e) => this.onChangeShippingAddress('shop')}
172
+ checked={this.state.shipping_address === 'shop'}
173
+ />
174
+ <label class='radio--label ml-2' for={'shipping_addr.shop'}>
175
+ <b>Nhận hàng tại shop</b>
176
+ </label>
177
+ <div class='radio--check'>
178
+ <div class='inside'></div>
179
+ </div>
180
+ </div>
181
+ {$shop}
182
+ </div>
183
+ </div>,
184
+ )
185
+ // let $oldaddress = sb.map()
186
+
187
+ return (
188
+ <div class='order_section'>
189
+ <div class='order_label'>{this.props.t('ship_to')}</div>
190
+ <div class='form'>{$addrs}</div>
191
+ </div>
192
+ )
193
+ }
194
+
195
+ let fulladdr = sb.get(order, 'shipping.address.full_address')
196
+ if (!fulladdr) return null
197
+ let $addr = fulladdr ? <div>{fulladdr}</div> : <i class='i muted'>Chưa có địa chỉ giao hàng</i>
198
+
199
+ return (
200
+ <div class='order_section'>
201
+ <div class='order_section_label'>{this.props.t('ship_to')}</div>
202
+ {$addr}
203
+ </div>
204
+ )
205
+ }
206
+
207
+
208
+
209
+ 1. ko co dia chi co san => dien luon new
210
+ 2. co dia chi => hien thi dia chi co san va option dia chi moi
211
+ 3.
package/src/plugin.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import sb from './util/index.js'
2
+ import * as common from './common.js'
2
3
  import {h, render, createRef} from 'preact'
3
4
 
4
5
  const LoadChatbox = () => import(/*webpackChunkName: "chatbox" */ './chatbox/main.js')
@@ -6,10 +7,6 @@ const LoadContact = () => import(/*webpackChunkName: "contact" */ './contact/con
6
7
  const LoadPopup = () => import(/*webpackChunkName: "popup" */ './popup/popup.js')
7
8
  const LoadNotif = () => import(/*webpackChunkName: "notif" */ './notif/notif.js')
8
9
 
9
- // cache lang messages
10
- let langMessages = {}
11
- let downloadLock = false
12
-
13
10
  function Plugin(plugin, store, $container, lib) {
14
11
  if (!$container) throw '$div must is a valid html node'
15
12
  var $div = document.createElement('div')
@@ -17,7 +14,7 @@ function Plugin(plugin, store, $container, lib) {
17
14
  $container.appendChild($div) // use body as container
18
15
 
19
16
  // auto detect language first
20
- let _locale = getLocale(plugin, sb.detectLang())
17
+ let _locale = common.getLocale(plugin, sb.detectLang())
21
18
 
22
19
  var domGate = new sb.Gate()
23
20
  var pageIndex = 0
@@ -136,11 +133,10 @@ function Plugin(plugin, store, $container, lib) {
136
133
  }
137
134
 
138
135
  // language
139
-
140
136
  let t = (key) => {
141
137
  if (_locale === 'debug') return `{{${key}}}`
142
138
 
143
- let messages = sb.get(langMessages, _locale, [])
139
+ let messages = sb.get(common.langMessages, _locale, [])
144
140
  let message = sb.find(messages, (message) => message.key === key)
145
141
  return sb.get(message, 'message', key)
146
142
  }
@@ -157,7 +153,7 @@ function Plugin(plugin, store, $container, lib) {
157
153
  t.locale = () => _locale
158
154
 
159
155
  this.forceDownloadLanguage = async () => {
160
- await downloadLanguage(store, _locale, true)
156
+ await common.downloadLanguage(store, _locale, true)
161
157
  this.update(plugin)
162
158
  }
163
159
 
@@ -167,8 +163,8 @@ function Plugin(plugin, store, $container, lib) {
167
163
  this.t = null
168
164
  _render() // hide plugin first
169
165
 
170
- _locale = getLocale(plugin, locale)
171
- await downloadLanguage(store, _locale)
166
+ _locale = common.getLocale(plugin, locale)
167
+ await common.downloadLanguage(store, _locale)
172
168
  this.t = t
173
169
  _render()
174
170
  return _locale
@@ -203,7 +199,7 @@ function Plugin(plugin, store, $container, lib) {
203
199
 
204
200
  this.update(plugin)
205
201
  // auto detect language firlst
206
- downloadLanguage(store, _locale).then(() => {
202
+ common.downloadLanguage(store, _locale).then(() => {
207
203
  this.t = t
208
204
  this.update(plugin)
209
205
  })
@@ -348,44 +344,3 @@ export default class PluginMgr {
348
344
  this._destroy = true
349
345
  }
350
346
  }
351
-
352
- function downloadLanguage(store, locale, force) {
353
- if (downloadLock)
354
- return new Promise((resolve) => setTimeout(() => downloadLanguage(store, locale, force).then(resolve), 100))
355
-
356
- downloadLock = true
357
- // let locale = getLocale()
358
- let messages
359
- if (locale === 'debug' || (langMessages[locale] && !force)) {
360
- downloadLock = false
361
- return Promise.resolve()
362
- }
363
-
364
- return store.getLocaleContent(locale).then((res) => {
365
- downloadLock = false
366
- messages = sb.get(res, 'body.messages', [])
367
- langMessages[locale] = messages
368
- })
369
- }
370
-
371
- const getLocale = (plugin, loc) => {
372
- if (!loc) loc = ''
373
- let found = sb.find(plugin.locales, (l) => l.toLowerCase().trim() === loc.toLowerCase().trim())
374
- if (found) return found
375
-
376
- found = sb.find(plugin.locales, (l) => {
377
- l = l
378
- .replace('-', '_')
379
- .split('_')[0]
380
- .trim()
381
- .toLowerCase()
382
- let compareloc = loc
383
- .replace('-', '_')
384
- .split('_')[0]
385
- .trim()
386
- .toLowerCase()
387
- return l == compareloc
388
- })
389
- if (found) return found
390
- return plugin.locale || 'en-US'
391
- }
@@ -83,7 +83,7 @@ export default class Popup extends Com {
83
83
  isFormFilled() {
84
84
  let page = sb.get(this.props.plugin.popup, `pages.${this.getPageIndex()}`)
85
85
  let form = sb.find(page.components, (com) => com.type === 'form')
86
- if (!form || !form.form) return
86
+ if (!form || !form.form) return true
87
87
 
88
88
  // fill form
89
89
  let fields = sb.get(form, 'form.fields', [])
@@ -209,7 +209,7 @@ export default class Popup extends Com {
209
209
  }
210
210
 
211
211
  if (hasConversion) {
212
- var formData = new FormData(this._formRef.current)
212
+ var formData = this._formRef.current ? new FormData(this._formRef.current) : new FormData()
213
213
  var summitFields = []
214
214
 
215
215
  let user = sb.cloneDeep(this.props.store.matchUser())
package/src/store/api.js CHANGED
@@ -47,7 +47,10 @@ export default class {
47
47
  .get('/conversations')
48
48
 
49
49
  listMessages = (cid, limit, start_id) =>
50
- this.apireq.addQuery('limit', limit).addQuery('start_id', start_id).get(`/conversations/${cid}/messages`)
50
+ this.apireq
51
+ .addQuery('limit', limit)
52
+ .addQuery('start_id', start_id)
53
+ .get(`/conversations/${cid}/messages`)
51
54
 
52
55
  ajax = ajax
53
56
 
@@ -156,4 +159,26 @@ export default class {
156
159
  this.apireq.post(`/accounts/${this.accid}/campaigns/${impression.campaign_id}/impressions`, impression)
157
160
  sendConversion = (conversion) =>
158
161
  this.apireq.post(`/accounts/${this.accid}/campaigns/${conversion.campaign_id}/conversions`, conversion)
162
+
163
+ lookupOrder = (key) =>
164
+ ajax
165
+ .setBaseUrl(this.ApiURL)
166
+ .setContentType('text/plain')
167
+ .beforeHook(jsonifyTextPlain)
168
+ .setParser('json')
169
+ .addQuery('x-signed-key', key)
170
+ .get(`/orders/123`)
171
+
172
+ getOrder = (id) => this.apireq.get(`/accounts/${this.accid}/orders/` + id)
173
+ updateOrder = (order) => this.apireq.post(`/accounts/${this.accid}/orders/` + order.id, order)
174
+
175
+ fetchShippingAddresses = () => this.apireq.get(`/accounts/${this.accid}/users/${this.uid}/shipping-addresses`)
176
+ createShippingAddress = (addr) =>
177
+ this.apireq.post(`/accounts/${this.accid}/users/${this.uid}/shipping-addresses`, addr)
178
+
179
+ list_provinces = () => this.apireq.get(`/accounts/${this.accid}/provinces`)
180
+ list_districts = (p) => this.apireq.setQuery(p).get(`/accounts/${this.accid}/districts`)
181
+ list_wards = (p) => this.apireq.setQuery(p).get(`/accounts/${this.accid}/wards`)
182
+
183
+ suggest_address = (keyword) => this.apireq.setQuery({keyword: keyword}).get(`/accounts/${this.accid}/addresses`)
159
184
  }
@@ -80,6 +80,23 @@ export default class Store {
80
80
  return sb.Date.now() - (this.g_sync[key] || 0) < 300000
81
81
  }
82
82
 
83
+ async fetchShippingAddresses() {
84
+ let out = await this.api.fetchShippingAddresses()
85
+ if (out.error) return null
86
+ this.cache.put('shipping_address', out.body.shipping_addresses)
87
+ }
88
+
89
+ matchShippingAddresses() {
90
+ return this.cache.match('shipping_address')
91
+ }
92
+
93
+ updateOrder(order) {
94
+ return this.api.updateOrder(order)
95
+ }
96
+ createShippingAddress(addr) {
97
+ return this.api.createShippingAddress(addr)
98
+ }
99
+
83
100
  async overrideAcc(acc) {
84
101
  this.forceAcc = sb.cloneDeep(acc)
85
102
  await this.readyGate.entry()
@@ -149,7 +166,7 @@ export default class Store {
149
166
  overridePlugin(plugins) {
150
167
  if (!Array.isArray(plugins)) throw 'plugins must be be an array'
151
168
  let pluginM = {}
152
- sb.map(plugins, function (plugin) {
169
+ sb.map(plugins, function(plugin) {
153
170
  pluginM[plugin.id] = plugin
154
171
  })
155
172
  this.forcePlugins = pluginM
@@ -176,8 +193,11 @@ export default class Store {
176
193
  return this.kv.match('user')
177
194
  }
178
195
 
196
+ suggest_addresses = (keyword) => this.api.suggest_address(keyword)
197
+
179
198
  matchSession = () => this.kv.match('session') || {}
180
199
  matchAccount = () => this.cache.match('account')
200
+ matchPaymentMethods = () => this.cache.match('payment_methods')
181
201
 
182
202
  matchUnread = () => {
183
203
  let user = this.matchUser()
@@ -231,6 +251,11 @@ export default class Store {
231
251
  return this.reconnectGate.open()
232
252
  }
233
253
 
254
+ list_provinces = () => this.api.list_provinces()
255
+ list_districts = (p) => this.api.list_districts(p)
256
+ list_wards = (p) => this.api.list_wards(p)
257
+
258
+ list_provices
234
259
  listEvents = (id) => {
235
260
  if (!id || id === '*' || typeof id !== 'string') return
236
261
  if (!this.isInsync('events' + id)) {
@@ -439,6 +464,7 @@ export default class Store {
439
464
  }
440
465
 
441
466
  _setUser(user) {
467
+ user = sb.cloneDeep(user)
442
468
  let olduser = this.kv.match('user') || {}
443
469
  var accid = olduser.account_id || user.account_id
444
470
  var id = olduser.id || user.id
@@ -536,6 +562,10 @@ export default class Store {
536
562
  this.cache.put('agent', agentM)
537
563
  }
538
564
 
565
+ // payment methods
566
+ let pms = sb.get(setting, 'payment_methods', [])
567
+ this.cache.put('payment_methods', pms)
568
+
539
569
  this.pubsub.publish('account')
540
570
  }
541
571
 
@@ -725,6 +755,14 @@ export default class Store {
725
755
  return {convo}
726
756
  }
727
757
 
758
+ fetchOrder(id) {
759
+ return this.api.getOrder(id)
760
+ }
761
+
762
+ lookupOrder(key) {
763
+ return this.api.lookupOrder(key)
764
+ }
765
+
728
766
  createPostback(cid, postback) {
729
767
  return this.api.createPostback(cid, postback)
730
768
  }
@@ -1046,7 +1084,7 @@ function getGaClientId() {
1046
1084
  if (!hasGA()) return clientId
1047
1085
 
1048
1086
  var allTrackers = window.ga.getAll() || []
1049
- allTrackers.forEach(function (tracker) {
1087
+ allTrackers.forEach(function(tracker) {
1050
1088
  clientId = tracker.get('clientId')
1051
1089
  })
1052
1090
 
@@ -1063,7 +1101,7 @@ function getGaTrackingIds() {
1063
1101
  if (!hasGA()) return trackingIds
1064
1102
 
1065
1103
  const allTrackers = window.ga.getAll() || []
1066
- allTrackers.forEach(function (tracker) {
1104
+ allTrackers.forEach(function(tracker) {
1067
1105
  var trackingId = tracker.get('trackingId')
1068
1106
  if (trackingId) trackingIds.push(trackingId)
1069
1107
  })
@@ -1081,7 +1119,7 @@ function sendToGA(category, action, label) {
1081
1119
  if (!hasGA()) return
1082
1120
 
1083
1121
  const allTrackers = window.ga.getAll() || []
1084
- allTrackers.forEach(function (tracker) {
1122
+ allTrackers.forEach(function(tracker) {
1085
1123
  const name = tracker.get('name')
1086
1124
  window.ga(name + '.send', 'event', category, action, label)
1087
1125
  })
@@ -1094,7 +1132,7 @@ function sendEventToThirdParty(category, action, label) {
1094
1132
  }
1095
1133
 
1096
1134
  // from http://detectmobilebrowsers.com/
1097
- let mobileCheck = (function (a) {
1135
+ let mobileCheck = (function(a) {
1098
1136
  return (
1099
1137
  /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
1100
1138
  a,
@@ -1105,7 +1143,6 @@ let mobileCheck = (function (a) {
1105
1143
  )
1106
1144
  })(navigator.userAgent || navigator.vendor || window.opera)
1107
1145
 
1108
- let tabletCheck =
1109
- /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(
1110
- navigator.userAgent,
1111
- )
1146
+ let tabletCheck = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(
1147
+ navigator.userAgent,
1148
+ )
@@ -924,6 +924,7 @@ export function preloadWebfonts(fonts, done) {
924
924
  node.style.color = 'transparent'
925
925
  node.style.fontSize = '20px'
926
926
  node.style.height = '0px'
927
+ node.style.top = '0px'
927
928
  node.style.width = '0px'
928
929
 
929
930
  node.style.fontWeight = weight
@@ -1074,9 +1075,9 @@ export function getUrlParameter() {
1074
1075
  export var sleep = (ms) => new Promise((res) => setTimeout(res, ms))
1075
1076
 
1076
1077
  export function formatCurrency(val) {
1077
- if (!val) return 0
1078
+ if (!val) return '0 đ'
1078
1079
  val = Math.round(val)
1079
- return val.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
1080
+ return val.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')+ ' đ'
1080
1081
  }
1081
1082
 
1082
1083
  function replaceFileUrl(src) {
@@ -1106,3 +1107,48 @@ function replaceFileUrl(src) {
1106
1107
  src = src.replace('http://file.mysubiz.com/', fileurl)
1107
1108
  return src
1108
1109
  }
1110
+
1111
+ export function unicodeToAscii(str) {
1112
+ str = str + ''
1113
+ // worka round Đ not work
1114
+ str = str.replace('đ', 'd').replace('Đ', 'D')
1115
+ return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
1116
+ }
1117
+
1118
+ export function scrollIntoViewIfNeeded($ele) {
1119
+ centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded
1120
+
1121
+ var parent = $ele.parentNode
1122
+ var parentComputedStyle = window.getComputedStyle(parent, null)
1123
+ var parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width'))
1124
+ var parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width'))
1125
+ var overTop = $ele.offsetTop - parent.offsetTop < parent.scrollTop
1126
+ var overBottom =
1127
+ $ele.offsetTop - parent.offsetTop + $ele.clientHeight - parentBorderTopWidth >
1128
+ parent.scrollTop + parent.clientHeight
1129
+ var overLeft = $ele.offsetLeft - parent.offsetLeft < parent.scrollLeft
1130
+ var overRight =
1131
+ $ele.offsetLeft - parent.offsetLeft + $ele.clientWidth - parentBorderLeftWidth >
1132
+ parent.scrollLeft + parent.clientWidth
1133
+ var alignWithTop = overTop && !overBottom
1134
+
1135
+ if ((overTop || overBottom) && centerIfNeeded) {
1136
+ parent.scrollTop =
1137
+ $ele.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + $ele.clientHeight / 2
1138
+ }
1139
+
1140
+ if ((overLeft || overRight) && centerIfNeeded) {
1141
+ parent.scrollLeft =
1142
+ $ele.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + $ele.clientWidth / 2
1143
+ }
1144
+
1145
+ if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
1146
+ $ele.scrollIntoView(alignWithTop)
1147
+ }
1148
+ }
1149
+
1150
+ // if (!Element.prototype.scrollIntoViewIfNeeded) {
1151
+ //Element.prototype.scrollIntoViewIfNeeded = function(centerIfNeeded) {
1152
+
1153
+ //}
1154
+ //}
package/webpack.dev.js CHANGED
@@ -7,6 +7,7 @@ module.exports = {
7
7
  inject: './inject.js',
8
8
  preview: './preview.js',
9
9
  library: './library.js',
10
+ order: './src/order/index.js',
10
11
  screenshoot: './screenshoot.js',
11
12
  },
12
13
  output: {publicPath: '/'},
@@ -14,6 +15,7 @@ module.exports = {
14
15
  optimization: {minimize: false},
15
16
  plugins: [
16
17
  new HtmlWebpackPlugin({filename: './index.html', template: './index.html', inject: 'body', chunks: ['app']}),
18
+ new HtmlWebpackPlugin({filename: './order.html', template: './order.html', inject: 'body', chunks: ['order']}),
17
19
  new HtmlWebpackPlugin({filename: './preview.html', template: './preview.html', chunks: ['preview']}),
18
20
  new HtmlWebpackPlugin({filename: './inject.html', template: './inject.html', inject: 'body', chunks: ['inject']}),
19
21
  new HtmlWebpackPlugin({filename: './library.html', template: './index.html', inject: 'body', chunks: ['library']}),