From 9eb53cfb9c5244292e1ee5f844586de02b81e540 Mon Sep 17 00:00:00 2001 From: Luis de Dios Date: Thu, 20 Aug 2026 13:15:20 +0200 Subject: [PATCH] :bug: Fix spacing between SSO buttons and email field --- frontend/src/app/main/ui/auth.cljs | 4 +- frontend/src/app/main/ui/auth/common.scss | 248 ++++++------------ frontend/src/app/main/ui/auth/login.cljs | 111 ++++---- frontend/src/app/main/ui/auth/login.scss | 80 ++++++ frontend/src/app/main/ui/auth/recovery.cljs | 19 +- frontend/src/app/main/ui/auth/recovery.scss | 4 - .../app/main/ui/auth/recovery_request.cljs | 28 +- .../app/main/ui/auth/recovery_request.scss | 15 -- frontend/src/app/main/ui/auth/register.cljs | 113 ++++---- frontend/src/app/main/ui/auth/register.scss | 77 +++--- frontend/src/app/main/ui/static.cljs | 2 +- frontend/src/app/main/ui/viewer/login.cljs | 66 +++-- frontend/src/app/main/ui/viewer/login.scss | 86 +++--- 13 files changed, 425 insertions(+), 428 deletions(-) diff --git a/frontend/src/app/main/ui/auth.cljs b/frontend/src/app/main/ui/auth.cljs index 790d8b0a3e..a77457c70c 100644 --- a/frontend/src/app/main/ui/auth.cljs +++ b/frontend/src/app/main/ui/auth.cljs @@ -13,7 +13,7 @@ [app.main.ui.auth.login :refer [login-page*]] [app.main.ui.auth.recovery :refer [recovery-page*]] [app.main.ui.auth.recovery-request :refer [recovery-request-page*]] - [app.main.ui.auth.register :refer [register-page* register-success-page* register-validate-page* terms-register*]] + [app.main.ui.auth.register :refer [register-page* register-success-page* register-validate-page* terms-service-privacy-policy*]] [app.main.ui.ds.foundations.assets.raw-svg :refer [raw-svg*] :as raw-svg] [app.main.ui.ds.foundations.typography.heading :refer [heading*]] [app.util.dom :as dom] @@ -74,7 +74,7 @@ [:> recovery-page* {:params params}]) (when (= section :auth-register) - [:> terms-register*])]])) + [:> terms-service-privacy-policy*])]])) (mf/defc auth-page* diff --git a/frontend/src/app/main/ui/auth/common.scss b/frontend/src/app/main/ui/auth/common.scss index 951ea442a6..066b6849d0 100644 --- a/frontend/src/app/main/ui/auth/common.scss +++ b/frontend/src/app/main/ui/auth/common.scss @@ -4,56 +4,15 @@ // // Copyright (c) KALEIDOS INC Sucursal en España SL -@use "ds/_utils.scss" as *; @use "ds/_sizes.scss" as *; @use "ds/_borders.scss" as *; @use "ds/typography.scss" as *; -.auth-form-wrapper { - inline-size: 100%; - padding-block-end: 0; - display: grid; +.form { + display: flex; + flex-direction: column; gap: var(--sp-m); - - // Native
inside auth-form-wrapper — no class available - form { - display: flex; - flex-direction: column; - gap: var(--sp-m); - margin-block-start: var(--sp-m); - } -} - -.auth-title-wrapper { - inline-size: 100%; - padding-block-end: 0; - display: grid; - gap: var(--sp-s); -} - -.separator { - border-color: var(--color-background-quaternary); - margin: 0; -} - -.auth-title { - @include use-typography("title-large"); - - line-height: 1.2; - color: var(--color-foreground-primary); -} - -.auth-subtitle { - @include use-typography("title-small"); - - color: var(--color-foreground-secondary); -} - -.auth-tagline { - @include use-typography("title-small"); - - margin: 0; - color: var(--color-foreground-secondary); + margin: var(--sp-m) 0; } .form-field { @@ -62,36 +21,40 @@ --input-min-width: 100%; } -.buttons-stack { - display: grid; - gap: var(--sp-s); -} +.form-submit-btn { + --button-bg-color: var(--color-accent-primary); + --button-border-color: var(--color-accent-primary); + --button-fg-color: var(--color-background-secondary); -.login-button, -.login-ldap-button { @include use-typography("headline-small"); display: flex; justify-content: center; align-items: center; - cursor: pointer; - background-color: var(--color-accent-primary); - border: $b-1 solid var(--color-accent-primary); - color: var(--color-background-secondary); + background-color: var(--button-bg-color); + border: $b-1 solid var(--button-border-color); + color: var(--button-fg-color); border-radius: $br-8; min-block-size: $sz-32; block-size: $sz-40; inline-size: 100%; + &:hover { + --button-bg-color: var(--color-accent-tertiary); + --button-border-color: var(--color-accent-tertiary); + --button-fg-color: var(--color-background-secondary); + + text-decoration: none; + } + &:disabled { - background-color: var(--color-background-quaternary); - border: 1px solid var(--color-background-quaternary); - color: var(--color-foreground-disabled); - cursor: unset; + --button-bg-color: var(--color-background-quaternary); + --button-border-color: var(--color-background-quaternary); + --button-fg-color: var(--color-foreground-disabled); } } -.go-back { +.go-back-row { display: flex; flex-direction: column; gap: var(--sp-m); @@ -100,19 +63,68 @@ } .go-back-link { + --button-bg-color: var(--color-background-tertiary); + --button-border-color: var(--color-background-tertiary); + --button-fg-color: var(--color-foreground-secondary); + + @include use-typography("headline-small"); + background: none; - cursor: pointer; display: flex; justify-content: center; align-items: center; border-radius: $br-8; - background-color: var(--color-background-tertiary); - border: $b-1 solid var(--color-background-tertiary); - color: var(--color-foreground-secondary); - - @include use-typography("headline-small"); - + background-color: var(--button-bg-color); + border: $b-1 solid var(--button-border-color); + color: var(--button-fg-color); block-size: $sz-40; + + &:hover { + --button-bg-color: var(--color-background-quaternary); + --button-border-color: var(--color-background-quaternary); + --button-fg-color: var(--color-accent-primary); + + text-decoration: none; + } +} + +.separator { + border-color: var(--color-background-quaternary); + margin: 0; +} + +.wrapper { + inline-size: 100%; + padding-block-end: 0; + display: grid; + gap: var(--sp-m); +} + +.title-wrapper { + inline-size: 100%; + padding-block-end: 0; + display: grid; + gap: var(--sp-s); +} + +.title { + @include use-typography("title-large"); + + line-height: 1.2; + color: var(--color-foreground-primary); +} + +.subtitle { + @include use-typography("title-small"); + + color: var(--color-foreground-secondary); +} + +.tagline { + @include use-typography("title-small"); + + margin: 0; + color: var(--color-foreground-secondary); } .links { @@ -120,104 +132,10 @@ gap: var(--sp-xxl); } -.register, -.account, -.recovery-request, -.demo-account { - display: flex; - justify-content: center; - gap: var(--sp-s); - padding: 0; -} +.notification-email { + @include use-typography("title-medium"); -.register-text, -.account-text, -.recovery-text, -.demo-account-text { - @include use-typography("title-small"); - - text-align: right; - color: var(--color-foreground-secondary); -} - -.register-link, -.account-link, -.recovery-link, -.forgot-pass-link, -.demo-account-link { - @include use-typography("title-small"); - - text-align: left; - background-color: transparent; - border: none; - display: inline; + line-height: 1.2; color: var(--color-accent-primary); - - &:hover { - text-decoration: underline; - } -} - -.forgot-password { - display: flex; - justify-content: flex-end; -} - -.submit-btn, -.register-btn, -.recover-btn { - @include use-typography("headline-small"); - - background: none; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - background-color: var(--color-accent-primary); - border: $b-1 solid var(--color-accent-primary); - color: var(--color-background-secondary); - border-radius: $br-8; - min-block-size: $sz-32; - block-size: $sz-40; - inline-size: 100%; - - &:disabled { - background-color: var(--color-background-quaternary); - border: $b-1 solid var(--color-background-quaternary); - color: var(--color-foreground-disabled); - cursor: unset; - } -} - -.login-btn { - @include use-typography("title-small"); - - display: flex; - align-items: center; - gap: px2rem(6); - inline-size: 100%; - border-radius: $br-8; - background-color: var(--color-background-tertiary); - color: var(--color-foreground-primary); - - span { - padding-block-start: var(--sp-xxs); - } - - &:hover { - color: var(--color-foreground-primary); - background-color: var(--color-background-quaternary); - } - - &:disabled { - background-color: var(--color-background-quaternary); - border: 1px solid var(--color-background-quaternary); - color: var(--color-foreground-disabled); - cursor: unset; - } -} - -.auth-buttons { - display: flex; - gap: var(--sp-s); + margin-inline: $sz-36; } diff --git a/frontend/src/app/main/ui/auth/login.cljs b/frontend/src/app/main/ui/auth/login.cljs index c23cbf1c53..5cb6953f6d 100644 --- a/frontend/src/app/main/ui/auth/login.cljs +++ b/frontend/src/app/main/ui/auth/login.cljs @@ -71,10 +71,17 @@ (mf/defc login-form* [{:keys [params handle-redirect on-success-callback on-recovery-request origin] :as props}] (let [initial (mf/with-memo [params] params) - error (mf/use-state false) + form (fm/use-form :schema schema:login-form :initial initial) + + error (mf/use-state false) + + show-password-field* (mf/use-state #(not (contains? cf/flags :login-with-custom-sso))) + show-password-field? (deref show-password-field*) + callback-url (:callback-url params) + on-error (fn [cause] (let [cause (ex-data cause)] @@ -102,12 +109,6 @@ :else (reset! error (tr "errors.generic"))))) - show-password-field* - (mf/use-state #(not (contains? cf/flags :login-with-custom-sso))) - - show-password-field? - (deref show-password-field*) - on-success (fn [data] (when (fn? on-success-callback) @@ -130,7 +131,8 @@ (->> (rp/cmd! :get-sso-provider {:email (:email params)}) (rx/map :id) (rx/catch (fn [cause] - (log/error :hint "error on retrieving sso provider" :cause cause) + (log/error :hint "error on retrieving sso provider" + :cause cause) (rx/of nil))) (rx/subs! (fn [sso-provider-id] (if sso-provider-id @@ -139,7 +141,7 @@ (reset! show-password-field* true)))))))))) on-submit-ldap - (mf/use-callback + (mf/use-fn (mf/deps form) (fn [event] (dom/prevent-default event) @@ -168,91 +170,102 @@ {:level :error} message]) [:& fm/form {:on-submit on-submit - :class (stl/css :login-form) + :class (stl/css :form) :form form} - [:div {:class (stl/css :fields-row)} - [:& fm/input - {:name :email - :type "email" - :label (tr "auth.work-email") - :class (stl/css :form-field)}]] + [:div {:class (stl/css :form-row)} + [:& fm/input {:name :email + :type "email" + :label (tr "auth.work-email") + :class (stl/css :form-field)}]] (when show-password-field? - [:div {:class (stl/css :fields-row)} - [:& fm/input - {:type "password" - :name :password - :auto-focus? true - :label (tr "auth.password") - :class (stl/css :form-field)}]]) + [:div {:class (stl/css :form-row)} + [:& fm/input {:type "password" + :name :password + :auto-focus? true + :label (tr "auth.password") + :class (stl/css :form-field)}]]) (when (and (not= origin :viewer) (or (contains? cf/flags :login) (contains? cf/flags :login-with-password))) - [:div {:class (stl/css :fields-row :forgot-password)} + [:div {:class (stl/css :form-row :forgot-password-row)} [:> lk/link* {:action on-recovery-request - :class (stl/css :forgot-pass-link) + :class (stl/css :forgot-password-link) :data-testid "forgot-password"} (tr "auth.forgot-password")]]) - [:div {:class (stl/css :buttons-stack)} + [:div {:class (stl/css :form-submit-buttons)} (when (or (contains? cf/flags :login) (contains? cf/flags :login-with-password)) - [:> fm/submit-button* - {:label (tr "labels.continue") - :data-testid "login-submit" - :class (stl/css :login-button)}]) + [:> fm/submit-button* {:label (tr "labels.continue") + :data-testid "login-submit" + :class (stl/css :form-submit-btn)}]) (when (contains? cf/flags :login-with-ldap) - [:> fm/submit-button* - {:label (tr "auth.login-with-ldap-submit") - :class (stl/css :login-ldap-button) - :on-click on-submit-ldap}])]]])) + [:> fm/submit-button* {:label (tr "auth.login-with-ldap-submit") + :class (stl/css :form-submit-btn) + :on-click on-submit-ldap}])]]])) (defn raw-icon [id] (mf/html [:> raw-svg* {:id id :class (stl/css :sso-icon)}])) -(mf/defc login-sso-buttons* +(mf/defc sso-buttons* [{:keys [params] :as props}] - (let [login-with-google (mf/use-fn (mf/deps params) #(login-with-sso "google" params)) - login-with-github (mf/use-fn (mf/deps params) #(login-with-sso "github" params)) - login-with-gitlab (mf/use-fn (mf/deps params) #(login-with-sso "gitlab" params)) - login-with-oidc (mf/use-fn (mf/deps params) #(login-with-sso "oidc" params))] + (let [login-with-google + (mf/use-fn + (mf/deps params) + #(login-with-sso "google" params)) - [:div {:class (stl/css :auth-buttons)} + login-with-github + (mf/use-fn + (mf/deps params) + #(login-with-sso "github" params)) + + login-with-gitlab + (mf/use-fn + (mf/deps params) + #(login-with-sso "gitlab" params)) + + login-with-oidc + (mf/use-fn + (mf/deps params) + #(login-with-sso "oidc" params))] + + [:div {:class (stl/css :sso-row)} (when (contains? cf/flags :login-with-google) [:> bl/button-link* {:on-click login-with-google :icon (raw-icon raw-icons/brand-google) :label (tr "auth.login-with-google-submit") - :class (stl/css :login-btn :btn-google-auth)}]) + :class (stl/css :sso-btn)}]) (when (contains? cf/flags :login-with-github) [:> bl/button-link* {:on-click login-with-github :icon (raw-icon raw-icons/brand-github) :label (tr "auth.login-with-github-submit") - :class (stl/css :login-btn :btn-github-auth)}]) + :class (stl/css :sso-btn)}]) (when (contains? cf/flags :login-with-gitlab) [:> bl/button-link* {:on-click login-with-gitlab :icon (raw-icon raw-icons/brand-gitlab) :label (tr "auth.login-with-gitlab-submit") - :class (stl/css :login-btn :btn-gitlab-auth)}]) + :class (stl/css :sso-btn)}]) (when (contains? cf/flags :login-with-oidc) [:> bl/button-link* {:on-click login-with-oidc :icon (raw-icon raw-icons/brand-openid) :label (or (not-empty cf/oidc-name) (tr "auth.login-with-oidc-submit")) - :class (stl/css :login-btn :btn-oidc-auth)}])])) + :class (stl/css :sso-btn)}])])) (mf/defc login-dialog* [{:keys [params] :as props}] [:* (when show-sso-login-buttons? [:* - [:> login-sso-buttons* {:params params}] + [:> sso-buttons* {:params params}] (when (or (contains? cf/flags :login) (contains? cf/flags :login-with-password) @@ -270,11 +283,11 @@ (mf/use-fn #(st/emit! (rt/nav :auth-register params)))] - [:div {:class (stl/css :auth-form-wrapper)} - [:h1 {:class (stl/css :auth-title) + [:div {:class (stl/css :wrapper)} + [:h1 {:class (stl/css :title) :data-testid "login-title"} (tr "auth.login-account-title")] - [:p {:class (stl/css :auth-tagline)} + [:p {:class (stl/css :tagline)} (tr "auth.login-tagline")] (when (contains? cf/flags :demo-warning) @@ -286,7 +299,7 @@ [:div {:class (stl/css :links)} (when (contains? cf/flags :registration) - [:div {:class (stl/css :register)} + [:div {:class (stl/css :register-row)} [:span {:class (stl/css :register-text)} (tr "auth.register") " "] [:> lk/link* {:action go-register diff --git a/frontend/src/app/main/ui/auth/login.scss b/frontend/src/app/main/ui/auth/login.scss index 5aa37946bb..270eea41bf 100644 --- a/frontend/src/app/main/ui/auth/login.scss +++ b/frontend/src/app/main/ui/auth/login.scss @@ -6,8 +6,88 @@ @use "./common"; @use "ds/_utils.scss" as *; +@use "ds/_sizes.scss" as *; +@use "ds/_borders.scss" as *; +@use "ds/typography.scss" as *; + +.forgot-password-row { + display: flex; + justify-content: flex-end; +} + +.forgot-password-link { + @include use-typography("title-small"); + + text-align: left; + background-color: transparent; + border: none; + display: inline; + color: var(--color-accent-primary); + + &:hover { + text-decoration: underline; + } +} + +.form-submit-buttons { + display: grid; + gap: var(--sp-s); +} .sso-icon { max-inline-size: px2rem(26); max-block-size: px2rem(26); } + +.sso-row { + display: flex; + gap: var(--sp-s); +} + +.sso-btn { + --button-bg-color: var(--color-background-tertiary); + --button-fg-color: var(--color-foreground-primary); + + @include use-typography("title-small"); + + display: flex; + align-items: center; + gap: px2rem(6); + inline-size: 100%; + border-radius: $br-8; + background-color: var(--button-bg-color); + color: var(--button-fg-color); + + &:hover { + --button-bg-color: var(--color-background-quaternary); + --button-fg-color: var(--color-foreground-primary); + } +} + +.register-row { + display: flex; + justify-content: center; + gap: var(--sp-s); + padding: 0; +} + +.register-text { + @include use-typography("title-small"); + + text-align: right; + color: var(--color-foreground-secondary); +} + +.register-link { + @include use-typography("title-small"); + + text-align: left; + background-color: transparent; + border: none; + display: inline; + color: var(--color-accent-primary); + + &:hover { + text-decoration: underline; + } +} diff --git a/frontend/src/app/main/ui/auth/recovery.cljs b/frontend/src/app/main/ui/auth/recovery.cljs index d91f200db9..854de36d80 100644 --- a/frontend/src/app/main/ui/auth/recovery.cljs +++ b/frontend/src/app/main/ui/auth/recovery.cljs @@ -60,39 +60,38 @@ :initial params)] [:& fm/form {:on-submit on-submit - :class (stl/css :recovery-form) + :class (stl/css :form) :form form} - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:type "password" :name :password-1 :show-success? true :label (tr "auth.new-password") :class (stl/css :form-field)}]] - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:type "password" :name :password-2 :show-success? true :label (tr "auth.confirm-password") :class (stl/css :form-field)}]] - [:> fm/submit-button* - {:label (tr "auth.recovery-submit") - :class (stl/css :submit-btn)}]])) + [:> fm/submit-button* {:label (tr "auth.recovery-submit") + :class (stl/css :form-submit-btn)}]])) ;; --- Recovery Request Page (mf/defc recovery-page* [{:keys [params]}] - [:div {:class (stl/css :auth-form-wrapper)} - [:h1 {:class (stl/css :auth-title)} "Forgot your password?"] - [:div {:class (stl/css :auth-subtitle)} "Please enter your new password"] + [:div {:class (stl/css :wrapper)} + [:h1 {:class (stl/css :title)} "Forgot your password?"] + [:div {:class (stl/css :subtitle)} "Please enter your new password"] [:hr {:class (stl/css :separator)}] [:> recovery-form* {:params params}] [:div {:class (stl/css :links)} - [:div {:class (stl/css :go-back)} + [:div {:class (stl/css :go-back-row)} [:a {:on-click #(st/emit! (rt/nav :auth-login)) :class (stl/css :go-back-link)} (tr "profile.recovery.go-to-login")]]]]) diff --git a/frontend/src/app/main/ui/auth/recovery.scss b/frontend/src/app/main/ui/auth/recovery.scss index 4d0d4750bd..136a0cd63a 100644 --- a/frontend/src/app/main/ui/auth/recovery.scss +++ b/frontend/src/app/main/ui/auth/recovery.scss @@ -5,7 +5,3 @@ // Copyright (c) KALEIDOS INC Sucursal en España SL @use "./common"; - -.submit-btn { - margin-block-start: var(--sp-l); -} diff --git a/frontend/src/app/main/ui/auth/recovery_request.cljs b/frontend/src/app/main/ui/auth/recovery_request.cljs index 78caa421ff..d6b8338bee 100644 --- a/frontend/src/app/main/ui/auth/recovery_request.cljs +++ b/frontend/src/app/main/ui/auth/recovery_request.cljs @@ -70,18 +70,17 @@ (st/emit! (du/request-profile-recovery params)))))] [:& fm/form {:on-submit on-submit - :class (stl/css :recovery-request-form) + :class (stl/css :form) :form form} - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:name :email :label (tr "auth.work-email") :type "text" :class (stl/css :form-field)}]] - [:> fm/submit-button* - {:label (tr "auth.recovery-request-submit") - :data-testid "recovery-resquest-submit" - :class (stl/css :recover-btn)}]])) + [:> fm/submit-button* {:label (tr "auth.recovery-request-submit") + :data-testid "recovery-resquest-submit" + :class (stl/css :form-submit-btn)}]])) ;; --- Recovery Request Page @@ -90,14 +89,14 @@ [{:keys [params on-success-callback go-back-callback]}] (let [default-go-back #(st/emit! (rt/nav :auth-login)) go-back (or go-back-callback default-go-back)] - [:div {:class (stl/css :auth-form-wrapper)} - [:h1 {:class (stl/css :auth-title)} (tr "auth.recovery-request-title")] - [:div {:class (stl/css :auth-subtitle)} (tr "auth.recovery-request-subtitle")] + [:div {:class (stl/css :wrapper)} + [:h1 {:class (stl/css :title)} (tr "auth.recovery-request-title")] + [:div {:class (stl/css :subtitle)} (tr "auth.recovery-request-subtitle")] [:hr {:class (stl/css :separator)}] [:> recovery-form* {:params params :on-success-callback on-success-callback}] [:hr {:class (stl/css :separator)}] - [:div {:class (stl/css :go-back)} + [:div {:class (stl/css :go-back-row)} [:> lk/link* {:action go-back :class (stl/css :go-back-link) :data-testid "go-back-link"} @@ -106,11 +105,10 @@ (mf/defc recovery-sent-page* [{:keys [email]}] - [:div {:class (stl/css :auth-form-wrapper :register-success)} - [:div {:class (stl/css :auth-title-wrapper)} - [:h2 {:class (stl/css :auth-title)} + [:div {:class (stl/css :wrapper :register-success)} + [:div {:class (stl/css :title-wrapper)} + [:h2 {:class (stl/css :title)} (tr "auth.check-email")] [:div {:class (stl/css :notification-text)} (tr "not-found.login.sent-recovery")]] - [:div {:class (stl/css :notification-text-email)} email] + [:div {:class (stl/css :notification-email)} email] [:div {:class (stl/css :notification-text)} (tr "not-found.login.sent-recovery-check")]]) - diff --git a/frontend/src/app/main/ui/auth/recovery_request.scss b/frontend/src/app/main/ui/auth/recovery_request.scss index 11d45df27b..136a0cd63a 100644 --- a/frontend/src/app/main/ui/auth/recovery_request.scss +++ b/frontend/src/app/main/ui/auth/recovery_request.scss @@ -4,19 +4,4 @@ // // Copyright (c) KALEIDOS INC Sucursal en España SL -@use "ds/_utils.scss" as *; -@use "ds/_sizes.scss" as *; -@use "ds/typography.scss" as *; @use "./common"; - -.fields-row { - margin-block-end: var(--sp-s); -} - -.notification-text-email { - @include use-typography("title-medium"); - - line-height: 1.2; - color: var(--color-accent-primary); - margin-inline: $sz-36; -} diff --git a/frontend/src/app/main/ui/auth/register.cljs b/frontend/src/app/main/ui/auth/register.cljs index be5f3f280b..41acc9e841 100644 --- a/frontend/src/app/main/ui/auth/register.cljs +++ b/frontend/src/app/main/ui/auth/register.cljs @@ -26,39 +26,38 @@ ;; --- PAGE: Register -(mf/defc newsletter-options* +(mf/defc newsletter-checkbox* {::mf/private true} [] - (let [updates-label + (let [newsletter-label (mf/html - [:> i18n/tr-html* - {:tag-name "div" - :content (tr "onboarding-v2.newsletter.updates")}])] - [:div {:class (stl/css :fields-row :input-visible :newsletter-option-wrapper)} + [:> i18n/tr-html* {:tag-name "div" + :content (tr "onboarding-v2.newsletter.updates")}])] + + [:div {:class (stl/css :form-row :input-visible :newsletter-option-wrapper)} [:& fm/input {:name :accept-newsletter-updates :class (stl/css :checkbox-newsletter-updates) :type "checkbox" :default-checked false - :label updates-label}]])) + :label newsletter-label}]])) -(mf/defc terms-and-privacy* +(mf/defc terms-and-privacy-checkbox* {::mf/private true} [] - (let [terms-label + (let [terms-and-privacy-label (mf/html - [:> i18n/tr-html* - {:tag-name "div" - :content (tr "auth.terms-and-privacy-agreement" - cf/terms-of-service-uri - cf/privacy-policy-uri)}])] + [:> i18n/tr-html* {:tag-name "div" + :content (tr "auth.terms-and-privacy-agreement" + cf/terms-of-service-uri + cf/privacy-policy-uri)}])] - [:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)} + [:div {:class (stl/css :form-row :input-visible :accept-terms-and-privacy-wrapper)} [:& fm/input {:name :accept-terms-and-privacy :show-error false :class (stl/css :checkbox-terms-and-privacy) :type "checkbox" :default-checked false - :label terms-label}]])) + :label terms-and-privacy-label}]])) (def ^:private schema:register-form [:map {:title "RegisterForm"} @@ -76,8 +75,7 @@ form (fm/use-form :schema schema:register-form :initial initial) - submitted? - (mf/use-state false) + submitted? (mf/use-state false) on-error (mf/use-fn @@ -167,22 +165,24 @@ (->> (rp/cmd! :prepare-register-profile cdata) (rx/subs! on-register-profile on-error #(reset! submitted? false))))))] - [:& fm/form {:on-submit on-submit :form form} - [:div {:class (stl/css :fields-row)} + [:& fm/form {:on-submit on-submit + :form form + :class (stl/css :form)} + [:div {:class (stl/css :form-row)} [:& fm/input {:name :fullname :label (tr "auth.fullname") :type "text" :show-success? true :class (stl/css :form-field)}]] - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:type "text" :name :email :label (tr "auth.work-email") :data-testid "email-input" :show-success? true :class (stl/css :form-field)}]] - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:name :password :hint (tr "auth.password-length-hint") :label (tr "auth.password") @@ -191,21 +191,20 @@ :class (stl/css :form-field)}]] (when (contains? cf/flags :terms-and-privacy-checkbox) - [:> terms-and-privacy*]) + [:> terms-and-privacy-checkbox*]) - [:> newsletter-options*] + [:> newsletter-checkbox*] - [:> fm/submit-button* - {:label (tr "auth.register-submit") - :disabled @submitted? - :data-testid "register-form-submit" - :class (stl/css :register-btn)}]])) + [:> fm/submit-button* {:label (tr "auth.register-submit") + :disabled @submitted? + :data-testid "register-form-submit" + :class (stl/css :form-submit-btn)}]])) (mf/defc register-methods* [{:keys [params hide-separator on-success-callback]}] [:* (when login/show-sso-login-buttons? - [:> login/login-sso-buttons* {:params params}]) + [:> login/sso-buttons* {:params params}]) (when (or login/show-sso-login-buttons? (false? hide-separator)) [:hr {:class (stl/css :separator)}]) (when (contains? cf/flags :login-with-password) @@ -213,8 +212,8 @@ (mf/defc register-page* [{:keys [params]}] - [:div {:class (stl/css :auth-form-wrapper :register-form)} - [:h1 {:class (stl/css :auth-title) + [:div {:class (stl/css :wrapper :register-form)} + [:h1 {:class (stl/css :title) :data-testid "registration-title"} (tr "auth.register-title")] (when (contains? cf/flags :demo-warning) @@ -223,7 +222,7 @@ [:> register-methods* {:params params}] [:div {:class (stl/css :links)} - [:div {:class (stl/css :account)} + [:div {:class (stl/css :account-row)} [:span {:class (stl/css :account-text)} (tr "auth.already-have-account") " "] [:> lk/link* {:action #(st/emit! (rt/nav :auth-login params)) :class (stl/css :account-link) @@ -233,9 +232,9 @@ (when (contains? cf/flags :demo-users) [:* [:hr {:class (stl/css :separator)}] - [:div {:class (stl/css :demo-account)} + [:div {:class (stl/css :account-row)} [:> lk/link* {:action login/create-demo-profile - :class (stl/css :demo-account-link)} + :class (stl/css :account-link)} (tr "auth.create-demo-account")]]])]]) @@ -244,31 +243,31 @@ (mf/defc register-success-page* [{:keys [params]}] (let [email (or (:email params) (::email storage/user))] - [:div {:class (stl/css :auth-form-wrapper :register-success)} - [:div {:class (stl/css :auth-title-wrapper)} - [:h2 {:class (stl/css :auth-title)} + [:div {:class (stl/css :wrapper :register-success)} + [:div {:class (stl/css :title-wrapper)} + [:h2 {:class (stl/css :register-success-title)} (tr "auth.check-email")] [:div {:class (stl/css :notification-text)} (tr "auth.verification-sent-email")]] - [:div {:class (stl/css :notification-text-email)} email]])) + [:div {:class (stl/css :notification-email)} email]])) -(mf/defc terms-register* +(mf/defc terms-service-privacy-policy* [] (let [show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri) show-terms? (some? cf/terms-of-service-uri) show-privacy? (some? cf/privacy-policy-uri)] (when show-all? - [:div {:class (stl/css :terms-register)} + [:div {:class (stl/css :terms)} (when show-terms? - [:a {:href cf/terms-of-service-uri :target "_blank" :class (stl/css :auth-link)} + [:a {:href cf/terms-of-service-uri :target "_blank" :class (stl/css :terms-link)} (tr "auth.terms-of-service")]) (when show-all? - [:span {:class (stl/css :and-text)} + [:span {:class (stl/css :terms-and)} (dm/str " " (tr "labels.and") " ")]) (when show-privacy? - [:a {:href cf/privacy-policy-uri :target "_blank" :class (stl/css :auth-link)} + [:a {:href cf/privacy-policy-uri :target "_blank" :class (stl/css :terms-link)} (tr "auth.privacy-policy")])]))) ;; --- PAGE: register validation @@ -334,9 +333,9 @@ [:& fm/form {:on-submit on-submit :form form - :class (stl/css :register-validate-form)} + :class (stl/css :auth-form)} - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :form-row)} [:& fm/input {:name :fullname :label (tr "auth.fullname") :type "text" @@ -344,30 +343,28 @@ :class (stl/css :form-field)}]] (when (contains? cf/flags :terms-and-privacy-checkbox) - [:> terms-and-privacy*]) + [:> terms-and-privacy-checkbox*]) - [:> newsletter-options*] - - [:> fm/submit-button* - {:label (tr "auth.register-submit") - :disabled @submitted? - :class (stl/css :register-btn)}]])) + [:> newsletter-checkbox*] + [:> fm/submit-button* {:label (tr "auth.register-submit") + :disabled @submitted? + :class (stl/css :form-submit-btn)}]])) (mf/defc register-validate-page* [{:keys [params]}] - [:div {:class (stl/css :auth-form-wrapper :register-form)} + [:div {:class (stl/css :wrapper :register-form)} - [:div {:class (stl/css :auth-title-wrapper)} - [:h2 {:class (stl/css :auth-title) + [:div {:class (stl/css :title-wrapper)} + [:h2 {:class (stl/css :title) :data-testid "register-title"} (tr "auth.register-account-title")] - [:div {:class (stl/css :auth-subtitle)} (tr "auth.register-account-tagline")]] + [:div {:class (stl/css :subtitle)} (tr "auth.register-account-tagline")]] [:> register-validate-form* {:params params}] [:div {:class (stl/css :links)} - [:div {:class (stl/css :go-back)} + [:div {:class (stl/css :go-back-row)} [:> lk/link* {:action #(st/emit! (rt/nav :auth-register {})) :class (stl/css :go-back-link)} (tr "labels.go-back")]]]]) diff --git a/frontend/src/app/main/ui/auth/register.scss b/frontend/src/app/main/ui/auth/register.scss index 1b238cb353..71b7c8b4a0 100644 --- a/frontend/src/app/main/ui/auth/register.scss +++ b/frontend/src/app/main/ui/auth/register.scss @@ -4,57 +4,64 @@ // // Copyright (c) KALEIDOS INC Sucursal en España SL +@use "./common"; @use "ds/_utils.scss" as *; @use "ds/_sizes.scss" as *; @use "ds/_borders.scss" as *; @use "ds/typography.scss" as *; -@use "./common"; -.checkbox-terms-and-privacy, .checkbox-newsletter-updates { align-items: flex-start; } +.checkbox-terms-and-privacy { + align-items: flex-start; +} + .register-form { gap: var(--sp-xxl); } +.account-row { + display: flex; + justify-content: center; + gap: var(--sp-s); + padding: 0; +} + +.account-text { + @include use-typography("title-small"); + + text-align: right; + color: var(--color-foreground-secondary); +} + +.account-link { + @include use-typography("title-small"); + + text-align: left; + background-color: transparent; + border: none; + display: inline; + color: var(--color-accent-primary); + + &:hover { + text-decoration: underline; + } +} + .register-success { gap: var(--sp-xxl); } -.register-success .auth-title { +.register-success-title { @include use-typography("title-medium"); line-height: 1.2; + color: var(--color-foreground-primary); } -.notification-text { - @include use-typography("body-medium"); - - color: var(--color-foreground-secondary); -} - -.notification-text-email { - @include use-typography("title-medium"); - - line-height: 1.2; - color: var(--color-accent-primary); - margin-inline: $sz-36; -} - -.logo-btn { - block-size: $sz-40; -} - -.logo-container { - display: flex; - justify-content: flex-start; - inline-size: $sz-120; - margin-block-end: var(--sp-xxl); -} - -.terms-register { +.terms { @include use-typography("body-small"); display: flex; @@ -63,15 +70,15 @@ inline-size: 100%; } -.and-text { - border-block-end: $b-1 solid transparent; - color: var(--color-foreground-secondary); -} - -.auth-link { +.terms-link { color: var(--color-accent-primary); &:hover { text-decoration: underline; } } + +.terms-and { + border-block-end: $b-1 solid transparent; + color: var(--color-foreground-secondary); +} diff --git a/frontend/src/app/main/ui/static.cljs b/frontend/src/app/main/ui/static.cljs index 95b73d0191..543eede969 100644 --- a/frontend/src/app/main/ui/static.cljs +++ b/frontend/src/app/main/ui/static.cljs @@ -185,7 +185,7 @@ :on-click set-section} (tr "auth.login-here")]] [:div {:class (stl/css :links)} [:hr {:class (stl/css :separator)}] - [:> register/terms-register*]]] + [:> register/terms-service-privacy-policy*]]] :register-validate [:div {:class (stl/css :form-container)} diff --git a/frontend/src/app/main/ui/viewer/login.cljs b/frontend/src/app/main/ui/viewer/login.cljs index 0371714419..6ede841b73 100644 --- a/frontend/src/app/main/ui/viewer/login.cljs +++ b/frontend/src/app/main/ui/viewer/login.cljs @@ -12,8 +12,10 @@ [app.main.store :as st] [app.main.ui.auth.login :refer [login-dialog*]] [app.main.ui.auth.recovery-request :refer [recovery-request-page*]] - [app.main.ui.auth.register :refer [register-methods* register-success-page* terms-register* register-validate-form*]] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.auth.register :refer [register-methods* register-success-page* + register-validate-form* terms-service-privacy-policy*]] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.foundations.assets.icon :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -24,14 +26,15 @@ {::mf/register modal/components ::mf/register-as :login-register} [_] - (let [user-email (mf/use-state "") + (let [user-email (mf/use-state "") register-token (mf/use-state "") current-section* (mf/use-state :login) - current-section (deref current-section*) + current-section (deref current-section*) set-current-section - (mf/use-fn #(reset! current-section* %)) + (mf/use-fn + #(reset! current-section* %)) set-section (mf/use-fn @@ -41,7 +44,9 @@ (keyword))] (set-current-section section)))) - go-back-to-login (mf/use-fn #(set-current-section :login)) + go-back-to-login + (mf/use-fn + #(set-current-section :login)) main-section (or (= current-section :login) @@ -51,13 +56,16 @@ (fn [event] (dom/prevent-default event) (st/emit! (modal/hide))) + success-email-sent (fn [email] (reset! user-email email) (set-current-section :email-sent)) + success-login (fn [] (.reload js/window.location true)) + success-register (fn [data] (reset! register-token (:token data)) @@ -66,48 +74,47 @@ [:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)} - [:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")] - [:button {:class (stl/css :modal-close-btn) - :title (tr "labels.close") - :on-click close} deprecated-icon/close]] + [:h2 {:class (stl/css :modal-header-title)} (tr "labels.continue-with-penpot")] + [:> icon-button* {:variant "ghost" + :class (stl/css :modal-close) + :aria-label (tr "labels.close") + :on-click close + :icon i/close}]] [:div {:class (stl/css :modal-content)} (case current-section :login - [:div {:class (stl/css :form-container)} - [:> login-dialog* - {:on-success-callback success-login - :origin :viewer}] - [:div {:class (stl/css :links)} - [:div {:class (stl/css :recovery-request)} + [:div {:class (stl/css :login-form)} + [:> login-dialog* {:on-success-callback success-login + :origin :viewer}] + [:div {:class (stl/css :login-links)} + [:div [:a {:on-click set-section - :class (stl/css :recovery-link) :data-value "recovery-request"} (tr "auth.forgot-password")]] - [:div {:class (stl/css :register)} - [:span {:class (stl/css :register-text)} + [:div + [:span (tr "auth.register") " "] [:a {:on-click set-section - :class (stl/css :register-link) :data-value "register"} (tr "auth.register-submit")]]]] :register - [:div {:class (stl/css :form-container)} + [:div {:class (stl/css :login-form)} [:> register-methods* {:on-success-callback success-register}] - [:div {:class (stl/css :links)} - [:div {:class (stl/css :account)} + [:div {:class (stl/css :login-links)} + [:div [:span (tr "auth.already-have-account") " "] [:a {:on-click set-section :data-value "login"} (tr "auth.login-here")]]]] :register-validate - [:div {:class (stl/css :form-container)} + [:div {:class (stl/css :login-form)} [:> register-validate-form* {:params {:token @register-token} :on-success-callback success-email-sent}] - [:div {:class (stl/css :links)} - [:div {:class (stl/css :register)} + [:div {:class (stl/css :login-links)} + [:div [:a {:on-click set-section :data-value "register"} (tr "labels.go-back")]]]] @@ -115,10 +122,11 @@ :recovery-request [:> recovery-request-page* {:go-back-callback go-back-to-login :on-success-callback success-email-sent}] + :email-sent - [:div {:class (stl/css :form-container)} + [:div {:class (stl/css :login-form)} [:> register-success-page* {:params {:email @user-email}}]]) (when main-section - [:div {:class (stl/css :links)} - [:> terms-register*]])]]])) + [:div {:class (stl/css :login-links)} + [:> terms-service-privacy-policy*]])]]])) diff --git a/frontend/src/app/main/ui/viewer/login.scss b/frontend/src/app/main/ui/viewer/login.scss index 11cb81d678..227d160ea6 100644 --- a/frontend/src/app/main/ui/viewer/login.scss +++ b/frontend/src/app/main/ui/viewer/login.scss @@ -4,75 +4,71 @@ // // Copyright (c) KALEIDOS INC Sucursal en España SL -@use "refactor/common-refactor.scss" as deprecated; +@use "ds/_utils.scss" as *; +@use "ds/_sizes.scss" as *; +@use "ds/_borders.scss" as *; +@use "ds/typography.scss" as *; +@use "ds/z-index.scss" as *; .modal-overlay { - @extend %modal-overlay-base; + display: flex; + justify-content: center; + align-items: center; + position: fixed; + inset: 0; + block-size: 100%; + inline-size: 100%; + z-index: var(--z-index-set); + background-color: var(--color-overlay-default); } .modal-container { - @extend %modal-container-base; - - width: deprecated.$s-368; + position: relative; + padding: var(--sp-xxxl); + border-radius: $br-8; + background-color: var(--color-background-primary); + border: $b-2 solid var(--color-background-quaternary); + min-inline-size: $sz-364; + min-block-size: $sz-192; + max-inline-size: $sz-512; + max-block-size: $sz-712; + inline-size: $sz-364; } .modal-header { - margin-bottom: deprecated.$s-24; + margin-block-end: var(--sp-xxl); } -.modal-title { - @include deprecated.uppercase-title-typography; +.modal-header-title { + @include use-typography("headline-small"); - color: var(--modal-title-foreground-color); + color: var(--color-foreground-primary); } -.modal-close-btn { - @extend %modal-close-btn-base; +.modal-close { + position: absolute; + inset-block-start: var(--sp-s); + inset-inline-end: var(--sp-s); } .modal-content { - @include deprecated.flex-column; - @include deprecated.body-small-typography; + @include use-typography("body-small"); - gap: deprecated.$s-24; - max-height: deprecated.$s-400; + display: flex; + flex-direction: column; + gap: var(--sp-xxl); + max-block-size: px2rem(576); overflow: hidden auto; - - form { - display: flex; - flex-direction: column; - margin-bottom: 1.5rem; - gap: 0.75rem; - } } -.form-container { +.login-form { display: flex; justify-content: center; flex-direction: column; + gap: var(--sp-m); } -.links { +.login-links { position: relative; -} - -.link-entry { - display: flex; - flex-direction: column; - gap: deprecated.$s-12; - - span { - text-align: center; - font-size: deprecated.$fs-14; - color: var(--modal-text-foreground-color); - margin-top: deprecated.$s-12; - } - - a { - @extend %button-secondary; - - height: deprecated.$s-40; - text-transform: uppercase; - font-size: deprecated.$fs-11; - } + color: var(--color-foreground-primary); }