Skip to content

Commit

Permalink
More style fixes. Templated unapproved problems, settings/golf, login
Browse files Browse the repository at this point in the history
  • Loading branch information
amcnamara committed Sep 24, 2011
1 parent 6504415 commit 8958e5c
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 115 deletions.
8 changes: 7 additions & 1 deletion resources/public/css/style.css
Expand Up @@ -239,7 +239,7 @@ div#heading-note {
margin: 11px 0 0 13px;
}

div#subheading {
div#sub-heading {
font-size: 13px;
font-weight: normal;
display: block;
Expand All @@ -248,6 +248,12 @@ div#subheading {
margin-bottom: 10px;
}

div#main {
display: block;
float: left;
clear: both;
}

div.message #flash-text {}
div.message #error-text {}

Expand Down
40 changes: 26 additions & 14 deletions src/foreclojure/golf.clj
Expand Up @@ -4,28 +4,40 @@
(:use [hiccup.form-helpers :only [form-to check-box]]
[hiccup.page-helpers :only [link-to]]
[foreclojure.utils :only [with-user]]
[foreclojure.template :only [def-page]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.users :only [golfer?]]
[compojure.core :only [defroutes POST GET]]
[somnium.congomongo :only [update!]]))

(def-page golfer-page []
"Your preferences have been saved.")

(defn golf-opt-in-box [user-obj]
(list
[:table
(form-to [:post "/golf/opt-in"]
[:tr
[:td
(check-box :opt-in
(golfer? user-obj))
[:label {:for "opt-in"}
"I want to join the golf league and compete to find the shortest solutions"]]]
[:tr [:td [:button {:type "submit"} "Update"]]])]))

This comment has been minimized.

Copy link
@amalloy

amalloy Sep 24, 2011

This doesn't need to be wrapped in list, though it won't hurt.

(def-page opt-in-page []
(with-user [user-obj]
[:div
[:h2 "League sign-up"]
[:div#explain "While the primary purpose of 4clojure.com is to teach Clojure \"by doing\", you may also choose to compete for the shortest solution. This is affectionately known as " (link-to "http://lbrandy.com/blog/2008/09/what-code-golf-taught-me-about-python/" "code golf") ": the lower your score the better, get it? If you choose to participate, we'll score your correct solutions based on the number of non-whitespace characters (and some more metrics in the future). We'll also provide a chart showing how you stack up compared to everyone else on the site."]
[:table
(form-to [:post "/golf/opt-in"]
[:tr
[:td
(check-box :opt-in
(golfer? user-obj))
[:label {:for "opt-in"}
"I want to join the golf league and compete to find the shortest solutions"]]]
[:tr [:td [:button {:type "submit"} "Update"]]])]]))
(with-user [{:keys [user] :as user-obj}]
{:title "Account Settings"
:content
(content-page
{:heading "League sign-up"
:sub-heading (list "While the primary purpose of 4clojure.com is to teach Clojure \"by doing\", you may "
"also choose to compete for the shortest solution. This is affectionately known as "
(link-to "http://lbrandy.com/blog/2008/09/what-code-golf-taught-me-about-python/" "code golf")
": the lower your score the better, get it? If you choose to participate, we'll score "
"your correct solutions based on the number of non-whitespace characters (and some more "
"metrics in the future). We'll also provide a chart showing how you stack up compared "
"to everyone else on the site.")
:main (golf-opt-in-box user-obj)})}))

