diff options
author | colin <colin@cicadas.surf> | 2023-01-01 08:48:50 -0800 |
---|---|---|
committer | colin <colin@cicadas.surf> | 2023-01-01 08:48:50 -0800 |
commit | 7a3b904c26e2a08a88f58684d03aff3fb2a39c86 (patch) | |
tree | e25e9f241715ec9003f10f8b2e704264e87bbf80 | |
parent | c0ff3d5317e2a70329fde1b56b52dfa203f9c445 (diff) |
Add: password reset feature
-rw-r--r-- | home.lisp | 48 | ||||
-rw-r--r-- | model.lisp | 7 | ||||
-rw-r--r-- | static/css/main-4.css | 159 | ||||
-rw-r--r-- | style.lisp | 2 |
4 files changed, 214 insertions, 2 deletions
@@ -84,6 +84,51 @@ (let ((invite (make-invite user (parse-integer (value count) :junk-allowed t)))) (create-invite-list-item invite-list invite))))))) +(defun create-password-reset (parent) + (with-clog-create parent + (div () + (button (:content "Password Reset" :bind pw-reset-toggle)) + (form (:hidden t :bind pw-reset-form) + (form-element (:password :bind pw-input)) + (br ()) + (form-element (:password :bind pw-repeated)) + (br ()) + (button (:content "Change password" :bind pw-update))) + (p (:bind notice-area))) + + (setf (place-holder pw-input) "New Password" + (place-holder pw-repeated) "Repeat New Password" + (disabledp pw-update) t) + + (set-on-key-down + pw-repeated + (thunk* (when (equal (value pw-input) (value pw-repeated)) + (setf (disabledp pw-update) nil)))) + + (flet ((toggle-form () + (cond ((visiblep pw-reset-form) + (setf (visiblep pw-reset-form) nil + (text pw-reset-toggle) "Password Reset" + (text notice-area) "" + (disabledp pw-update) t + (value pw-input) "" + (value pw-repeated) "")) + (t + (setf (visiblep pw-reset-form) t + (text notice-area) "" + (text pw-reset-toggle) "Nevermind"))))) + + (set-on-click pw-update + (thunk* + ;; assumes pw-input and pw-repeat are equal + (set-new-password (session-user parent) (value pw-input)) + (toggle-form) + (setf (text notice-area) + "Password updated!"))) + + (set-on-click pw-reset-toggle + (thunk* (toggle-form)))))) + (defun user-home-page (body) (include-style body) @@ -96,7 +141,8 @@ (section (:h3 :content "Your Playlists")) (div (:class "row") (playlist-listing ())) (new-playlist-form ()) - (invite-control ())))))) + (invite-control ()) + (password-reset ())))))) (defun user-key-from-url (url) (first (last (ppcre:split "/" (nth 4 (multiple-value-list (quri:parse-uri url))))))) @@ -99,6 +99,13 @@ (with-transaction () (make-instance 'user :name name))) +(defun set-new-password (user pw) + (with-transaction () + (setf (user-pwhash user) + (hash-string pw (user-pwsalt user))) + t)) + + (defun use-invite-with-code (code username pw) (with-transaction () (when-let (invite (invite-by-code code)) diff --git a/static/css/main-4.css b/static/css/main-4.css new file mode 100644 index 0000000..aa2463a --- /dev/null +++ b/static/css/main-4.css @@ -0,0 +1,159 @@ +body { + background-color: #1c1c1c; + color: #e8e7d5; + width: 90vw; + display: flex; + justify-content: center; + margin: auto; +} + +a { + color: #d478e0; +} + +h1,h2,h3,h4 { + color: #ff9430; +} + +button { + background: #1c1c1c; + color: #ff9430; + border: 1px solid #ff9430; + margin-left: 2px; + margin-right: 2px; +} + +button:hover { + cursor: pointer; +} + +button:disabled { + color: #666666; + border: 1px solid #666666; +} + +button:disabled:hover { + cursor: not-allowed; +} + +.header { + position: sticky; + top: 0px; + background-color: #1c1c1c; + padding: .1rem; + align-items: center; + justify-content: space-around; +} + +.center { + text-align: center; +} + +.row { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-evenly; + align-content: baseline; +} + +.column { + display: flex; + flex-direction: column; + flex-wrap: wrap; + justify-content: center; + align-content: baseline; +} + +.centered-column { + display: grid; + grid-template-columns: 1fr minmax(300px,500px) 1fr; + padding: 10px; + column-gap: 40px; +} + +.four-column > div { + max-width: 50%; +} + +.track-list-item:hover { + cursor: pointer; + background-color: #454545; +} + +.container { + width: 100%; +} + +.player { + display: flex; + justify-content: space-evenly; + width: 100%; + flex-wrap: wrap; +} + +.now-playing { + display: flex; + width: 300px; + flex-direction: column; +} + +.controls { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.controls button { + font-size: 2em; + width: -moz-available; + width: -webkit-fill-available; + width: stretch; +} + +.now-playing-track { + background-color: #454545; +} + + +.playlist-display { + margin-top: 2rem; + width: auto; + display: flex; + flex-direction: column; +} + +.login { + margin-top: 10rem; +} + + +.card { + display: flex; + width: 200px; + height: 200px; + align-items: center; + justify-content: center; +} + +.thumb { + max-width: 180px; +} + +@media (max-width: 500px) { + body { + font-size: small; + width: 100vw; + } + + h1 { + font-size: medium; + } +} + +@media (min-width: 500px) { + .playlist-display { + height: 80vh; + overflow-y: auto; + } +} @@ -2,7 +2,7 @@ (in-package :vampire) -(defvar css-version "3") +(defvar css-version "4") (defun include-style (body) (load-css (html-document body) (format nil "/css/main-~a.css" css-version) :load-only-once nil)) |