diff --git a/Dockerfile b/Dockerfile index 875382e1..0a18dcc8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx:1.27-alpine-slim as web +FROM nginx:1.27-alpine-slim AS web RUN rm -rf /etc/nginx/ /var/www/ diff --git a/env/nginx/nginx.conf b/env/nginx/nginx.conf index 0fb524f8..d4dcb083 100644 --- a/env/nginx/nginx.conf +++ b/env/nginx/nginx.conf @@ -4,8 +4,8 @@ error_log /dev/stdout info; events {} http { - include mime.types; - charset utf-8; + include mime.types; + charset utf-8; access_log off; absolute_redirect off; diff --git a/nuxt.config.js b/nuxt.config.js index e525baaf..51d549d2 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -304,5 +304,10 @@ export default defineNuxtConfig({ // Dev Tools Configuration devtools: { enabled: true + }, + + // Experimental Configuration + experimental: { + inlineRouteRules: true } }); diff --git a/package-lock.json b/package-lock.json index 0d195150..49921e0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,12 @@ "version": "3.3.0", "license": "UNLICENSED", "dependencies": { + "check-password-strength": "2.0.10", + "credit-card-type": "10.0.1", "crisp-sdk-web": "1.0.25", - "vue": "3.5.11" + "keycode": "2.2.1", + "vue": "3.5.11", + "vue-confetti": "2.3.0" }, "devDependencies": { "@nuxt/content": "2.13.2", @@ -5649,6 +5653,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-password-strength": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/check-password-strength/-/check-password-strength-2.0.10.tgz", + "integrity": "sha512-HRM5ICPmtnNtLnTv2QrfVkq1IxI9z3bzYpDJ1k5ixwD9HtJGHuv265R6JmHOV6r8wLhQMlULnIUVpkrC2yaiCw==" + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -6141,6 +6150,11 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/credit-card-type": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-10.0.1.tgz", + "integrity": "sha512-vQOuWmBgsgG1ovGeDi8m6Zeu1JaqH/JncrxKmaqMbv/LunyOQdLiQhPHtOsNlbUI05TocR5nod/Mbs3HYtr6sQ==" + }, "node_modules/crisp-sdk-web": { "version": "1.0.25", "resolved": "https://registry.npmjs.org/crisp-sdk-web/-/crisp-sdk-web-1.0.25.tgz", @@ -9124,6 +9138,11 @@ "promise": "^7.0.1" } }, + "node_modules/keycode": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz", + "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -16205,6 +16224,11 @@ "ufo": "^1.5.4" } }, + "node_modules/vue-confetti": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vue-confetti/-/vue-confetti-2.3.0.tgz", + "integrity": "sha512-zmPniVzBKv0ie/BEXBR6Isi08hYSd6lS18b8VduG5BzZ2tv6bO/rlwISg+IpGY2XsqAFTXFdTC28YR+UPocnAw==" + }, "node_modules/vue-devtools-stub": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz", diff --git a/package.json b/package.json index 5bc59ee1..efe45c44 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,10 @@ }, "dependencies": { "vue": "3.5.11", + "vue-confetti": "2.3.0", + "keycode": "2.2.1", + "check-password-strength": "2.0.10", + "credit-card-type": "10.0.1", "crisp-sdk-web": "1.0.25" }, "devDependencies": { diff --git a/src/assets/images/components/base/BaseButton/icon-open-external.svg b/src/assets/images/components/base/BaseButton/icon-open-external.svg new file mode 100644 index 00000000..e0ea5eaf --- /dev/null +++ b/src/assets/images/components/base/BaseButton/icon-open-external.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/american-express.svg b/src/assets/images/components/base/BasePaymentIcon/american-express.svg new file mode 100755 index 00000000..85e87145 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/american-express.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/diners-club.svg b/src/assets/images/components/base/BasePaymentIcon/diners-club.svg new file mode 100755 index 00000000..3dd2c52a --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/diners-club.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/discover.svg b/src/assets/images/components/base/BasePaymentIcon/discover.svg new file mode 100755 index 00000000..310608bf --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/discover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/elo.svg b/src/assets/images/components/base/BasePaymentIcon/elo.svg new file mode 100755 index 00000000..7eb77ee0 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/elo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/generic.svg b/src/assets/images/components/base/BasePaymentIcon/generic.svg new file mode 100755 index 00000000..a8633f3e --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/generic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/hiper.svg b/src/assets/images/components/base/BasePaymentIcon/hiper.svg new file mode 100644 index 00000000..192dc7a9 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/hiper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/hipercard.svg b/src/assets/images/components/base/BasePaymentIcon/hipercard.svg new file mode 100755 index 00000000..f28ec9a3 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/hipercard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/jcb.svg b/src/assets/images/components/base/BasePaymentIcon/jcb.svg new file mode 100755 index 00000000..637e49a3 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/jcb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/maestro.svg b/src/assets/images/components/base/BasePaymentIcon/maestro.svg new file mode 100755 index 00000000..49614cc1 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/maestro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/mastercard.svg b/src/assets/images/components/base/BasePaymentIcon/mastercard.svg new file mode 100755 index 00000000..b368f41d --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/mastercard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/mir.svg b/src/assets/images/components/base/BasePaymentIcon/mir.svg new file mode 100644 index 00000000..4fe99b19 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/mir.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/unionpay.svg b/src/assets/images/components/base/BasePaymentIcon/unionpay.svg new file mode 100755 index 00000000..41a37667 --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/unionpay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BasePaymentIcon/visa.svg b/src/assets/images/components/base/BasePaymentIcon/visa.svg new file mode 100755 index 00000000..170c94aa --- /dev/null +++ b/src/assets/images/components/base/BasePaymentIcon/visa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BaseProgressItem/icon-account.svg b/src/assets/images/components/base/BaseProgressItem/icon-account.svg new file mode 100644 index 00000000..7ce42a7c --- /dev/null +++ b/src/assets/images/components/base/BaseProgressItem/icon-account.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BaseProgressItem/icon-activate.svg b/src/assets/images/components/base/BaseProgressItem/icon-activate.svg new file mode 100644 index 00000000..60691f0a --- /dev/null +++ b/src/assets/images/components/base/BaseProgressItem/icon-activate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BaseProgressItem/icon-done.svg b/src/assets/images/components/base/BaseProgressItem/icon-done.svg new file mode 100644 index 00000000..79cba983 --- /dev/null +++ b/src/assets/images/components/base/BaseProgressItem/icon-done.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BaseProgressItem/icon-finished.svg b/src/assets/images/components/base/BaseProgressItem/icon-finished.svg new file mode 100644 index 00000000..272dedc1 --- /dev/null +++ b/src/assets/images/components/base/BaseProgressItem/icon-finished.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/base/BaseProgressItem/icon-progress.svg b/src/assets/images/components/base/BaseProgressItem/icon-progress.svg new file mode 100644 index 00000000..85cb2a87 --- /dev/null +++ b/src/assets/images/components/base/BaseProgressItem/icon-progress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-calls.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-calls.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-calls.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-calls.svg diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-encrypt.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-encrypt.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-encrypt.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-encrypt.svg diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-history.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-history.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-history.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-history.svg diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-integration.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-integration.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-integration.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-integration.svg diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-search.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-search.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-search.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-search.svg diff --git a/src/assets/images/components/section/home/SectionHomeFeatures/illustration-share.svg b/src/assets/images/components/partial/common/PartialCommonFeature/illustration-share.svg similarity index 100% rename from src/assets/images/components/section/home/SectionHomeFeatures/illustration-share.svg rename to src/assets/images/components/partial/common/PartialCommonFeature/illustration-share.svg diff --git a/src/assets/images/components/section/cloud/SectionCloudAccountSettingsForm/navigate-arrow.svg b/src/assets/images/components/section/cloud/SectionCloudAccountSettingsForm/navigate-arrow.svg new file mode 100644 index 00000000..d40a6278 --- /dev/null +++ b/src/assets/images/components/section/cloud/SectionCloudAccountSettingsForm/navigate-arrow.svg @@ -0,0 +1 @@ + diff --git a/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-settings.svg b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-settings.svg new file mode 100644 index 00000000..a7d35663 --- /dev/null +++ b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-settings.svg @@ -0,0 +1 @@ + diff --git a/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-workspace.svg b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-workspace.svg new file mode 100644 index 00000000..705781a9 --- /dev/null +++ b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesNavigator/icon-workspace.svg @@ -0,0 +1 @@ + diff --git a/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesPicker/logo-crisp.png b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesPicker/logo-crisp.png new file mode 100644 index 00000000..37d37a11 Binary files /dev/null and b/src/assets/images/components/section/cloud/SectionCloudAccountWorkspacesPicker/logo-crisp.png differ diff --git a/src/assets/images/components/section/download/illustration-version-archive.svg b/src/assets/images/components/section/download/SectionDownloadsArchives/illustration-version-archive.svg similarity index 100% rename from src/assets/images/components/section/download/illustration-version-archive.svg rename to src/assets/images/components/section/download/SectionDownloadsArchives/illustration-version-archive.svg diff --git a/src/assets/stylesheets/variables/_variables.colors.scss b/src/assets/stylesheets/variables/_variables.colors.scss index 97604013..90dee886 100644 --- a/src/assets/stylesheets/variables/_variables.colors.scss +++ b/src/assets/stylesheets/variables/_variables.colors.scss @@ -27,6 +27,11 @@ $color-base-grey-mid: #a4a4ae; $color-base-grey-light: #f5f6fa; $color-base-black-mid: #1d1d28; $color-base-green-mid: #00ab7e; +$color-base-yellow-light: #fff5e6; +$color-base-yellow-mid: #ebd9bc; +$color-base-yellow-dark: #d5ad6b; +$color-base-red-light: #ffe1e1; +$color-base-red-mid: #dd2f2f; $color-base-pink-light: #f67086; $color-base-purple-mid: #644eb4; $color-base-purple-light: #a19db6; diff --git a/src/assets/stylesheets/variables/_variables.sizes.scss b/src/assets/stylesheets/variables/_variables.sizes.scss index bd3a4b7a..4a44f3c5 100644 --- a/src/assets/stylesheets/variables/_variables.sizes.scss +++ b/src/assets/stylesheets/variables/_variables.sizes.scss @@ -22,6 +22,14 @@ $page-header-height: 80px; $page-header-bar-height: 60px; $page-header-announcement-height: 44px; +// Section + +$section-form-margin-top: 60px; + +// Form + +$form-field-border-radius: 10px; + // Screen $screen-large-width-breakpoint: $page-wrapper-max-width; diff --git a/src/components/base/BaseButton.vue b/src/components/base/BaseButton.vue index 99b6dd9b..9d9c2ff3 100644 --- a/src/components/base/BaseButton.vue +++ b/src/components/base/BaseButton.vue @@ -20,6 +20,7 @@ div( "c-base-button--squared": squared, "c-base-button--reverse": reverse, "c-base-button--disabled": disabled, + "c-base-button--loading": loading, "c-base-button--flat": flat, ["c-base-button--" + rightIcon]: rightIcon } @@ -41,8 +42,17 @@ div( ) slot - .c-base-button__icon( - v-if="rightIconHtml" + base-spinner( + v-if="loading" + :color="iconSpinnerColor" + speed="slow" + size="11px" + border-width="1px" + class="c-base-button__icon c-base-button__icon--spinner" + ) + + .c-base-button__icon.c-base-button__icon--icon( + v-else-if="rightIconHtml" v-html="rightIconHtml" ) @@ -56,6 +66,7 @@ div( import ImageIconArrowRight from "@/assets/images/components/base/BaseButton/icon-arrow-right.svg?raw"; import ImageIconArrowDown from "@/assets/images/components/base/BaseButton/icon-arrow-down.svg?raw"; import ImageIconChevronDown from "@/assets/images/components/base/BaseButton/icon-chevron-down.svg?raw"; +import ImageIconOpenExternal from "@/assets/images/components/base/BaseButton/icon-open-external.svg?raw"; export default { name: "BaseButton", @@ -66,7 +77,9 @@ export default { default: "dark", validator(x) { - return ["light", "dark", "gradient", "fancy", "none"].includes(x); + return ["light", "dark", "gradient", "fancy", "link", "none"].includes( + x + ); } }, @@ -75,7 +88,14 @@ export default { default: "normal", validator(x) { - return ["simple", "small", "normal", "large", "huge"].includes(x); + return [ + "simple", + "small", + "normal", + "large", + "huge", + "enormous" + ].includes(x); } }, @@ -104,6 +124,11 @@ export default { default: false }, + loading: { + type: Boolean, + default: false + }, + flat: { type: Boolean, default: false @@ -119,7 +144,12 @@ export default { default: null, validator(x) { - return ["arrow-right", "arrow-down", "chevron-down"].includes(x); + return [ + "arrow-right", + "arrow-down", + "chevron-down", + "open-external" + ].includes(x); } } }, @@ -141,10 +171,30 @@ export default { return ImageIconChevronDown; } + case "open-external": { + return ImageIconOpenExternal; + } + default: { return null; } } + }, + + iconSpinnerColor() { + const _prefix = this.reverse ? "reverse" : "normal"; + + switch (`${_prefix}/${this.tint}`) { + case "normal/none": + case "normal/light": + case "reverse/dark": { + return "blue"; + } + + default: { + return "white"; + } + } } }, @@ -158,8 +208,8 @@ export default { * @return {undefined} */ onClick(event) { - // Re-emit click event? (if not disabled) - if (this.disabled !== true) { + // Re-emit click event? (if not disabled or loading) + if (this.disabled !== true && this.loading !== true) { this.$emit("click", event); } } @@ -179,6 +229,7 @@ $size-small-padding-sides: 26px; $size-normal-padding-sides: 22px; $size-large-padding-sides: 28px; $size-huge-padding-sides: 38px; +$size-enormous-padding-sides: 32px; #{$c} { user-select: none; @@ -196,7 +247,7 @@ $size-huge-padding-sides: 38px; display: flex; align-items: center; cursor: pointer; - border-radius: 24px; + border-radius: 100px; transition: all 100ms linear; transition-property: transform, box-shadow, background-color; @@ -209,9 +260,15 @@ $size-huge-padding-sides: 38px; margin-right: -2px; flex: 0 1 auto; - svg { - width: auto; - height: 12px; + &--icon { + svg { + width: auto; + height: 12px; + } + } + + &--spinner { + margin-bottom: -1px; } } } @@ -361,6 +418,37 @@ $size-huge-padding-sides: 38px; } } + &--link { + #{$c}__inner { + background-color: darken($color-base-blue-link, 6%); + border: 1px solid $color-border-primary; + box-shadow: + 0 2px 3px 0 rgba($color-base-blue-link, 0.04), + inset 0 1px 0 0 rgba($color-white, 0.15); + + #{$c}__label { + color: $color-white; + } + + #{$c}__icon { + fill: $color-white; + } + } + + &:hover { + #{$c}__inner { + background-color: darken($color-base-blue-link, 1%); + } + } + + &:active { + #{$c}__inner { + background-color: darken($color-base-blue-link, 4%); + box-shadow: 0 1px 1px 0 rgba($color-base-blue-link, 0.1); + } + } + } + // --> SIZES <-- &--simple, @@ -380,6 +468,14 @@ $size-huge-padding-sides: 38px; } } + &--enormous { + #{$c}__inner { + line-height: 19px; + padding-top: 15px; + padding-bottom: 17px; + } + } + &--simple { #{$c}__inner { font-size: 14px; @@ -426,21 +522,38 @@ $size-huge-padding-sides: 38px; } } + &--enormous { + #{$c}__inner { + font-size: 15px; + padding-left: $size-enormous-padding-sides; + padding-right: $size-enormous-padding-sides; + + #{$c}__icon { + margin-left: 28px; + } + } + } + // --> RIGHT ICONS <-- &--arrow-right, &--chevron-down { #{$c}__inner { #{$c}__icon { - margin-bottom: -4px; + &--icon { + margin-bottom: -4px; + } } } } - &--arrow-down { + &--arrow-down, + &--open-external { #{$c}__inner { #{$c}__icon { - margin-bottom: -3px; + &--icon { + margin-bottom: -3px; + } } } } @@ -533,13 +646,27 @@ $size-huge-padding-sides: 38px; } } + &--disabled, + &--loading { + #{$c}__inner { + pointer-events: none; + } + } + &--disabled { cursor: not-allowed; #{$c}__inner { - pointer-events: none; opacity: 0.6; } } + + &--loading { + cursor: wait; + + #{$c}__inner { + opacity: 0.9; + } + } } diff --git a/src/components/base/BaseFloatingLink.vue b/src/components/base/BaseFloatingLink.vue new file mode 100644 index 00000000..69fd51d9 --- /dev/null +++ b/src/components/base/BaseFloatingLink.vue @@ -0,0 +1,97 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BaseNotice.vue b/src/components/base/BaseNotice.vue new file mode 100644 index 00000000..d9d55da4 --- /dev/null +++ b/src/components/base/BaseNotice.vue @@ -0,0 +1,127 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BasePaymentIcon.vue b/src/components/base/BasePaymentIcon.vue new file mode 100644 index 00000000..0c911709 --- /dev/null +++ b/src/components/base/BasePaymentIcon.vue @@ -0,0 +1,149 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BasePaymentPreview.vue b/src/components/base/BasePaymentPreview.vue new file mode 100644 index 00000000..c1c6ce0c --- /dev/null +++ b/src/components/base/BasePaymentPreview.vue @@ -0,0 +1,65 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BaseProgress.vue b/src/components/base/BaseProgress.vue new file mode 100644 index 00000000..03680b77 --- /dev/null +++ b/src/components/base/BaseProgress.vue @@ -0,0 +1,84 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BaseProgressItem.vue b/src/components/base/BaseProgressItem.vue new file mode 100644 index 00000000..184796e4 --- /dev/null +++ b/src/components/base/BaseProgressItem.vue @@ -0,0 +1,157 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BaseSecurityLevel.vue b/src/components/base/BaseSecurityLevel.vue new file mode 100644 index 00000000..060ac0e0 --- /dev/null +++ b/src/components/base/BaseSecurityLevel.vue @@ -0,0 +1,176 @@ + + + + + + + + + + + + + diff --git a/src/components/base/BaseSine.vue b/src/components/base/BaseSine.vue index 6053d77c..e2fefb97 100644 --- a/src/components/base/BaseSine.vue +++ b/src/components/base/BaseSine.vue @@ -102,7 +102,7 @@ $c: ".c-base-sine"; stroke-dasharray: 2400; stroke-dashoffset: 2400; pointer-events: none; - animation: revealSine 1.5s ease-out forwards; + animation: c-base-sine-path-reveal 1.5s ease-out forwards; } } } @@ -155,7 +155,7 @@ $c: ".c-base-sine"; // --> KEYFRAMES <-- -@keyframes revealSine { +@keyframes c-base-sine-path-reveal { to { stroke-dashoffset: 0; } diff --git a/src/components/base/BaseSpinner.vue b/src/components/base/BaseSpinner.vue index e2304e34..f7756120 100644 --- a/src/components/base/BaseSpinner.vue +++ b/src/components/base/BaseSpinner.vue @@ -101,7 +101,7 @@ $speeds: ( border-style: solid; display: inline-block; border-radius: 100%; - animation: spin 0s 0s infinite linear; + animation: c-base-spinner-icon-spin 0s 0s infinite linear; animation-fill-mode: both; } @@ -128,7 +128,7 @@ $speeds: ( // --> KEYFRAMES <-- -@keyframes spin { +@keyframes c-base-spinner-icon-spin { from { transform: rotate(0deg); } diff --git a/src/components/base/BaseTitle.vue b/src/components/base/BaseTitle.vue index d40ac08e..731659fe 100644 --- a/src/components/base/BaseTitle.vue +++ b/src/components/base/BaseTitle.vue @@ -39,7 +39,14 @@ export default { default: "normal", validator(x) { - return ["mini", "small", "medium", "normal", "large"].includes(x); + return [ + "lilliput", + "mini", + "small", + "medium", + "normal", + "large" + ].includes(x); } }, @@ -57,7 +64,7 @@ export default { default: "dark", validator(x) { - return ["light", "dark", "gradient"].includes(x); + return ["light", "dark", "black", "gradient"].includes(x); } }, @@ -92,6 +99,12 @@ $stroke-color: $color-background-secondary; #{$c} { // --> LEVELS <-- + &--lilliput { + font-size: 22px; + line-height: 22px; + letter-spacing: -0.005em; + } + &--mini { font-size: 26px; line-height: 26px; @@ -132,6 +145,10 @@ $stroke-color: $color-background-secondary; color: $color-white; } + &--black { + color: $color-black; + } + &--gradient { background-image: linear-gradient( -6deg, diff --git a/src/components/form/FormField.vue b/src/components/form/FormField.vue new file mode 100644 index 00000000..18a30f67 --- /dev/null +++ b/src/components/form/FormField.vue @@ -0,0 +1,438 @@ + + + + + + + + + + + + + diff --git a/src/components/form/FormFieldsetField.vue b/src/components/form/FormFieldsetField.vue new file mode 100644 index 00000000..fbdb22f4 --- /dev/null +++ b/src/components/form/FormFieldsetField.vue @@ -0,0 +1,126 @@ + + + + + + + + + + + + + diff --git a/src/components/form/FormLabel.vue b/src/components/form/FormLabel.vue new file mode 100644 index 00000000..c1c4872e --- /dev/null +++ b/src/components/form/FormLabel.vue @@ -0,0 +1,47 @@ + + + + + + + + + + + + + diff --git a/src/components/form/FormLabelledField.vue b/src/components/form/FormLabelledField.vue new file mode 100644 index 00000000..803c5c9b --- /dev/null +++ b/src/components/form/FormLabelledField.vue @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/src/components/form/FormTitledField.vue b/src/components/form/FormTitledField.vue new file mode 100644 index 00000000..1e6056e2 --- /dev/null +++ b/src/components/form/FormTitledField.vue @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/src/components/form/FormToggle.vue b/src/components/form/FormToggle.vue index f8e41b93..7782fad4 100644 --- a/src/components/form/FormToggle.vue +++ b/src/components/form/FormToggle.vue @@ -21,7 +21,9 @@ div( input( @change="onInputChange" :name="name" + :id="name" :checked="checked" + :disabled="disabled || loading" class="c-form-toggle__input" type="checkbox" ref="input" @@ -206,16 +208,19 @@ $toggle-field-height: ($toggle-height - (2 * $toggle-handle-offset)); // --> BOOLEANS <-- - &--disabled { - cursor: not-allowed; - - &#{$c}--loading { - cursor: wait; - } - + &--disabled, + &--loading { #{$c}__field { pointer-events: none; } } + + &--disabled { + cursor: not-allowed; + } + + &--loading { + cursor: wait; + } } diff --git a/src/components/page/PageContent.vue b/src/components/page/PageContent.vue index 8a47d767..be727e3b 100644 --- a/src/components/page/PageContent.vue +++ b/src/components/page/PageContent.vue @@ -13,7 +13,8 @@ div( :class=`[ "c-page-content", { - "c-page-content--showcase": showcase + "c-page-content--showcase": showcase, + "c-page-content--embedded": embedded } ]` ) @@ -32,6 +33,11 @@ export default { showcase: { type: Boolean, default: false + }, + + embedded: { + type: Boolean, + default: false } } }; @@ -55,13 +61,18 @@ $c: ".c-page-content"; &--showcase { padding-top: 0; } + + &--embedded { + padding-top: 64px; + padding-bottom: 0; + } } // --> MEDIA-QUERIES <-- @media (max-width: $screen-tiny-width-breakpoint) { #{$c} { - &:not(#{$c}--showcase) { + &:not(#{$c}--showcase):not(#{$c}--embedded) { padding-top: 52px; padding-bottom: 90px; } diff --git a/src/components/page/PageEntice.vue b/src/components/page/PageEntice.vue index d5f1f6fd..3fa7e20f 100644 --- a/src/components/page/PageEntice.vue +++ b/src/components/page/PageEntice.vue @@ -348,7 +348,7 @@ $animate-shake-base-depth: 2px; min-width: 400px; &--invalid { - animation-name: shake; + animation-name: c-page-entice-actions-shake; animation-duration: 800ms; animation-iteration-count: 1; } @@ -504,7 +504,7 @@ $animate-shake-base-depth: 2px; // --> KEYFRAMES <-- -@keyframes shake { +@keyframes c-page-entice-actions-shake { 10%, 90% { transform: translate3d((-1 * $animate-shake-base-depth), 0, 0); diff --git a/src/components/page/PageHeader.vue b/src/components/page/PageHeader.vue index f84d1e1a..710ea9ef 100644 --- a/src/components/page/PageHeader.vue +++ b/src/components/page/PageHeader.vue @@ -80,16 +80,28 @@ div( ) .c-page-header__right - a( - :href="$config.public.url.prose_app" - class="c-page-header__action" - ) - base-button( - class="c-page-header__action-button" - right-icon="arrow-right" - tint="fancy" + .c-page-header__actions + nuxt-link( + class="c-page-header__action" + to="/cloud/signin/" + ) + base-button( + class="c-page-header__action-button" + size="simple" + tint="none" + ) + | Log In + + nuxt-link( + class="c-page-header__action" + to="/cloud/signup/" ) - | Go to App + base-button( + class="c-page-header__action-button" + right-icon="arrow-right" + tint="fancy" + ) + | Create your Server .c-page-header__mobile-toggle page-header-menu-toggle( @@ -147,16 +159,28 @@ div( span.c-page-header__disclosure-panel-title.u-medium | {{ dropdownItem.title }} - a( - :href="$config.public.url.prose_app" - class="c-page-header__action" - ) - base-button( - class="c-page-header__action-button" - right-icon="arrow-right" - tint="fancy" + .c-page-header__actions + nuxt-link( + class="c-page-header__action" + to="/cloud/signin/" ) - | Go to App + base-button( + class="c-page-header__action-button" + size="simple" + tint="none" + ) + | Log In + + nuxt-link( + class="c-page-header__action" + to="/cloud/signup/" + ) + base-button( + class="c-page-header__action-button" + right-icon="arrow-right" + tint="fancy" + ) + | Create your Server .c-page-header__ghost( v-if="!embedded" @@ -327,7 +351,7 @@ $c: ".c-page-header"; // VARIABLES $icon-width: 18px; -$inner-width-maximum: 740px; +$inner-width-maximum: 800px; $hover-transition-duration: 150ms; @@ -453,6 +477,12 @@ $hover-transition-duration: 150ms; margin-top: 3px; } + #{$c}__actions { + display: flex; + align-items: center; + column-gap: 17px; + } + #{$c}__menu { font-size: 14px; margin-top: -1px; @@ -586,10 +616,6 @@ $hover-transition-duration: 150ms; } } } - - #{$c}__action { - display: inline-block; - } } #{$c}__disclosure-panel-icon { @@ -648,7 +674,7 @@ $hover-transition-duration: 150ms; } #{$c}__right { - #{$c}__action { + #{$c}__actions { display: none; } diff --git a/src/components/partial/cloud/PartialCloudSignupFormFieldsetAccount.vue b/src/components/partial/cloud/PartialCloudSignupFormFieldsetAccount.vue new file mode 100644 index 00000000..927ccf6d --- /dev/null +++ b/src/components/partial/cloud/PartialCloudSignupFormFieldsetAccount.vue @@ -0,0 +1,262 @@ + + + + + + + + + + + + + diff --git a/src/components/partial/cloud/PartialCloudSignupFormFieldsetActivate.vue b/src/components/partial/cloud/PartialCloudSignupFormFieldsetActivate.vue new file mode 100644 index 00000000..ca7da6a9 --- /dev/null +++ b/src/components/partial/cloud/PartialCloudSignupFormFieldsetActivate.vue @@ -0,0 +1,400 @@ + + + + + + + + + + + + + diff --git a/src/components/partial/cloud/PartialCloudSignupFormFieldsetWorkspace.vue b/src/components/partial/cloud/PartialCloudSignupFormFieldsetWorkspace.vue new file mode 100644 index 00000000..c99fbbb5 --- /dev/null +++ b/src/components/partial/cloud/PartialCloudSignupFormFieldsetWorkspace.vue @@ -0,0 +1,212 @@ + + + + + + + + + + + + + diff --git a/src/components/partial/common/PartialCommonFeature.vue b/src/components/partial/common/PartialCommonFeature.vue new file mode 100644 index 00000000..1ba2919a --- /dev/null +++ b/src/components/partial/common/PartialCommonFeature.vue @@ -0,0 +1,171 @@ + + + + + + + + + + + + + diff --git a/src/components/partial/pricing/PartialPricingCompareFoot.vue b/src/components/partial/pricing/PartialPricingCompareFoot.vue index 7ba445b0..39d50991 100644 --- a/src/components/partial/pricing/PartialPricingCompareFoot.vue +++ b/src/components/partial/pricing/PartialPricingCompareFoot.vue @@ -29,7 +29,9 @@ | /user/month .c-partial-pricing-compare-foot__action - base-tooltip + base-tooltip( + v-if="isSelfHosted" + ) template( v-slot:tooltip ) @@ -39,27 +41,24 @@ v-slot:default ) a - template( - v-if="isSelfHosted" + base-button( + tint="dark" + size="small" + reverse + disabled ) - base-button( - tint="dark" - size="small" - reverse - disabled - ) - | Self-Host Prose - - template( - v-else - ) - base-button( - right-icon="arrow-right" - tint="dark" - size="small" - disabled - ) - | Try for free + | Self-Host Prose + + nuxt-link( + v-else + to="/cloud/signup/" + ) + base-button( + right-icon="arrow-right" + tint="dark" + size="small" + ) + | Try for free + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudAccountSettingsForm.vue b/src/components/section/cloud/SectionCloudAccountSettingsForm.vue new file mode 100644 index 00000000..5da85cbc --- /dev/null +++ b/src/components/section/cloud/SectionCloudAccountSettingsForm.vue @@ -0,0 +1,292 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudAccountWorkspacesNavigator.vue b/src/components/section/cloud/SectionCloudAccountWorkspacesNavigator.vue new file mode 100644 index 00000000..de74f5a0 --- /dev/null +++ b/src/components/section/cloud/SectionCloudAccountWorkspacesNavigator.vue @@ -0,0 +1,74 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudAccountWorkspacesPicker.vue b/src/components/section/cloud/SectionCloudAccountWorkspacesPicker.vue new file mode 100644 index 00000000..cbbe7901 --- /dev/null +++ b/src/components/section/cloud/SectionCloudAccountWorkspacesPicker.vue @@ -0,0 +1,156 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudSigninAuthenticate.vue b/src/components/section/cloud/SectionCloudSigninAuthenticate.vue new file mode 100644 index 00000000..8c339f27 --- /dev/null +++ b/src/components/section/cloud/SectionCloudSigninAuthenticate.vue @@ -0,0 +1,364 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudSignupFinal.vue b/src/components/section/cloud/SectionCloudSignupFinal.vue new file mode 100644 index 00000000..0ddccfb0 --- /dev/null +++ b/src/components/section/cloud/SectionCloudSignupFinal.vue @@ -0,0 +1,179 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudSignupForm.vue b/src/components/section/cloud/SectionCloudSignupForm.vue new file mode 100644 index 00000000..90054762 --- /dev/null +++ b/src/components/section/cloud/SectionCloudSignupForm.vue @@ -0,0 +1,302 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudSignupProgress.vue b/src/components/section/cloud/SectionCloudSignupProgress.vue new file mode 100644 index 00000000..f0ff1f05 --- /dev/null +++ b/src/components/section/cloud/SectionCloudSignupProgress.vue @@ -0,0 +1,87 @@ + + + + + + + + + + + + + diff --git a/src/components/section/cloud/SectionCloudSignupTitle.vue b/src/components/section/cloud/SectionCloudSignupTitle.vue new file mode 100644 index 00000000..f34b3c72 --- /dev/null +++ b/src/components/section/cloud/SectionCloudSignupTitle.vue @@ -0,0 +1,59 @@ + + + + + + + + + diff --git a/src/components/section/downloads/SectionDownloadsArchive.vue b/src/components/section/downloads/SectionDownloadsArchive.vue index 9bf1b94b..3bba6768 100644 --- a/src/components/section/downloads/SectionDownloadsArchive.vue +++ b/src/components/section/downloads/SectionDownloadsArchive.vue @@ -69,7 +69,7 @@ $c: ".c-section-downloads-archives"; height: 600px; #{$c}__illustration { - background-image: url("@/assets/images/components/section/download/illustration-version-archive.svg"); + background-image: url("@/assets/images/components/section/download/SectionDownloadsArchives/illustration-version-archive.svg"); background-size: contain; background-repeat: no-repeat; background-position: center; diff --git a/src/components/section/home/SectionHomeFeatures.vue b/src/components/section/home/SectionHomeFeatures.vue index 5300868c..1b697db1 100644 --- a/src/components/section/home/SectionHomeFeatures.vue +++ b/src/components/section/home/SectionHomeFeatures.vue @@ -26,26 +26,11 @@ | teamwork easy .c-section-home-features__grid - template( - v-for="(item, index) in features" - :key="'feature_' + index" + partial-common-feature( + v-for="feature in features" + :key="'feature_' + feature" + :feature="feature" ) - .c-section-home-features__card - div( - :class=`[ - "c-section-home-features__illustration", - "c-section-home-features__illustration--" + item.id - ]` - ) - - .c-section-home-features__content - base-title( - level="mini", - align="center" - ) - | {{ item.title }} - - p.c-section-home-features__content-description {{ item.description }} MEDIA-QUERIES <-- diff --git a/src/components/section/home/SectionHomeMain.vue b/src/components/section/home/SectionHomeMain.vue index d9a3d032..e2abf1b2 100644 --- a/src/components/section/home/SectionHomeMain.vue +++ b/src/components/section/home/SectionHomeMain.vue @@ -227,7 +227,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-identity.svg"); - animation: 1s scale 0.7s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.7s ease-in-out + forwards; transform: scale(0); } } @@ -242,7 +243,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-attachment-blue.svg"); - animation: 1s scale 0.6s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.6s ease-in-out + forwards; transform: scale(0); } } @@ -259,7 +261,8 @@ $inner-padding-top-base: 74px; width: 100%; height: 100%; background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-attachment-purple.svg"); - animation: 1s scale ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale ease-in-out + forwards; transform: scale(0); } } @@ -274,7 +277,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-lewis.svg"); - animation: 1s scale 0.9s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.9s ease-in-out + forwards; transform: scale(0); } } @@ -290,7 +294,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-julia.webp"); - animation: 1s scale 0.3s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.3s ease-in-out + forwards; transform: scale(0); } } @@ -305,7 +310,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-liz.webp"); - animation: 1s scale 0.1s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.1s ease-in-out + forwards; transform: scale(0); } } @@ -322,7 +328,8 @@ $inner-padding-top-base: 74px; #{$c}__illustration-inner { background-image: url("@/assets/images/components/section/home/SectionHomeMain/illustration-message.svg"); - animation: 1s scale 0.5s ease-in-out forwards; + animation: 1s c-section-home-main-illustration-scale 0.5s ease-in-out + forwards; transform: scale(0); } } @@ -379,7 +386,7 @@ $inner-padding-top-base: 74px; // --> KEYFRAMES <-- -@keyframes scale { +@keyframes c-section-home-main-illustration-scale { 0% { transform: scale(0); } diff --git a/src/components/section/pricing/SectionPricingMain.vue b/src/components/section/pricing/SectionPricingMain.vue index 8bcb9eb1..a10e389e 100644 --- a/src/components/section/pricing/SectionPricingMain.vue +++ b/src/components/section/pricing/SectionPricingMain.vue @@ -95,23 +95,15 @@ | Cloud hosting, billed annually .c-section-pricing-main__plan-action - base-tooltip - template( - v-slot:tooltip - ) - | Our cloud offering is coming soon! - - template( - v-slot:default + nuxt-link( + to="/cloud/signup/" + ) + base-button( + right-icon="arrow-right" + tint="dark" + size="huge" ) - a - base-button( - right-icon="arrow-right" - tint="dark" - size="huge" - disabled - ) - | Create your Prose Server + | Create your Prose Server p.c-section-pricing-main__plan-notice | 7 days free trial diff --git a/src/components/section/pricing/SectionPricingSimulate.vue b/src/components/section/pricing/SectionPricingSimulate.vue index 8a0e43a2..51ece6a3 100644 --- a/src/components/section/pricing/SectionPricingSimulate.vue +++ b/src/components/section/pricing/SectionPricingSimulate.vue @@ -43,7 +43,9 @@ ) .c-section-pricing-simulate__calculator-field - label.c-section-pricing-simulate__calculator-label.c-section-pricing-simulate__calculator-label--secondary + label.c-section-pricing-simulate__calculator-label.c-section-pricing-simulate__calculator-label--secondary( + for="simulate_annual" + ) | I want to pay yearly ({{ yearlyDiscountPercent }}% discount) form-toggle( diff --git a/src/layouts/embedding.vue b/src/layouts/embedding.vue new file mode 100644 index 00000000..1b4b2927 --- /dev/null +++ b/src/layouts/embedding.vue @@ -0,0 +1,53 @@ + + + + + + + + + diff --git a/src/pages/cloud/account/settings.vue b/src/pages/cloud/account/settings.vue new file mode 100644 index 00000000..59437dfa --- /dev/null +++ b/src/pages/cloud/account/settings.vue @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + diff --git a/src/pages/cloud/account/workspaces.vue b/src/pages/cloud/account/workspaces.vue new file mode 100644 index 00000000..44e73e72 --- /dev/null +++ b/src/pages/cloud/account/workspaces.vue @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + diff --git a/src/pages/cloud/signin/index.vue b/src/pages/cloud/signin/index.vue new file mode 100644 index 00000000..35119b15 --- /dev/null +++ b/src/pages/cloud/signin/index.vue @@ -0,0 +1,40 @@ + + + + + + + + + + + diff --git a/src/pages/cloud/signin/recover.vue b/src/pages/cloud/signin/recover.vue new file mode 100644 index 00000000..f37ce07d --- /dev/null +++ b/src/pages/cloud/signin/recover.vue @@ -0,0 +1,42 @@ + + + + + + + + + + + diff --git a/src/pages/cloud/signup.vue b/src/pages/cloud/signup.vue new file mode 100644 index 00000000..465a13aa --- /dev/null +++ b/src/pages/cloud/signup.vue @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + diff --git a/src/plugins/directives.client.js b/src/plugins/directives.client.js new file mode 100644 index 00000000..d59ba87a --- /dev/null +++ b/src/plugins/directives.client.js @@ -0,0 +1,24 @@ +/* + * This file is part of prose-web + * + * Copyright 2024, Prose Foundation + */ + +/************************************************************************** + * IMPORTS + ***************************************************************************/ + +// NPM +import VueConfetti from "vue-confetti"; +import { defineNuxtPlugin } from "#imports"; + +/************************************************************************** + * EXPORTS + ***************************************************************************/ + +export default defineNuxtPlugin(nuxtApp => { + const _app = nuxtApp.vueApp; + + // Register all Vue directives + _app.use(VueConfetti); +});