Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display and navigate b/w organisations in the sidebar #12

Merged
merged 18 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions resources/public/assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ a:hover {
margin-bottom: 0px;
}

.formbox .form-control.check-invalid:invalid {
.formbox .form-control.invalid {
border: 1px solid #ce8383;
}

.formbox .form-control:valid {
.formbox .form-control.valid {
border: 1px solid #7dc37d;
}

Expand Down Expand Up @@ -140,6 +140,12 @@ a:hover {
background: #2e3344;
transition: left 0.1s;
color: white;
overflow-y: scroll;
overflow: -moz-scrollbars-none;
}

.sidebar::-webkit-scrollbar {
width: 0 !important
}

.sidebar-logo-box {
Expand All @@ -160,15 +166,10 @@ a:hover {
margin-bottom: 4px;
}

.sidebar-section {
padding-left: 10px;
}

.sidebar-section-head {
color: white;
font-weight: bolder;
margin-bottom: 5px;
margin-top: 25px;
margin: 25px 0px 5px 8px;
}

.sidebar-section-list {
Expand All @@ -179,9 +180,19 @@ a:hover {
.sidebar-section-list > .item {
display: block;
line-height: 35px;
padding: 0 15px 0 15px;
padding: 0 15px 0 20px;
width: 100%;
text-decoration: none;
border: 2px solid transparent;
}

.sidebar-section-list .item:hover {
background: #363c4e;
}

.sidebar .item.active {
border-left: 2px solid aliceblue;
background: #404040;
}

.sidebar-section-list .item-label {
Expand All @@ -205,6 +216,7 @@ a:hover {
.sidebar-link {
color: #d5e2f1 !important;
cursor: pointer;
display: block;
}

.sidebar-link:hover {
Expand Down Expand Up @@ -256,6 +268,7 @@ a:hover {
margin-bottom: 0;
background-color: #fff;
box-shadow: 0px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
padding: 10px 10px 0 10px;
}

/* End Dashboard*/
13 changes: 9 additions & 4 deletions src/clj/villagebook/organisation/handlers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
(let [{name :name
color :color
:as orgdata} (:params request)
{user-id :id} (:identity request)]
user-id (get-in request [:identity :id])]
(if (organisation-spec/valid-organisation-details? orgdata)
(let [{neworg :success} (models/create! orgdata user-id)]
(-> (res/response neworg)
Expand All @@ -20,9 +20,9 @@

(defn- retrieve-from-model
[id]
(let [message (models/retrieve id)
{org :success} message
{error :error} message]
(let [message (models/retrieve id)
org (:success message)
error (:error message)]
(if org
(res/response org)
(res/not-found error))))
Expand All @@ -33,3 +33,8 @@
(if (s/valid? ::organisation-spec/id id)
(retrieve-from-model id)
(res/bad-request "Invalid request."))))

(defn retrieve-by-user
[request]
(let [user-id (get-in request [:identity :id])]
(res/response (:success (models/retrieve-by-user user-id)))))
4 changes: 4 additions & 0 deletions src/clj/villagebook/organisation/models.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@
(if org
{:success org}
{:error "Organisation not found"})))

(defn retrieve-by-user
[user-id]
{:success (db/retrieve-by-user user-id)})
9 changes: 5 additions & 4 deletions src/clj/villagebook/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
[villagebook.handlers :refer [api-handler frontend-handler]]
[villagebook.config :as config]))

(def apiroutes
{"organisations" {["/" :id] {:get (with-auth org/retrieve)}
:post (with-auth org/create!)}
(def api-routes
{"organisations" {:get (with-auth org/retrieve-by-user)
:post (with-auth org/create!)
["/" :id] {:get (with-auth org/retrieve)}}
"user" {:get (with-auth user/retrieve)}})


;; Setup routes
(def routes
["/" {"assets" (resources {:prefix "public/assets/"})
"api/" apiroutes
"api/" api-routes
"signup" {:post user/signup}
"login" {:post user/login}
true frontend-handler}])
4 changes: 2 additions & 2 deletions src/clj/villagebook/user/handlers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
(res/bad-request "Invalid request.")))

(defn retrieve
[{identity :identity :as request}]
(if-let [user-id (:id identity)]
[request]
(if-let [user-id (get-in request [:identity :id])]
(if-let [userdata (models/retrieve user-id)]
(res/response userdata)
(-> (res/response "Something went wrong.")
Expand Down
20 changes: 10 additions & 10 deletions src/cljs/villagebookUI/api/auth.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
(def ^:private signup-api "/signup")
(def ^:private login-api "/login")

(defn signup [userdata handler-fn error-handler-fn]
(defn signup [userdata handler error-handler]
(POST signup-api
{:params userdata
:format :raw
:handler handler-fn
:error-handler error-handler-fn}))
{:params userdata
:format :raw
:handler handler
:error-handler error-handler}))

(defn login [userdata handler-fn error-handler-fn]
(defn login [userdata handler error-handler]
(POST login-api
{:params userdata
:format :raw
:handler handler-fn
:error-handler error-handler-fn}))
{:params userdata
:format :raw
:handler handler
:error-handler error-handler}))
15 changes: 11 additions & 4 deletions src/cljs/villagebookUI/api/organisation.cljs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
(ns villagebookUI.api.organisation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitals in the ns name seems odd.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes🤷‍♂ but decided to stick with it, changing would be too much effort.

[:require [ajax.core :refer [POST]]])
[:require [ajax.core :refer [GET POST]]])

(def ^:private create-org-api "/api/organisations")
(def ^:private get-all-orgs-api "/api/organisations")

(defn create-org [org-data handler-fn error-handler-fn]
(defn create [org-data handler error-handler]
(POST create-org-api
{:params org-data
:format :raw
:handler handler-fn
:error-handler error-handler-fn}))
:handler handler
:error-handler error-handler}))

(defn get-all [handler error-handler]
(GET get-all-orgs-api
{:handler handler
:response-format :json
:error-handler error-handler}))
11 changes: 6 additions & 5 deletions src/cljs/villagebookUI/api/user.cljs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
(ns villagebookUI.api.user
[:require [ajax.core :refer [GET]]])
(:require [ajax.core :refer [GET]]
[villagebookUI.store.user :as store]))

(def ^:private get-user-data-api "/api/user")

(defn get-user-data
[handler-fn error-handler-fn]
(defn get-data [handler error-handler finally-fn]
(GET get-user-data-api
{:handler handler-fn
:error-handler error-handler-fn}))
{:handler handler
:error-handler error-handler
:finally finally-fn}))
19 changes: 14 additions & 5 deletions src/cljs/villagebookUI/components/create_org.cljs
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
(ns villagebookUI.components.create-org
(:require [reagent.core :as r]
[villagebookUI.helpers :refer [random-color handle-esc]]
[villagebookUI.fetchers :as fetchers]
[villagebookUI.components.utils :as utils]
[villagebookUI.api.organisation :as org]))
[villagebookUI.api.organisation :as org-api]))

(defn- create-org [form success-handler error-handler]
(when (:name form)
(org/create-org form
(org-api/create form
success-handler
error-handler)))

(defn submit-create-org!
[org success-handler error-handler]
(create-org org
(fn [res]
(success-handler)
(fetchers/fetch-orgs! last))
error-handler))

(defn org-creation-form [on-close-handler]
(let [color (random-color)
form (r/atom {:name nil
Expand All @@ -18,9 +27,9 @@
(fn []
[:form.inline-block {:on-submit (fn [e]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this handler function out. Don't write more than a line of code inside the view, it isn't as tangible, and is not testable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(.preventDefault e) can stay perhaps, because it is specific to the view.

(.preventDefault e)
(create-org @form
on-close-handler
#(reset! error true)))}
(submit-create-org! @form
on-close-handler
#(reset! error true)))}
[:div.inline-block
[utils/color-picker-patch
{:init-color color
Expand Down
12 changes: 6 additions & 6 deletions src/cljs/villagebookUI/components/dashboard.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
(:require [villagebookUI.components.sidebar :refer [sidebar]]
[villagebookUI.components.main-content :refer [main-content]]))

(defn dashboard []
(let []
(fn []
[:div
[sidebar]
[main-content]])))
(defn dashboard [on-mount-cb]
(on-mount-cb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When in the component lifecycle is this called? Not sure that this gives you good enough control.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is called once per component (when it's rendered the first time). Reagent provides this construct for setup or initialising local state. Works just like componentDidMount. Relevant doc

(fn []
[:div
[sidebar]
[main-content]]))
86 changes: 40 additions & 46 deletions src/cljs/villagebookUI/components/login.cljs
Original file line number Diff line number Diff line change
@@ -1,54 +1,48 @@
(ns villagebookUI.components.login
(:require [reagent.core :as r]
[accountant.core :as accountant]
[villagebookUI.helpers :as helpers :refer [validate-input]]
[villagebookUI.components.utils :refer [reqd-input]]
[villagebookUI.fetchers :as fetchers]
[villagebookUI.api.auth :as auth-api]))

[villagebookUI.api.auth :as auth]
[villagebookUI.store :as store]))
(defn redirect-dashboard []
(fetchers/fetch-user!)
(accountant/navigate! "/dashboard"))

(defn validate!
[elementID formdata]
(if (.checkValidity (.getElementById js/document elementID))
(swap! formdata assoc-in [:validation-classes elementID] "")
(swap! formdata assoc-in [:validation-classes elementID] "check-invalid")))

(defn input [formdata k placeholder type & required]
[:input.form-control.mt-3.mt-3 {:placeholder placeholder
:name k
:id k
:on-change #(swap! formdata assoc-in [:user k] (-> % .-target .-value))
:on-blur #(validate! (name k) formdata)
:type type
:required required
:class (str
(get-in @formdata [:validation-classes (name k)]) " "
(get-in @formdata [:validation-classes "login-form"]))}])
(defn submit-login
[user show-validness show-error]
(helpers/submit-auth-form :login-form auth-api/login user redirect-dashboard show-validness show-error))

(defn login []
(let [formdata (r/atom {})
error (r/atom {})]
(let [user (r/atom {})
validness (r/atom {})
error (r/atom {})
fields [{:id :email :type :email :placeholder "Email"}
{:id :password :type :password :placeholder "Password"}]]
(fn []
(if @store/user
(do
(accountant/navigate! "/dashboard")
[:div])
[:div.l-page-center.formbox
[:a.brand {:href "/"} "villagebook"]
[:form#login-form.mt-5.form-group
[input formdata :email "Email" "email" :required]
[input formdata :password "Password" "password" :required]
[:div.auth-error (:message @error)]
[:button.btn.btn-outline-primary.login-btn.mt-2
{:type "submit"
:on-click #(do
(.preventDefault %)
(validate! "login-form" formdata)
(auth/login
(:user @formdata)
(fn [res]
(swap! error assoc :message "")
(accountant/navigate! "/dashboard"))
(fn [res]
(swap! error assoc :message (:response res)))))}
"Login"]]
[:span.small "Don't have an account? "]
[:a {:href "/signup"} "Signup"]]))))
[:div.l-page-center.formbox
[:a.brand {:href "/"} "villagebook"]
[:form#login-form.mt-5.form-group
(doall
(for [field fields
:let [id (:id field)]]
[reqd-input {:id id
:key id
:type (:type field)
:placeholder (:placeholder field)
:class [:form-control :mt-3 (get @validness id)(:form @validness)]
:on-change #(swap! user assoc id %)
:on-blur #(validate-input id
(fn [v] (swap! validness assoc id v)))}]))
[:div.auth-error (:message @error)]
[:button.btn.btn-outline-primary.login-btn.mt-2
{:type "submit"
:on-click (fn [e]
(.preventDefault e)
(submit-login @user
#(swap! validness assoc :form %)
#(swap! error assoc :message %)))}
"Login"]]
[:span.small "Don't have an account? "]
[:a {:href "/signup"} "Signup"]])))
6 changes: 4 additions & 2 deletions src/cljs/villagebookUI/components/main_content.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
(ns villagebookUI.components.main-content)
(ns villagebookUI.components.main-content
(:require [villagebookUI.store.organisations :as org-store]))

(defn main-content []
[:div.main-content
[:div.navbar]])
[:div.navbar
[:h5 (:name (org-store/get-selected))]]])
Loading