🚧 Initial work on password recovery and register refactor.

This commit is contained in:
Andrey Antukh 2020-01-13 23:52:31 +01:00
parent bd5f25eabf
commit 9e68041326
28 changed files with 607 additions and 561 deletions

View file

@ -2,6 +2,9 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
(ns ^:figwheel-hooks uxbox.main

View file

@ -2,7 +2,10 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.data.auth
(:require
@ -10,7 +13,7 @@
[beicon.core :as rx]
[potok.core :as ptk]
[uxbox.common.spec :as us]
[uxbox.main.repo :as rp]
[uxbox.main.repo.core :as rp]
[uxbox.main.store :refer [initial-state]]
[uxbox.main.data.users :as du]
[uxbox.util.messages :as um]
@ -57,8 +60,7 @@
:password password
:scope "webapp"}
on-error #(rx/of (um/error (tr "errors.auth.unauthorized")))]
(->> (rp/req :auth/login params)
(rx/map :payload)
(->> (rp/mutation :login params)
(rx/map logged-in)
(rx/catch rp/client-error? on-error))))))
@ -72,7 +74,7 @@
ptk/WatchEvent
(watch [_ state s]
(->> (rp/req :auth/logout)
(->> (rp/mutation :logout)
(rx/ignore)))
ptk/EffectEvent
@ -84,12 +86,12 @@
(ptk/reify ::logout
ptk/WatchEvent
(watch [_ state s]
(rx/of (rt/nav :auth/login)
(rx/of (rt/nav :login)
clear-user-data))))
;; --- Register
(s/def ::register-params
(s/def ::register
(s/keys :req-un [::fullname
::username
::password
@ -98,84 +100,53 @@
(defn register
"Create a register event instance."
[data on-error]
(us/assert ::register-params data)
(us/assert fn? on-error)
(s/assert ::register data)
(s/assert fn? on-error)
(ptk/reify ::register
ptk/WatchEvent
(watch [_ state stream]
(letfn [(handle-error [{payload :payload}]
(on-error payload)
(rx/empty))]
(rx/merge
(->> (rp/req :auth/register data)
(rx/map :payload)
(rx/map (constantly ::registered))
(rx/catch rp/client-error? handle-error))
(->> stream
(rx/filter #(= % ::registered))
(rx/take 1)
(rx/map #(login data))))))))
(->> (rp/mutation :register-profile data)
(rx/map (fn [_] (login data)))
(rx/catch rp/client-error? handle-error))))))
;; --- Recovery Request
(s/def ::recovery-request-params
(s/def ::recovery-request
(s/keys :req-un [::username]))
(defn recovery-request
[data]
(us/assert ::recovery-request-params data)
(ptk/reify ::recover-request
(defn request-profile-recovery
[data on-success]
(us/assert ::recovery-request data)
(us/assert fn? on-success)
(ptk/reify ::request-profile-recovery
ptk/WatchEvent
(watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(println "on-error" payload)
(rx/empty))]
(rx/merge
(->> (rp/req :auth/recovery-request data)
(rx/map (constantly ::recovery-requested))
(rx/catch rp/client-error? on-error))
(->> stream
(rx/filter #(= % ::recovery-requested))
(rx/take 1)
;; TODO: this should be moved to the UI part
(rx/map #(um/info (tr "auth.message.recovery-token-sent")))))))))
;; --- Check Recovery Token
(defrecord ValidateRecoveryToken [token]
ptk/WatchEvent
(watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(rx/of
(rt/navigate :auth/login)
(um/error (tr "errors.auth.invalid-recovery-token"))))]
(->> (rp/req :auth/validate-recovery-token token)
(rx/ignore)
(rx/catch rp/client-error? on-error)))))
(defn validate-recovery-token
[token]
{:pre [(string? token)]}
(ValidateRecoveryToken. token))
(->> (rp/mutation :request-profile-recovery data)
(rx/tap on-success)
(rx/catch rp/client-error? on-error))))))
;; --- Recovery (Password)
(s/def ::token string?)
(s/def ::recovery-params
(s/keys :req-un [::username ::token]))
(s/def ::on-error fn?)
(s/def ::on-success fn?)
(defn recovery
[{:keys [token password] :as data}]
(us/assert ::recovery-params data)
(ptk/reify ::recovery
(s/def ::recover-profile
(s/keys :req-un [::password ::token ::on-error ::on-success]))
(defn recover-profile
[{:keys [token password on-error on-success] :as data}]
(us/assert ::recover-profile data)
(ptk/reify ::recover-profile
ptk/WatchEvent
(watch [_ state stream]
(letfn [(on-error [{payload :payload}]
(rx/of (um/error (tr "errors.auth.invalid-recovery-token"))))
(on-success [{payload :payload}]
(rx/of
(rt/navigate :auth/login)
(um/info (tr "auth.message.password-recovered"))))]
(->> (rp/req :auth/recovery {:token token :password password})
(rx/mapcat on-success)
(rx/catch rp/client-error? on-error))))))
(->> (rp/mutation :recover-profile {:token token :password password})
(rx/tap on-success)
(rx/catch (fn [err]
(on-error)
(rx/empty)))))))

View file

@ -133,3 +133,24 @@
(.append form (name key) val))
(seq params))
(send-mutation! id form)))
(defmethod mutation :login
[id params]
(let [url (str url "/login")]
(->> (impl-send {:method :post :url url :body params})
(rx/map conditional-decode)
(rx/mapcat handle-response))))
(defmethod mutation :logout
[id params]
(let [url (str url "/logout")]
(->> (impl-send {:method :post :url url :body params :auth false})
(rx/map conditional-decode)
(rx/mapcat handle-response))))
;; (defmethod mutation :register-profile
;; [id params]
;; (let [url (str url "/register")]
;; (->> (impl-send {:method :post :url url :body params :auth false})
;; (rx/map conditional-decode)
;; (rx/mapcat handle-response))))

View file

@ -2,6 +2,9 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
@ -16,7 +19,11 @@
[uxbox.main.data.auth :refer [logout]]
[uxbox.main.data.projects :as dp]
[uxbox.main.store :as st]
[uxbox.main.ui.auth :as auth]
[uxbox.main.ui.login :refer [login-page]]
[uxbox.main.ui.profile.register :refer [profile-register-page]]
[uxbox.main.ui.profile.recovery-request :refer [profile-recovery-request-page]]
[uxbox.main.ui.profile.recovery :refer [profile-recovery-page]]
[uxbox.main.ui.dashboard :as dashboard]
[uxbox.main.ui.settings :as settings]
[uxbox.main.ui.shapes]
@ -29,14 +36,18 @@
[uxbox.util.router :as rt]
[uxbox.util.timers :as ts]))
(def route-iref
(-> (l/key :route)
(l/derive st/state)))
;; --- Routes
(def routes
[["/auth"
["/login" :auth/login]
["/register" :auth/register]
["/recovery/request" :auth/recovery-request]
["/recovery/token/:token" :auth/recovery]]
[["/login" :login]
["/profile"
["/register" :profile-register]
["/recovery/request" :profile-recovery-request]
["/recovery" :profile-recovery]]
["/settings"
["/profile" :settings/profile]
@ -51,58 +62,15 @@
["/workspace/:file-id" :workspace]])
;; --- Error Handling
(defn- on-error
"A default error handler."
[{:keys [type code] :as error}]
(reset! st/loader false)
(cond
(and (map? error)
(= :validation type)
(= :spec-validation code))
(do
(println "============ SERVER RESPONSE ERROR ================")
(println (:explain error))
(println "============ END SERVER RESPONSE ERROR ================"))
;; Unauthorized or Auth timeout
(and (map? error)
(= :authentication type)
(= :unauthorized code))
(ts/schedule 0 #(st/emit! (rt/nav :auth/login)))
;; Network error
(and (map? error)
(= :unexpected type)
(= :abort code))
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.network"))))
;; Something else
:else
(do
(js/console.error error)
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.generic")))))))
(set! st/*on-error* on-error)
;; --- Main App (Component)
(def route-iref
(-> (l/key :route)
(l/derive st/state)))
(mf/defc app
[props]
(let [route (mf/deref route-iref)]
(case (get-in route [:data :name])
:auth/login (mf/element auth/login-page)
:auth/register (mf/element auth/register-page)
:login (mf/element login-page)
;; :auth/recovery-request (auth/recovery-request-page)
;; :auth/recovery
;; (let [token (get-in route [:params :path :token])]
;; (auth/recovery-page token))
:profile-register (mf/element profile-register-page)
:profile-recovery-request (mf/element profile-recovery-request-page)
:profile-recovery (mf/element profile-recovery-page)
(:settings/profile
:settings/password
@ -125,3 +93,37 @@
:key file-id}])
nil)))
;; --- Error Handling
(defn- on-error
"A default error handler."
[{:keys [type code] :as error}]
(reset! st/loader false)
(cond
(and (map? error)
(= :validation type)
(= :spec-validation code))
(do
(println "============ SERVER RESPONSE ERROR ================")
(println (:explain error))
(println "============ END SERVER RESPONSE ERROR ================"))
;; Unauthorized or Auth timeout
(and (map? error)
(= :authentication type)
(= :unauthorized code))
(ts/schedule 0 #(st/emit! (rt/nav :login)))
;; Network error
(and (map? error)
(= :unexpected type)
(= :abort code))
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.network"))))
;; Something else
:else
(do
(js/console.error error)
(ts/schedule 100 #(st/emit! (uum/error (tr "errors.generic")))))))
(set! st/*on-error* on-error)

View file

@ -1,16 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.ui.auth
(:require [uxbox.main.ui.auth.login :as login]
[uxbox.main.ui.auth.register :as register]
#_[uxbox.main.ui.auth.recovery-request :as recovery-request]
#_[uxbox.main.ui.auth.recovery :as recovery]))
(def login-page login/login-page)
(def register-page register/register-page)
;; (def recovery-page recovery/recovery-page)
;; (def recovery-request-page recovery-request/recovery-request-page)

View file

@ -1,82 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.main.ui.auth.recovery
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[lentes.core :as l]
[rumext.core :as mx :include-macros true]
[uxbox.builtins.icons :as i]
[uxbox.main.data.auth :as uda]
[uxbox.main.store :as st]
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.navigation :as nav]
[uxbox.util.dom :as dom]
[uxbox.util.forms :as fm]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.router :as rt]))
;; (def form-data (fm/focus-data :recovery st/state))
;; (def form-errors (fm/focus-errors :recovery st/state))
;; (def assoc-value (partial fm/assoc-value :recovery))
;; (def assoc-errors (partial fm/assoc-errors :recovery))
;; (def clear-form (partial fm/clear-form :recovery))
;; ;; --- Recovery Form
;; (s/def ::password ::fm/non-empty-string)
;; (s/def ::recovery-form
;; (s/keys :req-un [::password]))
;; (mx/defc recovery-form
;; {:mixins [mx/static mx/reactive]}
;; [token]
;; (let [data (merge (mx/react form-data) {:token token})
;; valid? (fm/valid? ::recovery-form data)]
;; (letfn [(on-change [field event]
;; (let [value (dom/event->value event)]
;; (st/emit! (assoc-value field value))))
;; (on-submit [event]
;; (dom/prevent-default event)
;; (st/emit! (uda/recovery data)
;; (clear-form)))]
;; [:form {:on-submit on-submit}
;; [:div.login-content
;; [:input.input-text
;; {:name "password"
;; :value (:password data "")
;; :on-change (partial on-change :password)
;; :placeholder (tr "recover.password.placeholder")
;; :type "password"}]
;; [:input.btn-primary
;; {:name "login"
;; :class (when-not valid? "btn-disabled")
;; :disabled (not valid?)
;; :value (tr "recover.recover-password")
;; :type "submit"}]
;; [:div.login-links
;; [:a {:on-click #(st/emit! (rt/navigate :auth/login))} (tr "recover.go-back")]]]])))
;; ;; --- Recovery Page
;; (defn- recovery-page-init
;; [own]
;; (let [[token] (::mx/args own)]
;; (st/emit! (uda/validate-recovery-token token))
;; own))
;; (mx/defc recovery-page
;; {:mixins [mx/static (fm/clear-mixin st/store :recovery)]
;; :init recovery-page-init}
;; [token]
;; [:div.login
;; [:div.login-body
;; (messages-widget)
;; [:a i/logo]
;; (recovery-form token)]])

View file

@ -1,71 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.auth.recovery-request
(:require [cljs.spec.alpha :as s :include-macros true]
[lentes.core :as l]
[cuerdas.core :as str]
[uxbox.builtins.icons :as i]
[uxbox.main.store :as st]
[uxbox.main.data.auth :as uda]
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.navigation :as nav]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.dom :as dom]
[uxbox.util.forms :as fm]
[rumext.core :as mx :include-macros true]
[uxbox.util.router :as rt]))
;; (def form-data (fm/focus-data :recovery-request st/state))
;; (def form-errors (fm/focus-errors :recovery-request st/state))
;; (def assoc-value (partial fm/assoc-value :profile-password))
;; (def assoc-errors (partial fm/assoc-errors :profile-password))
;; (def clear-form (partial fm/clear-form :profile-password))
;; (s/def ::username ::fm/non-empty-string)
;; (s/def ::recovery-request-form (s/keys :req-un [::username]))
;; (mx/defc recovery-request-form
;; {:mixins [mx/static mx/reactive]}
;; []
;; (let [data (mx/react form-data)
;; valid? (fm/valid? ::recovery-request-form data)]
;; (letfn [(on-change [event]
;; (let [value (dom/event->value event)]
;; (st/emit! (assoc-value :username value))))
;; (on-submit [event]
;; (dom/prevent-default event)
;; (st/emit! (uda/recovery-request data)
;; (clear-form)))]
;; [:form {:on-submit on-submit}
;; [:div.login-content
;; [:input.input-text
;; {:name "username"
;; :value (:username data "")
;; :on-change on-change
;; :placeholder (tr "recovery-request.username-or-email.placeholder")
;; :type "text"}]
;; [:input.btn-primary
;; {:name "login"
;; :class (when-not valid? "btn-disabled")
;; :disabled (not valid?)
;; :value (tr "recovery-request.recover-password")
;; :type "submit"}]
;; [:div.login-links
;; [:a {:on-click #(st/emit! (rt/navigate :auth/login))} (tr "recovery-request.go-back")]]]])))
;; ;; --- Recovery Request Page
;; (mx/defc recovery-request-page
;; {:mixins [mx/static (fm/clear-mixin st/store :recovery-request)]}
;; []
;; [:div.login
;; [:div.login-body
;; (messages-widget)
;; [:a i/logo]
;; (recovery-request-form)]])

View file

@ -2,10 +2,13 @@
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2020 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.auth.login
(ns uxbox.main.ui.login
(:require
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]
@ -78,10 +81,10 @@
:type "submit"}]
[:div.login-links
[:a {:on-click #(st/emit! (rt/nav :auth/recovery-request))
[:a {:on-click #(st/emit! (rt/nav :profile-recovery-request))
:tab-index "5"}
(tr "auth.forgot-password")]
[:a {:on-click #(st/emit! (rt/nav :auth/register))
[:a {:on-click #(st/emit! (rt/nav :profile-register))
:tab-index "6"}
(tr "auth.no-account")]]]]))

View file

@ -0,0 +1,90 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.profile.recovery
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[lentes.core :as l]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.common.spec :as us]
[uxbox.main.data.auth :as uda]
[uxbox.main.store :as st]
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.navigation :as nav]
[uxbox.util.messages :as um]
[uxbox.util.dom :as dom]
[uxbox.util.forms :as fm]
[uxbox.util.i18n :as i18n]
[uxbox.util.router :as rt]))
(s/def ::token ::us/not-empty-string)
(s/def ::password ::us/not-empty-string)
(s/def ::recovery-form (s/keys :req-un [::token ::password]))
(mf/defc recovery-form
[]
(let [{:keys [data] :as form} (fm/use-form ::recovery-form {})
tr (i18n/use-translations)
on-success
(fn []
(st/emit! (um/info (tr "profile.recovery.password-changed"))
(rt/nav :login)))
on-error
(fn []
(st/emit! (um/error (tr "profile.recovery.invalid-token"))))
on-submit
(fn [event]
(dom/prevent-default event)
(st/emit! (uda/recover-profile (assoc (:clean-data form)
:on-error on-error
:on-success on-success))))]
[:form {:on-submit on-submit}
[:div.login-content
[:input.input-text
{:name "token"
:value (:token data "")
:class (fm/error-class form :token)
:on-blur (fm/on-input-blur form :token)
:on-change (fm/on-input-change form :token)
:placeholder (tr "profile.recovery.token")
:auto-complete "off"
:type "text"}]
[:input.input-text
{:name "password"
:value (:password data "")
:class (fm/error-class form :password)
:on-blur (fm/on-input-blur form :password)
:on-change (fm/on-input-change form :password)
:placeholder (tr "profile.recovery.password")
:type "password"}]
[:input.btn-primary
{:name "recover"
:class (when-not (:valid form) "btn-disabled")
:disabled (not (:valid form))
:value (tr "profile.recovery.submit-recover")
:type "submit"}]
[:div.login-links
[:a {:on-click #(st/emit! (rt/nav :login))}
(tr "profile.recovery.go-to-login")]]]]))
;; --- Recovery Request Page
(mf/defc profile-recovery-page
[]
[:div.login
[:div.login-body
[:& messages-widget]
[:a i/logo]
[:& recovery-form]]])

View file

@ -0,0 +1,72 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.profile.recovery-request
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[lentes.core :as l]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.common.spec :as us]
[uxbox.main.data.auth :as uda]
[uxbox.main.store :as st]
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.navigation :as nav]
[uxbox.util.messages :as um]
[uxbox.util.dom :as dom]
[uxbox.util.forms :as fm]
[uxbox.util.i18n :as i18n]
[uxbox.util.router :as rt]))
(s/def ::username ::us/not-empty-string)
(s/def ::recovery-request-form (s/keys :req-un [::username]))
(mf/defc recovery-form
[]
(let [{:keys [data] :as form} (fm/use-form ::recovery-request-form {})
tr (i18n/use-translations)
on-success
(fn []
(st/emit! (um/info (tr "profile.recovery.recovery-token-sent"))))
on-submit
(fn [event]
(dom/prevent-default event)
(st/emit! (uda/request-profile-recovery (:clean-data form) on-success)))]
[:form {:on-submit on-submit}
[:div.login-content
[:input.input-text
{:name "username"
:value (:username data "")
:class (fm/error-class form :username)
:on-blur (fm/on-input-blur form :username)
:on-change (fm/on-input-change form :username)
:placeholder (tr "profile.recovery.username-or-email")
:type "text"}]
[:input.btn-primary
{:name "login"
:class (when-not (:valid form) "btn-disabled")
:disabled (not (:valid form))
:value (tr "profile.recovery.submit-request")
:type "submit"}]
[:div.login-links
[:a {:on-click #(st/emit! (rt/nav :login))}
(tr "profile.recovery.go-to-login")]]]]))
;; --- Recovery Request Page
(mf/defc profile-recovery-request-page
[]
[:div.login
[:div.login-body
[:& messages-widget]
[:a i/logo]
[:& recovery-form]]])

View file

@ -5,7 +5,7 @@
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.auth.register
(ns uxbox.main.ui.profile.register
(:require
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
@ -69,7 +69,7 @@
:class (fm/error-class form :fullname)
:on-blur (fm/on-input-blur form :fullname)
:on-change (fm/on-input-change form :fullname)
:placeholder (tr "register.fullname.placeholder")
:placeholder (tr "profile.register.fullname")
:type "text"}]
[:& fm/field-error {:form form
@ -84,7 +84,7 @@
:on-blur (fm/on-input-blur form :username)
:on-change (fm/on-input-change form :username)
:value (:username data "")
:placeholder (tr "settings.profile.your-username")}]
:placeholder (tr "profile.register.username")}]
[:& fm/field-error {:form form
:type #{::api}
@ -98,7 +98,7 @@
:on-blur (fm/on-input-blur form :email)
:on-change (fm/on-input-change form :email)
:value (:email data "")
:placeholder (tr "settings.profile.your-email")}]
:placeholder (tr "profile.register.email")}]
[:& fm/field-error {:form form
:type #{::api}
@ -112,7 +112,7 @@
:class (fm/error-class form :password)
:on-blur (fm/on-input-blur form :password)
:on-change (fm/on-input-change form :password)
:placeholder (tr "register.password.placeholder")
:placeholder (tr "profile.register.password")
:type "password"}]
[:& fm/field-error {:form form
@ -124,15 +124,15 @@
:tab-index "5"
:class (when-not (:valid form) "btn-disabled")
:disabled (not (:valid form))
:value (tr "register.get-started")}]
:value (tr "profile.register.get-started")}]
[:div.login-links
[:a {:on-click #(st/emit! (rt/nav :auth/login))}
(tr "register.already-have-account")]]]]))
[:a {:on-click #(st/emit! (rt/nav :login))}
(tr "profile.register.already-have-account")]]]]))
;; --- Register Page
(mf/defc register-page
(mf/defc profile-register-page
[props]
[:div.login
[:div.login-body

View file

@ -42,7 +42,7 @@
[:& header-link {:section :settings/notifications
:content (tr "settings.notifications")}]]
#_[:li {:on-click #(st/emit! (da/logout))}
[:& header-link {:section :auth/login
[:& header-link {:section :logout
:content (tr "settings.exit")}]]]
[:& user]]))