Skip to content

Commit

Permalink
Bring back and rework the profile form
Browse files Browse the repository at this point in the history
  • Loading branch information
plexus committed Sep 14, 2024
1 parent 211b1ac commit a70f640
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 116 deletions.
30 changes: 19 additions & 11 deletions src/co/gaiwan/compass/db/queries.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,25 @@
[?e :public-profile/name]]
(db/db))))

(defn all-links [user-eid]
(sort-by
:db/id
(db/q
'[:find [(pull ?l [*
{:public-profile/_links [:db/id]}
{:private-profile/_links [:db/id]}]) ...]
:in $ ?u
:where
[?l :profile-link/user ?u]]
(db/db) user-eid)))
(defn public-links [user-eid]
(map db/entity
(db/q
'[:find [?l ...]
:in $ ?u
:where
[?u :public-profile/links ?l]]
(db/db)
user-eid)))

(defn private-links [user-eid]
(map db/entity
(db/q
'[:find [?l ...]
:in $ ?u
:where
[?u :public-profile/links ?l]]
(db/db)
user-eid)))

(defn all-session-types []
(db/q
Expand Down
2 changes: 1 addition & 1 deletion src/co/gaiwan/compass/db/schema.clj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
[:private-profile/bio :string "Free-form Markdown field"]
;; End user entity

[:profile-link/user :ref "User this link belongs too"]
#_[:profile-link/user :ref "User this link belongs too"]
[:profile-link/type :string "`mastodon`, `linkedin`, `personal-site`, etc."]
[:profile-link/href :string "http/mailto URL"]

Expand Down
11 changes: 11 additions & 0 deletions src/co/gaiwan/compass/html/graphics.clj
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,14 @@
{:d "M823.931359 27.629267l-131.187855 0 0 0.002047c-33.268708 0-60.241013 26.970258-60.241013 60.237943 0 33.270754 26.972305 60.238966 60.241013 60.238966 0.026606 0 0.054235-0.002047 0.082888-0.002047l116.879987 0c35.20992 0 63.754023 28.54308 63.754023 63.751976l0 116.966968 0 0c0 33.271778 26.969235 60.237943 60.238966 60.237943s60.238966-26.966165 60.238966-60.237943l0 0L993.938334 197.636243C993.938334 103.744829 917.823795 27.629267 823.931359 27.629267z"}]
[:path
{:d "M963.820386 449.299983c-0.026606 0-0.056282 0.002047-0.080841 0.002047L60.321854 449.302029c-0.028653 0-0.056282-0.002047-0.082888-0.002047-33.270754 0-60.238966 26.970258-60.238966 60.241013 0 33.266661 26.968212 60.237943 60.238966 60.237943l903.579373 0 0 0 0.002047 0c33.267685 0 60.234873-26.970258 60.234873-60.237943C1024.055259 476.270241 997.087047 449.299983 963.820386 449.299983z"}]]))

(o/defstyled github-icon :svg
([]
[:<> {:viewbox "0 0 24 24"}
[:path {:d "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"}]]))

(o/defstyled cog-icon :svg
([]
[:<> {:viewbox "0 -256 1536 1536"}
[:path {:d "m 1024,512 q 0,106 -75,181 -75,75 -181,75 -106,0 -181,-75 -75,-75 -75,-181 0,-106 75,-181 75,-75 181,-75 106,0 181,75 75,75 75,181 z m 512,109 V 399 q 0,-12 -8,-23 -8,-11 -20,-13 l -185,-28 q -19,-54 -39,-91 35,-50 107,-138 10,-12 10,-25 0,-13 -9,-23 -27,-37 -99,-108 -72,-71 -94,-71 -12,0 -26,9 L 1035,-4 q -44,-23 -91,-38 -16,-136 -29,-186 -7,-28 -36,-28 H 657 q -14,0 -24.5,8.5 Q 622,-239 621,-226 l -28,184 q -49,16 -90,37 L 362,-112 q -10,-9 -25,-9 -14,0 -25,11 Q 186,4 147,58 q -7,10 -7,23 0,12 8,23 15,21 51,66.5 36,45.5 54,70.5 -27,50 -41,99 L 29,367 Q 16,369 8,379.5 0,390 0,403 v 222 q 0,12 8,23 8,11 19,13 l 186,28 q 14,46 39,92 -40,57 -107,138 -10,12 -10,24 0,10 9,23 26,36 98.5,107.5 72.5,71.5 94.5,71.5 13,0 26,-10 l 138,-107 q 44,23 91,38 16,136 29,186 7,28 36,28 h 222 q 14,0 24.5,-8.5 Q 914,1263 915,1250 l 28,-184 q 49,-16 90,-37 l 142,107 q 9,9 24,9 13,0 25,-10 129,-119 165,-170 7,-8 7,-22 0,-12 -8,-23 -15,-21 -51,-66.5 -36,-45.5 -54,-70.5 26,-50 41,-98 l 183,-28 q 13,-2 21,-12.5 8,-10.5 8,-23.5 z"}]]
))
45 changes: 33 additions & 12 deletions src/co/gaiwan/compass/html/navigation.clj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@
[:a {:text-decoration "underline"}]]
[:a:visited {:color t/--link}]
["li:has(.notifier-dot)" :flex :gap-1]
[:svg :inline :mr-1 {:height "1em" :margin-bottom "-0.15em"}
[:path {:fill t/--text-1}]]
[:.bottom :fixed :bottom-0 :left-0
:w-full :mb-3
:text-center

[:p :m-2]]
([user]
[:<>
[:div.bar
Expand All @@ -95,18 +102,32 @@
:on-click "document.body.classList.toggle('menu-open')"}
[:strong "Claim your Ti.to ticket for full access"]]]
[:div.notifier-dot]]))
(for [[href caption] {(url-for :sessions/index) "Sessions & Activities"
;; (url-for :attendees/index) "Attendees"
;; (url-for :profile/index) "Profile & Settings"
(url-for :session/new) "Create Activity"
(url-for :contacts/index) "Contacts"}]
[:li [:a {:href href
:on-click "document.body.classList.toggle('menu-open')"}
caption]])
[:li [:a {:href (url-for :contact/qr)
:hx-target "#modal"
:on-click "document.body.classList.toggle('menu-open')"}
"Add Contact"]]]]))

