|
@@ -63,9 +63,37 @@ function cartReducer(state = {}, { type, count = 1, _id, name }) {
|
|
|
return state
|
|
|
}
|
|
|
|
|
|
+function authReducer(state, { type, token }) {
|
|
|
+
|
|
|
+ if (state === undefined) {
|
|
|
+ if (localStorage.authToken) {
|
|
|
+ type = "LOGIN"
|
|
|
+ token = localStorage.authToken
|
|
|
+ } else {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type === "LOGIN") {
|
|
|
+ localStorage.authToken = token
|
|
|
+ return { token, payload: jwt_decode(token) }
|
|
|
+ }
|
|
|
+ if (type === "LOGOUT") {
|
|
|
+ localStorage.removeItem("authToken")
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ return state
|
|
|
+}
|
|
|
+
|
|
|
let reducers = {
|
|
|
promise: promiseReducer,
|
|
|
- cart: cartReducer
|
|
|
+ cart: cartReducer,
|
|
|
+ auth: authReducer
|
|
|
+}
|
|
|
+
|
|
|
+let jwt_decode = (token) => {
|
|
|
+ let result = JSON.parse(atob(token.split(".")[1]))
|
|
|
+ return result
|
|
|
}
|
|
|
|
|
|
function combineReducers(reducers) {
|
|
@@ -168,6 +196,40 @@ let newOrder = async (obj) => {
|
|
|
return res
|
|
|
}
|
|
|
|
|
|
+let log = async (login, password) => {
|
|
|
+ let query = `query log($l: String, $p: String) {
|
|
|
+ login(login: $l, password: $p)
|
|
|
+ }`
|
|
|
+
|
|
|
+ let qVariables = {
|
|
|
+ "l": login,
|
|
|
+ "p": password
|
|
|
+ }
|
|
|
+
|
|
|
+ let token = await shopGQL(query, qVariables)
|
|
|
+ console.log(token)
|
|
|
+ return token.data.login
|
|
|
+}
|
|
|
+
|
|
|
+let reg = async (login, password) => {
|
|
|
+ let query = `mutation reg($l: String, $p: String) {
|
|
|
+ UserUpsert(user: {
|
|
|
+ login: $l,
|
|
|
+ password: $p
|
|
|
+ } ) {
|
|
|
+ _id
|
|
|
+ }
|
|
|
+ }`
|
|
|
+
|
|
|
+ let qVariables = {
|
|
|
+ "l": login,
|
|
|
+ "p": password
|
|
|
+ }
|
|
|
+
|
|
|
+ let res = await shopGQL(query, qVariables)
|
|
|
+ return res
|
|
|
+}
|
|
|
+
|
|
|
//actions
|
|
|
const actionPending = name => ({ type: 'PROMISE', status: 'PENDING', name })
|
|
|
const actionResolved = (name, payload) => ({ type: 'PROMISE', status: 'RESOLVED', name, payload })
|
|
@@ -209,6 +271,32 @@ const actionCartRemove = id => ({ type: "CART_REMOVE", _id: id })
|
|
|
|
|
|
const actionCartClear = () => ({ type: "CART_CLEAR" })
|
|
|
|
|
|
+const actionAuthLogin = token => ({ type: "LOGIN", token })
|
|
|
+
|
|
|
+const actionAuthLogout = () => ({ type: "LOGOUT" })
|
|
|
+
|
|
|
+const actionLogin = (login, password) => actionPromise("login", log(login, password))
|
|
|
+
|
|
|
+const actionFullLogin = (login, password) => {
|
|
|
+ return async (dispatch) => {
|
|
|
+ let result = await dispatch(actionLogin(login, password))
|
|
|
+
|
|
|
+ dispatch(actionAuthLogin(result))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const actionRegister = (login, password) => actionPromise("register", reg(login, password))
|
|
|
+
|
|
|
+const actionFullRegister = (login, password) => {
|
|
|
+ return async (dispatch) => {
|
|
|
+ let result = await dispatch(actionRegister(login, password))
|
|
|
+
|
|
|
+ if (result.data.UserUpsert !== null) {
|
|
|
+ dispatch(actionFullLogin(login, password))
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
store.dispatch(actionRootCategories())
|
|
|
|
|
|
window.onhashchange = () => {
|
|
@@ -224,6 +312,14 @@ window.onhashchange = () => {
|
|
|
if (route === 'cart') {
|
|
|
cartDraw(store.getState().cart, main)
|
|
|
}
|
|
|
+
|
|
|
+ if (route === "login") {
|
|
|
+ loginDraw(main)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (route === "registration") {
|
|
|
+ registrationDraw(main)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//рисовашки
|
|
@@ -389,10 +485,195 @@ let cartValueDraw = () => {
|
|
|
cart.lastChild.textContent = sum
|
|
|
}
|
|
|
|
|
|
+let userStatus = (parent = userpanel) => {
|
|
|
+ if (parent.children.length > 1) {
|
|
|
+ parent.lastChild.remove()
|
|
|
+ }
|
|
|
+
|
|
|
+ let status = store.getState().auth
|
|
|
+ let box = document.createElement("div")
|
|
|
+ box.style.display = "flex"
|
|
|
+ box.style.alignItems = "center"
|
|
|
+ let userName = document.createElement("span")
|
|
|
+
|
|
|
+ box.append(userName)
|
|
|
+ parent.append(box)
|
|
|
+
|
|
|
+ if (status.payload) {
|
|
|
+ let btn = document.createElement("button")
|
|
|
+ userName.textContent = status.payload.sub.login
|
|
|
+ btn.textContent = "Выход"
|
|
|
+ btn.onclick = () => {
|
|
|
+ store.dispatch(actionAuthLogout())
|
|
|
+ }
|
|
|
+ box.append(btn)
|
|
|
+ } else {
|
|
|
+ let btn = document.createElement("a")
|
|
|
+ let btnREG = document.createElement("a")
|
|
|
+ userName.textContent = "Гость"
|
|
|
+ btn.textContent = "Вход"
|
|
|
+ btnREG.textContent = "Регистрация"
|
|
|
+ btn.href = "#/login"
|
|
|
+ btnREG.href = "#/registration"
|
|
|
+
|
|
|
+ box.append(btn, btnREG)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function Form(parent, type, open) {
|
|
|
+ let h3 = document.createElement("h3");
|
|
|
+ let loginInput = document.createElement("input");
|
|
|
+ let passwordInput = document.createElement("input");
|
|
|
+ let checkbox = document.createElement("input");
|
|
|
+ let btn = document.createElement("button");
|
|
|
+ let form = document.createElement("div");
|
|
|
+ let box = document.createElement("div")
|
|
|
+ box.style.display = "flex"
|
|
|
+ box.style.alignItems = "center"
|
|
|
+ box.append(passwordInput, checkbox)
|
|
|
+ loginInput.id = "login"
|
|
|
+ loginInput.placeholder = "логин"
|
|
|
+ passwordInput.id = "password"
|
|
|
+ passwordInput.placeholder = "пароль"
|
|
|
+ btn.id = "btn"
|
|
|
+ checkbox.type = "checkbox";
|
|
|
+ checkbox.style.marginLeft = "5px"
|
|
|
+ btn.disabled = true;
|
|
|
+
|
|
|
+ if (type === "reg") {
|
|
|
+ h3.textContent = "РЕГИСТРАЦИЯ"
|
|
|
+ btn.textContent = "ЗАРЕГИСТРИРОВАТЬСЯ";
|
|
|
+ } else {
|
|
|
+ h3.textContent = "ВХОД"
|
|
|
+ btn.textContent = "Войти";
|
|
|
+ }
|
|
|
+
|
|
|
+ form.append(h3, loginInput, box, btn)
|
|
|
+ form.className = "form"
|
|
|
+ parent.append(form)
|
|
|
+
|
|
|
+ let btnOpen = () => {
|
|
|
+ if (type === "reg" && checkbox.checked === false) {
|
|
|
+ passwordInput.value !== "" && password.value === passwordVerify.value ? btn.disabled = false : btn.disabled = true;
|
|
|
+ } else {
|
|
|
+ (loginInput.value != "" && passwordInput.value != "") ? btn.disabled = false : btn.disabled = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let checker = (check) => {
|
|
|
+ if (check) {
|
|
|
+ passwordInput.type = "text";
|
|
|
+ checkbox.checked = true;
|
|
|
+
|
|
|
+ if (type === "reg" && passwordVerify) {
|
|
|
+ passwordVerify.remove()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ passwordInput.type = "password";
|
|
|
+ checkbox.checked = false;
|
|
|
+
|
|
|
+ if (type === "reg") {
|
|
|
+ let passwordInput2 = document.createElement("input");
|
|
|
+ passwordInput2.placeholder = "повторите пароль"
|
|
|
+ passwordInput2.id = "passwordVerify"
|
|
|
+ passwordInput2.type = "password"
|
|
|
+
|
|
|
+ passwordInput2.oninput = () => {
|
|
|
+ btnOpen();
|
|
|
+ }
|
|
|
+ form.append(passwordInput2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ checker(open);
|
|
|
+
|
|
|
+ loginInput.oninput = () => {
|
|
|
+ btnOpen();
|
|
|
+
|
|
|
+ if (typeof this.onChange === "function") {
|
|
|
+ this.onChange([loginInput.value, passwordInput.value]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ passwordInput.oninput = () => {
|
|
|
+ btnOpen();
|
|
|
+
|
|
|
+ if (typeof this.onChange === "function") {
|
|
|
+ this.onChange([loginInput.value, passwordInput.value]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ checkbox.onchange = () => {
|
|
|
+ checker(checkbox.checked)
|
|
|
+ btnOpen()
|
|
|
+
|
|
|
+ if (typeof this.onOpenChange === "function") {
|
|
|
+ this.onOpenChange(checkbox.checked);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.getValue = () => [loginInput.value, passwordInput.value];
|
|
|
+
|
|
|
+ this.setValue = (valueLogin, valuePassword) => {
|
|
|
+ loginInput.value = valueLogin;
|
|
|
+ passwordInput.value = valuePassword;
|
|
|
+ btnOpen();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.getOpen = () => checkbox.checked;
|
|
|
+
|
|
|
+ this.setOpen = (open) => {
|
|
|
+ checker(open);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+let loginDraw = (parent) => {
|
|
|
+ while (parent.lastChild) {
|
|
|
+ parent.lastChild.remove()
|
|
|
+ }
|
|
|
+
|
|
|
+ if (store.getState().auth.payload) {
|
|
|
+ let h2 = document.createElement("h2")
|
|
|
+ h2.textContent = "ВЫ ВОШЛИ"
|
|
|
+ h2.style.color = "grey"
|
|
|
+ parent.append(h2)
|
|
|
+ } else {
|
|
|
+ let form = new Form(parent)
|
|
|
+ btn.onclick = () => {
|
|
|
+ store.dispatch(actionFullLogin(login.value, password.value))
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+let registrationDraw = (parent) => {
|
|
|
+ while (parent.lastChild) {
|
|
|
+ parent.lastChild.remove()
|
|
|
+ }
|
|
|
+
|
|
|
+ if (store.getState().auth.payload) {
|
|
|
+ let h2 = document.createElement("h2")
|
|
|
+ h2.textContent = "ВЫ УСПЕШНО ЗАРЕГИСТРИРОВАЛИСЬ"
|
|
|
+ h2.style.color = "grey"
|
|
|
+ parent.append(h2)
|
|
|
+ } else if (store.getState().promise.register && store.getState().promise.register.status === "RESOLVED") {
|
|
|
+ let h3 = document.createElement("h3")
|
|
|
+ h3.textContent = "Error: " + store.getState().promise.register.payload.errors[0].message
|
|
|
+ h3.style.color = "red"
|
|
|
+ parent.append(h3)
|
|
|
+ } else {
|
|
|
+ let form = new Form(parent, "reg")
|
|
|
+
|
|
|
+ btn.onclick = () => {
|
|
|
+ store.dispatch(actionFullRegister(login.value, password.value))
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//subscribers
|
|
|
const unsubscribe1 = store.subscribe(() => console.log(store.getState()))
|
|
|
store.subscribe(drawMainMenu)
|
|
|
store.subscribe(cartValueDraw)
|
|
|
+store.subscribe(userStatus)
|
|
|
|
|
|
store.subscribe(() => {
|
|
|
const { 1: route, 2: id } = location.hash.split('/')
|
|
@@ -426,4 +707,10 @@ store.subscribe(() => {
|
|
|
if (route === 'cart') {
|
|
|
cartDraw(store.getState().cart, main)
|
|
|
}
|
|
|
+ if (route === 'login') {
|
|
|
+ loginDraw(main)
|
|
|
+ }
|
|
|
+ if (route === "registration") {
|
|
|
+ registrationDraw(main)
|
|
|
+ }
|
|
|
})
|