mirror of
https://github.com/penpot/penpot.git
synced 2025-05-19 11:56:45 +02:00
🎉 Add register confirmation page.
This commit is contained in:
parent
1eff1c94c4
commit
c14dbc19f8
5 changed files with 97 additions and 59 deletions
|
@ -35,6 +35,18 @@
|
||||||
"es" : "¿Quieres probar?"
|
"es" : "¿Quieres probar?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"auth.verification-email-sent": {
|
||||||
|
"translations": {
|
||||||
|
"en": "We've sent a verification email to %s."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"auth.check-your-email": {
|
||||||
|
"translations": {
|
||||||
|
"en": "Check your email and click on the link to verify and start using Penpot."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"auth.demo-warning" : {
|
"auth.demo-warning" : {
|
||||||
"used-in" : [ "src/app/main/ui/auth/register.cljs:33" ],
|
"used-in" : [ "src/app/main/ui/auth/register.cljs:33" ],
|
||||||
"translations" : {
|
"translations" : {
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
[["/auth"
|
[["/auth"
|
||||||
["/login" :auth-login]
|
["/login" :auth-login]
|
||||||
["/register" :auth-register]
|
["/register" :auth-register]
|
||||||
|
["/register/success" :auth-register-success]
|
||||||
["/recovery/request" :auth-recovery-request]
|
["/recovery/request" :auth-recovery-request]
|
||||||
["/recovery" :auth-recovery]
|
["/recovery" :auth-recovery]
|
||||||
["/verify-token" :auth-verify-token]]
|
["/verify-token" :auth-verify-token]]
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
(case (get-in route [:data :name])
|
(case (get-in route [:data :name])
|
||||||
(:auth-login
|
(:auth-login
|
||||||
:auth-register
|
:auth-register
|
||||||
|
:auth-register-success
|
||||||
:auth-recovery-request
|
:auth-recovery-request
|
||||||
:auth-recovery)
|
:auth-recovery)
|
||||||
[:& auth {:route route}]
|
[:& auth {:route route}]
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
[app.main.ui.auth.login :refer [login-page]]
|
[app.main.ui.auth.login :refer [login-page]]
|
||||||
[app.main.ui.auth.recovery :refer [recovery-page]]
|
[app.main.ui.auth.recovery :refer [recovery-page]]
|
||||||
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
|
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
|
||||||
[app.main.ui.auth.register :refer [register-page]]
|
[app.main.ui.auth.register :refer [register-page register-success-page]]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.util.forms :as fm]
|
[app.util.forms :as fm]
|
||||||
[app.util.storage :refer [cache]]
|
[app.util.storage :refer [cache]]
|
||||||
|
@ -42,8 +42,18 @@
|
||||||
|
|
||||||
[:section.auth-content
|
[:section.auth-content
|
||||||
(case section
|
(case section
|
||||||
:auth-register [:& register-page {:locale locale :params params}]
|
:auth-register
|
||||||
:auth-login [:& login-page {:locale locale :params params}]
|
[:& register-page {:locale locale :params params}]
|
||||||
:auth-recovery-request [:& recovery-request-page {:locale locale}]
|
|
||||||
:auth-recovery [:& recovery-page {:locale locale
|
:auth-register-success
|
||||||
:params (:query-params route)}])]]))
|
[:& register-success-page {:params params}]
|
||||||
|
|
||||||
|
:auth-login
|
||||||
|
[:& login-page {:locale locale :params params}]
|
||||||
|
|
||||||
|
:auth-recovery-request
|
||||||
|
[:& recovery-request-page {:locale locale}]
|
||||||
|
|
||||||
|
:auth-recovery
|
||||||
|
[:& recovery-page {:locale locale
|
||||||
|
:params (:query-params route)}])]]))
|
||||||
|
|
|
@ -33,42 +33,12 @@
|
||||||
{:type :warning
|
{:type :warning
|
||||||
:content (tr "auth.demo-warning")}])
|
:content (tr "auth.demo-warning")}])
|
||||||
|
|
||||||
(defn- on-error
|
|
||||||
[form error]
|
|
||||||
(case (:code error)
|
|
||||||
:registration-disabled
|
|
||||||
(st/emit! (dm/error (tr "errors.registration-disabled")))
|
|
||||||
|
|
||||||
:email-already-exists
|
|
||||||
(swap! form assoc-in [:errors :email]
|
|
||||||
{:message "errors.email-already-exists"})
|
|
||||||
|
|
||||||
(st/emit! (dm/error (tr "errors.unexpected-error")))))
|
|
||||||
|
|
||||||
(defn- on-success
|
|
||||||
[form data]
|
|
||||||
(if (and (:is-active data) (:claims data))
|
|
||||||
(let [message (tr "auth.notifications.team-invitation-accepted")]
|
|
||||||
(st/emit! (rt/nav :dashboard-projects {:team-id (get-in data [:claims :team-id])})
|
|
||||||
du/fetch-profile
|
|
||||||
(dm/success message)))
|
|
||||||
(let [message (tr "notifications.validation-email-sent" (:email data))]
|
|
||||||
(st/emit! (rt/nav :auth-login)
|
|
||||||
(dm/success message)))))
|
|
||||||
|
|
||||||
(defn- validate
|
(defn- validate
|
||||||
[data]
|
[data]
|
||||||
(let [password (:password data)]
|
(let [password (:password data)]
|
||||||
(when (> 8 (count password))
|
(when (> 8 (count password))
|
||||||
{:password {:message "errors.password-too-short"}})))
|
{:password {:message "errors.password-too-short"}})))
|
||||||
|
|
||||||
(defn- on-submit
|
|
||||||
[form event]
|
|
||||||
(let [data (with-meta (:clean-data @form)
|
|
||||||
{:on-error (partial on-error form)
|
|
||||||
:on-success (partial on-success form)})]
|
|
||||||
(st/emit! (da/register data))))
|
|
||||||
|
|
||||||
(s/def ::fullname ::us/not-empty-string)
|
(s/def ::fullname ::us/not-empty-string)
|
||||||
(s/def ::password ::us/not-empty-string)
|
(s/def ::password ::us/not-empty-string)
|
||||||
(s/def ::email ::us/email)
|
(s/def ::email ::us/email)
|
||||||
|
@ -81,62 +51,106 @@
|
||||||
:opt-un [::token]))
|
:opt-un [::token]))
|
||||||
|
|
||||||
(mf/defc register-form
|
(mf/defc register-form
|
||||||
[{:keys [locale params] :as props}]
|
[{:keys [params] :as props}]
|
||||||
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
(let [initial (mf/use-memo (mf/deps params) (constantly params))
|
||||||
form (fm/use-form :spec ::register-form
|
form (fm/use-form :spec ::register-form
|
||||||
:validators [validate]
|
:validators [validate]
|
||||||
:initial initial)]
|
:initial initial)
|
||||||
|
submitted? (mf/use-state false)
|
||||||
|
|
||||||
|
on-error
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [form error]
|
||||||
|
(reset! submitted? false)
|
||||||
|
(case (:code error)
|
||||||
|
:registration-disabled
|
||||||
|
(st/emit! (dm/error (tr "errors.registration-disabled")))
|
||||||
|
|
||||||
|
:email-already-exists
|
||||||
|
(swap! form assoc-in [:errors :email]
|
||||||
|
{:message "errors.email-already-exists"})
|
||||||
|
|
||||||
|
(st/emit! (dm/error (tr "errors.unexpected-error"))))))
|
||||||
|
|
||||||
|
on-success
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [form data]
|
||||||
|
(reset! submitted? false)
|
||||||
|
(if (and (:is-active data) (:claims data))
|
||||||
|
(let [message (tr "auth.notifications.team-invitation-accepted")]
|
||||||
|
(st/emit! (rt/nav :dashboard-projects {:team-id (get-in data [:claims :team-id])})
|
||||||
|
du/fetch-profile
|
||||||
|
(dm/success message)))
|
||||||
|
(st/emit! (rt/nav :auth-register-success {} {:email (:email data)})))))
|
||||||
|
|
||||||
|
on-submit
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [form event]
|
||||||
|
(reset! submitted? true)
|
||||||
|
(let [data (with-meta (:clean-data @form)
|
||||||
|
{:on-error (partial on-error form)
|
||||||
|
:on-success (partial on-success form)})]
|
||||||
|
(st/emit! (da/register data)))))]
|
||||||
|
|
||||||
|
|
||||||
[:& fm/form {:on-submit on-submit
|
[:& fm/form {:on-submit on-submit
|
||||||
:form form}
|
:form form}
|
||||||
[:div.fields-row
|
[:div.fields-row
|
||||||
[:& fm/input {:name :fullname
|
[:& fm/input {:name :fullname
|
||||||
:tab-index "1"
|
:tab-index "1"
|
||||||
:label (t locale "auth.fullname")
|
:label (tr "auth.fullname")
|
||||||
:type "text"}]]
|
:type "text"}]]
|
||||||
[:div.fields-row
|
[:div.fields-row
|
||||||
[:& fm/input {:type "email"
|
[:& fm/input {:type "email"
|
||||||
:name :email
|
:name :email
|
||||||
:tab-index "2"
|
:tab-index "2"
|
||||||
:help-icon i/at
|
:help-icon i/at
|
||||||
:label (t locale "auth.email")}]]
|
:label (tr "auth.email")}]]
|
||||||
[:div.fields-row
|
[:div.fields-row
|
||||||
[:& fm/input {:name :password
|
[:& fm/input {:name :password
|
||||||
:tab-index "3"
|
:tab-index "3"
|
||||||
:hint (t locale "auth.password-length-hint")
|
:hint (tr "auth.password-length-hint")
|
||||||
:label (t locale "auth.password")
|
:label (tr "auth.password")
|
||||||
:type "password"}]]
|
:type "password"}]]
|
||||||
|
|
||||||
[:& fm/submit-button
|
[:& fm/submit-button
|
||||||
{:label (t locale "auth.register-submit")}]]))
|
{:label (tr "auth.register-submit")
|
||||||
|
:disabled @submitted?
|
||||||
|
}]]))
|
||||||
|
|
||||||
;; --- Register Page
|
;; --- Register Page
|
||||||
|
|
||||||
(mf/defc register-page
|
(mf/defc register-success-page
|
||||||
[{:keys [locale params] :as props}]
|
[{:keys [params] :as props}]
|
||||||
[:div.form-container
|
[:div.form-container
|
||||||
[:h1 (t locale "auth.register-title")]
|
[:div.subtitle (tr "auth.verification-email-sent" (:email params ""))]
|
||||||
[:div.subtitle (t locale "auth.register-subtitle")]
|
[:div.subtitle (tr "auth.check-your-email")]])
|
||||||
|
|
||||||
|
|
||||||
|
(mf/defc register-page
|
||||||
|
[{:keys [params] :as props}]
|
||||||
|
[:div.form-container
|
||||||
|
[:h1 (tr "auth.register-title")]
|
||||||
|
[:div.subtitle (tr "auth.register-subtitle")]
|
||||||
|
|
||||||
(when cfg/demo-warning
|
(when cfg/demo-warning
|
||||||
[:& demo-warning])
|
[:& demo-warning])
|
||||||
|
|
||||||
[:& register-form {:locale locale
|
[:& register-form {:params params}]
|
||||||
:params params}]
|
|
||||||
|
|
||||||
[:div.links
|
[:div.links
|
||||||
[:div.link-entry
|
[:div.link-entry
|
||||||
[:span (t locale "auth.already-have-account") " "]
|
[:span (tr "auth.already-have-account") " "]
|
||||||
[:a {:on-click #(st/emit! (rt/nav :auth-login))
|
[:a {:on-click #(st/emit! (rt/nav :auth-login))
|
||||||
:tab-index "4"}
|
:tab-index "4"}
|
||||||
(t locale "auth.login-here")]]
|
(tr "auth.login-here")]]
|
||||||
|
|
||||||
(when cfg/allow-demo-users
|
(when cfg/allow-demo-users
|
||||||
[:div.link-entry
|
[:div.link-entry
|
||||||
[:span (t locale "auth.create-demo-profile") " "]
|
[:span (tr "auth.create-demo-profile") " "]
|
||||||
[:a {:on-click #(st/emit! da/create-demo-profile)
|
[:a {:on-click #(st/emit! da/create-demo-profile)
|
||||||
:tab-index "5"}
|
:tab-index "5"}
|
||||||
(t locale "auth.create-demo-account")]])]
|
(tr "auth.create-demo-account")]])]
|
||||||
|
|
||||||
(when cfg/google-client-id
|
(when cfg/google-client-id
|
||||||
[:a.btn-ocean.btn-large.btn-google-auth
|
[:a.btn-ocean.btn-large.btn-google-auth
|
||||||
|
|
|
@ -122,12 +122,12 @@
|
||||||
i/arrow-slide]]]))
|
i/arrow-slide]]]))
|
||||||
|
|
||||||
(mf/defc submit-button
|
(mf/defc submit-button
|
||||||
[{:keys [label form on-click] :as props}]
|
[{:keys [label form on-click disabled] :as props}]
|
||||||
(let [form (or form (mf/use-ctx form-ctx))]
|
(let [form (or form (mf/use-ctx form-ctx))]
|
||||||
[:input.btn-primary.btn-large
|
[:input.btn-primary.btn-large
|
||||||
{:name "submit"
|
{:name "submit"
|
||||||
:class (when-not (:valid @form) "btn-disabled")
|
:class (when-not (:valid @form) "btn-disabled")
|
||||||
:disabled (not (:valid @form))
|
:disabled (or (not (:valid @form)) (true? disabled))
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:value label
|
:value label
|
||||||
:type "submit"}]))
|
:type "submit"}]))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue