diff --git a/frontend/gulpfile.js b/frontend/gulpfile.js index 767ef69ecf..e232a4db1c 100644 --- a/frontend/gulpfile.js +++ b/frontend/gulpfile.js @@ -29,7 +29,7 @@ paths.resources = "./resources/"; paths.output = "./resources/public/"; paths.dist = "./target/dist/"; -const touchSourceOnStyleChange = true; +const touchSourceOnStyleChange = false; /*********************************************** * Marked Extensions diff --git a/frontend/package.json b/frontend/package.json index f9801e1553..38ef1334bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "test:compile": "clojure -M:dev:shadow-cljs compile test --config-merge '{:autorun false}'", "lint:clj": "clj-kondo --parallel --lint src/", "lint:scss": "yarn run prettier -c resources/styles -c src/**/*.scss", + "lint:fix": "yarn run prettier -c resources/styles -c src/**/*.scss -w", "test:run": "node target/tests.js", "test:watch": "clojure -M:dev:shadow-cljs watch test", "test": "yarn run test:compile && yarn run test:run", diff --git a/frontend/resources/images/icons/logo-error-screen.svg b/frontend/resources/images/icons/logo-error-screen.svg new file mode 100644 index 0000000000..7e71215fac --- /dev/null +++ b/frontend/resources/images/icons/logo-error-screen.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs index aff9e778fc..d6efe6e4af 100644 --- a/frontend/src/app/main/ui/icons.cljs +++ b/frontend/src/app/main/ui/icons.cljs @@ -170,6 +170,7 @@ (def lock (icon-xref :lock)) (def logo (icon-xref :penpot-logo)) (def logo-icon (icon-xref :penpot-logo-icon)) +(def logo-error-screen (icon-xref :logo-error-screen)) (def logout (icon-xref :logout)) (def lowercase (icon-xref :lowercase)) (def mail (icon-xref :mail)) diff --git a/frontend/src/app/main/ui/static.cljs b/frontend/src/app/main/ui/static.cljs index 9164f1041a..a9fa000c16 100644 --- a/frontend/src/app/main/ui/static.cljs +++ b/frontend/src/app/main/ui/static.cljs @@ -5,8 +5,11 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.static + (:require-macros [app.main.style :as stl]) (:require + [app.main.features :as features] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.globals :as globals] [app.util.i18n :refer [tr]] @@ -17,66 +20,115 @@ (mf/defc static-header {::mf/wrap-props false} [props] - (let [children (obj/get props "children") + (let [new-css-system (mf/use-ctx ctx/new-css-system) + children (obj/get props "children") on-click (mf/use-callback #(set! (.-href globals/location) "/"))] - [:section.exception-layout - [:div.exception-header - {:on-click on-click} - i/logo] - [:div.exception-content - [:div.container children]]])) + (if new-css-system + [:section {:class (stl/css :exception-layout)} + [:div + {:class (stl/css :exception-header) + :on-click on-click} + i/logo-icon] + [:div {:class (stl/css :deco-before)} i/logo-error-screen] + + [:div {:class (stl/css :exception-content)} + [:div {:class (stl/css :container)} children]] + + [:div {:class (stl/css :deco-after)} i/logo-error-screen]] + [:section.exception-layout + [:div.exception-header + {:on-click on-click} + i/logo] + [:div.exception-content + [:div.container children]]]))) (mf/defc not-found [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.not-found.main-message")] - [:div.desc-message (tr "labels.not-found.desc-message")]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.not-found.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.not-found.desc-message")]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.not-found.main-message")] + [:div.desc-message (tr "labels.not-found.desc-message")]]))) (mf/defc bad-gateway [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.bad-gateway.main-message")] - [:div.desc-message (tr "labels.bad-gateway.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.bad-gateway.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.bad-gateway.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.bad-gateway.main-message")] + [:div.desc-message (tr "labels.bad-gateway.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! #(dissoc % :exception)))} + (tr "labels.retry")]]]))) (mf/defc service-unavailable [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.service-unavailable.main-message")] - [:div.desc-message (tr "labels.service-unavailable.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.service-unavailable.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.service-unavailable.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.main-message (tr "labels.service-unavailable.main-message")] + [:div.desc-message (tr "labels.service-unavailable.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! #(dissoc % :exception)))} + (tr "labels.retry")]]]))) (mf/defc internal-error [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.internal-error.main-message")] - [:div.desc-message (tr "labels.internal-error.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.internal-error.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.internal-error.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.internal-error.main-message")] + [:div.desc-message (tr "labels.internal-error.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]]))) (mf/defc exception-page [{:keys [data] :as props}] - (case (:type data) - :not-found - [:& not-found] + (let [new-css-system (features/use-feature "styles/v2")] + [:& (mf/provider ctx/new-css-system) {:value new-css-system} + (case (:type data) + :not-found + [:& not-found] - :bad-gateway - [:& bad-gateway] + :bad-gateway + [:& bad-gateway] - :service-unavailable - [:& service-unavailable] - - [:& internal-error])) + :service-unavailable + [:& service-unavailable] + [:& internal-error])])) diff --git a/frontend/src/app/main/ui/static.scss b/frontend/src/app/main/ui/static.scss new file mode 100644 index 0000000000..63e00828b5 --- /dev/null +++ b/frontend/src/app/main/ui/static.scss @@ -0,0 +1,91 @@ +// 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 *; + +.exception-layout { + width: 100%; + height: 100%; + background-color: $db-secondary; +} + +.deco-before, +.deco-after { + position: absolute; + left: calc(50% - $s-40); + + svg { + position: absolute; + fill: $df-secondary; + height: 1537px; + width: $s-80; + } +} + +.deco-before { + height: 34vh; + top: 0; + svg { + bottom: 0; + } +} + +.deco-after { + height: 34vh; + bottom: 0; + svg { + top: 0; + } +} + +.exception-header { + padding: $s-24 $s-32; + position: fixed; + svg { + fill: $df-primary; + width: $s-48; + height: auto; + } +} + +.exception-content { + display: flex; + height: 100%; + justify-content: center; + width: 100%; + + .container { + align-items: center; + display: flex; + flex-direction: column; + gap: $s-16; + height: 34vh; + justify-content: center; + margin-top: 33vh; + text-align: center; + width: $s-640; + } +} + +.main-message { + @include bigTitleTipography; + color: $df-primary; +} + +.desc-message { + @include bigTitleTipography; + color: $df-secondary; +} + +.sign-info { + text-align: center; + button { + @extend .button-primary; + text-transform: uppercase; + padding: $s-8 $s-16; + font-size: $fs-11; + } +}