[:li
[:a
{:href (url-for :sessions/index), :on-click "document.body.classList.toggle('menu-open')"}
"Sessions & Activities"]]
[:li
[:a
{:href (url-for :profile/edit), :on-click "document.body.classList.toggle('menu-open')"}
[graphics/cog-icon] "Profile & Settings"]]
[:li
[:a
{:href (url-for :contacts/index), :on-click "document.body.classList.toggle('menu-open')"}
"Contacts"]]
[:li
[:a {:href (url-for :contact/qr)
:hx-target "#modal"
:on-click "document.body.classList.toggle('menu-open')"}
[graphics/scan-icon] "Add Contact"]]
[:li
[:a
{:href (url-for :session/new), :on-click "document.body.classList.toggle('menu-open')"}
"Create Activity"]]
[:div.bottom
[:p "Proudly made by the " [:a {:href "https://gaiwan.co" :target "_blank"} "Gaiwan Team"] " and contributors."]
[:p [:a {:href "https://github.com/GaiwanTeam/compass" :target "_blank"} [graphics/github-icon] "GaiwanTeam/compass"]]]
]]))

(o/defrules toggle-menu-button)

Expand Down
145 changes: 72 additions & 73 deletions src/co/gaiwan/compass/html/profiles.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@

;; UI of profile detail

(o/defstyled edit-profile-btn :button
(o/defstyled edit-profile-btn :a.btn
([user]
[:<>
{:hx-get (url-for :profile/edit)
:hx-select "#form"
:hx-target "#detail"
:hx-swap "outerHTML"}
"Edit Profile"]))
{:href (url-for :profile/edit)} "Edit Profile"]))

(o/defstyled profile-detail :div#detail
[c/image-frame :w-100px {t/--arc-thickness "7%"}]
Expand Down Expand Up @@ -52,36 +48,51 @@
[:div#private-name-block])))

(o/defstyled row :tr.link-row
([link {:keys [row-index] :as params}]
([{:keys [variant] :as link}]
[:<>
[:td
;; (pr-str link)
(when (:db/id link)
[:input {:type "hidden" :name (str "link-id-" row-index) :value (:db/id link)}])
[:input {:type "hidden" :name (str variant "-link-id[]") :value (:db/id link)}])
(let [link-type (:profile-link/type link)]
[:select {:name (str "link-type-" row-index)}
[:select {:name (str variant "-link-type[]")}
[:option {:value "email" :selected (= link-type "email")} "Email"]
[:option {:value "twitter" :selected (= link-type "twitter")} "Twitter"]
[:option {:value "mastodon" :selected (= link-type "mastodon")} "Mastodon"]
[:option {:value "linkedin" :selected (= link-type "linkedin")} "LinkedIn"]
[:option {:value "personal-site" :selected (= link-type "personal-site")} "Personal Site"]
[:option {:value "other" :selected (= link-type "other")} "Other"]])]
[:td
[:input (cond-> {:name (str "link-ref-" row-index) :type "text" :required true
:min-length 2}
(:db/id link)
(assoc :value (:profile-link/href link)))]]
[:td
[:input {:name (str "public-" row-index) :type "checkbox"
:checked (:public-link link)}]]
[:td
[:input {:name (str "private-" row-index) :type "checkbox"
:checked (:private-link link)}]]]))
[:input
{:type "text"
:name (str variant "-link-ref[]")
:value (str (:profile-link/href link))}]]]))

(def always-show ["email" "mastodon"])