(defn set-golfer [opt-in]
(with-user [{:keys [_id]}]
Expand Down
135 changes: 71 additions & 64 deletions src/foreclojure/login.clj
Expand Up @@ -4,39 +4,38 @@
(:import [org.jasypt.util.password StrongPasswordEncryptor])
(:use [hiccup.form-helpers :only [form-to label text-field password-field check-box]]
[foreclojure.utils :only [from-mongo flash-error flash-msg with-user form-row assuming send-email login-url]]
[foreclojure.template :only [def-page]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.users :only [disable-codebox? set-disable-codebox hide-solutions? set-hide-solutions]]
[compojure.core :only [defroutes GET POST]]
[useful.map :only [keyed]]
[clojail.core :only [thunk-timeout]]
[clojure.stacktrace :only [print-cause-trace]]
[somnium.congomongo :only [update! fetch-one]]))

(def login-box
(form-to [:post "/login"]
[:table
[:tr
[:td (label :user "Username")]
[:td (text-field :user)]]
[:tr
[:td (label :pwd "Password")]
[:td (password-field :pwd)]]
[:tr
[:td]
[:td [:button {:type "submit"} "Log In"]]]
[:tr
[:td]
[:td
[:a {:href "/login/reset"} "Forgot your password?"]]]]))

(def-page my-login-page [location]
{:title "4clojure - login"
:content
(list
(when location
(session/session-put! :login-to location)
nil) ;; don't include this in HTML output
[:div.error
(session/flash-get :error)
(session/flash-get :message)]
(form-to [:post "/login"]
[:table
[:tr
[:td (label :user "Username")]
[:td (text-field :user)]]
[:tr
[:td (label :pwd "Password")]
[:td (password-field :pwd)]]
[:tr
[:td]
[:td [:button {:type "submit"} "Log In"]]]
[:tr
[:td]
[:td
[:a {:href "/login/reset"} "Forgot your password?"]]]]))})
(do
(if location (session/session-put! :login-to location))
{:title "4clojure - login"
:content
(content-page
{:main login-box})}))

(defn do-login [user pwd]
(let [user (.toLowerCase user)
Expand All @@ -51,48 +50,56 @@
(response/redirect (or location "/problems")))
(flash-error "Error logging in." "/login"))))

;; TODO this page is getting hella gross. Need a real Settings page soon.
(defn account-settings-box [user]
[:table
(form-to [:post "/login/update"]
(map form-row
[[text-field :new-username "Username" user]
[password-field :old-pwd "Current password"]
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]])
[:tr
[:td [:button {:type "submit"} "Reset now"]]])])

(defn js-settings-box [user-obj]
(list
[:p "Selecting this will disable the JavaScript code entry box and just give you plain text entry"]
(form-to [:post "/users/set-disable-codebox"]
(check-box :disable-codebox
(disable-codebox? user-obj))
[:label {:for "disable-codebox"}
"Disable JavaScript in code entry box"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])))

(defn hide-settings-box [user-obj]
(list
[:p "When you solve a problem, we allow any user who has solved a problem to view your solutions to that problem. Check this box to keep your solutions private."]
(form-to [:post "/users/set-hide-solutions"]
(check-box :hide-solutions
(hide-solutions? user-obj))
[:label {:for "hide-solutions"}
"Hide my solutions"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])))

This comment has been minimized.

Copy link
@amalloy

amalloy Sep 24, 2011

Hm. Definitely an improvement, but I think we should leave the "hella gross" comment in. I was complaining about the page as seen by users, not the backend code.

This comment has been minimized.

Copy link
@amcnamara

amcnamara Sep 24, 2011

Author Owner

I'll put the todo back, this should probably be a ticket. /hint

(def-page update-credentials-page []
{:title "Change password"
:content
(with-user [{:keys [user] :as user-obj}]
[:div#account-settings
[:div#update-pwd
[:h2 "Change password for " user]
[:span.error (session/flash-get :error)]
[:table
(form-to [:post "/login/update"]
(map form-row
[[text-field :new-username "Username" user]
[password-field :old-pwd "Current password"]
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]])
[:tr
[:td [:button {:type "submit"} "Reset now"]]])]
[:hr]
[:div#settings-codebox
(with-user [{:keys [user] :as user-obj}]
{:title "Change password"
:content
(content-page
{:main
(list
[:h2 "Change password for " user]
[:div#account-settings (account-settings-box user)]
[:hr]
[:h2 "Disable JavaScript Code Box"]
[:p "Selecting this will disable the JavaScript code entry box and just give you plain text entry"]
(form-to [:post "/users/set-disable-codebox"]
(check-box :disable-codebox
(disable-codebox? user-obj))
[:label {:for "disable-codebox"}
"Disable JavaScript in code entry box"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])]
[:hr]
[:div#settings-follow
[:div#settings-codebox (js-settings-box user-obj)]
[:hr]
[:h2 "Hide My Solutions"]
[:p "When you solve a problem, we allow any user who has solved a problem to view your solutions to that problem. Check this box to keep your solutions private."]
(form-to [:post "/users/set-hide-solutions"]
(check-box :hide-solutions
(hide-solutions? user-obj))
[:label {:for "hide-solutions"}
"Hide my solutions"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])]]])})
[:div#settings-follow (hide-settings-box user-obj)])})}))

(defn do-update-credentials! [new-username old-pwd new-pwd repeat-pwd]
(with-user [{:keys [user pwd]}]
Expand Down
56 changes: 29 additions & 27 deletions src/foreclojure/problems.clj
Expand Up @@ -5,7 +5,7 @@
[ring.util.response :as response])
(:import [org.apache.commons.mail EmailException])
(:use [foreclojure.utils :only [from-mongo get-user get-solved login-link *url* flash-msg flash-error row-class approver? can-submit? send-email image-builder with-user as-int maybe-update]]
[foreclojure.template :only [def-page]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.social :only [tweet-link gist!]]
[foreclojure.feeds :only [create-feed]]
[foreclojure.users :only [golfer? get-user-id disable-codebox?]]
Expand Down Expand Up @@ -400,34 +400,36 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
[:td.centered (checkbox-img (contains? solved id))]])
problems))])}))

