diff --git a/src/uxbox/data/forms.cljs b/src/uxbox/data/forms.cljs index 3b643e61c..357ad2723 100644 --- a/src/uxbox/data/forms.cljs +++ b/src/uxbox/data/forms.cljs @@ -31,9 +31,11 @@ (defrecord AssignFieldValue [type field value] rs/UpdateEvent (-apply-update [_ state] - (-> state - (assoc-in [:forms type field] value) - (update-in [:errors type] dissoc field)))) + (let [form-path (into [:forms type] (if (coll? field) field [field])) + errors-path (into [:errors type] (if (coll? field) field [field]))] + (-> state + (assoc-in form-path value) + (update-in errors-path dissoc field))))) (defn assign-field-value [type field value] diff --git a/src/uxbox/data/users.cljs b/src/uxbox/data/users.cljs index 962c91bca..05d3d95ad 100644 --- a/src/uxbox/data/users.cljs +++ b/src/uxbox/data/users.cljs @@ -44,13 +44,26 @@ (defrecord UpdateProfile [data] rs/WatchEvent (-apply-watch [_ state s] - (->> (rp/req :update/profile data) - (rx/map :payload) - (rx/map profile-fetched)))) + (letfn [(on-error [{payload :payload}] + (->> (:payload payload) + (udf/assign-errors :profile/main) + (rx/of)))] + (->> (rp/req :update/profile data) + (rx/map :payload) + (rx/map profile-fetched) + (rx/catch rp/client-error? on-error))))) + +(def update-profile-schema + {:fullname [sc/required sc/string] + :email [sc/required sc/email] + :username [sc/required sc/string]}) (defn update-profile [data] - (UpdateProfile. data)) + (let [[errors data] (sc/validate data update-profile-schema)] + (if errors + (udf/assign-errors :profile/main errors) + (UpdateProfile. data)))) ;; --- Password Updated @@ -67,7 +80,7 @@ [] (PasswordUpdated.)) -;; --- Update Password +;; --- Update Password (Form) (defrecord UpdatePassword [data] rs/WatchEvent @@ -82,8 +95,7 @@ (rx/map password-updated) (rx/catch rp/client-error? on-error)))))) - -(def ^:private update-password-schema +(def update-password-schema [[:password-1 sc/required sc/string [sc/min-len 6]] [:password-2 sc/required sc/string [sc/identical-to :password-1 :message "errors.form.password-not-match"]] diff --git a/src/uxbox/schema.cljs b/src/uxbox/schema.cljs index 0f3769df1..a5f661c2b 100644 --- a/src/uxbox/schema.cljs +++ b/src/uxbox/schema.cljs @@ -41,7 +41,7 @@ (def integer-str st/integer-str) (def number-str st/number-str) ;; (def boolean-like st/boolean-like) -;; (def email st/email) +(def email st/email) ;; (def function st/function) ;; (def positive st/positive) ;; (def validate st/validate) @@ -74,9 +74,7 @@ ([data schema] (validate data schema nil)) ([data schema opts] - (let [opts (merge {:strip true} - opts)] - (st/validate data schema opts)))) + (st/validate data schema opts))) (defn validate! ([data schema] diff --git a/src/uxbox/ui/settings/profile.cljs b/src/uxbox/ui/settings/profile.cljs index bc54203cf..92d3eff7a 100644 --- a/src/uxbox/ui/settings/profile.cljs +++ b/src/uxbox/ui/settings/profile.cljs @@ -10,18 +10,33 @@ [rum.core :as rum] [cuerdas.core :as str] [lentes.core :as l] + [uxbox.schema :as sc] [uxbox.router :as r] [uxbox.state :as st] [uxbox.rstore :as rs] [uxbox.ui.icons :as i] [uxbox.ui.mixins :as mx] + [uxbox.ui.forms :as forms] [uxbox.ui.dashboard.header :refer (header)] + [uxbox.ui.messages :as uum] [uxbox.data.users :as udu] + [uxbox.data.forms :as udf] [uxbox.util.dom :as dom])) -;; --- Lentes +;; --- Profile Form -(def ^:const ^:private profile-l +(def formdata + (-> (l/in [:forms :profile/main]) + (l/focus-atom st/state))) + +(def formerrors + (-> (l/in [:errors :profile/main]) + (l/focus-atom st/state))) + +(def assign-field-value + (partial udf/assign-field-value :profile/main)) + +(def ^:private profile-l (-> (l/key :profile) (l/focus-atom st/state))) @@ -29,43 +44,53 @@ (defn profile-form-render [own] - (let [local (:rum/local own) - profile (merge (rum/react profile-l) - (deref local)) - theme (get-in profile [:metadata :theme] "light")] - (letfn [(on-theme-change [event] + (let [form (merge (rum/react profile-l) + (rum/react formdata)) + errors (rum/react formerrors) + valid? (sc/valid? form udu/update-profile-schema) + theme (get-in form [:metadata :theme] "light")] + + (letfn [(on-change [field event] (let [value (dom/event->value event)] - (println "on-theme-change" value) - (swap! local assoc-in [:metadata :theme] value))) - (on-field-change [field event] - (let [value (dom/event->value event)] - (swap! local assoc field value))) + (rs/emit! (assign-field-value field value)))) + + ;; (on-theme-change [event] + ;; (let [value (dom/event->value event)] + ;; (println "on-theme-change" value) + ;; (swap! local assoc-in [:metadata :theme] value))) + + (on-submit [event] - (rs/emit! (udu/update-profile profile)))] + ;; (println form) + (rs/emit! (udu/update-profile form)))] (html [:form.profile-form [:span.user-settings-label "Name, username and email"] [:input.input-text {:type "text" - :on-change (partial on-field-change :fullname) - :value (:fullname profile "") + :on-change (partial on-change :fullname) + :value (:fullname form "") :placeholder "Your name"}] + (forms/input-error errors :fullname) [:input.input-text {:type "text" - :on-change (partial on-field-change :username) - :value (:username profile "") + :on-change (partial on-change :username) + :value (:username form "") :placeholder "Your username"}] + (forms/input-error errors :username) + [:input.input-text {:type "email" - :on-change (partial on-field-change :email) - :value (:email profile "") + :on-change (partial on-change :email) + :value (:email form "") :placeholder "Your email"}] + (forms/input-error errors :email) [:span.user-settings-label "Choose a color theme"] [:div.input-radio.radio-primary [:input {:type "radio" :checked (= theme "light") - :on-change on-theme-change + :on-change (partial on-change [:metadata :theme]) :id "light-theme" :name "theme" :value "light"}] @@ -73,7 +98,7 @@ [:input {:type "radio" :checked (= theme "dark") - :on-change on-theme-change + :on-change (partial on-change [:metadata :theme]) :id "dark-theme" :name "theme" :value "dark"}] @@ -81,7 +106,7 @@ [:input {:type "radio" :checked (= theme "high-contrast") - :on-change on-theme-change + :on-change (partial on-change [:metadata :theme]) :id "high-contrast-theme" :name "theme" :value "high-contrast"}] @@ -89,6 +114,8 @@ [:input.btn-primary {:type "button" + :class (when-not valid? "btn-disabled") + :disabled (not valid?) :on-click on-submit :value "Update settings"}]])))) @@ -105,6 +132,7 @@ (html [:main.dashboard-main (header) + (uum/messages) [:section.dashboard-content.user-settings [:div.user-settings-nav [:ul.user-settings-nav-inside