Skip to content
Snippets Groups Projects
Commit be1fc7f6 authored by Dmytro Zaporozhets (DZ)'s avatar Dmytro Zaporozhets (DZ) :palm_tree:
Browse files

User avatar upload

parent c5062c1f
Branches
No related tags found
1 merge request!22User avatar upload
......@@ -9,3 +9,4 @@ pom.xml.asc
/.lein-*
/.nrepl-port
.DS_Store
resources/public/avatars/
......@@ -34,12 +34,12 @@ Just in case you are curious how it looks when started
* PostgreSQL database with migrations
* Layout with Bootstrap CSS and jQuery
* Send email confirmation on signup (optional)
* Avatar upload
### TODO
* add remember me checkbox for authentication
* add forget password feature
* avatar upload
## Running
......
DROP TABLE IF EXISTS avatars;
CREATE TABLE IF NOT EXISTS avatars (
id SERIAL PRIMARY KEY,
name varchar(255) NOT NULL,
user_id integer NOT NULL,
timestamp timestamp DEFAULT current_timestamp
);
......@@ -2,3 +2,9 @@
max-width: 500px;
margin: 0 auto;
}
.avatar-preview {
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 20px;
}
......@@ -5,6 +5,7 @@
[sample.routes.home :refer [home-routes]]
[sample.routes.profile :refer [profile-routes]]
[sample.routes.auth :refer [auth-routes]]
[sample.routes.files :refer [files-routes]]
[sample.views.layout :as layout]
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
......@@ -30,6 +31,7 @@
auth-routes
home-routes
profile-routes
files-routes
static-routes))
(def app
......
(ns sample.helpers
(:require [compojure.core :refer :all]
[sample.models.user :as user-db]
[ring.util.codec :refer [url-encode]]
[struct.core :as st]
[hiccup.form :refer :all]
[hiccup.element :refer :all]))
......@@ -18,3 +19,6 @@
(label id name)
(if error (error-item error))
(type {:class "form-control" :required required} id value))])
(defn avatar-uri [file-name]
(str "/files/avatars/" (url-encode file-name)))
(ns sample.models.avatar
(:require [clojure.java.jdbc :as sql]
[sample.db :refer :all]))
(defn get-avatar-by-name [name]
(sql/query db
["SELECT * FROM avatars WHERE name = ?", name]
{:result-set-fn first}))
(defn get-avatar-by-user [user-id]
(sql/query db
["SELECT * FROM avatars WHERE user_id = ?", user-id]
{:result-set-fn last}))
(defn create-avatar [avatar]
(first (sql/insert! db :avatars avatar)))
(defn delete-avatar-by-user [user-id]
(sql/delete! db :avatars ["user_id = ?", user-id]))
(ns sample.routes.files
(:require [compojure.core :refer :all]
[sample.models.avatar :as avatar-db]
[ring.util.response :refer [file-response]]
[ring.util.codec :refer [url-decode]]))
(defn avatar-file [avatar]
(file-response (str "resources/public/avatars/" (url-decode (:name avatar)))))
(defroutes files-routes
(context "/files" {}
(GET "/avatars/:name" [name]
(if-let [avatar (avatar-db/get-avatar-by-name name)]
(avatar-file avatar)))))
......@@ -2,8 +2,10 @@
(:require [compojure.core :refer :all]
[sample.crypt :as crypt]
[ring.util.response :as response]
[clojure.java.io :as io]
[sample.helpers :refer :all]
[sample.models.user :as db]
[sample.models.avatar :as avatar-db]
[sample.views.layout :as layout]
[sample.views.profile :as view]))
......@@ -25,9 +27,13 @@
(defn password-page [user]
(layout/common (view/password-page user) user))
(defn update-profile [name user]
(defn update-profile [name user file]
(do
(db/update-user (:id user) {:name name})
(when (seq (:filename file))
(avatar-db/create-avatar {:user_id (:id user)
:name (:filename file)})
(io/copy (:tempfile file) (io/file "resources" "public" "avatars" (:filename file))))
(response/redirect "/profile")))
(defn update-password [current-password new-password confirm-password user]
......@@ -52,9 +58,9 @@
(if user-id
(profile-edit-page (get-user user-id))
(response/redirect "/login")))
(POST "/update" [name]
(POST "/update" [name file]
(if user-id
(update-profile name (get-user user-id))
(update-profile name (get-user user-id) file)
(response/redirect "/login")))
(GET "/password" []
(if user-id
......
......@@ -4,6 +4,7 @@
[hiccup.form :refer :all]
[clj-time.coerce :as c]
[clj-time.format :as f]
[sample.models.avatar :as avatar-db]
[sample.models.user :as db]
[sample.helpers :refer :all]
[ring.util.anti-forgery :refer [anti-forgery-field]]))
......@@ -12,6 +13,9 @@
[:div
[:h1 "Profile"]
[:div {:class "user-info"}
(if-let [avatar (avatar-db/get-avatar-by-user (:id user))]
[:div
[:img {:src (avatar-uri (:name avatar)) :width 200 :class "avatar-preview"}]])
[:p
[:span "Name: "]
[:strong (:name user)]]
......@@ -33,10 +37,15 @@
(defn profile-edit-page [user & [errors]]
[:div
[:h1 "Edit profile"]
(form-to [:post "/profile/update"]
(form-to {:enctype "multipart/form-data"} [:post "/profile/update"]
(anti-forgery-field)
(input-control text-field "name" "User name" (:name user) true)
(submit-button {:class "btn btn-primary"} "Save changes"))])
[:div {:class "change-user-info"}
(input-control text-field "name" "User name" (:name user) true)]
[:div {:class "form-group"}
(label "file" "Avatar")
(file-upload :file)]
[:div
(submit-button {:class "btn btn-primary"} "Save changes")])])
(defn password-page [user & [errors]]
[:div
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment