@thefittingroom/shop-ui 0.0.2 → 0.0.4
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/README.md +32 -57
- package/dist/esm/index.js +48 -17
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +80 -81
- package/dist/esm/init.d.ts +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -1,75 +1,50 @@
|
|
|
1
|
-
# The Fitting Room - Shop
|
|
1
|
+
# The Fitting Room - Shop UI
|
|
2
|
+
|
|
3
|
+
Modal UI for The Fitting Room. Provides UI hooks to integrate into the parent UI.
|
|
2
4
|
|
|
3
5
|
## Installation
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
|
-
|
|
7
|
-
ASSETS_URL=https://assets.dev.thefittingroom.xyz/shop-sdk/assets
|
|
8
|
-
|
|
9
|
-
# build everytime changes are detected
|
|
10
|
-
npm run dev:rollup
|
|
11
|
-
# run a live server on localhost:3030 and disable cors
|
|
12
|
-
npx live-server --host=localhost --port=3030 --cors
|
|
8
|
+
npm i @thefittingroom/shop-ui
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
or
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## Merges on main branch
|
|
13
|
+
```bash
|
|
14
|
+
yarn @thefittingroom/shop-ui
|
|
15
|
+
```
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
You can access the development builds by using a commit sha on main like this:
|
|
17
|
+
## Usage
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
```typescript
|
|
20
|
+
import { initFittingRoom } from '@thefittingroom/shop-ui'
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
// Your brandId: Number
|
|
23
|
+
const shopId: number = 9001
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
// UI Hooks
|
|
26
|
+
const hooks: TfrHooks = {
|
|
27
|
+
onLoading: () => {},
|
|
28
|
+
onLoadingComplete: () => {},
|
|
29
|
+
onAvatarReady: (frames: string[]) => {},
|
|
30
|
+
onError: () => {},
|
|
31
|
+
onLogin: () => {},
|
|
32
|
+
onLogout: () => {},
|
|
33
|
+
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
InitLocale()
|
|
35
|
+
// the div id to contain the modal elements
|
|
36
|
+
const modalDivId: string = 'tfr-modal'
|
|
37
37
|
|
|
38
|
-
//
|
|
39
|
-
|
|
38
|
+
// initFittingRoom is an async function and must be awaited
|
|
39
|
+
const tfr = await initFittingRoom(shopId, modalDivId, hooks)
|
|
40
40
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
signout.addEventListener('click', () => {
|
|
44
|
-
// pass an empty sku to the onSignout since its not being used in a modal
|
|
45
|
-
// call the onSignout function wrapper to return a promise
|
|
46
|
-
// wait for the promise
|
|
47
|
-
// shows signed out modal by default
|
|
48
|
-
tfr
|
|
49
|
-
.onSignout('')()
|
|
50
|
-
.then(() => {
|
|
51
|
-
// do something after signing out of the fitting room
|
|
52
|
-
})
|
|
53
|
-
})
|
|
41
|
+
// on page nav to new product
|
|
42
|
+
tfr.setSku(sku)
|
|
54
43
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
tfr.TryOn('5003-007-08')
|
|
58
|
-
})
|
|
44
|
+
// close the modal
|
|
45
|
+
tfr.close()
|
|
59
46
|
```
|
|
60
47
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
You can call `SetLocale` to change the language of the sdk without using url searchParams.
|
|
64
|
-
|
|
65
|
-
```javascript
|
|
66
|
-
SetLocale('en')
|
|
67
|
-
.then(() => {
|
|
68
|
-
// do something after setting the locale
|
|
69
|
-
})
|
|
70
|
-
.catch((err) => {
|
|
71
|
-
// handle error
|
|
72
|
-
})
|
|
73
|
-
```
|
|
48
|
+
Several low level methods are exposed via `tfr.shop`
|
|
74
49
|
|
|
75
|
-
|
|
50
|
+
See [@thefittingroom/sdk](https://github.com/TheFittingRoom/shop-sdk/tree/main)
|
package/dist/esm/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* thefittingroom v0.0.
|
|
2
|
+
* thefittingroom v0.0.4 (2023-07-19T15:30:35.007Z)
|
|
3
3
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
/*!
|
|
6
|
-
* thefittingroom v0.0.
|
|
6
|
+
* thefittingroom v0.0.7 (2023-07-19T15:29:31.094Z)
|
|
7
7
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
@@ -16354,8 +16354,8 @@ const devKeys = {
|
|
|
16354
16354
|
url: "https://tfr.dev.thefittingroom.xyz",
|
|
16355
16355
|
},
|
|
16356
16356
|
config: {
|
|
16357
|
-
avatarTimeout: "120000",
|
|
16358
|
-
vtoTimeout: "120000",
|
|
16357
|
+
avatarTimeout: Number("120000"),
|
|
16358
|
+
vtoTimeout: Number("120000"),
|
|
16359
16359
|
},
|
|
16360
16360
|
};
|
|
16361
16361
|
const prodKeys = {
|
|
@@ -16371,8 +16371,8 @@ const prodKeys = {
|
|
|
16371
16371
|
url: "https://tfr.p.thefittingroom.xyz",
|
|
16372
16372
|
},
|
|
16373
16373
|
config: {
|
|
16374
|
-
avatarTimeout: "120000",
|
|
16375
|
-
vtoTimeout: "120000",
|
|
16374
|
+
avatarTimeout: Number("120000"),
|
|
16375
|
+
vtoTimeout: Number("120000"),
|
|
16376
16376
|
},
|
|
16377
16377
|
};
|
|
16378
16378
|
|
|
@@ -22813,6 +22813,20 @@ class FirebaseUser {
|
|
|
22813
22813
|
const userProfile = await Ol(Aa(this.firestore, 'users', this.id));
|
|
22814
22814
|
return userProfile.data();
|
|
22815
22815
|
}
|
|
22816
|
+
watchUserProfileForChanges(predicate, timeout) {
|
|
22817
|
+
let unsub;
|
|
22818
|
+
const q = sl(Ta(this.firestore, 'users'), rl(Eh(), '==', this.id));
|
|
22819
|
+
const cancel = setTimeout(() => unsub(), timeout);
|
|
22820
|
+
return new Promise((resolve) => {
|
|
22821
|
+
unsub = jl(q, (snapshot) => {
|
|
22822
|
+
if (!predicate(snapshot))
|
|
22823
|
+
return;
|
|
22824
|
+
clearTimeout(cancel);
|
|
22825
|
+
unsub();
|
|
22826
|
+
resolve(snapshot.docs[0].data());
|
|
22827
|
+
});
|
|
22828
|
+
});
|
|
22829
|
+
}
|
|
22816
22830
|
async login(username, password) {
|
|
22817
22831
|
if (this.auth.currentUser)
|
|
22818
22832
|
await this.auth.signOut();
|
|
@@ -22833,9 +22847,15 @@ class FirebaseUser {
|
|
|
22833
22847
|
|
|
22834
22848
|
class Firebase {
|
|
22835
22849
|
constructor() {
|
|
22836
|
-
this.promisefyOnSnapshot = (q) => {
|
|
22850
|
+
this.promisefyOnSnapshot = (q, unsubscribeWhenData) => {
|
|
22837
22851
|
let unsub;
|
|
22838
|
-
const promise = new Promise((resolve) =>
|
|
22852
|
+
const promise = new Promise((resolve) => {
|
|
22853
|
+
unsub = jl(q, (snapshot) => {
|
|
22854
|
+
resolve(snapshot);
|
|
22855
|
+
if (unsubscribeWhenData)
|
|
22856
|
+
unsub();
|
|
22857
|
+
});
|
|
22858
|
+
});
|
|
22839
22859
|
return { promise, unsubscribe: () => unsub() };
|
|
22840
22860
|
};
|
|
22841
22861
|
const firebaseKeys = Config.getInstance().firebase;
|
|
@@ -22846,9 +22866,9 @@ class Firebase {
|
|
|
22846
22866
|
onInit() {
|
|
22847
22867
|
return this.user.onInit();
|
|
22848
22868
|
}
|
|
22849
|
-
query(collectionName, constraint) {
|
|
22869
|
+
query(collectionName, constraint, unsubscribeWhenData = true) {
|
|
22850
22870
|
const q = sl(Ta(this.firestore, collectionName), constraint);
|
|
22851
|
-
return this.promisefyOnSnapshot(q);
|
|
22871
|
+
return this.promisefyOnSnapshot(q, unsubscribeWhenData);
|
|
22852
22872
|
}
|
|
22853
22873
|
getDocs(collectionName, constraints) {
|
|
22854
22874
|
const q = sl(Ta(this.firestore, collectionName), ...constraints);
|
|
@@ -22868,7 +22888,7 @@ const getFirebaseError = (e) => {
|
|
|
22868
22888
|
const asyncTry = (promise) => promise.then((data) => [null, data]).catch((error) => [error]);
|
|
22869
22889
|
|
|
22870
22890
|
class Fetcher {
|
|
22871
|
-
static endpoint() {
|
|
22891
|
+
static get endpoint() {
|
|
22872
22892
|
const api = Config.getInstance().api;
|
|
22873
22893
|
return api.url;
|
|
22874
22894
|
}
|
|
@@ -22998,10 +23018,15 @@ class TfrShop {
|
|
|
22998
23018
|
const res = await Fetcher.Post(this.user, '/ios-app-link', { phone_number: sanitizedTel }, false);
|
|
22999
23019
|
console.log(res);
|
|
23000
23020
|
}
|
|
23001
|
-
awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
|
|
23021
|
+
async awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
|
|
23022
|
+
var _a, _b, _c, _d;
|
|
23002
23023
|
if (!this.isLoggedIn)
|
|
23003
23024
|
throw new UserNotLoggedInError();
|
|
23004
|
-
return this.
|
|
23025
|
+
const predicate = (data) => { var _a, _b, _c; return Boolean((_c = (_b = (_a = data.docs[0].data()) === null || _a === void 0 ? void 0 : _a.vto) === null || _b === void 0 ? void 0 : _b[this.brandId]) === null || _c === void 0 ? void 0 : _c[colorwaySizeAssetSKU]); };
|
|
23026
|
+
const userProfile = (await this.user.watchUserProfileForChanges(predicate, TfrShop.vtoTimeout));
|
|
23027
|
+
if (!((_d = (_c = (_b = (_a = userProfile === null || userProfile === void 0 ? void 0 : userProfile.vto) === null || _a === void 0 ? void 0 : _a[this.brandId]) === null || _b === void 0 ? void 0 : _b[colorwaySizeAssetSKU]) === null || _c === void 0 ? void 0 : _c.frames) === null || _d === void 0 ? void 0 : _d.length))
|
|
23028
|
+
throw new NoFramesFoundError();
|
|
23029
|
+
return userProfile.vto[this.brandId][colorwaySizeAssetSKU].frames;
|
|
23005
23030
|
}
|
|
23006
23031
|
async requestThenGetColorwaySizeAssetFrames(colorwaySizeAssetSku) {
|
|
23007
23032
|
var _a, _b;
|
|
@@ -23070,6 +23095,8 @@ class TfrShop {
|
|
|
23070
23095
|
return frames;
|
|
23071
23096
|
}
|
|
23072
23097
|
}
|
|
23098
|
+
TfrShop.avatarTimeout = 120000;
|
|
23099
|
+
TfrShop.vtoTimeout = 120000;
|
|
23073
23100
|
const initShop = (brandId, env = 'dev') => {
|
|
23074
23101
|
if (env === 'dev' || env === 'development')
|
|
23075
23102
|
console.warn('TfrShop is in development mode');
|
|
@@ -36151,7 +36178,7 @@ class FittingRoom {
|
|
|
36151
36178
|
this.shopId = shopId;
|
|
36152
36179
|
this.hooks = hooks;
|
|
36153
36180
|
this.nav = new FittingRoomNav(modalDivId, this.signIn.bind(this), this.forgotPassword.bind(this), this.submitTel.bind(this));
|
|
36154
|
-
this.tfrShop = initShop(Number(this.shopId), "
|
|
36181
|
+
this.tfrShop = initShop(Number(this.shopId), "prod");
|
|
36155
36182
|
}
|
|
36156
36183
|
get sku() {
|
|
36157
36184
|
return this.nav.sku;
|
|
@@ -36195,7 +36222,8 @@ class FittingRoom {
|
|
|
36195
36222
|
this.nav.onNotCreated();
|
|
36196
36223
|
break;
|
|
36197
36224
|
case AvatarState.PENDING:
|
|
36198
|
-
this.
|
|
36225
|
+
if (this.hooks.onLoading)
|
|
36226
|
+
this.hooks.onLoading();
|
|
36199
36227
|
break;
|
|
36200
36228
|
case AvatarState.CREATED:
|
|
36201
36229
|
console.debug('avatar_state: created');
|
|
@@ -36231,7 +36259,6 @@ class FittingRoom {
|
|
|
36231
36259
|
try {
|
|
36232
36260
|
if (this.hooks.onLoading)
|
|
36233
36261
|
this.hooks.onLoading();
|
|
36234
|
-
this.nav.onLoading();
|
|
36235
36262
|
const frames = await this.tfrShop.tryOn(this.sku);
|
|
36236
36263
|
this.nav.close();
|
|
36237
36264
|
if (this.hooks.onAvatarReady)
|
|
@@ -36252,7 +36279,11 @@ class FittingRoom {
|
|
|
36252
36279
|
}
|
|
36253
36280
|
}
|
|
36254
36281
|
|
|
36255
|
-
const initFittingRoom = (shopId, modalDivId, hooks) =>
|
|
36282
|
+
const initFittingRoom = async (shopId, modalDivId, hooks) => {
|
|
36283
|
+
const tfr = new FittingRoom(shopId, modalDivId, hooks);
|
|
36284
|
+
await tfr.onInit();
|
|
36285
|
+
return tfr;
|
|
36286
|
+
};
|
|
36256
36287
|
|
|
36257
36288
|
export { VTO_TIMEOUT_MS, initFittingRoom };
|
|
36258
36289
|
//# sourceMappingURL=index.js.map
|