0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-01 17:41:50 -05:00

💄 New UI for auth screens

This commit is contained in:
alonso.torres 2023-11-30 00:16:38 +01:00
parent 727d3cfb77
commit fa711cdd75
37 changed files with 1074 additions and 324 deletions

View file

@ -13,6 +13,7 @@
"A common flags that affects both: backend and frontend."
[:enable-registration
:enable-login-with-password
:enable-login-illustration
:enable-feature-styles-v2])
(defn parse

View file

@ -1,7 +1,6 @@
const fs = require("fs");
const l = require("lodash");
const path = require("path");
const stringHash = require("string-hash");
const gulp = require("gulp");
const gulpConcat = require("gulp-concat");
@ -13,7 +12,6 @@ const gulpSass = require("gulp-sass")(require("sass"));
const svgSprite = require("gulp-svg-sprite");
const rename = require("gulp-rename");
const autoprefixer = require("autoprefixer");
const modules = require("postcss-modules");

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

@ -4,6 +4,8 @@
//
// Copyright (c) KALEIDOS INC
@use "sass:color" as color;
:root {
// DARK
--dark-gray-1: #1d1f20;
@ -46,4 +48,21 @@
//GENERIC
--color-canvas: #e8e9ea;
// SOCIAL LOGIN BUTTONS
--google-login-background: #4285f4;
--google-login-background-hover: #{color.adjust(#4285f4, $lightness: -15%)};
--google-login-foreground: var(--white);
--github-login-background: #4c4c4c;
--github-login-background-hover: #{color.adjust(#4c4c4c, $lightness: -15%)};
--github-login-foreground: var(--white);
--oidc-login-background: #b3b3b3;
--oidc-login-background-hover: #{color.adjust(#b3b3b3, $lightness: -15%)};
--oidc-login-foreground: var(--white);
--gitlab-login-background: #fc6d26;
--gitlab-login-background-hover: #{color.adjust(#fc6d26, $lightness: -15%)};
--gitlab-login-foreground: var(--white);
}

View file

@ -145,6 +145,7 @@ $s-580: #{0.25 * 145}rem;
$s-612: #{0.25 * 153}rem;
$s-640: #{0.25 * 160}rem;
$s-664: #{0.25 * 166}rem;
$s-688: #{0.25 * 172}rem;
$s-712: #{0.25 * 178}rem;
$s-736: #{0.25 * 184}rem;
$s-800: #{0.25 * 200}rem;

View file

@ -100,8 +100,8 @@
(def browser (parse-browser))
(def platform (parse-platform))
(def terms-of-service-uri (obj/get global "penpotTermsOfServiceURI" nil))
(def privacy-policy-uri (obj/get global "penpotPrivacyPolicyURI" nil))
(def terms-of-service-uri (obj/get global "penpotTermsOfServiceURI" "https://penpot.app/terms"))
(def privacy-policy-uri (obj/get global "penpotPrivacyPolicyURI" "https://penpot.app/privacy"))
(defn- normalize-uri
[uri-str]

View file

@ -14,7 +14,7 @@
[cuerdas.core :as str]
[rumext.v2.util :as mfu]))
;; Should coincide with the `ROOT_NAME` constant in gulpfile.js
;; Should match with the `ROOT_NAME` constant in gulpfile.js
(def ROOT-NAME "app")
(def ^:dynamic *css-prefix* nil)

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth
(:require-macros [app.main.style :as stl])
(:require
[app.config :as cf]
[app.main.ui.auth.login :refer [login-page]]
@ -19,57 +20,99 @@
(mf/defc terms-login
[]
(let [show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
(let [new-css-system (mf/use-ctx ctx/new-css-system)
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.terms-login
(when show-terms?
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
(if new-css-system
(when show-all?
[:div {:class (stl/css :terms-login)}
(when show-terms?
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
(when show-all?
[:span (tr "labels.and")])
(when show-all?
[:span (tr "labels.and")])
(when show-privacy?
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])))
(when show-privacy?
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])
(when show-all?
[:div.terms-login
(when show-terms?
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
(when show-all?
[:span (tr "labels.and")])
(when show-privacy?
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])]))))
(mf/defc auth
[{:keys [route] :as props}]
(let [section (get-in route [:data :name])
params (:query-params route)]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
section (get-in route [:data :name])
params (:query-params route)
show-illustration? (contains? cf/flags :login-illustration)]
(mf/use-effect
#(dom/set-html-title (tr "title.default")))
;; FIXME: Temporary disabled new css system until we redesign the login with the new styles
[:& (mf/provider ctx/new-css-system) {:value false}
[:main.auth
[:section.auth-sidebar
[:a.logo {:href "#/"}
[:span {:aria-hidden true} i/logo]
[:span.hidden-name "Home"]]
[:span.tagline (tr "auth.sidebar-tagline")]]
(if new-css-system
[:main {:class (stl/css-case :auth-section true
:no-illustration (not show-illustration?))}
(when show-illustration?
[:div {:class (stl/css :login-illustration)}
i/login-illustration])
[:section {:class (stl/css :auth-content)}
(case section
:auth-register
[:& register-page {:params params}]
[:section.auth-content
(case section
:auth-register
[:& register-page {:params params}]
:auth-register-validate
[:& register-validate-page {:params params}]
:auth-register-validate
[:& register-validate-page {:params params}]
:auth-register-success
[:& register-success-page {:params params}]
:auth-register-success
[:& register-success-page {:params params}]
:auth-login
[:& login-page {:params params}]
:auth-login
[:& login-page {:params params}]
:auth-recovery-request
[:& recovery-request-page]
:auth-recovery-request
[:& recovery-request-page]
:auth-recovery
[:& recovery-page {:params params}])
:auth-recovery
[:& recovery-page {:params params}])
(when (contains? #{:auth-login :auth-register} section)
[:& terms-login])]]
[:& terms-login {}]]]]))
;; OLD
[:main.auth
[:section.auth-sidebar
[:a.logo {:href "#/"}
[:span {:aria-hidden true} i/logo]
[:span.hidden-name "Home"]]
[:span.tagline (tr "auth.sidebar-tagline")]]
[:section.auth-content
(case section
:auth-register
[:& register-page {:params params}]
:auth-register-validate
[:& register-validate-page {:params params}]
:auth-register-success
[:& register-success-page {:params params}]
:auth-login
[:& login-page {:params params}]
:auth-recovery-request
[:& recovery-request-page]
:auth-recovery
[:& recovery-page {:params params}])
[:& terms-login {}]]])))

View file

@ -0,0 +1,74 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
.auth-section {
align-items: center;
background: $db-primary;
display: grid;
gap: $s-32;
grid-template-columns: repeat(3, 1fr);
height: 100%;
padding: $s-32;
width: 100%;
&.no-illustration {
display: flex;
justify-content: center;
}
@media (max-width: 992px) {
display: flex;
justify-content: center;
}
.login-illustration {
display: flex;
justify-content: center;
grid-column: 1 / 3;
svg {
width: $s-688;
fill: $df-primary;
height: auto;
}
@media (max-width: 992px) {
display: none;
}
}
.auth-content {
align-items: center;
display: flex;
height: fit-content;
justify-content: center;
max-width: $s-412;
padding-bottom: $s-8;
position: relative;
width: 100%;
}
}
.terms-login {
font-size: $fs-11;
position: absolute;
bottom: 0;
width: 100%;
display: flex;
gap: $s-4;
justify-content: center;
a {
font-weight: $fw700;
color: $df-secondary;
}
span {
border-bottom: $s-1 solid transparent;
color: $df-secondary;
}
}

View file

@ -0,0 +1,148 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
.auth-form {
width: 100%;
padding-bottom: $s-16;
form {
display: flex;
flex-direction: column;
gap: $s-12;
margin-bottom: $s-24;
}
}
.separator {
border-color: $db-cuaternary;
margin: $s-24 0;
}
.auth-title {
@include bigTitleTipography;
color: $df-primary;
}
.auth-subtitle {
margin-top: $s-24;
font-size: $fs-14;
color: $df-secondary;
}
.form-field {
--input-width: 100%;
--input-height: #{$s-40};
--input-min-width: 100%;
}
.buttons-stack button,
.buttons-stack :global(.btn-primary) {
@extend .button-primary;
font-size: $fs-11;
height: $s-40;
text-transform: uppercase;
width: 100%;
}
.link-entry {
display: flex;
flex-direction: column;
gap: $s-12;
padding: $s-24 0;
border-top: $s-1 solid $db-cuaternary;
span {
text-align: center;
font-size: $fs-14;
color: $df-secondary;
}
a {
@extend .button-secondary;
height: $s-40;
text-transform: uppercase;
font-size: $fs-11;
}
}
.forgot-password {
display: flex;
justify-content: flex-end;
a {
font-size: $fs-14;
color: $df-secondary;
font-weight: $fw400;
}
}
.submit-btn,
.register-btn,
.recover-btn {
@extend .button-primary;
font-size: $fs-11;
height: $s-40;
text-transform: uppercase;
width: 100%;
}
.login-btn {
border-radius: $br-8;
font-size: $fs-14;
display: flex;
align-items: center;
gap: $s-6;
width: 100%;
span {
padding-top: $s-2;
}
&:hover {
color: var(--white);
}
}
.auth-buttons {
display: flex;
gap: $s-8;
}
.btn-google-auth {
color: var(--google-login-foreground);
background-color: var(--google-login-background);
&:hover {
background: var(--google-login-background-hover);
}
}
.btn-github-auth {
color: var(--github-login-foreground);
background: var(--github-login-background);
&:hover {
background: var(--github-login-background-hover);
}
}
.btn-oidc-auth {
color: var(--oidc-login-foreground);
background: var(--oidc-login-background);
&:hover {
background: var(--oidc-login-background-hover);
}
}
.btn-gitlab-auth {
color: var(--gitlab-login-foreground);
background: var(--gitlab-login-background);
&:hover {
background: var(--gitlab-login-background-hover);
}
}
.banner {
margin: $s-16 0;
}

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth.login
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.logging :as log]
@ -17,6 +18,7 @@
[app.main.ui.components.button-link :as bl]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.dom :as dom]
@ -92,7 +94,8 @@
(mf/defc login-form
[{:keys [params on-success-callback] :as props}]
(let [initial (mf/use-memo (mf/deps params) (constantly params))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (mf/deps params) (constantly params))
error (mf/use-state false)
form (fm/use-form :spec ::login-form
@ -150,137 +153,269 @@
(login-with-ldap event (with-meta params
{:on-error on-error
:on-success on-success})))))]
[:*
(when-let [message @error]
[:& msgs/inline-banner
{:type :warning
:content message
:on-close #(reset! error nil)
:data-test "login-banner"
:role "alert"}])
(if new-css-system
[:*
(when-let [message @error]
[:& msgs/inline-banner
{:type :warning
:content message
:on-close #(reset! error nil)
:data-test "login-banner"
:role "alert"}])
[:& fm/form {:on-submit on-submit :form form}
[:div.fields-row
[:& fm/input
{:name :email
:type "email"
:help-icon i/at
:label (tr "auth.email")}]]
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:name :email
:type "email"
:label (tr "auth.email")
:class (stl/css :form-field)}]]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password
:help-icon i/eye
:label (tr "auth.password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password
:label (tr "auth.password")
:class (stl/css :form-field)}]]
[:div.buttons-stack
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:> fm/submit-button*
{:label (tr "auth.login-submit")
:data-test "login-submit"}])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:div {:class (stl/css :fields-row :forgot-password)}
[:& lk/link {:action #(st/emit! (rt/nav :auth-recovery-request))
:data-test "forgot-password"}
(tr "auth.forgot-password")]])
(when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]]))
[:div {:class (stl/css :buttons-stack)}
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:> fm/submit-button*
{:label (tr "auth.login-submit")
:data-test "login-submit"
:class (stl/css :login-button)}])
(when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]]
;; OLD
[:*
(when-let [message @error]
[:& msgs/inline-banner
{:type :warning
:content message
:on-close #(reset! error nil)
:data-test "login-banner"
:role "alert"}])
[:& fm/form {:on-submit on-submit :form form}
[:div.fields-row
[:& fm/input
{:name :email
:type "email"
:help-icon i/at
:label (tr "auth.email")
:class (stl/css :form-field)}]]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password
:help-icon i/eye
:label (tr "auth.password")
:class (stl/css :form-field)}]]
[:div.buttons-stack
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:> fm/submit-button*
{:label (tr "auth.login-submit")
:data-test "login-submit"}])
(when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]])))
(mf/defc login-buttons
[{:keys [params] :as props}]
(let [login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
login-with-github (mf/use-fn (mf/deps params) #(login-with-oidc % :github params))
login-with-gitlab (mf/use-fn (mf/deps params) #(login-with-oidc % :gitlab params))
login-with-oidc (mf/use-fn (mf/deps params) #(login-with-oidc % :oidc params))]
[:div.auth-buttons
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
:icon i/brand-google
:label (tr "auth.login-with-google-submit")
:class "btn-google-auth"}])
(if new-css-system
[:div {:class (stl/css :auth-buttons)}
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
:icon i/brand-google
:label (tr "auth.login-with-google-submit")
:class (stl/css :login-btn :btn-google-auth)}])
(when (contains? cf/flags :login-with-github)
[:& bl/button-link {:on-click login-with-github
:icon i/brand-github
:label (tr "auth.login-with-github-submit")
:class "btn-github-auth"}])
(when (contains? cf/flags :login-with-github)
[:& bl/button-link {:on-click login-with-github
:icon i/brand-github
:label (tr "auth.login-with-github-submit")
:class (stl/css :login-btn :btn-github-auth)}])
(when (contains? cf/flags :login-with-gitlab)
[:& bl/button-link {:on-click login-with-gitlab
:icon i/brand-gitlab
:label (tr "auth.login-with-gitlab-submit")
:class "btn-gitlab-auth"}])
(when (contains? cf/flags :login-with-gitlab)
[:& bl/button-link {:on-click login-with-gitlab
:icon i/brand-gitlab
:label (tr "auth.login-with-gitlab-submit")
:class (stl/css :login-btn :btn-gitlab-auth)}])
(when (contains? cf/flags :login-with-oidc)
[:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class "btn-github-auth"}])]))
(when (contains? cf/flags :login-with-oidc)
[:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class (stl/css :login-btn :btn-oidc-auth)}])]
[:div.auth-buttons
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
:icon i/brand-google
:label (tr "auth.login-with-google-submit")
:class "btn-google-auth"}])
(when (contains? cf/flags :login-with-github)
[:& bl/button-link {:on-click login-with-github
:icon i/brand-github
:label (tr "auth.login-with-github-submit")
:class "btn-github-auth"}])
(when (contains? cf/flags :login-with-gitlab)
[:& bl/button-link {:on-click login-with-gitlab
:icon i/brand-gitlab
:label (tr "auth.login-with-gitlab-submit")
:class "btn-gitlab-auth"}])
(when (contains? cf/flags :login-with-oidc)
[:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class "btn-github-auth"}])])))
(mf/defc login-button-oidc
[{:keys [params] :as props}]
(when (contains? cf/flags :login-with-oidc)
[:div.link-entry.link-oidc
[:a {:tab-index "0"
:on-key-down (fn [event]
(when (k/enter? event)
(login-with-oidc event :oidc params)))
:on-click #(login-with-oidc % :oidc params)}
(tr "auth.login-with-oidc-submit")]]))
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
(when (contains? cf/flags :login-with-oidc)
[:div {:class (stl/css :link-entry :link-oidc)}
[:a {:tab-index "0"
:on-key-down (fn [event]
(when (k/enter? event)
(login-with-oidc event :oidc params)))
:on-click #(login-with-oidc % :oidc params)}
(tr "auth.login-with-oidc-submit")]])
(when (contains? cf/flags :login-with-oidc)
[:div.link-entry.link-oidc
[:a {:tab-index "0"
:on-key-down (fn [event]
(when (k/enter? event)
(login-with-oidc event :oidc params)))
:on-click #(login-with-oidc % :oidc params)}
(tr "auth.login-with-oidc-submit")]]))))
(mf/defc login-methods
[{:keys [params on-success-callback] :as props}]
[:*
(when show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(when show-alt-login-buttons?
[:*
[:& login-buttons {:params params}]
[:& login-buttons {:params params}]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:hr {:class (stl/css :separator)}])])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback}])]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback}])])
;; OLD
[:*
(when show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
[:& login-buttons {:params params}]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback}])])))
(mf/defc login-page
[{:keys [params] :as props}]
[:div.generic-form.login-form
[:div.form-container
[:h1 {:data-test "login-title"} (tr "auth.login-title")]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "login-title"} (tr "auth.login-title")]
[:& login-methods {:params params}]
[:hr {:class (stl/css :separator)}]
[:div.links
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:div.link-entry
[:& lk/link {:action #(st/emit! (rt/nav :auth-recovery-request))
:data-test "forgot-password"}
(tr "auth.forgot-password")]])
[:& login-methods {:params params}]
(when (contains? cf/flags :registration)
[:div.link-entry
[:span (tr "auth.register") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} params))
:data-test "register-submit"}
(tr "auth.register-submit")]])]
[:div {:class (stl/css :links)}
(when (contains? cf/flags :registration)
[:div {:class (stl/css :link-entry :register)}
[:span (tr "auth.register") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} params))
:data-test "register-submit"}
(tr "auth.register-submit")]])]
(when (contains? cf/flags :demo-users)
[:div {:class (stl/css :link-entry :demo-account)}
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]])]
;; OLD
[:div.generic-form.login-form
[:div.form-container
[:h1 {:data-test "login-title"} (tr "auth.login-title")]
[:& login-methods {:params params}]
[:div.links
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:div.link-entry
[:& lk/link {:action #(st/emit! (rt/nav :auth-recovery-request))
:data-test "forgot-password"}
(tr "auth.forgot-password")]])
(when (contains? cf/flags :registration)
[:div.link-entry
[:span (tr "auth.register") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} params))
:data-test "register-submit"}
(tr "auth.register-submit")]])]
(when (contains? cf/flags :demo-users)
[:div.links.demo
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]]])]])))
(when (contains? cf/flags :demo-users)
[:div.links.demo
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]]])]])

View file

@ -0,0 +1,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "./common.scss";

View file

@ -5,12 +5,14 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth.recovery
(:require-macros [app.main.style :as stl])
(:require
[app.common.spec :as us]
[app.main.data.messages :as dm]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[cljs.spec.alpha :as s]
@ -55,38 +57,71 @@
(mf/defc recovery-form
[{:keys [params] :as props}]
(let [form (fm/use-form :spec ::recovery-form
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::recovery-form
:validators [password-equality
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))]
:initial params)]
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "password"
:name :password-1
:label (tr "auth.new-password")}]]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-1
:label (tr "auth.new-password")
:class (stl/css :form-field)}]]
[:div.fields-row
[:& fm/input {:type "password"
:name :password-2
:label (tr "auth.confirm-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-2
:label (tr "auth.confirm-password")
:class (stl/css :form-field)}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")}]]))
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")
:class (stl/css :submit-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "password"
:name :password-1
:label (tr "auth.new-password")}]]
[:div.fields-row
[:& fm/input {:type "password"
:name :password-2
:label (tr "auth.confirm-password")}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")}]])))
;; --- Recovery Request Page
(mf/defc recovery-page
[{:keys [params] :as props}]
[:section.generic-form
[:div.form-container
[:h1 "Forgot your password?"]
[:div.subtitle "Please enter your new password"]
[:& recovery-form {:params params}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)} "Forgot your password?"]
[:div {:class (stl/css :auth-subtitle)} "Please enter your new password"]
[:hr {:class (stl/css :separator)}]
[:& recovery-form {:params params}]
[:div.links
[:div.link-entry
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]]])
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)}
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]]
;; TODO
[:section.generic-form
[:div.form-container
[:h1 "Forgot your password?"]
[:div.subtitle "Please enter your new password"]
[:& recovery-form {:params params}]
[:div.links
[:div.link-entry
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]]])))

View file

@ -0,0 +1,12 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
@use "./common.scss";
.submit-btn {
margin-top: $s-16;
}

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth.recovery-request
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.spec :as us]
@ -13,6 +14,7 @@
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
@ -32,7 +34,8 @@
(mf/defc recovery-form
[{:keys [on-success-callback] :as props}]
(let [form (fm/use-form :spec ::recovery-request-form
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::recovery-request-form
:validators [handle-error-messages]
:initial {})
submitted (mf/use-state false)
@ -74,32 +77,62 @@
(reset! form nil)
(st/emit! (du/request-profile-recovery params)))))]
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :email
:label (tr "auth.email")
:help-icon i/at
:type "text"}]]
(if new-css-system
[:& fm/form {:on-submit on-submit
:form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:name :email
:label (tr "auth.email")
:type "text"
:class (stl/css :form-field)}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-request-submit")
:data-test "recovery-resquest-submit"}]]))
[:> fm/submit-button*
{:label (tr "auth.recovery-request-submit")
:data-test "recovery-resquest-submit"
:class (stl/css :recover-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :email
:label (tr "auth.email")
:help-icon i/at
:type "text"}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-request-submit")
:data-test "recovery-resquest-submit"}]])))
;; --- Recovery Request Page
(mf/defc recovery-request-page
[{:keys [params on-success-callback go-back-callback] :as props}]
(let [default-go-back #(st/emit! (rt/nav :auth-login))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
default-go-back #(st/emit! (rt/nav :auth-login))
go-back (or go-back-callback default-go-back)]
[:section.generic-form
[:div.form-container
[:h1 (tr "auth.recovery-request-title")]
[:div.subtitle (tr "auth.recovery-request-subtitle")]
[:& recovery-form {:params params :on-success-callback on-success-callback}]
[:div.links
[:div.link-entry
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)} (tr "auth.recovery-request-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.recovery-request-subtitle")]
[:hr {:class (stl/css :separator)}]
[:& recovery-form {:params params :on-success-callback on-success-callback}]
[:div {:class (stl/css :link-entry)}
[:& lk/link {:action go-back
:data-test "go-back-link"}
(tr "labels.go-back")]]]]]))
(tr "labels.go-back")]]]
;; old
[:section.generic-form
[:div.form-container
[:h1 (tr "auth.recovery-request-title")]
[:div.subtitle (tr "auth.recovery-request-subtitle")]
[:& recovery-form {:params params :on-success-callback on-success-callback}]
[:div.links
[:div.link-entry
[:& lk/link {:action go-back
:data-test "go-back-link"}
(tr "labels.go-back")]]]]])))

View file

@ -0,0 +1,12 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
@use "./common.scss";
.fields-row {
margin-bottom: $s-8;
}

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth.register
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.spec :as us]
@ -16,9 +17,10 @@
[app.main.ui.auth.login :as login]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.i18n :refer [tr]]
[app.util.i18n :refer [tr tr-html]]
[app.util.router :as rt]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
@ -26,9 +28,10 @@
(mf/defc demo-warning
[_]
[:& msgs/inline-banner
{:type :warning
:content (tr "auth.demo-warning")}])
[:div {:class (stl/css :banner)}
[:& msgs/inline-banner
{:type :warning
:content (tr "auth.demo-warning")}]])
;; --- PAGE: Register
@ -85,7 +88,8 @@
(mf/defc register-form
[{:keys [params on-success-callback] :as props}]
(let [initial (mf/use-memo (mf/deps params) (constantly params))
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (mf/deps params) (constantly params))
form (fm/use-form :spec ::register-form
:validators [validate
(fm/validate-not-empty :password (tr "auth.password-not-empty"))]
@ -110,72 +114,131 @@
(partial handle-prepare-register-error form))))))]
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "email"
:name :email
:help-icon i/at
:label (tr "auth.email")
:data-test "email-input"}]]
[:div.fields-row
[:& fm/input {:name :password
:hint (tr "auth.password-length-hint")
:label (tr "auth.password")
:type "password"}]]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "email"
:name :email
:label (tr "auth.email")
:data-test "email-input"
:class (stl/css :form-field)}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:name :password
:hint (tr "auth.password-length-hint")
:label (tr "auth.password")
:type "password"
:class (stl/css :form-field)}]]
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:data-test "register-form-submit"}]]))
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:data-test "register-form-submit"
:class (stl/css :register-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "email"
:name :email
:help-icon i/at
:label (tr "auth.email")
:data-test "email-input"}]]
[:div.fields-row
[:& fm/input {:name :password
:hint (tr "auth.password-length-hint")
:label (tr "auth.password")
:type "password"}]]
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:data-test "register-form-submit"}]])))
(mf/defc register-methods
[{:keys [params on-success-callback] :as props}]
[:*
(when login/show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(when login/show-alt-login-buttons?
[:*
[:hr {:class (stl/css :separator)}]
[:& login/login-buttons {:params params}]])
[:hr {:class (stl/css :separator)}]
[:& register-form {:params params :on-success-callback on-success-callback}]]
[:& login/login-buttons {:params params}]
;; OLD
[:*
(when login/show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
[:& login/login-buttons {:params params}]
[:& register-form {:params params :on-success-callback on-success-callback}]])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
[:& register-form {:params params :on-success-callback on-success-callback}]])))
(mf/defc register-page
[{:keys [params] :as props}]
[:div.form-container
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "registration-title"} (tr "auth.register-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
[:h1 {:data-test "registration-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
(when (contains? cf/flags :demo-warning)
[:& demo-warning])
(when (contains? cf/flags :demo-warning)
[:& demo-warning])
[:& register-methods {:params params}]
[:& register-methods {:params params}]
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry :account)}
[:span (tr "auth.already-have-account") " "]
[:div.links
[:div.link-entry
[:span (tr "auth.already-have-account") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
:data-test "login-here-link"}
(tr "auth.login-here")]]
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
:data-test "login-here-link"}
(tr "auth.login-here")]]
(when (contains? cf/flags :demo-users)
[:div {:class (stl/css :link-entry :demo-users)}
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]]
(when (contains? cf/flags :demo-users)
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]])
;; OLD
[:div.form-container
[:h1 {:data-test "registration-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
(when (contains? cf/flags :demo-warning)
[:& demo-warning])
[:& register-methods {:params params}]
[:div.links
[:div.link-entry
[:span (tr "auth.already-have-account") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
:data-test "login-here-link"}
(tr "auth.login-here")]]
(when (contains? cf/flags :demo-users)
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]])))
;; --- PAGE: register validation
@ -219,7 +282,8 @@
(mf/defc register-validate-form
[{:keys [params on-success-callback] :as props}]
(let [form (fm/use-form :spec ::register-validate-form
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::register-validate-form
:validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))
(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))]
:initial params)
@ -240,48 +304,102 @@
(rx/subs on-success
(partial handle-register-error form))))))]
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :fullname
:label (tr "auth.fullname")
:type "text"}]]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:name :fullname
:label (tr "auth.fullname")
:type "text"
:class (stl/css :form-field)}]]
(when (contains? cf/flags :terms-and-privacy-checkbox)
[:div.fields-row.input-visible.accept-terms-and-privacy-wrapper
[:& fm/input {:name :accept-terms-and-privacy
:class "check-primary"
:type "checkbox"}
[:span
(tr "auth.terms-privacy-agreement")]]
[:div.auth-links
[:a {:href "https://penpot.app/terms" :target "_blank"} (tr "auth.terms-of-service")]
[:span ",\u00A0"]
[:a {:href "https://penpot.app/privacy" :target "_blank"} (tr "auth.privacy-policy")]]])
(when (contains? cf/flags :terms-and-privacy-checkbox)
(let [terms-label
(mf/html
[:& tr-html
{:tag-name "div"
:label "auth.terms-privacy-agreement-md"
:params [cf/terms-of-service-uri cf/privacy-policy-uri]}])]
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
[:& fm/input {:name :accept-terms-and-privacy
:class "check-primary"
:type "checkbox"
:label terms-label}]]))
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?}]]))
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:class (stl/css :register-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :fullname
:label (tr "auth.fullname")
:type "text"}]]
(when (contains? cf/flags :terms-and-privacy-checkbox)
[:div.fields-row.input-visible.accept-terms-and-privacy-wrapper
[:& fm/input {:name :accept-terms-and-privacy
:class "check-primary"
:type "checkbox"}
[:span
(tr "auth.terms-privacy-agreement")]]
[:div.auth-links
[:a {:href "https://penpot.app/terms" :target "_blank"} (tr "auth.terms-of-service")]
[:span ",\u00A0"]
[:a {:href "https://penpot.app/privacy" :target "_blank"} (tr "auth.privacy-policy")]]])
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?}]])))
(mf/defc register-validate-page
[{:keys [params] :as props}]
[:div.form-container
[:h1 {:data-test "register-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "register-title"} (tr "auth.register-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
[:& register-validate-form {:params params}]
[:hr {:class (stl/css :separator)}]
[:div.links
[:div.link-entry
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]])
[:& register-validate-form {:params params}]
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry :go-back)}
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]]
;; OLD
[:div.form-container
[:h1 {:data-test "register-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
[:& register-validate-form {:params params}]
[:div.links
[:div.link-entry
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]])))
(mf/defc register-success-page
[{:keys [params] :as props}]
[:div.form-container
[:div.notification-icon i/icon-verify]
[:div.notification-text (tr "auth.verification-email-sent")]
[:div.notification-text-email (:email params "")]
[:div.notification-text (tr "auth.check-your-email")]])
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form :register-success)}
[:div {:class (stl/css :notification-icon)} i/icon-verify]
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
[:div {:class (stl/css :notification-text-email)} (:email params "")]
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]]
;; OLD
[:div.form-container
[:div.notification-icon i/icon-verify]
[:div.notification-text (tr "auth.verification-email-sent")]
[:div.notification-text-email (:email params "")]
[:div.notification-text (tr "auth.check-your-email")]])))

View file

@ -0,0 +1,38 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
@use "./common.scss";
.accept-terms-and-privacy-wrapper {
margin: $s-16 0;
:global(a) {
color: $df-secondary;
font-weight: $fw700;
}
}
.register-success {
padding-bottom: $s-32;
}
.notification-icon {
fill: $df-primary;
display: flex;
justify-content: center;
margin-bottom: $s-32;
svg {
width: $s-92;
height: $s-92;
}
}
.notification-text-email,
.notification-text {
font-size: $fs-16;
color: $df-secondary;
margin-bottom: $s-16;
}

View file

@ -5,11 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.auth.verify-token
(:require-macros [app.main.style :as stl])
(:require
[app.main.data.messages :as dm]
[app.main.data.users :as du]
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.static :as static]
[app.util.dom :as dom]
@ -60,7 +62,8 @@
(mf/defc verify-token
[{:keys [route] :as props}]
(let [token (get-in route [:query-params :token])
(let [new-css-system (mf/use-ctx ctx/new-css-system)
token (get-in route [:query-params :token])
bad-token (mf/use-state false)]
(mf/with-effect []
@ -92,9 +95,7 @@
(st/emit! (rt/nav :auth-login))))))))
(if @bad-token
[:> static/static-header {}
[:div.image i/unchain]
[:div.main-message (tr "errors.invite-invalid")]
[:div.desc-message (tr "errors.invite-invalid.info")]]
[:div.verify-token
[:> static/invalid-token {}]
[:div {:class (stl/css-case :verify-token new-css-system
:global/verify-token (not new-css-system))}
i/loader-pencil])))

View file

@ -0,0 +1,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "./common.scss";

View file

@ -54,11 +54,11 @@
help-icon' (cond
(and (= input-type "password")
(= @type' "password"))
i/eye
i/shown-refactor
(and (= input-type "password")
(= @type' "text"))
i/eye-closed
i/hide-refactor
:else
help-icon)
@ -137,23 +137,30 @@
:input-label is-text?
:radio-label is-radio?
:checkbox-label is-checkbox?)
:tab-index "0"
:tab-index "-1"
:for (name input-name)} label
(when is-checkbox?
[:span {:class (stl/css-case :global/checked value)} i/status-tick-refactor])
[:> :input props]]
(if is-checkbox?
[:> :input props]
[:div {:class (stl/css :input-and-icon)}
[:> :input props]
(when help-icon'
[:span {:class (stl/css :help-icon)
:on-click (when (= "password" input-type)
swap-text-password)}
help-icon'])])]
(some? children)
[:label {:for (name input-name)}
[:> :input props]
children])
(when help-icon'
[:span {:class (stl/css :help-icon)
:on-click (when (= "password" input-type)
swap-text-password)}
help-icon'])
(cond
(and touched? (:message error))
[:div {:id (dm/str "error-" input-name)
@ -387,7 +394,7 @@
(true? (unchecked-get props "disabled")))
klass (dm/str class " " (if disabled? "btn-disabled" ""))
new-klass (if disabled? (stl/css :btn-disabled) class)
new-klass (dm/str class " " (if disabled? (stl/css :btn-disabled) ""))
on-key-down
(mf/use-fn

View file

@ -10,8 +10,8 @@
.input-wrapper {
display: flex;
flex-direction: column;
gap: $s-6;
align-items: center;
position: relative;
.input-with-label {
@include flexColumn;
gap: $s-8;
@ -24,11 +24,13 @@
cursor: pointer;
color: var(--modal-title-foreground-color);
text-transform: uppercase;
input {
@extend .input-element;
color: var(--input-foreground-color-active);
width: calc(100% - $s-1);
margin-top: 0;
width: 100%;
height: 100%;
&:focus {
outline: none;
@ -41,9 +43,12 @@
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-text-fill-color: var(--input-foreground-color-active) !important;
-webkit-box-shadow: 0 0 0 28px var(--input-background-color) inset !important;
-webkit-text-fill-color: var(--input-foreground-color-active);
-webkit-box-shadow: inset 0 0 20px 20px var(--input-background-color);
border: $s-1 solid var(--input-background-color);
-webkit-background-clip: text;
transition: background-color 5000s ease-in-out 0s;
caret-color: var(--input-foreground-color-active);
}
}
&:global(.invalid) {
@ -54,15 +59,29 @@
}
}
.input-and-icon {
position: relative;
width: var(--input-width, calc(100% - $s-1));
min-width: var(--input-min-width);
height: var(--input-height, $s-32);
}
.help-icon {
cursor: pointer;
position: absolute;
right: $s-12;
top: calc(50% - $s-8);
svg {
@extend .button-icon-small;
stroke: var(--input-details-color);
stroke: $df-secondary;
width: $s-16;
height: $s-16;
}
}
.error {
color: var(--input-border-color-error);
width: 100%;
font-size: $fs-14;
}
.hint {
@ -181,9 +200,6 @@
// SUBMIT-BUTTON
.btn-disabled {
@extend .button-disabled;
height: $s-32;
padding: $s-8 $s-24;
border-radius: $br-8;
}
// MULTI INPUT

View file

@ -139,8 +139,9 @@
(if new-css-system
[:*
[:li {:tab-index "0"
:class (if selected? (stl/css :current)
(when (:dragging? local) (stl/css :dragging)))
:class (stl/css-case :project-element true
:current selected?
:dragging (:dragging? local))
:on-click on-click
:on-key-down on-key-down
:on-double-click on-edit-open
@ -1255,3 +1256,4 @@
[:& profile-section
{:profile profile
:team team}]])))

View file

@ -356,8 +356,13 @@
cursor: pointer;
display: flex;
flex-shrink: 0;
padding: $s-8 $s-8 $s-8 $s-24;
&.project-element {
padding: $s-8 $s-8 $s-8 $s-24;
}
a {
padding: $s-8 $s-8 $s-8 $s-24;
font-weight: $fw400;
width: 100%;
&:hover {

View file

@ -504,10 +504,9 @@
border-radius: 50%;
color: $df-primary;
z-index: $z-index-modal;
background-color: $da-primary;
height: $s-120;
width: $s-120;
height: 100%;
width: 100%;
svg {
fill: $db-primary;
@ -517,8 +516,6 @@
&:hover {
.update-overlay {
opacity: 1;
width: $s-72;
height: $s-72;
top: $s-16;
left: $s-16;
}

View file

@ -172,6 +172,7 @@
(def logo-icon (icon-xref :penpot-logo-icon))
(def logo-error-screen (icon-xref :logo-error-screen))
(def logout (icon-xref :logout))
(def login-illustration (icon-xref :login-illustration))
(def lowercase (icon-xref :lowercase))
(def mail (icon-xref :mail))
(def mask (icon-xref :mask))

View file

@ -80,7 +80,7 @@
[:div {:ref wrapper-ref
:class (stl/css-case
:modal-wrapper new-css-system
:old-css/modal-wrapper (not new-css-system))}
:global/modal-wrapper (not new-css-system))}
(mf/element component (:props data))])))
(def modal-ref

View file

@ -105,7 +105,8 @@
[:> fm/submit-button*
{:label (t locale "dashboard.update-settings")
:data-test "submit-password"}]]
:data-test "submit-password"
:class (stl/css :update-btn)}]]
;; OLD
[:& fm/form {:class "password-form"
@ -153,4 +154,3 @@
[:section.dashboard-settings.form-container
[:div.form-container
[:& password-form {:locale locale}]]])))

View file

@ -4,4 +4,11 @@
//
// Copyright (c) KALEIDOS INC
@use "common/refactor/common-refactor.scss" as *;
@use "./profile" as *;
.update-btn {
margin-top: $s-16;
@extend .button-primary;
height: $s-36;
}

View file

@ -48,6 +48,7 @@
}
.fields-row {
--input-height: $s-40;
margin-bottom: $s-20;
flex-direction: column;
@ -57,10 +58,6 @@
font-size: $fs-14;
margin-top: $s-12;
}
:global(input) {
height: $s-40;
}
}
.field {

View file

@ -25,7 +25,7 @@
on-click (mf/use-callback #(set! (.-href globals/location) "/"))]
(if new-css-system
[:section {:class (stl/css :exception-layout)}
[:div
[:button
{:class (stl/css :exception-header)
:on-click on-click}
i/logo-icon]
@ -42,6 +42,19 @@
[:div.exception-content
[:div.container children]]])))
(mf/defc invalid-token
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "errors.invite-invalid")]
[:div {:class (stl/css :desc-message)} (tr "errors.invite-invalid.info")]]
[:> static-header {}
[:div.image i/unchain]
[:div.main-message (tr "errors.invite-invalid")]
[:div.desc-message (tr "errors.invite-invalid.info")]])))
(mf/defc not-found
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]

View file

@ -44,6 +44,9 @@
.exception-header {
padding: $s-24 $s-32;
position: fixed;
background: none;
border: none;
cursor: pointer;
svg {
fill: $df-primary;
width: $s-48;
@ -89,3 +92,9 @@
font-size: $fs-11;
}
}
.image {
svg {
fill: $df-primary;
}
}

View file

@ -196,8 +196,8 @@
(obj/set! "on-expand" handle-expand))]
[:aside {:class (stl/css-case new-css-system
:old-css/settings-bar true
:old-css/settings-bar-right true
:global/settings-bar true
:global/settings-bar-right true
:right-settings-bar true
:not-expand (not can-be-expanded?)
:expanded (> size 276))

View file

@ -156,7 +156,7 @@
[:div.shadow-option {:class (stl/css-case new-css-system
:old-css/shadow-option true
:global/shadow-option true
:shadow-element true
:dnd-over-top (= (:over dprops) :top)
:dnd-over-bot (= (:over dprops) :bot))

View file

@ -7,6 +7,7 @@
(ns app.util.i18n
"A i18n foundation."
(:require
[app.common.data :as d]
[app.common.logging :as log]
[app.config :as cfg]
[app.util.dom :as dom]
@ -175,8 +176,10 @@
{::mf/wrap-props false}
[props]
(let [label (obj/get props "label")
tag-name (obj/get props "tag-name" "p")]
[:> tag-name {:dangerouslySetInnerHTML #js {:__html (tr label)}}]))
tag-name (obj/get props "tag-name" "p")
params (obj/get props "params" [])
html (apply tr (d/concat-vec [label] params))]
[:> tag-name {:dangerouslySetInnerHTML #js {:__html html}}]))
;; DEPRECATED
(defn use-locale

View file

@ -168,10 +168,14 @@ msgid "auth.terms-of-service"
msgstr "Terms of service"
#: src/app/main/ui/auth/register.cljs
#, markdown
msgid "auth.terms-privacy-agreement-md"
msgstr ""
"When creating a new account, you agree to our [terms of service](%s) and [privacy policy](%s)."
msgid "auth.terms-privacy-agreement"
msgstr ""
"When creating a new account, you agree to our terms of service and privacy "
"policy."
"When creating a new account, you agree to ourf terms of service and privacy policy."
#: src/app/main/ui/auth/register.cljs
msgid "auth.verification-email-sent"

View file

@ -173,10 +173,14 @@ msgid "auth.terms-of-service"
msgstr "Términos de servicio"
#: src/app/main/ui/auth/register.cljs
#, markdown
msgid "auth.terms-privacy-agreement-md"
msgstr ""
"Al crear una nueva cuenta, aceptas nuestros [términos de servicio](%s) y [política de privacidad](%s)."
msgid "auth.terms-privacy-agreement"
msgstr ""
"Al crear una nueva cuenta, aceptas nuestros términos de servicio y política "
"de privacidad."
"Al crear una nueva cuenta, aceptas nuestros [términos de servicio](%s) y [política de privacidad](%s)."
#: src/app/main/ui/auth/register.cljs
msgid "auth.verification-email-sent"