@social-mail/social-mail-client 1.2.643 → 1.2.645

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 (87) hide show
  1. package/dist/admin/AdminAppIndex.pack.js +274 -85
  2. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.min.js +5 -5
  4. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  5. package/dist/common/pages/stores/orders/EditOrderPage.js +1 -1
  6. package/dist/common/pages/stores/orders/EditOrderPage.js.map +1 -1
  7. package/dist/common/pages/stores/payment-gateway/PaymentGatewayEditorPage.d.ts +4 -4
  8. package/dist/common/pages/stores/payment-gateway/PaymentGatewayEditorPage.d.ts.map +1 -1
  9. package/dist/common/pages/stores/payment-gateway/PaymentGatewayEditorPage.js +7 -3
  10. package/dist/common/pages/stores/payment-gateway/PaymentGatewayEditorPage.js.map +1 -1
  11. package/dist/common/pages/stores/payment-gateway/PaymentGatewayListPage.d.ts +3 -3
  12. package/dist/common/pages/stores/payment-gateway/PaymentGatewayListPage.d.ts.map +1 -1
  13. package/dist/common/pages/stores/payment-gateway/PaymentGatewayListPage.js +6 -5
  14. package/dist/common/pages/stores/payment-gateway/PaymentGatewayListPage.js.map +1 -1
  15. package/dist/model/model.d.ts +61 -27
  16. package/dist/model/model.d.ts.map +1 -1
  17. package/dist/model/model.js +245 -75
  18. package/dist/model/model.js.map +1 -1
  19. package/dist/public/channel/ChannelView.pack.js +245 -75
  20. package/dist/public/channel/ChannelView.pack.js.map +1 -1
  21. package/dist/public/channel/ChannelView.pack.min.js +1 -1
  22. package/dist/public/channel/ChannelView.pack.min.js.map +1 -1
  23. package/dist/public/preview/zip/DownloadZip.pack.js +245 -75
  24. package/dist/public/preview/zip/DownloadZip.pack.js.map +1 -1
  25. package/dist/public/preview/zip/DownloadZip.pack.min.js +1 -1
  26. package/dist/public/preview/zip/DownloadZip.pack.min.js.map +1 -1
  27. package/dist/public/store/Store.pack.js +2231 -2142
  28. package/dist/public/store/Store.pack.js.map +1 -1
  29. package/dist/public/store/Store.pack.min.js +214 -214
  30. package/dist/public/store/Store.pack.min.js.map +1 -1
  31. package/dist/public/store/StoreApp.d.ts.map +1 -1
  32. package/dist/public/store/StoreApp.js +34 -4
  33. package/dist/public/store/StoreApp.js.map +1 -1
  34. package/dist/public/store/StoreApp.pack.js +13829 -693
  35. package/dist/public/store/StoreApp.pack.js.map +1 -1
  36. package/dist/public/store/StoreApp.pack.min.js +829 -2
  37. package/dist/public/store/StoreApp.pack.min.js.map +1 -1
  38. package/dist/public/store/StoreItemDetailView.d.ts.map +1 -1
  39. package/dist/public/store/StoreItemDetailView.js +3 -8
  40. package/dist/public/store/StoreItemDetailView.js.map +1 -1
  41. package/dist/public/store/cart/ShoppingCart.pack.js +245 -75
  42. package/dist/public/store/cart/ShoppingCart.pack.js.map +1 -1
  43. package/dist/public/store/cart/ShoppingCart.pack.min.js +1 -1
  44. package/dist/public/store/cart/ShoppingCart.pack.min.js.map +1 -1
  45. package/dist/public/store/commands/StoreCommands.d.ts +5 -1
  46. package/dist/public/store/commands/StoreCommands.d.ts.map +1 -1
  47. package/dist/public/store/commands/StoreCommands.js +12 -1
  48. package/dist/public/store/commands/StoreCommands.js.map +1 -1
  49. package/dist/public/store/pages/StoreProductDetailPage.d.ts +23 -0
  50. package/dist/public/store/pages/StoreProductDetailPage.d.ts.map +1 -0
  51. package/dist/public/store/pages/StoreProductDetailPage.js +355 -0
  52. package/dist/public/store/pages/StoreProductDetailPage.js.map +1 -0
  53. package/dist/public/store/pages/StoreProductListPage.d.ts +24 -0
  54. package/dist/public/store/pages/StoreProductListPage.d.ts.map +1 -0
  55. package/dist/public/store/pages/StoreProductListPage.js +358 -0
  56. package/dist/public/store/pages/StoreProductListPage.js.map +1 -0
  57. package/dist/public/user/WebSiteUserService.d.ts.map +1 -1
  58. package/dist/public/user/WebSiteUserService.js +8 -8
  59. package/dist/public/user/WebSiteUserService.js.map +1 -1
  60. package/dist/public/user/pages/SiteLoginPage.d.ts +29 -0
  61. package/dist/public/user/pages/SiteLoginPage.d.ts.map +1 -0
  62. package/dist/public/user/pages/SiteLoginPage.js +204 -0
  63. package/dist/public/user/pages/SiteLoginPage.js.map +1 -0
  64. package/dist/services/store/StoreOrderService.js +1 -1
  65. package/dist/services/store/StoreOrderService.js.map +1 -1
  66. package/dist/site-editor/editor/HtmlPageEditor.d.ts.map +1 -1
  67. package/dist/site-editor/editor/HtmlPageEditor.js +14 -0
  68. package/dist/site-editor/editor/HtmlPageEditor.js.map +1 -1
  69. package/dist/tsconfig.tsbuildinfo +1 -1
  70. package/dist/web/AppIndex.pack.js +274 -85
  71. package/dist/web/AppIndex.pack.js.map +1 -1
  72. package/dist/web/AppIndex.pack.min.js +5 -5
  73. package/dist/web/AppIndex.pack.min.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/common/pages/stores/orders/EditOrderPage.tsx +1 -1
  76. package/src/common/pages/stores/payment-gateway/PaymentGatewayEditorPage.tsx +7 -4
  77. package/src/common/pages/stores/payment-gateway/PaymentGatewayListPage.tsx +7 -6
  78. package/src/model/model.ts +100 -42
  79. package/src/public/store/StoreApp.tsx +30 -0
  80. package/src/public/store/StoreItemDetailView.tsx +0 -3
  81. package/src/public/store/commands/StoreCommands.ts +13 -1
  82. package/src/public/store/pages/StoreProductDetailPage.tsx +354 -0
  83. package/src/public/store/pages/StoreProductListPage.tsx +344 -0
  84. package/src/public/user/WebSiteUserService.ts +3 -6
  85. package/src/public/user/pages/SiteLoginPage.tsx +202 -0
  86. package/src/services/store/StoreOrderService.ts +3 -3
  87. package/src/site-editor/editor/HtmlPageEditor.tsx +15 -0
@@ -0,0 +1,344 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind";
2
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+ import Action from "@web-atoms/core/dist/view-model/Action";
5
+ import AtomRepeater from "@web-atoms/web-controls/dist/basic/AtomRepeater";
6
+ import { ContentPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
7
+ import { apiPath } from "../../../common/apiPath";
8
+ import InfiniteRepeater from "../../../common/controls/repeater/InfiniteRepeater";
9
+ import { formatPrice } from "../../../common/currency";
10
+ import { Sql } from "../../../common/Sql";
11
+ import { IStoreItem, IStoreTag, StoreTag, StoreMediaFile, StoreItem } from "../../../model/model";
12
+ import EntityService from "../../../services/EntityService";
13
+ import styled from "@web-atoms/core/dist/style/styled";
14
+ import StoreCommands from "../commands/StoreCommands";
15
+
16
+ styled.css`
17
+
18
+ display:grid;
19
+ grid-template-rows: auto 1fr auto;
20
+ background-color: var(--hover-color);
21
+
22
+ & > header {
23
+ grid-row:1;
24
+ padding: 10px;
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: 10px;
28
+
29
+ & > .search {
30
+ width: 100%;
31
+ text-indent: 15px;
32
+ height: 42px;
33
+ font-weight: 400;
34
+ font-size: var(--font-xs);
35
+ border: 1px solid var(--border-color, #d3d3d3);
36
+ outline: none;
37
+ background-color: var(--accent-text-color);
38
+
39
+ }
40
+
41
+ & > .tags {
42
+ display: flex;
43
+ flex-wrap: wrap;
44
+ flex-wrap: wrap;
45
+ gap: 12px;
46
+ padding: 10px;
47
+ justify-content: start;
48
+ & > * {
49
+ cursor: pointer;
50
+ font-size: 15px;
51
+ font-weight: 600;
52
+ padding: 8px 16px;
53
+ border-radius: 25px;
54
+ border: 1px solid transparent;
55
+ cursor: pointer;
56
+ transition: all 0.3s ease;
57
+ text-decoration: none;
58
+ background-color: var(--accent-text-color);
59
+ &:hover {
60
+ transform: translateY(-3px);
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ & > section {
67
+ grid-row: 2;
68
+ padding: 10px;
69
+ display: flex;
70
+ flex-direction: row;
71
+ flex-wrap: wrap;
72
+ justify-content: center;
73
+ gap: 10px;
74
+
75
+ & .store-item {
76
+ display: inline-grid;
77
+ padding: 8px 12px;
78
+ border-radius: 5px;
79
+ background-color: var(--accent-text-color);
80
+ grid-template-columns: 1fr 1fr;
81
+ grid-template-rows: auto 1fr auto auto;
82
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
83
+ gap: 10px;
84
+ & > .name {
85
+ grid-column: 1 / span 2;
86
+ grid-row: 1;
87
+ max-width:200px;
88
+ overflow: hidden;
89
+ text-overflow: ellipsis;
90
+ white-space: nowrap;
91
+ color: var(--accent-color);
92
+ text-decoration: none;
93
+ }
94
+ & > img {
95
+ grid-column: 1 / span 2;
96
+ grid-row: 2;
97
+ object-fit: contain;
98
+ width: 200px;
99
+ height: 200px;
100
+ }
101
+ & > .description {
102
+ grid-column: 1 / span 2;
103
+ grid-row: 3;
104
+ max-width: 200px;
105
+ height: 3ch;
106
+ overflow: hidden;
107
+ text-overflow: ellipsis;
108
+ white-space: nowrap;
109
+ color: var(--primary-color);
110
+ text-decoration: none;
111
+ }
112
+ & > .buy {
113
+ grid-column: 1 / span 2;
114
+ grid-row: 5;
115
+ display: inline-flex;
116
+ -webkit-box-align: center;
117
+ align-items: center;
118
+ -webkit-box-pack: center;
119
+ justify-content: center;
120
+ position: relative;
121
+ box-sizing: border-box;
122
+ -webkit-tap-highlight-color: transparent;
123
+ cursor: pointer;
124
+ user-select: none;
125
+ vertical-align: middle;
126
+ appearance: none;
127
+ line-height: 1.75;
128
+ text-transform: uppercase;
129
+ min-width: 64px;
130
+ width: 100%;
131
+ font-weight: bold;
132
+ font-size: 14px;
133
+ font-family: Mulish, sans-serif;
134
+ background-color: var(--button-background);
135
+ color: var(--button-text);
136
+ outline: 0px;
137
+ border-width: 0px;
138
+ border-style: initial;
139
+ border-color: initial;
140
+ border-image: initial;
141
+ margin: 0px;
142
+ text-decoration: none;
143
+ padding: 6px 16px;
144
+ border-radius: 4px;
145
+ transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), border-color 250ms cubic-bezier(0.4, 0, 0.2, 1), color 250ms cubic-bezier(0.4, 0, 0.2, 1);
146
+
147
+ }
148
+ & > .price {
149
+ grid-column: 1/ span 2;
150
+ grid-row: 4;
151
+ text-align: center;
152
+ font-weight: 700;
153
+ font-size: var(--font-xs);
154
+ text-align: center;
155
+
156
+ }
157
+ }
158
+
159
+ }
160
+
161
+ & > footer {
162
+ grid-row: 3;
163
+ }
164
+
165
+ `.installGlobal("[data-shopping-cart-list=shopping-cart-list]");
166
+
167
+ export default class StoreProductListPage extends ContentPage {
168
+
169
+ search = "";
170
+
171
+ items: IStoreItem[] = [];
172
+
173
+ tags: IStoreTag[] = [];
174
+
175
+ version = 0;
176
+
177
+ @InjectProperty
178
+ entityService: EntityService;
179
+
180
+ constructor(app, e) {
181
+ super(app, e);
182
+ this.element.setAttribute("data-shopping-cart-list", "shopping-cart-list");
183
+ }
184
+
185
+ async init() {
186
+
187
+ this.render(<div data-shopping-cart-list="shopping-cart-list">
188
+ <header>
189
+ <AtomRepeater
190
+ class="search-tags"
191
+ items={this.tags}
192
+ itemRenderer={(x) => <div data-layout="row"> <label text={`${x.tag.label} (${x.count})`}/> <i data-click-event="remove-tag" class="fas fa-times-circle"/> </div>}
193
+ />
194
+ <input type="search" class="search" value={Bind.twoWaysImmediate(() => this.search)}/>
195
+ <AtomRepeater
196
+ class="tags"
197
+ items={Bind.oneWayAsync((c, e, cancelToken) => this.searchTags(this.search, cancelToken, this.version), { default: [] })}
198
+ itemRenderer={(x: IStoreTag) => <label text={`${x.tag.label} (${x.count})`}/>}
199
+ data-click-event="select-tag"
200
+ />
201
+ </header>
202
+ <AtomRepeater
203
+ for="section"
204
+ items={this.items}
205
+ { ... InfiniteRepeater.pagedItems((start) =>
206
+ (c, e, cancelToken) =>
207
+ this.searchItems({
208
+ start,
209
+ search: this.search,
210
+ version: this.version,
211
+ cancelToken
212
+ })
213
+ )}
214
+ itemRenderer={(item: IStoreItem) => <div class="store-item">
215
+ <a
216
+ class="name"
217
+ title={item.name || item.variantFor?.name || item.name}
218
+ text={item.name || item.variantFor?.name || item.name}
219
+ href={StoreCommands.productDetail.displayRoute(item)}/>
220
+ <label
221
+ class="description"
222
+ title={item.description || item.variantFor?.description || item.description}
223
+ text={item.description || item.variantFor?.description || item.description}
224
+ />
225
+ <img
226
+ src={Bind.oneTimeAsync(() => this.downloadImage(item))}
227
+ />
228
+ <a
229
+ title={item.name || item.variantFor?.name || item.name}
230
+ href={StoreCommands.productDetail.displayRoute(item)}><button
231
+ class="buy"
232
+ text="Buy"/></a>
233
+ <div class="price">
234
+ <label text={ formatPrice(item.storeItemPrices?.[0] ?? item.variantFor?.storeItemPrices?.[0] )}/>
235
+ </div>
236
+ </div>}
237
+ />
238
+ <footer>
239
+ </footer>
240
+ </div>);
241
+
242
+ }
243
+
244
+ @Action({ onEvent: "remove-tag"})
245
+ removeTag(tag: IStoreTag) {
246
+ this.tags.remove(tag);
247
+ this.version++;
248
+ }
249
+
250
+ @Action({ onEvent: "select-tag"})
251
+ selectTag(tag: IStoreTag) {
252
+ if(this.tags.find((t) => t.tagID === tag.tagID)) {
253
+ return;
254
+ }
255
+ this.tags.add(tag);
256
+ this.version++;
257
+ }
258
+
259
+ async searchTags(search: string, cancelToken, v): Promise<any> {
260
+ let q = this.entityService.query(StoreTag, "storeQuery");
261
+ if (search) {
262
+ search = search.trim().toLocaleLowerCase() + "%";
263
+ q = q.where({ search }, (p) => (x) =>
264
+ (Sql.text.like(x.tag.lowerCaseName, p.search)
265
+ || Sql.text.like(x.tag.parent.lowerCaseName, p.search))
266
+ && x.count > 0
267
+ );
268
+ }
269
+ if (this.tags.length) {
270
+ const ids = this.tags.map((t) => t.tagID);
271
+ q = q.where({ ids }, (p) => (x) => ! Sql.in(x.tagID, p.ids));
272
+ }
273
+ const tags = await q
274
+ .orderByDescending((x) => x.count)
275
+ .include((x) => x.tag)
276
+ .toPagedList({
277
+ size: 10,
278
+ cancelToken
279
+ });
280
+ return tags.items;
281
+ }
282
+
283
+ async downloadImage(item: IStoreItem) {
284
+ const file = await this.entityService.query(StoreMediaFile, "storeQuery", item.storeItemID, item.signed)
285
+ .where((x) => x.isPreview === true)
286
+ .orderBy((x) => x.sortOrder)
287
+ .firstOrDefault();
288
+ if (!file) {
289
+ return;
290
+ }
291
+ return apiPath(`/api/signed/webp(700)/${file.appFileID}/${file.fileContentID}/${file.signed}/file.webp`);
292
+ }
293
+
294
+
295
+ async searchItems({
296
+ start,
297
+ search = "",
298
+ size = 50,
299
+ version = 0,
300
+ cancelToken
301
+ }) {
302
+
303
+ let q = this.entityService.query(StoreItem, "storeQuery")
304
+ .where((x) =>
305
+ x.itemType in [ "product", "service", "resource", "variant", "e-product"]
306
+ && x.sizeForID === null
307
+ );
308
+ if (search) {
309
+ search = search + "%";
310
+ const lowerSearch = search.trim().toLocaleLowerCase();
311
+ q = q.where({ search, lowerSearch }, (p) => (x) =>
312
+ (Sql.text.iLike(x.name, p.search)
313
+ || Sql.text.iLike(x.description, p.search)
314
+ || x.sizes.some((s) => Sql.text.iLike(s.name, p.search) || Sql.text.iLike(s.description, p.search))
315
+ || x.variants.some((s) => Sql.text.iLike(s.name, p.search) || Sql.text.iLike(s.description, p.search))
316
+ || x.storeItemTags.some((t) => Sql.text.like(t.tag.lowerCaseName, p.lowerSearch)
317
+ || Sql.text.like(t.tag.parent.lowerCaseName, p.lowerSearch)))
318
+ );
319
+ }
320
+ if (this.tags.length) {
321
+ const ids = this.tags.map((t) => t.tagID);
322
+ q = q.where({ ids}, (p) => (x) => x.storeItemTags.some((st) => Sql.in(st.tagID, p.ids)));
323
+ }
324
+ const items = await q.orderByDescending((x) => x.storeItemID)
325
+ .include((x) => [
326
+ x.storeItemPrices,
327
+ x.storeItemTags.forEach((t) => t.tag),
328
+ x.variantFor
329
+ ])
330
+ // .trace()
331
+ .toPagedList({
332
+ start,
333
+ size,
334
+ cancelToken
335
+ });
336
+
337
+ const tasks = [];
338
+
339
+ for (const item of items.items) {
340
+ item.storeItemTags?.sort((a, b) => a.sortOrder - b.sortOrder);
341
+ }
342
+ return items;
343
+ }
344
+ }
@@ -5,6 +5,8 @@ import EntityService from "../../services/EntityService";
5
5
  import SocialMailApp from "../../common/SocialMailApp";
6
6
  import SiteLogin from "./SiteLogin";
7
7
  import { App } from "@web-atoms/core/dist/App";
8
+ import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
9
+ import SiteLoginPage from "./pages/SiteLoginPage";
8
10
 
9
11
  @DISingleton()
10
12
  export default class WebSiteUserService {
@@ -26,12 +28,7 @@ export default class WebSiteUserService {
26
28
  return this.user;
27
29
  }
28
30
 
29
-
30
- // request login..
31
- const sl = new SiteLogin(this.app);
32
-
33
- const c = document.body.querySelector(`[styler-layout="component"]`) ?? document.body;
34
- c.appendChild(sl.element);
31
+ await PageNavigator.pushPageForResultOrCancel(SiteLoginPage);
35
32
 
36
33
  return this.user;
37
34
  }
@@ -0,0 +1,202 @@
1
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
2
+ import { Inject } from "@web-atoms/core/dist/di/Inject";
3
+ import { ContentPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
4
+ import EntityService from "../../../services/EntityService";
5
+ import XNode from "@web-atoms/core/dist/core/XNode";
6
+ import Bind from "@web-atoms/core/dist/core/Bind";
7
+ import Form from "@web-atoms/web-controls/dist/basic/Form";
8
+ import FormField from "@web-atoms/web-controls/dist/basic/FormField";
9
+ import { EmailIconTextButton, UploadIconButton } from "../../../common/controls/buttons/IconButton";
10
+ import { IVerificationToken, VerificationToken } from "../../../model/model";
11
+ import ToggleButtonBar from "@web-atoms/web-controls/dist/basic/ToggleButtonBar";
12
+ import PhoneEditor from "../../../common/controls/phone-editor/PhoneEditor";
13
+ import Action from "@web-atoms/core/dist/view-model/Action";
14
+ import QRCodeControl from "../../../common/controls/qrcode/QRCode";
15
+ import styled from "@web-atoms/core/dist/style/styled";
16
+
17
+ styled.css `
18
+ & [data-page-element=content] {
19
+ display: grid;
20
+ align-items: center;
21
+ justify-items: center;
22
+ }
23
+ `.installGlobal("[site-login-page]");
24
+
25
+ export interface IVerification {
26
+ id: any;
27
+ accessCode: string;
28
+ code: string;
29
+ }
30
+
31
+ export interface IUserModel {
32
+ emailAddress?: string;
33
+ phoneNumber?: string;
34
+ name?: string;
35
+
36
+ email?: IVerification;
37
+ phone?: IVerification;
38
+ captcha?: IVerification;
39
+ }
40
+
41
+ const verifyModes = [
42
+ { label: "Email", value: "email" },
43
+ { label: "Cell Phone", value: "phone" }
44
+ ];
45
+
46
+ export default class SiteLoginPage extends ContentPage {
47
+
48
+ @InjectProperty
49
+ entityService: EntityService;
50
+
51
+ model: IUserModel = { emailAddress: "", phoneNumber: "", name: "" };
52
+
53
+ verifyMode: string = "email";
54
+
55
+ captcha: IVerificationToken = null;
56
+ verification: IVerificationToken = null;
57
+
58
+ async init() {
59
+
60
+ this.element.setAttribute("site-login-page", "site-login");
61
+
62
+ const captcha = await this.entityService.save(VerificationToken.create({
63
+ type: "captcha"
64
+ }));
65
+
66
+ this.captcha = captcha;
67
+
68
+ const { verificationID: id, accessCode } = captcha;
69
+
70
+ this.model.captcha = {
71
+ id,
72
+ accessCode,
73
+ code: ""
74
+ };
75
+
76
+ this.renderer = <div>
77
+ <Form>
78
+ <FormField label="Verify">
79
+ <ToggleButtonBar items={verifyModes} value={Bind.twoWaysImmediate(() => this.verifyMode)} />
80
+ </FormField>
81
+ <FormField label="Email" style-display={Bind.oneWay(() => this.verifyMode === "email")}>
82
+ <input autofocus={true} value={Bind.twoWaysImmediate(() => this.model.emailAddress)} />
83
+ </FormField>
84
+ <FormField label="Cell Phone" style-display={Bind.oneWay(() => this.verifyMode === "phone")}>
85
+ <PhoneEditor value={Bind.twoWaysImmediate(() => this.model.phoneNumber)} />
86
+ </FormField>
87
+
88
+
89
+ <FormField label="Captcha">
90
+ <img src={`/api/users/captcha/${id}/${accessCode}`}/>
91
+ </FormField>
92
+ <FormField label="Enter 5 Digit Code">
93
+ <input
94
+ type="tel"
95
+ value={Bind.twoWaysImmediate(() => this.model.captcha.code)}/>
96
+ </FormField>
97
+
98
+ <div>
99
+ <EmailIconTextButton
100
+ text="Verify"
101
+ data-submit-event="proceed-verification"
102
+ />
103
+ </div>
104
+ </Form>
105
+ </div>;
106
+ }
107
+
108
+ @Action({ onEvent: "proceed-verification"})
109
+ async proceedVerification() {
110
+ const captcha = this.captcha;
111
+ const { verificationID: id, accessCode } = captcha;
112
+ const vt = await this.entityService.invoke(VerificationToken, "verifyCode", captcha, id, accessCode, this.model.captcha.code);
113
+ if (!vt.verified) {
114
+ throw new Error("Verification failed, try again");
115
+ }
116
+
117
+ const isEmail = this.verifyMode === "email";
118
+
119
+ const type = isEmail ? "email" : "sms";
120
+
121
+ const address = isEmail ? this.model.emailAddress : this.model.phoneNumber;
122
+
123
+ const ve = VerificationToken.create({
124
+ type,
125
+ verifyAddresses: address
126
+ });
127
+
128
+ this.verification = ve;
129
+
130
+ await this.entityService.save(ve, (c) => c.include((x) => x.addresses));
131
+
132
+ if (!isEmail) {
133
+ await this.displayPhoneVerification(ve);
134
+ return;
135
+ }
136
+
137
+ this.model.email = {
138
+ id: ve.verificationID,
139
+ accessCode: ve.accessCode,
140
+ code: ""
141
+ };
142
+
143
+ this.renderer = <div>
144
+ <Form>
145
+ <FormField label="Email Verification">
146
+ <div>We have sent you the verification code in your email, please enter it again to complete the verification.</div>
147
+ </FormField>
148
+ <FormField label="Code">
149
+ <input value={Bind.twoWaysImmediate(() => this.model.email.code)}/>
150
+ </FormField>
151
+ <div>
152
+ <EmailIconTextButton
153
+ text="Verify"
154
+ data-submit-event="verify-email"
155
+ />
156
+ </div>
157
+ </Form>
158
+ </div>;
159
+
160
+ }
161
+
162
+
163
+ async displayPhoneVerification(ve: IVerificationToken) {
164
+ this.renderer = <div>
165
+ <QRCodeControl
166
+ smsConfig={ve.smsConfig} />
167
+ </div>;
168
+
169
+ for (let index = 0; index < 5; index++) {
170
+ const v = await this.entityService.query(VerificationToken, "get", ve.verificationID, ve.accessCode)
171
+ .firstOrDefault();
172
+ if (v.verified) {
173
+ ve.verified = true;
174
+ if (ve.userID) {
175
+ await this.login(ve);
176
+ return;
177
+ }
178
+ break;
179
+ }
180
+ }
181
+ }
182
+
183
+ @Action({ onEvent: "verify-email"})
184
+ async verifyEmail() {
185
+ const v = this.verification;
186
+ const vt = await this.entityService.invoke(VerificationToken, "verifyCode", v, v.verificationID, v.accessCode, this.model.email.code);
187
+ if (!vt.verified) {
188
+ throw new Error("Verification failed, try again");
189
+ }
190
+ if (vt.userID) {
191
+ await this.login(vt);
192
+ return;
193
+ }
194
+ }
195
+
196
+ @Action({})
197
+ async login(v: IVerificationToken) {
198
+ await this.entityService.invoke(VerificationToken, "login", v, v.verificationID, v.accessCode);
199
+ location.reload();
200
+ }
201
+
202
+ }
@@ -16,9 +16,9 @@ export default class StoreOrderService {
16
16
  .where({ orderID }, (p) => (x) => x.journalID === p.orderID)
17
17
  .include((x) => [
18
18
  x.lineItems.forEach((oi) => [oi.itemPrice.storeItem.store]),
19
- x.entries.forEach((e) => e.ledger),
20
- x.buyer.items,
21
- x.seller.items
19
+ x.entries.forEach((e) => e.storeAccount),
20
+ x.buyer,
21
+ x.seller
22
22
  ])
23
23
  .firstOrDefault();
24
24
  }
@@ -963,6 +963,21 @@ export default class HtmlPageEditor extends AtomControl {
963
963
  }
964
964
  }
965
965
 
966
+ let wc = clone.querySelector("script[web-components]");
967
+ if (!wc) {
968
+ wc = this.htmlDocument.createElement("script");
969
+ wc.setAttribute("web-components", "social");
970
+ wc.setAttribute("async", "true");
971
+ wc.setAttribute("defer", "true");
972
+ clone.head.appendChild(doc.createTextNode("\n"));
973
+ clone.head.appendChild(wc);
974
+ clone.head.appendChild(doc.createTextNode("\n"));
975
+ }
976
+ const wcs = `${WebComponents.path}/dist/main.js`;
977
+ if (wc.getAttribute("src") !== wcs) {
978
+ wc.setAttribute("src", wcs);
979
+ }
980
+
966
981
  },10);
967
982
  }
968
983