(defn generate-unapproved-problems-list []
(let [problems (get-problem-list {:approved false})]
(list
[:table#unapproved-problems.my-table
[:thead
[:tr
[:th "Title"]
[:th "Difficulty"]
[:th "Topics"]
[:th "Submitted By"]]]
(map-indexed
(fn [x {:keys [title difficulty tags user], id :_id}]
[:tr (row-class x)
[:td.titlelink
[:a {:href (str "/problem/" id)}
title]]
[:td.centered difficulty]
[:td.centered
(s/join " " (map #(str "<span class='tag'>" % "</span>")
tags))]
[:td.centered user]])
problems)])))

(def-page unapproved-problem-list-page []
{:title "Unapproved problems"
:content
(list
[:div.message (session/flash-get :message)]
[:div#problems-error.error (session/flash-get :error)]
[:table#unapproved-problems.my-table
[:thead
[:tr
[:th "Title"]
[:th "Difficulty"]
[:th "Topics"]
[:th "Submitted By"]]]
(let [problems (get-problem-list {:approved false})]
(map-indexed
(fn [x {:keys [title difficulty tags user], id :_id}]
[:tr (row-class x)
[:td.titlelink
[:a {:href (str "/problem/" id)}
title]]
[:td.centered difficulty]
[:td.centered
(s/join " " (map #(str "<span class='tag'>" % "</span>")
tags))]
[:td.centered user]])
problems))])})

(defn unapproved-problem-list []
(content-page
{:main (generate-unapproved-problems-list)})})

(defn access-unapproved-problem-list-page []
(let [user (session/session-get :user)]
(if (approver? user)
(unapproved-problem-list-page)
Expand Down Expand Up @@ -563,7 +565,7 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
(GET "/problems/submit" [] (problem-submission-page))
(POST "/problems/submit" [prob-id author title difficulty tags restricted description code]
(create-problem title difficulty tags restricted description code (when (not= "" prob-id) (Integer. prob-id)) author))
(GET "/problems/unapproved" [] (unapproved-problem-list))
(GET "/problems/unapproved" [] (access-unapproved-problem-list-page))
(GET "/problem/:id/edit" [id]
(edit-problem (Integer. id)))
(POST "/problem/edit" [id]
Expand Down
21 changes: 12 additions & 9 deletions src/foreclojure/template.clj
Expand Up @@ -84,15 +84,18 @@
)]]])))

;; Content templates
(defn content-page [body-map]
(list
[:div#heading (:heading body-map)]
[:div#heading-note (:heading-note body-map)]
[:div#subheading (:sub-heading body-map)]
[:div.message
[:span#flash-text (session/flash-get :message)]
[:span#error-text (session/flash-get :error)]]
[:div.main (:main body-map)]))
(defn content-page [{:keys [heading heading-note sub-heading main]}]
(let [flash-message (session/flash-get :message)
flash-error (session/flash-get :error)]
(list
(when heading [:div#heading heading])
(when heading-note [:div#heading-note heading-note])
(when sub-heading [:div#sub-heading sub-heading])
(when flash-message [:div.message
[:span#flash-text flash-message]])
(when flash-error [:div.message
[:span#error-text flash-error]])
(when main [:div#main main]))))

(defmacro def-page [page-name [& args] & code]
`(defn ~page-name [~@args]
Expand Down

0 comments on commit 8958e5c

Please sign in to comment.