diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 6f61ac5..0426c1d 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -1,15 +1,70 @@ import api, {client} from "@/api" import store from "@/store"; +import { hasError } from "@/utils"; const login = async (username: string, password: string): Promise => { - return api({ - url: "login", - method: "post", - data: { - username, - password + let token = '' + try { + const resp = await api({ + url: "login", + method: "post", + data: { + username, + password + } + }) as any; + + if(!hasError(resp) && resp.data.token) { + token = resp.data.token + } else { + throw "Sorry, login failed. Please try again"; } - }); + } catch(err) { + return Promise.reject(err); + } + return Promise.resolve(token) +} + +const getUserProfile = async (token: any): Promise => { + const baseURL = store.getters["user/getBaseUrl"]; + try { + const resp = await client({ + url: "user/profile", + method: "GET", + baseURL, + headers: { + "api_key": token, + "Content-Type": "application/json" + } + }); + if(hasError(resp)) throw "Error getting user profile"; + return Promise.resolve(resp.data) + } catch(error: any) { + return Promise.reject(error) + } +} + +const getEComStores = async (token: any): Promise => { + try { + const baseURL = store.getters["user/getBaseUrl"]; + const resp = await client({ + url: "user/productStore", + method: "GET", + baseURL, + headers: { + "api_key": token, + "Content-Type": "application/json" + } + }); + // Disallow login if the user is not associated with any product store + if (hasError(resp) || resp.data.length === 0) { + throw resp.data; + } else { + return Promise.resolve(resp.data); + } + } catch(error: any) { + return Promise.reject(error) + } } const getAvailableTimeZones = async (): Promise => { @@ -39,8 +94,10 @@ const checkPermission = async (payload: any): Promise => { } export const UserService = { - login, + checkPermission, getAvailableTimeZones, + getEComStores, + getUserProfile, + login, setUserTimeZone, - checkPermission } \ No newline at end of file diff --git a/src/store/modules/user/UserState.ts b/src/store/modules/user/UserState.ts index 73ef910..496544a 100644 --- a/src/store/modules/user/UserState.ts +++ b/src/store/modules/user/UserState.ts @@ -1,6 +1,6 @@ export default interface UserState { token: string; current: object | null; - currentFacility: object; instanceUrl: string; + currentEComStore: object | null, } \ No newline at end of file diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts index a83cc20..0b5f043 100644 --- a/src/store/modules/user/actions.ts +++ b/src/store/modules/user/actions.ts @@ -10,55 +10,41 @@ import logger from "@/logger" const actions: ActionTree = { /** - * Login user and return token - */ + * Login user and return token + */ async login({ commit }, { username, password }) { try { - // TODO: implement support for fetching user-profile // TODO: implement support for permission check - // TODO: implement support for fetching product stores for user - const resp = await UserService.login(username, password) - if (resp.status === 200 && resp.data) { - if (resp.data.token) { - commit(types.USER_TOKEN_CHANGED, { newToken: resp.data.token }) - return resp.data; - } else if (hasError(resp)) { - showToast(translate("Sorry, your username or password is incorrect. Please try again.")); - logger.error("error", resp.data._ERROR_MESSAGE_); - return Promise.reject(new Error(resp.data._ERROR_MESSAGE_)); - } - } else { - showToast(translate("Something went wrong")); - logger.error("error", resp.data._ERROR_MESSAGE_); - return Promise.reject(new Error(resp.data._ERROR_MESSAGE_)); - } + const token = await UserService.login(username, password) + + const userProfile = await UserService.getUserProfile(token); + + // Check if we need to fetch only associated product stores of user + userProfile.stores = await UserService.getEComStores(token); + + commit(types.USER_TOKEN_CHANGED, { newToken: token }) + commit(types.USER_INFO_UPDATED, userProfile); + commit(types.USER_CURRENT_ECOM_STORE_UPDATED, userProfile.stores.length ? userProfile.stores[0] : {}); + return Promise.resolve({ token }) } catch (err: any) { - showToast(translate("Something went wrong")); + showToast(translate(err)); logger.error("error", err); return Promise.reject(new Error(err)) } }, /** - * Logout user - */ - async logout ({ commit }) { + * Logout user + */ + async logout({ commit }) { // TODO add any other tasks if need commit(types.USER_END_SESSION) - - }, - - /** - * update current facility information - */ - async setFacility ({ commit }, payload) { - commit(types.USER_CURRENT_FACILITY_UPDATED, payload.facility); }, /** - * Update user timeZone - */ - async setUserTimeZone ( { state, commit }, payload) { + * Update user timeZone + */ + async setUserTimeZone({ state, commit }, payload) { const resp = await UserService.setUserTimeZone(payload) if (resp.status === 200 && !hasError(resp)) { const current: any = state.current; @@ -69,10 +55,18 @@ const actions: ActionTree = { }, /** - * Set User Instance Url - */ - setUserInstanceUrl ({ commit }, payload){ + * Set User Instance Url + */ + setUserInstanceUrl({ commit }, payload) { commit(types.USER_INSTANCE_URL_UPDATED, payload) + }, + + setEcomStore({ commit, state }, payload) { + let productStore = payload.productStore; + if(!productStore) { + productStore = (state.current as any).stores.find((store: any) => store.productStoreId === payload.productStoreId); + } + commit(types.USER_CURRENT_ECOM_STORE_UPDATED, productStore); } } diff --git a/src/store/modules/user/getters.ts b/src/store/modules/user/getters.ts index d83899d..7e2c3e6 100644 --- a/src/store/modules/user/getters.ts +++ b/src/store/modules/user/getters.ts @@ -3,24 +3,29 @@ import UserState from "./UserState" import RootState from "@/store/RootState" const getters: GetterTree = { - isAuthenticated (state) { + isAuthenticated(state) { return !!state.token; }, isUserAuthenticated(state) { return state.token && state.current }, - getUserToken (state) { + getUserToken(state) { return state.token }, - getUserProfile (state) { + getUserProfile(state) { return state.current }, - getCurrentFacility (state){ - return state.currentFacility; - }, - getInstanceUrl (state) { + getInstanceUrl(state) { const baseUrl = process.env.VUE_APP_BASE_URL; return baseUrl ? baseUrl : state.instanceUrl; + }, + getCurrentEComStore(state) { + return state.currentEComStore + }, + getBaseUrl(state) { + let baseURL = process.env.VUE_APP_BASE_URL; + if (!baseURL) baseURL = state.instanceUrl; + return baseURL.startsWith('http') ? baseURL : `https://${baseURL}.hotwax.io/rest/s1/order-routing/`; } } export default getters; \ No newline at end of file diff --git a/src/store/modules/user/index.ts b/src/store/modules/user/index.ts index 0ce5100..6f575f4 100644 --- a/src/store/modules/user/index.ts +++ b/src/store/modules/user/index.ts @@ -10,8 +10,8 @@ const userModule: Module = { state: { token: "", current: null, - currentFacility: {}, instanceUrl: "", + currentEComStore: {} }, getters, actions, diff --git a/src/store/modules/user/mutation-types.ts b/src/store/modules/user/mutation-types.ts index 532596c..0df98ab 100644 --- a/src/store/modules/user/mutation-types.ts +++ b/src/store/modules/user/mutation-types.ts @@ -2,5 +2,5 @@ export const SN_USER = "user" export const USER_TOKEN_CHANGED = SN_USER + "/TOKEN_CHANGED" export const USER_END_SESSION = SN_USER + "/END_SESSION" export const USER_INFO_UPDATED = SN_USER + "/INFO_UPDATED" -export const USER_CURRENT_FACILITY_UPDATED = SN_USER + "/CURRENT_FACILITY_UPDATED" -export const USER_INSTANCE_URL_UPDATED = SN_USER + "/INSTANCE_URL_UPDATED" \ No newline at end of file +export const USER_INSTANCE_URL_UPDATED = SN_USER + "/INSTANCE_URL_UPDATED" +export const USER_CURRENT_ECOM_STORE_UPDATED = SN_USER + '/CURRENT_ECOM_STORE_UPDATED' \ No newline at end of file diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts index 5811c81..a4f5e12 100644 --- a/src/store/modules/user/mutations.ts +++ b/src/store/modules/user/mutations.ts @@ -9,16 +9,16 @@ const mutations: MutationTree = { [types.USER_END_SESSION] (state) { state.token = "" state.current = null - state.currentFacility = {} + state.currentEComStore = {} }, [types.USER_INFO_UPDATED] (state, payload) { state.current = payload }, - [types.USER_CURRENT_FACILITY_UPDATED] (state, payload) { - state.currentFacility = payload; - }, [types.USER_INSTANCE_URL_UPDATED] (state, payload) { state.instanceUrl = payload; + }, + [types.USER_CURRENT_ECOM_STORE_UPDATED] (state, payload) { + state.currentEComStore = payload; } } export default mutations; \ No newline at end of file diff --git a/src/views/Settings.vue b/src/views/Settings.vue index 0fe6193..69db17e 100644 --- a/src/views/Settings.vue +++ b/src/views/Settings.vue @@ -2,106 +2,149 @@ - - {{ $t("Settings") }} + + {{ "Settings" }} - - - - {{ $t("Store") }} - - {{ facility.name }} - - - - - - {{ $t("OMS") }} -

{{ instanceUrl }}

-
- - - - {{ userProfile && userProfile.userTimeZone ? userProfile.userTimeZone : "-" }} - {{ $t("Change") }} - - - - - {{ userProfile !== null ? userProfile.partyName : "" }} - {{ $t("Logout") }} - + +
+

{{ "OMS" }}

+
+
+ + + + {{ "Product Store" }} + + + {{ "Store" }} + + + + {{ "A store repesents a company or a unique catalog of products. If your OMS is connected to multiple eCommerce stores sellling different collections of products, you may have multiple Product Stores set up in HotWax Commerce." }} + + + + {{ store.storeName }} + + + +
+
+
+

+ {{ "App" }} +

{{ "Version: " + appVersion }}

+

+

{{ "Built: " + getDateTime(appInfo.builtTime) }}

+
+
+ + + + {{ "Timezone" }} + + + + {{ "The timezone you select is used to ensure automations you schedule are always accurate to the time you select." }} + + + {{ userProfile && userProfile.timeZone ? userProfile.timeZone : "-" }} + {{ "Change" }} + + +
- + +