@thefittingroom/shop-ui 0.0.1

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.
@@ -0,0 +1,2 @@
1
+ import { FittingRoom, TfrHooks } from './tfr';
2
+ export declare const initFittingRoom: (shopId: string | number, modalDivId: string, hooks: TfrHooks) => FittingRoom;
@@ -0,0 +1,7 @@
1
+ import './colors.css';
2
+ import './general.css';
3
+ import './input.css';
4
+ import './media.css';
5
+ import './spaces.css';
6
+ import './telephone.css';
7
+ import './text.css';
@@ -0,0 +1,23 @@
1
+ import * as types from './types';
2
+ export declare class FittingRoomNav {
3
+ private readonly signIn;
4
+ private readonly forgotPassword;
5
+ private readonly submitTel;
6
+ private readonly manager;
7
+ private _sku;
8
+ constructor(modalDivId: string, signIn: types.SignInModalProps['onSignIn'], forgotPassword: types.ForgotPasswordModalProps['onPasswordReset'], submitTel: types.ScanCodeModalProps['onTelSubmit']);
9
+ get sku(): string;
10
+ setSku(sku: string): void;
11
+ close(): void;
12
+ onSignOut(): void;
13
+ onNotCreated(): void;
14
+ onLoading(): void;
15
+ toScan(): void;
16
+ toSignIn(): void;
17
+ toForgotPassword(): void;
18
+ toPasswordReset(): void;
19
+ onTryOn(frames: types.TryOnFrames): void;
20
+ onError(error: string): void;
21
+ onSizeError(recommended: string, available: string[]): void;
22
+ navBack(): void;
23
+ }
@@ -0,0 +1,29 @@
1
+ import { TfrShop } from '@thefittingroom/sdk';
2
+ import { FittingRoomNav } from './tfr-nav';
3
+ import * as types from './types';
4
+ export interface TfrHooks {
5
+ onLoading?: () => void;
6
+ onLoadingComplete?: () => void;
7
+ onError?: (error: string) => void;
8
+ onAvatarReady?: (frames: types.TryOnFrames) => void;
9
+ onLogin?: () => void;
10
+ onLogout?: () => void;
11
+ }
12
+ export declare class FittingRoom {
13
+ private readonly shopId;
14
+ private readonly hooks;
15
+ readonly nav: FittingRoomNav;
16
+ private readonly tfrShop;
17
+ constructor(shopId: string | number, modalDivId: string, hooks?: TfrHooks);
18
+ get sku(): string;
19
+ get shop(): TfrShop;
20
+ onInit(): Promise<boolean>;
21
+ setSku(sku: string): void;
22
+ close(): void;
23
+ signOut(): Promise<void>;
24
+ signIn(username: string, password: string, validationError: (message: string) => void): Promise<void>;
25
+ submitTel(tel: string): Promise<void>;
26
+ forgotPassword(email: string): Promise<void>;
27
+ passwordReset(code: string, newPassword: string): Promise<void>;
28
+ tryOn(): Promise<void>;
29
+ }
@@ -0,0 +1,145 @@
1
+ import { FirebaseUser, TfrShop } from '@thefittingroom/sdk';
2
+ import { ModalManager } from '../components';
3
+ import { UIError } from '../components/uiError';
4
+ import * as types from '../types';
5
+ export declare const TfrLogo: string;
6
+ export declare const AposeLogo: string;
7
+ export declare const AppStoreLogo: string;
8
+ export declare const QrCodeLogo: string;
9
+ export declare const NotLoggedIn: Error;
10
+ export declare const NoFramesFound: Error;
11
+ export declare const NoColorwaySizeAssetsFound: Error;
12
+ export declare const NoStylesFound: Error;
13
+ export interface RecommendedAvailableSizes {
14
+ error: string;
15
+ recommended_size: string;
16
+ available_sizes: string[];
17
+ }
18
+ export interface FittingRoom {
19
+ shop: TfrShop;
20
+ manager: ModalManager;
21
+ onSignout(colorwaySizeAssetSKU: string): () => Promise<void>;
22
+ onClose(): void;
23
+ onNavBack(): void;
24
+ onTryOn(colorwaySizeAssetSKU: string): void;
25
+ whenAvatarNotCreated(colorwaySizeAssetSKU: string): void;
26
+ whenAvatarPending(colorwaySizeAssetSKU: string): void;
27
+ whenAvatarCreated(colorwaySizeAssetSKU: string): void;
28
+ whenNotSignedIn(colorwaySizeAssetSKU: string): void;
29
+ whenTryOnReady(colorwaySizeAssetSKU: string, frames: types.TryOnFrames): void;
30
+ whenTryOnLoading(colorwaySizeAssetSKU: string): void;
31
+ whenTryOnFailed(colorwaySizeAssetSKU: string, error: Error): void;
32
+ whenError(colorwaySizeAssetSKU: string, error: UIError): void;
33
+ whenSignedIn(user: FirebaseUser, colorwaySizeAssetSKU: string): void;
34
+ whenSignedOut(colorwaySizeAssetSKU: string): void;
35
+ onSignIn(colorwaySizeAssetSKU: string): (username: string, password: string, validation: (message: string) => void) => void;
36
+ onNavSignIn(colorwaySizeAssetSKU: string): (email: string) => void;
37
+ onPasswordReset(colorwaySizeAssetSKU: string): (email: string) => void;
38
+ onNavForgotPassword(colorwaySizeAssetSKU: string): (email: string) => void;
39
+ onNavScanCode(colorwaySizeAssetSKU: string): void;
40
+ TryOn(colorwaySizeAssetSKU: string): void;
41
+ }
42
+ export interface ModalContent {
43
+ Body: () => string;
44
+ Hook(): void;
45
+ Unhook(): void;
46
+ }
47
+ export interface ModalProps {
48
+ }
49
+ export interface SignInParams {
50
+ email: string;
51
+ password: string;
52
+ }
53
+ export interface SignInModalProps extends ModalProps {
54
+ email?: string;
55
+ onSignIn: (email: string, password: string, validationError: (message: string) => void) => void;
56
+ onNavForgotPassword: (email?: string) => void;
57
+ onNavScanCode: () => void;
58
+ }
59
+ export interface ForgotPasswordModalProps extends ModalProps {
60
+ email?: string;
61
+ onNavSignIn: (email: string) => void;
62
+ onPasswordReset: (email: string) => void;
63
+ }
64
+ export type NoAvatarModalProps = ModalProps;
65
+ export interface LoadingAvatarModalProps extends ModalProps {
66
+ timeoutMS: number;
67
+ }
68
+ export interface TryOnModalProps extends ModalProps {
69
+ frames: TryOnFrames;
70
+ onNavBack: () => void;
71
+ onClose: () => void;
72
+ }
73
+ export interface ErrorModalProps extends ModalProps {
74
+ error: string;
75
+ onNavBack: () => void;
76
+ onClose: () => void;
77
+ }
78
+ export interface SizeErrorModalProps {
79
+ onNavBack: () => void;
80
+ onClose: () => void;
81
+ sizes?: {
82
+ recommended: string;
83
+ available: string[];
84
+ };
85
+ }
86
+ export interface ResetLinkModalProps {
87
+ email: string;
88
+ onNavSignIn: (email: string) => void;
89
+ }
90
+ export interface ScanCodeModalProps {
91
+ onSignInNav: () => void;
92
+ onTelSubmit: (tel: string) => void;
93
+ }
94
+ export interface LoggedOutModalProps {
95
+ onClose: () => void;
96
+ onNavSignIn: (email: string) => void;
97
+ }
98
+ export type TryOnFrames = string[];
99
+ export declare enum AvatarState {
100
+ NOT_CREATED = "NOT_CREATED",
101
+ CREATED = "CREATED",
102
+ PENDING = "PENDING"
103
+ }
104
+ export type FirestoreColorwaySizeAsset = {
105
+ id: number;
106
+ size_id: number;
107
+ style_id: number;
108
+ colorway_id: number;
109
+ colorway_name: string;
110
+ sku: string;
111
+ };
112
+ export type FirestoreGarmentMeasurement = {
113
+ id: number;
114
+ garment_measurement_location: string;
115
+ tolerance: number;
116
+ value: number;
117
+ };
118
+ export type FirestoreSize = {
119
+ id: number;
120
+ size: string;
121
+ label: string;
122
+ size_system: string;
123
+ size_value_id: string;
124
+ garment_measurements: Map<string, FirestoreGarmentMeasurement>;
125
+ };
126
+ export type FirestoreColorway = {
127
+ id: number;
128
+ name: string;
129
+ };
130
+ export type FirestoreStyle = {
131
+ id: number;
132
+ brand_id: number;
133
+ brand_style_id: string;
134
+ name: string;
135
+ description: string;
136
+ garment_category: string;
137
+ is_published: boolean;
138
+ sale_type: string;
139
+ colorways: {
140
+ [key: number]: FirestoreColorway;
141
+ };
142
+ sizes: {
143
+ [key: number]: FirestoreSize;
144
+ };
145
+ };
package/index.html ADDED
@@ -0,0 +1,126 @@
1
+ <html lang="en">
2
+ <head>
3
+ <title>TheFittingRoom</title>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5
+
6
+ <link href="https://fonts.googleapis.com" rel="preconnect" />
7
+ <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin />
8
+ <link
9
+ href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500&family=Roboto&display=swap"
10
+ rel="stylesheet"
11
+ />
12
+
13
+ <script type="module">
14
+ import { InitFittingRoom, InitLocale, comps } from 'http://localhost:3030/dist/esm/main.js?language=en'
15
+
16
+ InitLocale()
17
+ window.mm = comps.InitModalManager('tfr-manual-modal')
18
+ window.comps = comps
19
+ window.onSignout = (colorwaySizeAssetSKU) => {
20
+ console.log('signout', colorwaySizeAssetSKU)
21
+ }
22
+ window.onClose = () => {
23
+ console.log('close')
24
+ }
25
+ window.onNavBack = () => {
26
+ console.log('back')
27
+ }
28
+ window.onTryOn = (colorwaySizeAssetSKU) => {
29
+ console.log('try on', colorwaySizeAssetSKU)
30
+ }
31
+ window.whenSignedIn = (user, colorwaySizeAssetSKU) => {
32
+ console.log('after sign in', user, colorwaySizeAssetSKU)
33
+ }
34
+ window.onSignIn = (colorwaySizeAssetSKU) => (username, password, validationError) => {
35
+ if (username.length == 0 || password.length == 0) {
36
+ validationError('Username or password is empty')
37
+ }
38
+ }
39
+ window.onNavSignIn = (colorwaySizeAssetSKU) => (email) => {
40
+ console.log('nav sign in', colorwaySizeAssetSKU, email)
41
+ }
42
+ window.onPasswordReset = (colorwaySizeAssetSKU) => (email) => {
43
+ console.log('password reset', colorwaySizeAssetSKU, email)
44
+ }
45
+ window.onNavForgotPassword = (colorwaySizeAssetSKU) => (email) => {
46
+ console.log('nav forgot password', colorwaySizeAssetSKU, email)
47
+ }
48
+ window.onNavScanCode = () => {
49
+ console.log('nav scan code')
50
+ }
51
+
52
+ window.addEventListener('load', (e) => {
53
+ let tryOnImage = document.getElementById('tfr-tryon-image')
54
+ let signout = document.getElementById('signout')
55
+ let onChange = (slider, imageUrl) => {
56
+ tryOnImage.src = imageUrl
57
+ }
58
+ let slider = comps.InitImageSlider('tfr-slider', onChange)
59
+ let tfr = InitFittingRoom(1, 'tfr-tryon-modal')
60
+
61
+ tfr.whenFramesReady = (sku, frames) => {
62
+ console.log('frames ready', sku, frames)
63
+ slider.Load(frames)
64
+ }
65
+
66
+ signout.addEventListener('click', () => {
67
+ tfr
68
+ .onSignout('')()
69
+ .then(() => {
70
+ console.log('signout')
71
+ })
72
+ })
73
+
74
+ document.getElementById('tryon').addEventListener('click', (e) => {
75
+ tfr.TryOn('5003-007-08')
76
+ })
77
+ })
78
+ </script>
79
+ </head>
80
+
81
+ <body>
82
+ <div class="tfr-home-button-container">
83
+ <button
84
+ onclick="window.mm.Open(window.comps.ErrorModal({error: 'custom error message', onNavBack: window.onNavBack, onClose: window.onClose}))"
85
+ >
86
+ Error Modal
87
+ </button>
88
+ <br />
89
+ <button onclick="window.mm.Open(window.comps.ScanCodeModal())">Scan Code Modal</button>
90
+ <br />
91
+ <button
92
+ onclick="window.mm.Open(window.comps.SignInModal({email:'email@mail.com', onSignIn: window.onSignIn('abc'), onNavForgotPassword: window.onNavForgotPassword('123'), onNavScanCode: window.onNavScanCode}))"
93
+ >
94
+ Sign In Modal
95
+ </button>
96
+ <br />
97
+ <button
98
+ onclick="window.mm.Open(window.comps.ForgotPasswordModal({email: 'email@mail.com', onNavSignIn: window.onNavSignIn('123'), onPasswordReset: window.onPasswordReset('123')}))"
99
+ >
100
+ Forgot Password Modal
101
+ </button>
102
+ <br />
103
+ <button onclick="window.mm.Open(window.comps.NoAvatarModal({}))">No Avatar Modal</button>
104
+ <br />
105
+ <button onclick="window.mm.Open(window.comps.LoadingAvatarModal({timeoutMS: 12000}))">
106
+ Loading Avatar Modal
107
+ </button>
108
+ <br />
109
+ <button
110
+ onclick="window.mm.Open(window.comps.SizeErrorModal({onNavBack: window.onNavBack, onClose: window.onClose, sizes: {recommended: 'large', avaliable: ['small', 'medium', 'large']}}))"
111
+ >
112
+ Size Error Modal
113
+ </button>
114
+ <br />
115
+ <button onclick="window.mm.Open(window.comps.ResetLinkModal({onNavSignIn: window.onNavSignIn('abc')}))">
116
+ Reset Link Modal
117
+ </button>
118
+ <button id="tryon">Try On</button>
119
+ <button id="signout">Sign Out</button>
120
+ </div>
121
+ <div id="tfr-manual-modal"></div>
122
+ <div id="tfr-tryon-modal"></div>
123
+ <input type="range" id="tfr-slider" />
124
+ <img id="tfr-tryon-image" src="" />
125
+ </body>
126
+ </html>
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@thefittingroom/shop-ui",
3
+ "version": "0.0.1",
4
+ "description": "the fitting room UI library",
5
+ "type": "module",
6
+ "scripts": {
7
+ "clean": "rm -rf dist",
8
+ "clean:all": "rm -rf dist && rm -rf build && rm -rf .rollup.cache",
9
+ "build:prod": "npm run clean && NODE_ENV=prod rollup --config",
10
+ "build:dev": "npm run clean && NODE_ENV=dev rollup --config",
11
+ "watch:prod": "npm run clean && NODE_ENV=prod rollup --config -w",
12
+ "watch:dev": "npm run clean && NODE_ENV=dev rollup --config -w",
13
+ "serve": "live-server --host=localhost --port=3030 --cors"
14
+ },
15
+ "engines": {
16
+ "node": ">=10"
17
+ },
18
+ "dependencies": {
19
+ "@thefittingroom/sdk": "^0.0.5"
20
+ },
21
+ "devDependencies": {
22
+ "@rollup/plugin-node-resolve": "^14.1.0",
23
+ "@rollup/plugin-typescript": "^8.5.0",
24
+ "@trivago/prettier-plugin-sort-imports": "^4.1.1",
25
+ "live-server": "^1.2.2",
26
+ "prettier": "^2.8.8",
27
+ "rollup": "^2.79.1",
28
+ "rollup-plugin-dotenv": "^0.4.0",
29
+ "rollup-plugin-styles": "^4.0.0",
30
+ "rollup-plugin-terser": "^7.0.2",
31
+ "ts-node": "^9.0.0",
32
+ "tslib": "^2.4.0",
33
+ "typescript": "^4.0.2"
34
+ }
35
+ }