(o/defstyled links-table :div
([link {:keys [row-index] :as params}]
[:table
[row link params]]))
([links {:keys [caption variant]}]
(let [link-map (into {} (map (juxt :profile-link/type :profile-link/href)) links)
link-vals (concat
(for [t always-show]
[t (get link-map t)])
(apply dissoc link-map always-show))]
[:<>
[:template
[row {:profile-link/type "other"
:profile-link/href ""
:variant variant}]]
[:table
[:thead
[:tr
[:th {:colspan 2} caption]]]
[:tbody
(for [[t h] link-vals]
[row {:profile-link/type t
:profile-link/href h
:variant variant}])]]
[:input#add-link
{:value "+ Add Link"
:type "button"
:on-click "let form = this.parentElement; form.querySelector('tbody').append(form.querySelector('template').content.cloneNode(true))"}]])))

(o/defstyled profile-form :div#form
[c/image-frame :w-100px {t/--arc-thickness "7%"}]
Expand All @@ -98,7 +109,15 @@
:flex
:gap-3]]
[:table :w-full]
[:.contact-card
:shadow-3
:my-6
{:background-color t/--surface-2
:padding t/--size-3
:border-radius t/--size-2}
[#{:textarea "input[type='text']"} {:background-color t/--surface-3}]]
([user]
(def user user)
[:<>
[:h2 "Edit Profile"]
[:form {:method "POST" :action "/profile/save" :enctype "multipart/form-data"}
Expand All @@ -107,63 +126,43 @@
[:input {:id "hidding" :name "hidden?" :type "checkbox"
:checked (:public-profile/hidden? user)}]
"Hide profile from public listings?"]
[:label {:for "name"} "Name (public)"]
[:label {:for "name"} "Display Name"]
[:input {:id "name" :name "name_public" :type "text"
:required true :min-length 2
:required true
:value (:public-profile/name user)}]
[:label {:for "show-another-name"}
[:input {:id "show-another-name" :name "private-name-switch" :type "checkbox"
:hx-get (url-for :profile/private-name)
:hx-target "#private-name-block"
:hx-select "#private-name-block"
:hx-trigger "change"
:hx-swap "outerHTML"}]
"Show different name to confidantes?"]
[:div.input-block {:id "private-name-block"}]
[:div
(when user
[c/image-frame {:profile/image (user/avatar-css-value user)}])
[:label {:for "image"} "Avatar"]
[:input {:id "image" :name "image" :type "file" :accept "image/png, image/jpeg"}]]
[:div
[:label {:for "bio_public"}
"Bio (public, markdown)"]
"Bio (accepts markdown)"]
[:textarea {:id "bio_public" :name "bio_public"}
(when (:public-profile/bio user)
(:public-profile/bio user))]]

[:div
[:label {:for "bio_private"}
"Bio (confidential, markdown)"]
[:textarea {:id "bio_private" :name "bio_private"}
(when (:private-profile/bio user)
(:private-profile/bio user))]]
[:div
[:table
[:thead
[:tr
[:th {:colspan 2} "Links"]
[:th "public"]
[:th "confidential"]]]
[:tbody#links-block
(let [links (map (fn [link]
(cond-> link
(:public-profile/_links link)
(assoc :public-link true)
(:private-profile/_links link)
(assoc :private-link true)))
(queries/all-links (:db/id user)))]
(map-indexed
(fn [idx itm]
[row itm {:row-index idx}]) links))]]
[:input#rows-count {:type "hidden" :name "rows-count" :value (count (queries/all-links (:db/id user)))}]
[:input#add-link {:type "button" :value "Add Links"
:hx-get (url-for :profile/add-link)
:hx-target "#links-block"
:hx-select ".link-row"
:hx-trigger "click"
:hx-swap "beforeend"}]]
[:input {:type "submit" :value "Save"}]]
(when user
[c/image-frame {:profile/image (user/avatar-css-value user)}])
[:label {:for "image"} "Avatar"]
[:input {:id "image" :name "image" :type "file" :accept "image/png, image/jpeg"}]]
[links-table (:public-profile/links user)
{:variant "public"
:caption "Public Profile Links"}]

[:div.contact-card
[:h3 "Contact Card"]
[:p.info "This information is only shown to people you add as a contact."]
[:label {:for "name"} "Name"]
[:input {:id "name" :name "name_private" :type "text"
:value (:private-profile/name user)}]
[:div
[:label {:for "bio_private"}
"Private Bio (accepts markdown)"]
[:textarea {:id "bio_private" :name "bio_private"}
(when (:private-profile/bio user)
(:private-profile/bio user))]]
[links-table (:private-profile/links user)
{:variant "private"
:caption "Links Visible to Contacts"}]
]

[:input {:type "submit" :value "Save Profile"}]]
[:script
"document.getElementById('add-link').addEventListener('htmx:configRequest', function(evt) {
const url = new URL(evt.detail.path, window.location.origin);
Expand Down
Loading

0 comments on commit a70f640

Please sign in to comment.