mirror of
https://github.com/penpot/penpot.git
synced 2025-03-26 06:31:26 -05:00
commit
990f63a136
48 changed files with 1432 additions and 378 deletions
|
@ -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
|
||||
|
|
|
@ -29,12 +29,13 @@ paths.resources = "./resources/";
|
|||
paths.output = "./resources/public/";
|
||||
paths.dist = "./target/dist/";
|
||||
|
||||
const touchSourceOnStyleChange = false;
|
||||
|
||||
/***********************************************
|
||||
* Marked Extensions
|
||||
***********************************************/
|
||||
|
||||
// Name of Penpot's top level package
|
||||
const ROOT_NAME = "app";
|
||||
|
||||
const renderer = {
|
||||
link(href, title, text) {
|
||||
return `<a href="${href}" target="_blank">${text}</a>`;
|
||||
|
@ -223,7 +224,18 @@ gulp.task("scss:modules", function () {
|
|||
.pipe(
|
||||
gulpPostcss([
|
||||
modules({
|
||||
generateScopedName: "[folder]_[name]_[local]_[hash:base64:5]",
|
||||
getJSON: function (cssFileName, json, outputFileName) {
|
||||
// We do nothing because we don't want the generated JSON files
|
||||
},
|
||||
// Calculates the whole css-module selector name.
|
||||
// Should be the same as the one in the file `/src/app/main/style.clj`
|
||||
generateScopedName: function (selector, filename, css) {
|
||||
const dir = path.dirname(filename);
|
||||
const name = path.basename(filename, ".css");
|
||||
const parts = dir.split("/");
|
||||
const rootIdx = parts.findIndex(s => s === ROOT_NAME);
|
||||
return parts.slice(rootIdx + 1).join("_") + "_" + name + "__" + selector;
|
||||
},
|
||||
}),
|
||||
autoprefixer(),
|
||||
]),
|
||||
|
@ -350,13 +362,6 @@ gulp.task("dev:dirs", async function (next) {
|
|||
gulp.task("watch:main", function () {
|
||||
const watchTask = gulp.watch("src/**/**.scss", gulp.series("scss"));
|
||||
|
||||
if (touchSourceOnStyleChange) {
|
||||
watchTask.on("change", function (path) {
|
||||
// Replace ".scss" for ".cljs" to refresh the file
|
||||
gulp.src(path.replace(".scss", ".cljs")).pipe(touch());
|
||||
});
|
||||
}
|
||||
|
||||
gulp.watch(paths.resources + "styles/**/**.scss", gulp.series("scss"));
|
||||
gulp.watch(paths.resources + "images/**/*", gulp.series("copy:assets:images"));
|
||||
|
||||
|
|
3
frontend/resources/images/icons/login-illustration.svg
Normal file
3
frontend/resources/images/icons/login-illustration.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.2 KiB |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
--input-foreground-color-disabled: var(--color-foreground-secondary);
|
||||
--input-border-color-disabled: var(--color-background-quaternary);
|
||||
--input-border-color-error: var(--error-color);
|
||||
--input-border-color-success: var(--color-accent-primary);
|
||||
--input-details-color: var(--color-background-primary);
|
||||
--input-checkbox-background-color-rest: var(--color-background-quaternary);
|
||||
--input-checkbox-border-color-active: var(--color-background-quaternary);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "sass:meta";
|
||||
|
||||
:root {
|
||||
--color-background-primary: var(--dark-gray-1);
|
||||
--color-background-secondary: var(--dark-gray-2);
|
||||
|
@ -25,4 +27,6 @@
|
|||
--pending-color: var(--dark-pending-color);
|
||||
--error-color: var(--dark-error-color);
|
||||
--canvas-color: var(--color-canvas);
|
||||
|
||||
@include meta.load-css("hljs-dark-theme");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Panda Syntax Theme for Highlight.js
|
||||
* Based on: https://github.com/tinkertrain/panda-syntax-vscode
|
||||
* Author: Annmarie Switzer <https://github.com/annmarie-switzer>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #e6e6e6;
|
||||
background: #2a2c2d;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #bbbbbb;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.hljs-punctuation,
|
||||
.hljs-attr {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-meta {
|
||||
color: #ff4b82;
|
||||
}
|
||||
|
||||
.hljs-operator,
|
||||
.hljs-char.escape_ {
|
||||
color: #b084eb;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-deletion {
|
||||
color: #ff75b5;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-selector-attr,
|
||||
.hljs-variable.language_ {
|
||||
color: #ff9ac1;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-property,
|
||||
.hljs-code,
|
||||
.hljs-formula,
|
||||
.hljs-section,
|
||||
.hljs-title.function_ {
|
||||
color: #45a9f9;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-selector-class,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #19f9d8;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-link,
|
||||
.hljs-built_in,
|
||||
.hljs-title,
|
||||
.hljs-selector-id,
|
||||
.hljs-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-attribute,
|
||||
.hljs-template-tag,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-punctuation {
|
||||
color: #ffb86c;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* Panda Syntax Theme for Highlight.js
|
||||
* Based on: https://github.com/tinkertrain/panda-syntax-vscode
|
||||
* Author: Annmarie Switzer <https://github.com/annmarie-switzer>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
color: #2a2c2d;
|
||||
background: #e6e6e6;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #676b79;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-params {
|
||||
color: #676b79;
|
||||
}
|
||||
|
||||
.hljs-punctuation,
|
||||
.hljs-attr {
|
||||
color: #2a2c2d;
|
||||
}
|
||||
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-meta,
|
||||
.hljs-operator,
|
||||
.hljs-char.escape_ {
|
||||
color: #c56200;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-deletion {
|
||||
color: #d92792;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-selector-attr,
|
||||
.hljs-variable.language_ {
|
||||
color: #cc5e91;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-property,
|
||||
.hljs-code,
|
||||
.hljs-formula,
|
||||
.hljs-section,
|
||||
.hljs-title.function_ {
|
||||
color: #3787c7;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-selector-class,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-meta .hljs-string {
|
||||
color: #0d7d6c;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-link,
|
||||
.hljs-built_in,
|
||||
.hljs-title,
|
||||
.hljs-selector-id,
|
||||
.hljs-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-attribute,
|
||||
.hljs-template-tag,
|
||||
.hljs-meta .hljs-keyword {
|
||||
color: #7641bb;
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "sass:meta";
|
||||
|
||||
.light {
|
||||
--color-background-primary: var(--light-gray-1);
|
||||
--color-background-secondary: var(--light-gray-2);
|
||||
|
@ -24,4 +26,6 @@
|
|||
--pending-color: var(--light-pending-color);
|
||||
--error-color: var(--light-error-color);
|
||||
--canvas-color: var(--color-canvas);
|
||||
|
||||
@include meta.load-css("hljs-light-theme");
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -11,9 +11,25 @@
|
|||
[clojure.core :as c]
|
||||
[clojure.data.json :as json]
|
||||
[clojure.java.io :as io]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2.util :as mfu]))
|
||||
|
||||
(def ^:dynamic *css-data* nil)
|
||||
;; Should match with the `ROOT_NAME` constant in gulpfile.js
|
||||
(def ROOT-NAME "app")
|
||||
|
||||
(def ^:dynamic *css-prefix* nil)
|
||||
|
||||
(defn get-prefix
|
||||
;; Calculates the css-modules prefix given the filename
|
||||
;; should be the same as the calculation inside the `gulpfile.js`
|
||||
[fname]
|
||||
(let [file (io/file fname)
|
||||
parts
|
||||
(->> (str/split (.getParent file) #"/")
|
||||
(drop-while #(not= % ROOT-NAME))
|
||||
(rest)
|
||||
(str/join "_"))]
|
||||
(str parts "_" (subs (.getName file) 0 (- (count (.getName file)) 5)) "__")))
|
||||
|
||||
(def ^:private xform-css
|
||||
(keep (fn [k]
|
||||
|
@ -22,9 +38,8 @@
|
|||
(let [knm (name k)
|
||||
kns (namespace k)]
|
||||
(case kns
|
||||
"global" knm
|
||||
"old-css" (if (nil? *css-data*) knm "")
|
||||
(or (get *css-data* (keyword knm)) (str "_not_found_" knm))))
|
||||
"global" knm
|
||||
(str *css-prefix* knm)))
|
||||
|
||||
(string? k)
|
||||
k))))
|
||||
|
@ -49,14 +64,13 @@
|
|||
all classes with space in the same way as `css*`."
|
||||
[& selectors]
|
||||
(let [fname (-> *ns* meta :file)
|
||||
path (str (subs fname 0 (- (count fname) 4)) "css.json")
|
||||
data (read-json-file path)]
|
||||
prefix (get-prefix fname)]
|
||||
(if (symbol? (first selectors))
|
||||
`(if ~(with-meta (first selectors) {:tag 'boolean})
|
||||
(css* ~@(binding [*css-data* data]
|
||||
(css* ~@(binding [*css-prefix* prefix]
|
||||
(into [] xform-css (rest selectors))))
|
||||
(css* ~@(rest selectors)))
|
||||
`(css* ~@(binding [*css-data* data]
|
||||
`(css* ~@(binding [*css-prefix* prefix]
|
||||
(into [] xform-css selectors))))))
|
||||
|
||||
(defmacro styles
|
||||
|
@ -76,8 +90,7 @@
|
|||
kns (namespace k)]
|
||||
(case kns
|
||||
"global" knm
|
||||
"old-css" (if (nil? *css-data*) knm "")
|
||||
(or (get *css-data* (keyword knm)) knm)))
|
||||
(str *css-prefix* knm)))
|
||||
|
||||
(string? k)
|
||||
k)]
|
||||
|
@ -95,7 +108,6 @@
|
|||
;;
|
||||
;; (stl/css-case new-css-system
|
||||
;; :left-settings-bar true
|
||||
;; :old-css/settings-bar true
|
||||
;; :global/two-row (<= size 300))
|
||||
;;
|
||||
;; The first argument to the `css-case` macro is optional an if you don't
|
||||
|
@ -118,17 +130,16 @@
|
|||
(defmacro css-case
|
||||
[& params]
|
||||
(let [fname (-> *ns* meta :file)
|
||||
path (str (subs fname 0 (- (count fname) 4)) "css.json")
|
||||
data (read-json-file path)]
|
||||
prefix (get-prefix fname)]
|
||||
|
||||
(if (symbol? (first params))
|
||||
`(if ~(with-meta (first params) {:tag 'boolean})
|
||||
~(binding [*css-data* data]
|
||||
~(binding [*css-prefix* prefix]
|
||||
(-> (into [] xform-css-case (rest params))
|
||||
(mfu/compile-concat :safe? false)))
|
||||
~(-> (into [] xform-css-case (rest params))
|
||||
(mfu/compile-concat :safe? false)))
|
||||
`~(binding [*css-data* data]
|
||||
`~(binding [*css-prefix* prefix]
|
||||
(-> (into [] xform-css-case params)
|
||||
(mfu/compile-concat :safe? false))))))
|
||||
|
||||
|
|
|
@ -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 {}]]])))
|
||||
|
|
74
frontend/src/app/main/ui/auth.scss
Normal file
74
frontend/src/app/main/ui/auth.scss
Normal 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;
|
||||
}
|
||||
}
|
154
frontend/src/app/main/ui/auth/common.scss
Normal file
154
frontend/src/app/main/ui/auth/common.scss
Normal file
|
@ -0,0 +1,154 @@
|
|||
// 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 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-8;
|
||||
|
||||
button,
|
||||
: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;
|
||||
}
|
|
@ -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")]]])]])
|
||||
|
|
7
frontend/src/app/main/ui/auth/login.scss
Normal file
7
frontend/src/app/main/ui/auth/login.scss
Normal 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";
|
|
@ -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,73 @@
|
|||
|
||||
(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
|
||||
:show-success? true
|
||||
: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
|
||||
:show-success? true
|
||||
: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")]]]]])))
|
||||
|
|
12
frontend/src/app/main/ui/auth/recovery.scss
Normal file
12
frontend/src/app/main/ui/auth/recovery.scss
Normal 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;
|
||||
}
|
|
@ -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")]]]]])))
|
||||
|
|
12
frontend/src/app/main/ui/auth/recovery_request.scss
Normal file
12
frontend/src/app/main/ui/auth/recovery_request.scss
Normal 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;
|
||||
}
|
|
@ -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,133 @@
|
|||
(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"
|
||||
:show-success? true
|
||||
: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")
|
||||
:show-success? true
|
||||
: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 +284,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 +306,103 @@
|
|||
(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"
|
||||
:show-success? true
|
||||
: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")]])))
|
||||
|
||||
|
||||
|
|
38
frontend/src/app/main/ui/auth/register.scss
Normal file
38
frontend/src/app/main/ui/auth/register.scss
Normal 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;
|
||||
}
|
|
@ -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])))
|
||||
|
|
7
frontend/src/app/main/ui/auth/verify_token.scss
Normal file
7
frontend/src/app/main/ui/auth/verify_token.scss
Normal 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";
|
|
@ -10,16 +10,20 @@
|
|||
["highlight.js" :as hljs]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.context :as ctx]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc code-block
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [code type]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
block-ref (mf/use-ref)]
|
||||
block-ref (mf/use-ref)
|
||||
code (str/trim code)]
|
||||
(mf/with-effect [code type]
|
||||
(when-let [node (mf/ref-val block-ref)]
|
||||
(hljs/highlightElement node)))
|
||||
|
||||
[:pre {:class (dm/str type " " (stl/css new-css-system :code-display)) :ref block-ref} code]))
|
||||
(if new-css-system
|
||||
[:pre {:class (dm/str type " " (stl/css :code-display)) :ref block-ref} code]
|
||||
[:pre {:class (dm/str type " " "code-display") :ref block-ref} code])))
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.code-display {
|
||||
user-select: text;
|
||||
border-radius: $br-8;
|
||||
margin-top: $s-8;
|
||||
padding: $s-12;
|
||||
background-color: var(--menu-background-color);
|
||||
overflow: auto;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
(def use-form fm/use-form)
|
||||
|
||||
(mf/defc input
|
||||
[{:keys [label help-icon disabled form hint trim children data-test on-change-value placeholder] :as props}]
|
||||
[{:keys [label help-icon disabled form hint trim children data-test on-change-value placeholder show-success?] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
input-type (get props :type "text")
|
||||
input-name (get props :name)
|
||||
more-classes (get props :class)
|
||||
|
@ -54,36 +55,17 @@
|
|||
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)
|
||||
|
||||
on-change-value (or on-change-value (constantly nil))
|
||||
|
||||
klass (str more-classes " "
|
||||
(dom/classnames
|
||||
:focus @focus?
|
||||
:valid (and touched? (not error))
|
||||
:invalid (and touched? error)
|
||||
:disabled disabled
|
||||
:empty (and is-text? (str/empty? value))
|
||||
:with-icon (not (nil? help-icon'))
|
||||
:custom-input is-text?
|
||||
:input-radio is-radio?
|
||||
:input-checkbox is-checkbox?))
|
||||
|
||||
new-classes (dm/str more-classes " "
|
||||
(stl/css-case
|
||||
:input-wrapper true
|
||||
:global/invalid (and touched? error)
|
||||
:checkbox is-checkbox?
|
||||
:global/disabled disabled))
|
||||
|
||||
swap-text-password
|
||||
(fn []
|
||||
(swap! type' (fn [input-type]
|
||||
|
@ -100,9 +82,7 @@
|
|||
|
||||
on-blur
|
||||
(fn [_]
|
||||
(reset! focus? false)
|
||||
(when-not (get-in @form [:touched input-name])
|
||||
(swap! form assoc-in [:touched input-name] true)))
|
||||
(reset! focus? false))
|
||||
|
||||
on-click
|
||||
(fn [_]
|
||||
|
@ -126,10 +106,19 @@
|
|||
(cond-> (and value is-checkbox?) (assoc :default-checked value))
|
||||
(cond-> (and touched? (:message error)) (assoc "aria-invalid" "true"
|
||||
"aria-describedby" (dm/str "error-" input-name)))
|
||||
(obj/clj->props))]
|
||||
(obj/clj->props))
|
||||
|
||||
show-valid? (and show-success? touched? (not error))
|
||||
show-invalid? (and touched? error)]
|
||||
|
||||
(if new-css-system
|
||||
[:div {:class new-classes}
|
||||
[:div {:class (dm/str more-classes " "
|
||||
(stl/css-case
|
||||
:input-wrapper true
|
||||
:valid show-valid?
|
||||
:invalid show-invalid?
|
||||
:checkbox is-checkbox?
|
||||
:disabled disabled))}
|
||||
[:*
|
||||
(cond
|
||||
(some? label)
|
||||
|
@ -137,23 +126,38 @@
|
|||
: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'])
|
||||
|
||||
(when show-valid?
|
||||
[:span {:class (stl/css :valid-icon)}
|
||||
i/tick-refactor])
|
||||
|
||||
(when show-invalid?
|
||||
[:span {:class (stl/css :invalid-icon)}
|
||||
i/close-refactor])])]
|
||||
|
||||
(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)
|
||||
|
@ -164,9 +168,19 @@
|
|||
(string? hint)
|
||||
[:div {:class (stl/css :hint)} hint])]]
|
||||
|
||||
|
||||
;;OLD
|
||||
[:div
|
||||
{:class klass}
|
||||
{:class (str more-classes " "
|
||||
(dom/classnames
|
||||
:focus @focus?
|
||||
:valid (and touched? (not error))
|
||||
:invalid (and touched? error)
|
||||
:disabled disabled
|
||||
:empty (and is-text? (str/empty? value))
|
||||
:with-icon (not (nil? help-icon'))
|
||||
:custom-input is-text?
|
||||
:input-radio is-radio?
|
||||
:input-checkbox is-checkbox?))}
|
||||
[:*
|
||||
[:> :input props]
|
||||
(cond
|
||||
|
@ -387,7 +401,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
|
||||
|
|
|
@ -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,28 +43,101 @@
|
|||
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) {
|
||||
&.valid {
|
||||
input {
|
||||
border: $s-1 solid var(--input-border-color-success);
|
||||
@extend .disabled-input;
|
||||
&:hover,
|
||||
&:focus {
|
||||
border: $s-1 solid var(--input-border-color-success);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.invalid {
|
||||
input {
|
||||
border: $s-1 solid var(--input-border-color-error);
|
||||
@extend .disabled-input;
|
||||
&:hover,
|
||||
&:focus {
|
||||
border: $s-1 solid var(--input-border-color-error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.valid .help-icon,
|
||||
&.invalid .help-icon {
|
||||
right: $s-40;
|
||||
}
|
||||
}
|
||||
|
||||
.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-16;
|
||||
top: calc(50% - $s-8);
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--input-details-color);
|
||||
stroke: $df-secondary;
|
||||
width: $s-16;
|
||||
height: $s-16;
|
||||
}
|
||||
}
|
||||
.invalid-icon {
|
||||
width: $s-16;
|
||||
height: $s-16;
|
||||
background: var(--input-border-color-error);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
right: $s-16;
|
||||
top: calc(50% - $s-8);
|
||||
svg {
|
||||
width: $s-12;
|
||||
height: $s-12;
|
||||
stroke: var(--input-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.valid-icon {
|
||||
width: $s-16;
|
||||
height: $s-16;
|
||||
background: var(--input-border-color-success);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
right: $s-16;
|
||||
top: calc(50% - $s-8);
|
||||
svg {
|
||||
width: $s-12;
|
||||
height: $s-12;
|
||||
fill: var(--input-border-color-success);
|
||||
stroke: var(--input-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--input-border-color-error);
|
||||
width: 100%;
|
||||
font-size: $fs-14;
|
||||
}
|
||||
|
||||
.hint {
|
||||
|
@ -181,9 +256,6 @@
|
|||
// SUBMIT-BUTTON
|
||||
.btn-disabled {
|
||||
@extend .button-disabled;
|
||||
height: $s-32;
|
||||
padding: $s-8 $s-24;
|
||||
border-radius: $br-8;
|
||||
}
|
||||
|
||||
// MULTI INPUT
|
||||
|
|
|
@ -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}]])))
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
:name :name
|
||||
:disabled @created?
|
||||
:label (tr "modals.create-access-token.name.label")
|
||||
:show-success? true
|
||||
:placeholder (tr "modals.create-access-token.name.placeholder")}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
:name :email-1
|
||||
:label (tr "modals.change-email.new-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
|
@ -129,6 +130,7 @@
|
|||
:name :email-2
|
||||
:label (tr "modals.change-email.confirm-email")
|
||||
:trim true
|
||||
:show-success? true
|
||||
:on-change-value on-email-change}]]]
|
||||
|
||||
[:div {:class (stl/css :modal-footer)}
|
||||
|
|
|
@ -73,7 +73,8 @@
|
|||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input {:label (tr "feedback.subject")
|
||||
:name :subject}]]
|
||||
:name :subject
|
||||
:show-success? true}]]
|
||||
[:div {:class (stl/css :fields-row :description)}
|
||||
[:& fm/textarea
|
||||
{:label (tr "feedback.description")
|
||||
|
|
|
@ -95,17 +95,20 @@
|
|||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password-1
|
||||
:show-success? true
|
||||
:label (t locale "labels.new-password")}]]
|
||||
|
||||
[:div {:class (stl/css :fields-row)}
|
||||
[:& fm/input
|
||||
{:type "password"
|
||||
:name :password-2
|
||||
:show-success? true
|
||||
:label (t locale "labels.confirm-password")}]]
|
||||
|
||||
[:> 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 +156,3 @@
|
|||
[:section.dashboard-settings.form-container
|
||||
[:div.form-container
|
||||
[:& password-form {:locale locale}]]])))
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
{:type "email"
|
||||
:name :email
|
||||
:disabled true
|
||||
:help-icon i/at
|
||||
:label (tr "dashboard.your-email")}]
|
||||
|
||||
[:div {:class (stl/css :options)}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 (not new-css-system)
|
||||
:global/settings-bar-right (not new-css-system)
|
||||
:right-settings-bar true
|
||||
:not-expand (not can-be-expanded?)
|
||||
:expanded (> size 276))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue