mirror of
https://github.com/penpot/penpot.git
synced 2025-06-14 04:51:39 +02:00
Update profile form integration.
This commit is contained in:
parent
105f995877
commit
f7013d6e8b
9 changed files with 365 additions and 138 deletions
|
@ -16,36 +16,9 @@
|
||||||
[uxbox.schema :as sc]
|
[uxbox.schema :as sc]
|
||||||
[uxbox.locales :refer (tr)]
|
[uxbox.locales :refer (tr)]
|
||||||
[uxbox.data.projects :as dp]
|
[uxbox.data.projects :as dp]
|
||||||
|
[uxbox.data.users :as udu]
|
||||||
[uxbox.ui.messages :as uum]))
|
[uxbox.ui.messages :as uum]))
|
||||||
|
|
||||||
;; --- Profile Fetched
|
|
||||||
|
|
||||||
(defrecord ProfileFetched [data]
|
|
||||||
rs/UpdateEvent
|
|
||||||
(-apply-update [this state]
|
|
||||||
(assoc state :profile data)))
|
|
||||||
|
|
||||||
(defn profile-fetched
|
|
||||||
[data]
|
|
||||||
(ProfileFetched. data))
|
|
||||||
|
|
||||||
;; --- Fetch Profile
|
|
||||||
|
|
||||||
(defrecord FetchProfile []
|
|
||||||
rs/WatchEvent
|
|
||||||
(-apply-watch [_ state s]
|
|
||||||
(letfn [(on-error [err]
|
|
||||||
(uum/error (tr "errors.profile-fetch"))
|
|
||||||
(rx/empty))]
|
|
||||||
(->> (rp/do :fetch/profile)
|
|
||||||
(rx/catch on-error)
|
|
||||||
(rx/map :payload)
|
|
||||||
(rx/map profile-fetched)))))
|
|
||||||
|
|
||||||
(defn fetch-profile
|
|
||||||
[]
|
|
||||||
(FetchProfile.))
|
|
||||||
|
|
||||||
;; --- Logged In
|
;; --- Logged In
|
||||||
|
|
||||||
(defrecord LoggedIn [data]
|
(defrecord LoggedIn [data]
|
||||||
|
@ -85,8 +58,7 @@
|
||||||
(rx/map :payload)
|
(rx/map :payload)
|
||||||
(rx/mapcat #(rx/of (logged-in %)
|
(rx/mapcat #(rx/of (logged-in %)
|
||||||
(dp/fetch-projects)
|
(dp/fetch-projects)
|
||||||
(fetch-profile))))))))
|
(udu/fetch-profile))))))))
|
||||||
|
|
||||||
|
|
||||||
(def ^:const ^:private +login-schema+
|
(def ^:const ^:private +login-schema+
|
||||||
{:username [sc/required sc/string]
|
{:username [sc/required sc/string]
|
||||||
|
|
78
src/uxbox/data/users.cljs
Normal file
78
src/uxbox/data/users.cljs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
;; 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.data.users
|
||||||
|
(:require [beicon.core :as rx]
|
||||||
|
[promesa.core :as p]
|
||||||
|
[uxbox.repo :as rp]
|
||||||
|
[uxbox.rstore :as rs]
|
||||||
|
[uxbox.state :as st]
|
||||||
|
[uxbox.schema :as sc]
|
||||||
|
[uxbox.locales :refer (tr)]
|
||||||
|
[uxbox.ui.messages :as uum]))
|
||||||
|
|
||||||
|
;; --- Profile Fetched
|
||||||
|
|
||||||
|
(defrecord ProfileFetched [data]
|
||||||
|
rs/UpdateEvent
|
||||||
|
(-apply-update [this state]
|
||||||
|
(assoc state :profile data)))
|
||||||
|
|
||||||
|
(defn profile-fetched
|
||||||
|
[data]
|
||||||
|
(ProfileFetched. data))
|
||||||
|
|
||||||
|
;; --- Fetch Profile
|
||||||
|
|
||||||
|
(defrecord FetchProfile []
|
||||||
|
rs/WatchEvent
|
||||||
|
(-apply-watch [_ state s]
|
||||||
|
(letfn [(on-error [err]
|
||||||
|
(uum/error (tr "errors.profile-fetch"))
|
||||||
|
(rx/empty))]
|
||||||
|
(->> (rp/do :fetch/profile)
|
||||||
|
(rx/catch on-error)
|
||||||
|
(rx/map :payload)
|
||||||
|
(rx/map profile-fetched)))))
|
||||||
|
|
||||||
|
(defn fetch-profile
|
||||||
|
[]
|
||||||
|
(FetchProfile.))
|
||||||
|
|
||||||
|
;; --- Update Profile
|
||||||
|
|
||||||
|
(defrecord UpdateProfile [data]
|
||||||
|
rs/WatchEvent
|
||||||
|
(-apply-watch [_ state s]
|
||||||
|
(letfn [(on-error [err]
|
||||||
|
(uum/error (tr "errors.update-profile"))
|
||||||
|
(rx/empty))]
|
||||||
|
(->> (rp/do :update/profile data)
|
||||||
|
(rx/catch on-error)
|
||||||
|
(rx/map :payload)
|
||||||
|
(rx/map profile-fetched)))))
|
||||||
|
|
||||||
|
(defn update-profile
|
||||||
|
[data]
|
||||||
|
(UpdateProfile. data))
|
||||||
|
|
||||||
|
;; --- Update Password
|
||||||
|
|
||||||
|
(defrecord UpdatePassword [password]
|
||||||
|
rs/WatchEvent
|
||||||
|
(-apply-watch [_ state s]
|
||||||
|
;; (letfn [(on-error [err]
|
||||||
|
;; (uum/error (tr "errors.update-password"))
|
||||||
|
;; (rx/empty))]
|
||||||
|
;; (->> (rp/do :update/password data)
|
||||||
|
;; (rx/catch on-error)))))
|
||||||
|
(js/alert "Not implemented")
|
||||||
|
(rx/empty)))
|
||||||
|
|
||||||
|
(defn update-password
|
||||||
|
[password]
|
||||||
|
{:pre [(string? password)]}
|
||||||
|
(UpdatePassword. password))
|
|
@ -23,3 +23,10 @@
|
||||||
:method :post
|
:method :post
|
||||||
:auth false
|
:auth false
|
||||||
:body data})))
|
:body data})))
|
||||||
|
|
||||||
|
(defmethod -do :update/profile
|
||||||
|
[type data]
|
||||||
|
(let [params {:url (str url "/profile/me")
|
||||||
|
:method :put
|
||||||
|
:body data}]
|
||||||
|
(send! params)))
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[uxbox.router :as r]
|
[uxbox.router :as r]
|
||||||
[uxbox.rstore :as rs]
|
[uxbox.rstore :as rs]
|
||||||
[uxbox.data.projects :as dp]
|
[uxbox.data.projects :as dp]
|
||||||
[uxbox.data.auth :as uda]
|
[uxbox.data.users :as udu]
|
||||||
[uxbox.ui.lightbox :as ui-lightbox]
|
[uxbox.ui.lightbox :as ui-lightbox]
|
||||||
[uxbox.ui.auth :as ui-auth]
|
[uxbox.ui.auth :as ui-auth]
|
||||||
[uxbox.ui.dashboard :as ui-dashboard]
|
[uxbox.ui.dashboard :as ui-dashboard]
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
(defn app-will-mount
|
(defn app-will-mount
|
||||||
[own]
|
[own]
|
||||||
(when @auth-data
|
(when @auth-data
|
||||||
(rs/emit! (uda/fetch-profile)
|
(rs/emit! (udu/fetch-profile)
|
||||||
(dp/fetch-projects)))
|
(dp/fetch-projects)))
|
||||||
own)
|
own)
|
||||||
|
|
||||||
|
|
|
@ -15,111 +15,11 @@
|
||||||
[uxbox.ui.mixins :as mx]
|
[uxbox.ui.mixins :as mx]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.data.dashboard :as dd]
|
[uxbox.data.dashboard :as dd]
|
||||||
|
[uxbox.ui.settings.profile :as profile]
|
||||||
|
[uxbox.ui.settings.password :as password]
|
||||||
|
[uxbox.ui.settings.notifications :as notifications]
|
||||||
[uxbox.ui.dashboard.header :refer (header)]))
|
[uxbox.ui.dashboard.header :refer (header)]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
(def profile-page profile/profile-page)
|
||||||
;; Page: Profile
|
(def password-page password/password-page)
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
(def notifications-page notifications/notifications-page)
|
||||||
|
|
||||||
(defn profile-page-render
|
|
||||||
[own]
|
|
||||||
(html
|
|
||||||
[:main.dashboard-main
|
|
||||||
(header)
|
|
||||||
[:section.dashboard-content.user-settings
|
|
||||||
[:div.user-settings-nav
|
|
||||||
[:ul.user-settings-nav-inside
|
|
||||||
[:li.current {:on-click #(r/go :settings/profile)} "Profile"]
|
|
||||||
[:li {:on-click #(r/go :settings/password)} "Password"]
|
|
||||||
[:li {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
|
||||||
|
|
||||||
[:section.user-settings-content
|
|
||||||
[:span.user-settings-label "Your avatar"]
|
|
||||||
[:form.avatar-form
|
|
||||||
[:img {:src "images/favicon.png" :border "0"}]
|
|
||||||
[:input {:type "file"}]]
|
|
||||||
[:span.user-settings-label "Name, username and email"]
|
|
||||||
[:input.input-text {:type "text" :placeholder "Your name"}]
|
|
||||||
[:input.input-text {:type "text" :placeholder "Your username"}]
|
|
||||||
[:input.input-text {:type "email" :placeholder "Your email"}]
|
|
||||||
[:span.user-settings-label "Choose a color theme"]
|
|
||||||
[:div.input-radio.radio-primary
|
|
||||||
[:input {:type "radio" :id "light-theme" :name "light theme" :value "none"}]
|
|
||||||
[:label {:for "light-theme" :value "None"} "Light theme"]
|
|
||||||
[:input {:type "radio" :id "dark-theme" :name "dark theme" :value "every-hour"}]
|
|
||||||
[:label {:for "dark-theme" :value "Every hour"} "Dark theme"]
|
|
||||||
[:input {:type "radio" :id "contrast-theme" :name "contrast theme" :value "every-day"}]
|
|
||||||
[:label {:for "contrast-theme" :value "Every day"} "High-contrast theme"]]
|
|
||||||
[:input.btn-primary {:type "submit" :value "Update settings"}]
|
|
||||||
]]]))
|
|
||||||
|
|
||||||
(def ^:static profile-page
|
|
||||||
(mx/component
|
|
||||||
{:render profile-page-render
|
|
||||||
:name "profile-page"
|
|
||||||
:mixins [mx/static]}))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Page: password
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(defn password-page-render
|
|
||||||
[own]
|
|
||||||
(html
|
|
||||||
[:main.dashboard-main
|
|
||||||
(header)
|
|
||||||
[:section.dashboard-content.user-settings
|
|
||||||
[:div.user-settings-nav
|
|
||||||
[:ul.user-settings-nav-inside
|
|
||||||
[:li {:on-click #(r/go :settings/profile)} "Profile"]
|
|
||||||
[:li.current {:on-click #(r/go :settings/password)} "Password"]
|
|
||||||
[:li {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
|
||||||
|
|
||||||
[:section.user-settings-content
|
|
||||||
[:span.user-settings-label "Change password"]
|
|
||||||
[:input.input-text {:type "password" :placeholder "Old password"}]
|
|
||||||
[:input.input-text {:type "password" :placeholder "New password"}]
|
|
||||||
[:input.input-text {:type "password" :placeholder "Confirm password"}]
|
|
||||||
[:input.btn-primary {:type "submit" :value "Update settings"}]
|
|
||||||
]]]))
|
|
||||||
|
|
||||||
(def ^:static password-page
|
|
||||||
(mx/component
|
|
||||||
{:render password-page-render
|
|
||||||
:name "password-page"
|
|
||||||
:mixins [mx/static]}))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Page: notifications
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(defn notifications-page-render
|
|
||||||
[own]
|
|
||||||
(html
|
|
||||||
[:main.dashboard-main
|
|
||||||
(header)
|
|
||||||
[:section.dashboard-content.user-settings
|
|
||||||
[:div.user-settings-nav
|
|
||||||
[:ul.user-settings-nav-inside
|
|
||||||
[:li {:on-click #(r/go :settings/profile)} "Profile"]
|
|
||||||
[:li {:on-click #(r/go :settings/password)} "Password"]
|
|
||||||
[:li.current {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
|
||||||
|
|
||||||
[:section.user-settings-content
|
|
||||||
[:span.user-settings-label "Prototype notifications"]
|
|
||||||
[:p "Get a roll up of prototype changes in your inbox."]
|
|
||||||
[:div.input-radio.radio-primary
|
|
||||||
[:input {:type "radio" :id "notification-1" :name "notification-1" :value "none"}]
|
|
||||||
[:label {:for "notification-1" :value "None"} "None"]
|
|
||||||
[:input {:type "radio" :id "notification-2" :name "notification-2" :value "every-hour"}]
|
|
||||||
[:label {:for "notification-2" :value "Every hour"} "Every hour"]
|
|
||||||
[:input {:type "radio" :id "notification-3" :name "notification-3" :value "every-day"}]
|
|
||||||
[:label {:for "notification-3" :value "Every day"} "Every day"]]
|
|
||||||
[:input.btn-primary {:type "submit" :value "Update settings"}]
|
|
||||||
]]]))
|
|
||||||
|
|
||||||
(def ^:static notifications-page
|
|
||||||
(mx/component
|
|
||||||
{:render notifications-page-render
|
|
||||||
:name "notifications-page"
|
|
||||||
:mixins [mx/static]}))
|
|
||||||
|
|
49
src/uxbox/ui/settings/notifications.cljs
Normal file
49
src/uxbox/ui/settings/notifications.cljs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
;; 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>
|
||||||
|
;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
|
(ns uxbox.ui.settings.notifications
|
||||||
|
(:require [sablono.core :as html :refer-macros [html]]
|
||||||
|
[rum.core :as rum]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[uxbox.router :as r]
|
||||||
|
[uxbox.rstore :as rs]
|
||||||
|
[uxbox.ui.icons :as i]
|
||||||
|
[uxbox.ui.mixins :as mx]
|
||||||
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.data.dashboard :as dd]
|
||||||
|
[uxbox.ui.dashboard.header :refer (header)]))
|
||||||
|
|
||||||
|
(defn notifications-page-render
|
||||||
|
[own]
|
||||||
|
(html
|
||||||
|
[:main.dashboard-main
|
||||||
|
(header)
|
||||||
|
[:section.dashboard-content.user-settings
|
||||||
|
[:div.user-settings-nav
|
||||||
|
[:ul.user-settings-nav-inside
|
||||||
|
[:li {:on-click #(r/go :settings/profile)} "Profile"]
|
||||||
|
[:li {:on-click #(r/go :settings/password)} "Password"]
|
||||||
|
[:li.current {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
||||||
|
|
||||||
|
[:section.user-settings-content
|
||||||
|
[:span.user-settings-label "Prototype notifications"]
|
||||||
|
[:p "Get a roll up of prototype changes in your inbox."]
|
||||||
|
[:div.input-radio.radio-primary
|
||||||
|
[:input {:type "radio" :id "notification-1" :name "notification-1" :value "none"}]
|
||||||
|
[:label {:for "notification-1" :value "None"} "None"]
|
||||||
|
[:input {:type "radio" :id "notification-2" :name "notification-2" :value "every-hour"}]
|
||||||
|
[:label {:for "notification-2" :value "Every hour"} "Every hour"]
|
||||||
|
[:input {:type "radio" :id "notification-3" :name "notification-3" :value "every-day"}]
|
||||||
|
[:label {:for "notification-3" :value "Every day"} "Every day"]]
|
||||||
|
[:input.btn-primary {:type "submit" :value "Update settings"}]
|
||||||
|
]]]))
|
||||||
|
|
||||||
|
(def ^:static notifications-page
|
||||||
|
(mx/component
|
||||||
|
{:render notifications-page-render
|
||||||
|
:name "notifications-page"
|
||||||
|
:mixins [mx/static]}))
|
86
src/uxbox/ui/settings/password.cljs
Normal file
86
src/uxbox/ui/settings/password.cljs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
;; 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>
|
||||||
|
;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
|
(ns uxbox.ui.settings.password
|
||||||
|
(:require [sablono.core :as html :refer-macros [html]]
|
||||||
|
[rum.core :as rum]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[uxbox.router :as r]
|
||||||
|
[uxbox.rstore :as rs]
|
||||||
|
[uxbox.ui.icons :as i]
|
||||||
|
[uxbox.ui.mixins :as mx]
|
||||||
|
[uxbox.util.dom :as dom]
|
||||||
|
[uxbox.data.users :as udu]
|
||||||
|
[uxbox.ui.dashboard.header :refer (header)]))
|
||||||
|
|
||||||
|
;; --- Password Form
|
||||||
|
|
||||||
|
(defn password-form-render
|
||||||
|
[own]
|
||||||
|
(let [local (:rum/local own)
|
||||||
|
valid? (and (not (str/empty? (:password-1 @local)))
|
||||||
|
(not (str/empty? (:password-2 @local)))
|
||||||
|
(= 6 (count (:password-1 @local "")))
|
||||||
|
(= (:password-1 @local)
|
||||||
|
(:password-2 @local)))]
|
||||||
|
(println "valid?" valid?)
|
||||||
|
(letfn [(on-field-change [field event]
|
||||||
|
(let [value (dom/event->value event)]
|
||||||
|
(swap! local assoc field value)))
|
||||||
|
(on-submit [event]
|
||||||
|
(let [password (:password-1 @local)]
|
||||||
|
(rs/emit! (udu/update-password password))))]
|
||||||
|
|
||||||
|
(html
|
||||||
|
[:form.password-form
|
||||||
|
[:span.user-settings-label "Change password"]
|
||||||
|
#_[:input.input-text {:type "password" :placeholder "Old password"}]
|
||||||
|
[:input.input-text
|
||||||
|
{:type "password"
|
||||||
|
:value (:password-1 @local "")
|
||||||
|
:on-change (partial on-field-change :password-1)
|
||||||
|
:placeholder "New password"}]
|
||||||
|
[:input.input-text
|
||||||
|
{:type "password"
|
||||||
|
:value (:password-2 @local "")
|
||||||
|
:on-change (partial on-field-change :password-2)
|
||||||
|
:placeholder "Confirm password"}]
|
||||||
|
[:input.btn-primary
|
||||||
|
{:type "button"
|
||||||
|
:class (when-not valid? "btn-disabled")
|
||||||
|
:disabled (not valid?)
|
||||||
|
:value "Update settings"}]]))))
|
||||||
|
|
||||||
|
(def password-form
|
||||||
|
(mx/component
|
||||||
|
{:render password-form-render
|
||||||
|
:name "password-form"
|
||||||
|
:mixins [mx/static (mx/local)]}))
|
||||||
|
|
||||||
|
;; --- Password Page
|
||||||
|
|
||||||
|
(defn password-page-render
|
||||||
|
[own]
|
||||||
|
(html
|
||||||
|
[:main.dashboard-main
|
||||||
|
(header)
|
||||||
|
[:section.dashboard-content.user-settings
|
||||||
|
[:div.user-settings-nav
|
||||||
|
[:ul.user-settings-nav-inside
|
||||||
|
[:li {:on-click #(r/go :settings/profile)} "Profile"]
|
||||||
|
[:li.current {:on-click #(r/go :settings/password)} "Password"]
|
||||||
|
[:li {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
||||||
|
|
||||||
|
[:section.user-settings-content
|
||||||
|
(password-form)]]]))
|
||||||
|
|
||||||
|
(def password-page
|
||||||
|
(mx/component
|
||||||
|
{:render password-page-render
|
||||||
|
:name "password-page"
|
||||||
|
:mixins [mx/static]}))
|
||||||
|
|
127
src/uxbox/ui/settings/profile.cljs
Normal file
127
src/uxbox/ui/settings/profile.cljs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
;; 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-2016 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
|
||||||
|
|
||||||
|
(ns uxbox.ui.settings.profile
|
||||||
|
(:require [sablono.core :as html :refer-macros [html]]
|
||||||
|
[rum.core :as rum]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[lentes.core :as l]
|
||||||
|
[uxbox.router :as r]
|
||||||
|
[uxbox.state :as st]
|
||||||
|
[uxbox.rstore :as rs]
|
||||||
|
[uxbox.ui.icons :as i]
|
||||||
|
[uxbox.ui.mixins :as mx]
|
||||||
|
[uxbox.ui.dashboard.header :refer (header)]
|
||||||
|
[uxbox.data.users :as udu]
|
||||||
|
[uxbox.util.dom :as dom]))
|
||||||
|
|
||||||
|
;; --- Lentes
|
||||||
|
|
||||||
|
(def ^:const ^:private profile-l
|
||||||
|
(-> (l/key :profile)
|
||||||
|
(l/focus-atom st/state)))
|
||||||
|
|
||||||
|
;; --- Profile Form
|
||||||
|
|
||||||
|
(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 [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)))
|
||||||
|
(on-submit [event]
|
||||||
|
(rs/emit! (udu/update-profile profile)))]
|
||||||
|
(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 "")
|
||||||
|
:placeholder "Your name"}]
|
||||||
|
[:input.input-text
|
||||||
|
{:type "text"
|
||||||
|
:on-change (partial on-field-change :username)
|
||||||
|
:value (:username profile "")
|
||||||
|
:placeholder "Your username"}]
|
||||||
|
[:input.input-text
|
||||||
|
{:type "email"
|
||||||
|
:on-change (partial on-field-change :email)
|
||||||
|
:value (:email profile "")
|
||||||
|
:placeholder "Your 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
|
||||||
|
:id "light-theme"
|
||||||
|
:name "theme"
|
||||||
|
:value "light"}]
|
||||||
|
[:label {:for "light-theme"} "Light theme"]
|
||||||
|
|
||||||
|
[:input {:type "radio"
|
||||||
|
:checked (= theme "dark")
|
||||||
|
:on-change on-theme-change
|
||||||
|
:id "dark-theme"
|
||||||
|
:name "theme"
|
||||||
|
:value "dark"}]
|
||||||
|
[:label {:for "dark-theme"} "Dark theme"]
|
||||||
|
|
||||||
|
[:input {:type "radio"
|
||||||
|
:checked (= theme "high-contrast")
|
||||||
|
:on-change on-theme-change
|
||||||
|
:id "high-contrast-theme"
|
||||||
|
:name "theme"
|
||||||
|
:value "high-contrast"}]
|
||||||
|
[:label {:for "high-contrast-theme"} "High-contrast theme"]]
|
||||||
|
|
||||||
|
[:input.btn-primary
|
||||||
|
{:type "button"
|
||||||
|
:on-click on-submit
|
||||||
|
:value "Update settings"}]]))))
|
||||||
|
|
||||||
|
(def profile-form
|
||||||
|
(mx/component
|
||||||
|
{:render profile-form-render
|
||||||
|
:name "profile-form"
|
||||||
|
:mixins [(mx/local) rum/reactive mx/static]}))
|
||||||
|
|
||||||
|
;; --- Profile Page
|
||||||
|
|
||||||
|
(defn profile-page-render
|
||||||
|
[own]
|
||||||
|
(html
|
||||||
|
[:main.dashboard-main
|
||||||
|
(header)
|
||||||
|
[:section.dashboard-content.user-settings
|
||||||
|
[:div.user-settings-nav
|
||||||
|
[:ul.user-settings-nav-inside
|
||||||
|
[:li.current {:on-click #(r/go :settings/profile)} "Profile"]
|
||||||
|
[:li {:on-click #(r/go :settings/password)} "Password"]
|
||||||
|
[:li {:on-click #(r/go :settings/notifications)} "Notifications"]]]
|
||||||
|
[:section.user-settings-content
|
||||||
|
[:span.user-settings-label "Your avatar"]
|
||||||
|
[:form.avatar-form
|
||||||
|
[:img {:src "images/favicon.png" :border "0"}]
|
||||||
|
[:input {:type "file"}]]
|
||||||
|
(profile-form)
|
||||||
|
]]]))
|
||||||
|
|
||||||
|
(def profile-page
|
||||||
|
(mx/component
|
||||||
|
{:render profile-page-render
|
||||||
|
:name "profile-page"
|
||||||
|
:mixins [mx/static]}))
|
||||||
|
|
|
@ -53,6 +53,14 @@
|
||||||
value
|
value
|
||||||
item)) coll))
|
item)) coll))
|
||||||
|
|
||||||
|
|
||||||
|
(defn deep-merge
|
||||||
|
"Like merge, but merges maps recursively."
|
||||||
|
[& maps]
|
||||||
|
(if (every? map? maps)
|
||||||
|
(apply merge-with deep-merge maps)
|
||||||
|
(last maps)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Numbers Parsing
|
;; Numbers Parsing
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue