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 @@
+
+
+
+
+
+nuxt-link(
+ :to="to"
+ class="c-base-floating-link"
+)
+ span.c-base-floating-link__text
+ slot
+
+ span.c-base-floating-link__icon(
+ v-if="iconHtml"
+ v-html="iconHtml"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-base-notice",
+ "c-base-notice--" + color,
+ {
+ "c-base-notice--shaky": shaky,
+ "u-medium": emphasis
+ }
+ ]`
+ :key="'notice_' + updateTime"
+)
+ slot
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+span(
+ :style="iconStyle"
+ :key="'card_' + providerName"
+ :class=`[
+ "c-base-payment-icon",
+ "c-base-payment-icon--" + providerName,
+ {
+ "c-base-payment-icon--animated": animated
+ }
+ ]`
+)
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-base-payment-preview
+ base-payment-icon(
+ :provider="provider"
+ :animated="animated"
+ height="21px"
+ class="c-base-payment-preview__input-preview-brand"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-base-progress
+ base-progress-item(
+ v-for="item in items"
+ :key="'item_' + item.id"
+ :label="item.label"
+ :icon="item.icon"
+ :ongoing="item.ongoing"
+ :elapsed="item.elapsed"
+ :finished="item.finished"
+ :class=`[
+ "c-base-progress__item",
+ {
+ "c-base-progress__item--spaced": !item.label
+ }
+ ]`
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-base-progress-item",
+ {
+ "c-base-progress-item--ongoing": ongoing,
+ "c-base-progress-item--elapsed": elapsed,
+ "c-base-progress-item--finished": finished
+ }
+ ]`
+)
+ span.c-base-progress-item__icon(
+ v-if="iconHtml"
+ v-html="iconHtml"
+ )
+
+ span.c-base-progress-item__label.u-medium.u-ellipsis(
+ v-if="label"
+ )
+ | {{ label }}
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-base-security-level",
+ "c-base-security-level--" + security
+ ]`
+)
+ span.c-base-security-level__steps
+ span(
+ v-for="step in steps"
+ :key="'step_' + step"
+ :class=`[
+ "c-base-security-level__step",
+ {
+ "c-base-security-level__step--active": (level >= step)
+ }
+ ]`
+ )
+
+ span.c-base-security-level__label.u-medium
+ slot(
+ v-if="security === 'bad'"
+ name="bad"
+ )
+
+ slot(
+ v-else-if="security === 'okay'"
+ name="okay"
+ )
+
+ slot(
+ v-else-if="security === 'good'"
+ name="good"
+ )
+
+ slot(
+ v-else
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-form-field",
+ "c-form-field--" + type,
+ "c-form-field--" + size,
+ "c-form-field--" + align,
+ "c-form-field--" + tint,
+ {
+ "c-form-field--focused": isFocused,
+ "c-form-field--disabled": disabled,
+ "c-form-field--loading": loading
+ }
+ ]`
+)
+ slot
+
+ input(
+ @keypress.stop
+ @keydown.stop="onFieldKeyDown"
+ @keyup.stop="onFieldKeyUp"
+ @input="onFieldInput"
+ @focus="onFieldFocus"
+ @blur="onFieldBlur"
+ :type="type"
+ :name="name"
+ :id="name"
+ :value="value"
+ :placeholder="placeholder"
+ :pattern="pattern"
+ :disabled="disabled"
+ :autocomplete="autocomplete"
+ :class=`[
+ "c-form-field__inner",
+ {
+ [innerClass]: innerClass
+ }
+ ]`
+ ref="field"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-form-fieldset-field",
+ "c-form-fieldset-field--" + align,
+ {
+ "c-form-fieldset-field--with-for": forName
+ }
+ ]`
+)
+ div(
+ v-if="$slots['input-before']"
+ class="c-form-fieldset-field__input c-form-fieldset-field__input--before"
+ )
+ slot(
+ name="input-before"
+ )
+
+ label.c-form-fieldset-field__label(
+ :for="forName"
+ )
+ | {{ label }}
+
+ div(
+ v-if="$slots['input-after']"
+ class="c-form-fieldset-field__input c-form-fieldset-field__input--after"
+ )
+ slot(
+ name="input-after"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+label.c-form-label(
+ :for="forName"
+)
+ slot
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-form-labelled-field
+ form-label(
+ :for-name="name"
+ class="c-form-labelled-field__label"
+ )
+ | {{ label }}
+
+ .c-form-labelled-field__field
+ slot
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-form-titled-field
+ base-title(
+ level="lilliput"
+ tint="black"
+ class="c-form-titled-field__title"
+ )
+ | {{ title }}
+
+ .c-form-titled-field__field
+ slot
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-partial-cloud-signup-form-fieldset-account
+ base-notice(
+ v-if="error.code"
+ :class="noticeClass"
+ :update-time="error.time"
+ color="red"
+ emphasis
+ shaky
+ )
+ template(
+ v-if="error.code === 'incomplete_form'"
+ )
+ | Please provide an email and a password to continue.
+
+ template(
+ v-else-if="error.code === 'account_exists'"
+ )
+ | An account already exists with this email.
+
+ template(
+ v-else-if="error.code === 'invalid_email'"
+ )
+ | Your email address looks invalid. Check for typos.
+
+ template(
+ v-else-if="error.code === 'invalid_password'"
+ )
+ | Your provided password could not be accepted. Try another one.
+
+ template(
+ v-else
+ )
+ | We could not create your account. Try again.
+
+ form-titled-field(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-account__part",
+ partClass
+ ]`
+ title="What’s your work email?"
+ )
+ form-field(
+ v-model="form.email"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="account_email"
+ type="email"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your work email… (eg. john@acme.com)"
+ autofocus
+ submittable
+ )
+
+ form-titled-field(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-account__part",
+ partClass
+ ]`
+ title="Choose a strong password!"
+ )
+ form-field(
+ v-model="form.password"
+ @submit="onFieldSubmit"
+ @keystroke="onFieldPasswordKeystroke"
+ :loading="pending"
+ name="account_password"
+ type="password"
+ align="left"
+ size="mid-large"
+ placeholder="Enter a password…"
+ submittable
+ )
+
+ base-security-level(
+ :level="passwordLevel"
+ )
+ template(
+ v-slot:bad
+ )
+ | Your password is not secure enough.
+
+ template(
+ v-slot:okay
+ )
+ | Your password could be better.
+
+ template(
+ v-slot:good
+ )
+ | Your password looks secure!
+
+ template(
+ v-slot:default
+ )
+ template(
+ v-if="form.password"
+ )
+ | Your password is not long enough.
+
+ template(
+ v-else
+ )
+ | Please enter a password.
+
+ div(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-account__part",
+ "c-partial-cloud-signup-form-fieldset-account__part--action",
+ partClass
+ ]`
+ )
+ base-button(
+ @click="onContinueClick"
+ :loading="pending"
+ size="enormous"
+ tint="link"
+ right-icon="arrow-right"
+ )
+ | Continue to Server Activation
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-partial-cloud-signup-form-fieldset-activate
+ base-notice(
+ v-if="error.code"
+ :class="noticeClass"
+ :update-time="error.time"
+ color="red"
+ emphasis
+ shaky
+ )
+ template(
+ v-if="error.code === 'incomplete_form'"
+ )
+ | Please fill all fields with your payment method details.
+
+ template(
+ v-else-if="error.code === 'invalid_card_number'"
+ )
+ | Oops, your card number is invalid. Check for typos.
+
+ template(
+ v-else-if="error.code === 'invalid_card_cvv'"
+ )
+ | Oops, your card security code is invalid. Enter it again.
+
+ template(
+ v-else-if="error.code === 'invalid_card_zip'"
+ )
+ | The postal code do not match your card's. It could be a different ZIP.
+
+ template(
+ v-else-if="error.code === 'invalid_card_expire'"
+ )
+ | The expire date is wrong. Make sure you entered it as MM/YY.
+
+ template(
+ v-else
+ )
+ | We could not validate your card. Try submitting again.
+
+ base-notice(
+ v-else
+ :class="noticeClass"
+ )
+ | Your server is almost activated! Please
+
+ base-space
+
+ span.u-semibold
+ | provide a valid credit card to verify your account
+
+ | . We need this in order to prevent abuse.
+
+ form-titled-field(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-activate__part",
+ partClass
+ ]`
+ title="Credit card details"
+ )
+ .c-partial-cloud-signup-form-fieldset-activate__nest.c-partial-cloud-signup-form-fieldset-activate__nest--number
+ form-labelled-field(
+ name="activate_number"
+ label="Card number"
+ )
+ form-field(
+ v-model="form.number"
+ @submit="onFieldSubmit"
+ @keystroke="onFieldNumberKeystroke"
+ :loading="pending"
+ name="activate_number"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="XXXX XXXX XXXX XXXX"
+ inner-class="c-partial-cloud-signup-form-fieldset-activate__input-inner"
+ class="c-partial-cloud-signup-form-fieldset-activate__input c-partial-cloud-signup-form-fieldset-activate__input--card"
+ autofocus
+ submittable
+ )
+ base-payment-preview(
+ :provider="cardBrand"
+ class="c-partial-cloud-signup-form-fieldset-activate__input-preview"
+ animated
+ )
+
+ .c-partial-cloud-signup-form-fieldset-activate__nest.c-partial-cloud-signup-form-fieldset-activate__nest--name-and-cvv
+ form-labelled-field(
+ name="activate_name"
+ label="Name on card"
+ )
+ form-field(
+ v-model="form.name"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="activate_name"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your name…"
+ submittable
+ )
+
+ form-labelled-field(
+ name="activate_cvv"
+ label="Security code"
+ )
+ form-field(
+ v-model="form.cvv"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="activate_cvv"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="CVV"
+ pattern="[0-9]{3,4}"
+ submittable
+ )
+
+ .c-partial-cloud-signup-form-fieldset-activate__nest.c-partial-cloud-signup-form-fieldset-activate__nest--zip-and-expire
+ form-labelled-field(
+ name="activate_zip"
+ label="Postal code"
+ )
+ form-field(
+ v-model="form.zip"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="activate_zip"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="ZIP / Postcode"
+ submittable
+ )
+
+ form-labelled-field(
+ name="activate_expire"
+ label="Expiration date"
+ )
+ form-field(
+ v-model="form.expire"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="activate_expire"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="MM/YY"
+ pattern="((0[1-9])|(1[0-2]))\/([0-9]{2})"
+ submittable
+ )
+
+ div(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-activate__part",
+ "c-partial-cloud-signup-form-fieldset-activate__part--information",
+ partClass
+ ]`
+ )
+ .c-partial-cloud-signup-form-fieldset-activate__information
+ .c-partial-cloud-signup-form-fieldset-activate__information-lines
+ p.u-medium
+ | We will only perform a check. Your card will not be charged.
+
+ p
+ | This will activate your 30 days free trial, which you can cancel anytime.
+
+ div(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-activate__part",
+ "c-partial-cloud-signup-form-fieldset-activate__part--action",
+ partClass
+ ]`
+ )
+ base-button(
+ @click="onContinueClick"
+ :loading="pending"
+ size="enormous"
+ tint="link"
+ right-icon="arrow-right"
+ )
+ | Activate my Prose Server Now
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-partial-cloud-signup-form-fieldset-workspace
+ base-notice(
+ :class="noticeClass"
+ )
+ | This section is coming soon! Please check back later.
+
+ base-notice(
+ v-if="error.code"
+ :class="noticeClass"
+ :update-time="error.time"
+ color="red"
+ emphasis
+ shaky
+ )
+ template(
+ v-if="error.code === 'incomplete_form'"
+ )
+ | We are missing some information, could you check?
+
+ template(
+ v-else
+ )
+ | We could not continue with your information. Try again.
+
+ form-titled-field(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-workspace__part",
+ partClass
+ ]`
+ title="What’s your company name?"
+ )
+ form-field(
+ v-model="form.name"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="workspace_name"
+ type="text"
+ align="left"
+ size="mid-large"
+ placeholder="Enter name for your workspace… (eg. Acme)"
+ autofocus
+ submittable
+ disabled
+ )
+
+ form-titled-field(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-workspace__part",
+ partClass
+ ]`
+ title="Do you have a website?"
+ )
+ form-field(
+ v-model="form.website"
+ @submit="onFieldSubmit"
+ :disabled="form.noWebsite"
+ :loading="pending"
+ name="workspace_website"
+ type="url"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your website URL… (eg. www.acme.com)"
+ submittable
+ )
+
+ form-fieldset-field(
+ label="I currently do not have a website"
+ for-name="no_workspace_website"
+ )
+ template(
+ v-slot:input-before
+ )
+ form-toggle(
+ v-model="form.noWebsite"
+ :loading="pending"
+ name="no_workspace_website"
+ disabled
+ )
+
+ div(
+ :class=`[
+ "c-partial-cloud-signup-form-fieldset-workspace__part",
+ "c-partial-cloud-signup-form-fieldset-workspace__part--action",
+ partClass
+ ]`
+ )
+ base-button(
+ @click="onContinueClick"
+ :loading="pending"
+ size="enormous"
+ tint="link"
+ right-icon="arrow-right"
+ disabled
+ )
+ | Continue to Account Creation
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+div(
+ :class=`[
+ "c-partial-common-feature",
+ "c-partial-common-feature--" + feature
+ ]`
+)
+ .c-partial-common-feature__illustration
+
+ .c-partial-common-feature__content
+ base-title(
+ level="mini",
+ align="center"
+ )
+ | {{ featureItem.title }}
+
+ p.c-partial-common-feature__content-description
+ | {{ featureItem.description }}
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+.c-section-cloud-account-content
+ .c-section-cloud-account-content__title
+ page-wrapper
+ base-title(
+ level="medium"
+ align="center"
+ tint="gradient"
+ )
+ | {{ title }}
+
+ span.c-section-cloud-account-content__title-emoji(
+ v-if="titleEmoji"
+ )
+ base-space(
+ :repeat="2"
+ )
+
+ | {{ titleEmoji }}
+
+ .c-section-cloud-account-content__form
+ slot
+
+ slot(
+ name="outer"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-account-settings-form
+ page-wrapper
+ .c-section-cloud-account-settings-form__inner
+ .c-section-cloud-account-settings-form__navigate
+ nuxt-link(
+ to="/cloud/account/workspaces/"
+ class="c-section-cloud-account-settings-form__navigate-link u-medium"
+ )
+ image-navigate-arrow(
+ class="c-section-cloud-account-settings-form__navigate-icon"
+ )
+
+ | Back to my workspaces
+
+ .c-section-cloud-account-settings-form__fields
+ form-labelled-field(
+ name="account_email"
+ label="Your email address"
+ class="c-section-cloud-account-settings-form__field"
+ )
+ .c-section-cloud-account-settings-form__field-sider
+ form-field(
+ v-model="form.email"
+ name="account_email"
+ type="email"
+ align="left"
+ tint="light"
+ size="mid-large"
+ placeholder="Enter an email…"
+ )
+
+ base-button(
+ tint="link"
+ )
+ | Edit Email
+
+ form-labelled-field(
+ name="account_password"
+ label="Change your password"
+ class="c-section-cloud-account-settings-form__field"
+ )
+ .c-section-cloud-account-settings-form__field-sider
+ form-field(
+ v-model="form.password"
+ name="account_password"
+ type="password"
+ align="left"
+ tint="light"
+ size="mid-large"
+ placeholder="Enter a new password…"
+ )
+
+ base-button(
+ tint="link"
+ )
+ | Edit Password
+
+ form-labelled-field(
+ name="billing_card"
+ label="Edit your payment method"
+ class="c-section-cloud-account-settings-form__field"
+ )
+ .c-section-cloud-account-settings-form__field-card
+ .c-section-cloud-account-settings-form__field-card-badge
+ base-payment-preview(
+ :provider="card.brand"
+ class="c-section-cloud-account-settings-form__field-card-badge-preview"
+ )
+
+ .c-section-cloud-account-settings-form__field-card-preview
+ p.c-section-cloud-account-settings-form__field-card-number.u-ellipsis.u-medium
+ | {{ card.numberPreview }}
+
+ p.c-section-cloud-account-settings-form__field-card-identity
+ span.u-ellipsis
+ | {{ card.nameOnCard }}
+
+ span.u-ellipsis
+ | Exp. {{ card.expireMonthYear }}
+
+ .c-section-cloud-account-settings-form__field-card-action
+ base-button(
+ tint="link"
+ )
+ | Edit Card
+
+ .c-section-cloud-account-settings-form__field-navigate
+ nuxt-link(
+ to="/cloud/account/settings/"
+ class="c-section-cloud-account-settings-form__field-navigate-link"
+ )
+ | View my invoices
+
+ image-navigate-arrow(
+ class="c-section-cloud-account-settings-form__field-navigate-icon"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-account-workspaces-navigator
+ page-wrapper(
+ class="c-section-cloud-account-workspaces-navigator__wrapper"
+ )
+ base-floating-link(
+ v-for="(link, index) in links"
+ :to="link.target"
+ :icon-html="link.icon"
+ :key="'link_' + index"
+ )
+ | {{ link.label }}
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-account-workspaces-picker
+ page-wrapper
+ base-title(
+ level="lilliput"
+ align="center"
+ tint="black"
+ )
+ | Select the workspace you want to open:
+
+ ul.c-section-cloud-account-workspaces-picker__items
+ li.c-section-cloud-account-workspaces-picker__item(
+ v-for="(workspace, index) in workspaces"
+ :key="'workspace_' + index"
+ )
+ .c-section-cloud-account-workspaces-picker__item-logo(
+ :style="{ 'background-image': 'url(' + workspace.logoUrl + ')' }"
+ )
+
+ .c-section-cloud-account-workspaces-picker__item-identity
+ p.c-section-cloud-account-workspaces-picker__item-name.u-medium.u-ellipsis
+ | {{ workspace.name }}
+
+ p.c-section-cloud-account-workspaces-picker__item-address.u-ellipsis
+ | {{ workspace.username }}@{{ workspace.domain }}
+
+ .c-section-cloud-account-workspaces-picker__item-actions
+ base-button(
+ size="normal"
+ right-icon="open-external"
+ tint="link"
+ )
+ | Open in Prose
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-signin-authenticate
+ page-wrapper
+ base-title(
+ level="medium"
+ align="center"
+ tint="gradient"
+ )
+ template(
+ v-if="mode === 'recover'"
+ )
+ | Reset your account password
+
+ template(
+ v-else
+ )
+ | Log in to your workspace
+
+ .c-section-cloud-signin-authenticate__form(
+ v-if="mode === 'recover'"
+ )
+ base-notice(
+ class="c-section-cloud-signin-authenticate__notice"
+ )
+ | This section is coming soon! Please check back later.
+
+ base-notice(
+ v-if="error.code"
+ :update-time="error.time"
+ color="red"
+ class="c-section-cloud-signin-authenticate__notice"
+ emphasis
+ shaky
+ )
+ template(
+ v-if="error.code === 'incomplete_form'"
+ )
+ | Please provide your email to reset your password.
+
+ template(
+ v-else
+ )
+ | We could not reset your password. Try again.
+
+ form-titled-field(
+ title="Account email address"
+ class="c-section-cloud-signin-authenticate__part"
+ )
+ form-field(
+ v-model="form.email"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="account_email"
+ type="email"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your account email…"
+ autofocus
+ submittable
+ disabled
+ )
+
+ .c-section-cloud-signin-authenticate__controls
+ span.c-section-cloud-signin-authenticate__control.c-section-cloud-signin-authenticate__control--spacer
+
+ nuxt-link(
+ to="/cloud/signin/"
+ class="c-section-cloud-signin-authenticate__control c-section-cloud-signin-authenticate__control--login"
+ )
+ | Go back to log in
+
+ .c-section-cloud-signin-authenticate__part.c-section-cloud-signin-authenticate__part--action
+ base-button(
+ @click="onRecoverClick"
+ :loading="pending"
+ size="enormous"
+ tint="link"
+ disabled
+ )
+ | Receive a Password Reset Email
+
+ .c-section-cloud-signin-authenticate__form(
+ v-else
+ )
+ base-notice(
+ class="c-section-cloud-signin-authenticate__notice"
+ )
+ | This section is coming soon! Please check back later.
+
+ base-notice(
+ v-if="error.code"
+ :update-time="error.time"
+ color="red"
+ class="c-section-cloud-signin-authenticate__notice"
+ emphasis
+ shaky
+ )
+ template(
+ v-if="error.code === 'incomplete_form'"
+ )
+ | Please provide an email and a password to continue.
+
+ template(
+ v-else-if="error.code === 'invalid_credentials'"
+ )
+ | Your credentials could not be verified. Check for typos.
+
+ template(
+ v-else
+ )
+ | We could not log in your account. Try again.
+
+ form-titled-field(
+ title="Work email address"
+ class="c-section-cloud-signin-authenticate__part"
+ )
+ form-field(
+ v-model="form.email"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="account_email"
+ type="email"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your account email…"
+ autofocus
+ submittable
+ disabled
+ )
+
+ form-titled-field(
+ title="Your password"
+ class="c-section-cloud-signin-authenticate__part"
+ )
+ form-field(
+ v-model="form.password"
+ @submit="onFieldSubmit"
+ :loading="pending"
+ name="account_password"
+ type="password"
+ align="left"
+ size="mid-large"
+ placeholder="Enter your password…"
+ submittable
+ disabled
+ )
+
+ .c-section-cloud-signin-authenticate__controls
+ form-fieldset-field(
+ label="Stay logged in on this device"
+ for-name="session_remember"
+ class="c-section-cloud-signin-authenticate__control c-section-cloud-signin-authenticate__control--remember"
+ )
+ template(
+ v-slot:input-before
+ )
+ form-toggle(
+ v-model="form.remember"
+ :loading="pending"
+ name="session_remember"
+ disabled
+ )
+
+ nuxt-link(
+ to="/cloud/signin/recover/"
+ class="c-section-cloud-signin-authenticate__control c-section-cloud-signin-authenticate__control--recover"
+ )
+ | Forgot your password?
+
+ .c-section-cloud-signin-authenticate__part.c-section-cloud-signin-authenticate__part--action
+ base-button(
+ @click="onLoginClick"
+ :loading="pending"
+ size="enormous"
+ tint="link"
+ right-icon="arrow-right"
+ disabled
+ )
+ | Log in to my Workspace
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-signup-final
+ page-wrapper(
+ class="c-section-cloud-signup-final__wrapper"
+ )
+ .c-section-cloud-signup-final__box
+ base-descripted-title(
+ level="medium"
+ align="center"
+ tint="dark"
+ class="c-section-cloud-signup-final__title"
+ )
+ template(
+ v-slot:title
+ )
+ | Your server is live!
+
+ span.c-section-cloud-signup-final__title-emoji
+ base-space(
+ :repeat="2"
+ )
+
+ | 🎉
+
+ template(
+ v-slot:description
+ )
+ p
+ | You can now
+
+ base-space
+
+ span.u-medium
+ | go to your server administration dashboard
+
+ | .
+
+ p
+ | There, you can invite your team members.
+
+ .c-section-cloud-signup-final__action
+ base-button(
+ @click="onFinishClick"
+ size="enormous"
+ tint="link"
+ right-icon="arrow-right"
+ )
+ | Go to my Server Dashboard
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-signup-form
+ .c-section-cloud-signup-form__inner
+ .c-section-cloud-signup-form__wrapper
+ div(
+ :class=`[
+ "c-section-cloud-signup-form__fieldset",
+ {
+ "c-section-cloud-signup-form__fieldset--wide": isFieldsetWide
+ }
+ ]`
+ )
+ template(
+ v-for="(partial, index) in fieldsetPartials"
+ )
+ component(
+ v-if="stage === (index + 1)"
+ @submit="partial.submit"
+ :is="partial.component"
+ :pending="pending"
+ part-class="c-section-cloud-signup-form__fieldset-part"
+ notice-class="c-section-cloud-signup-form__fieldset-notice"
+ )
+
+ .c-section-cloud-signup-form__aside
+ partial-common-feature(
+ v-if="feature"
+ v-memo="[feature]"
+ :key="'feature_' + feature"
+ :feature="feature"
+ class="c-section-cloud-signup-form__feature"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-signup-progress
+ base-progress(
+ :items="progressItems"
+ )
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.c-section-cloud-signup-title
+ page-wrapper
+ base-title(
+ level="medium"
+ align="center"
+ tint="gradient"
+ )
+ | {{ titleText }}
+
+
+
+
+
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 @@
+
+
+
+
+
+page-container(
+ class="l-embedding"
+)
+ page-header(
+ class="l-embedding__header"
+ )
+
+ page-content(
+ class="l-embedding__content"
+ embedded
+ )
+ slot
+
+
+
+
+
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 @@
+
+
+
+
+
+.p-cloud-account-settings
+ section-cloud-account-content(
+ title="Your account settings"
+ class="p-cloud-account-settings__content"
+ )
+ section-cloud-account-settings-form(
+ class="p-cloud-account-settings__form"
+ )
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.p-cloud-account-workspaces
+ section-cloud-account-content(
+ title="Welcome back, Valerian"
+ title-emoji="👋"
+ class="p-cloud-account-workspaces__content"
+ )
+ template(
+ v-slot:default
+ )
+ section-cloud-account-workspaces-picker(
+ class="p-cloud-account-workspaces__picker"
+ )
+
+ template(
+ v-slot:outer
+ )
+ section-cloud-account-workspaces-navigator(
+ class="p-cloud-account-workspaces__navigator"
+ )
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.p-cloud-signin-index
+ section-cloud-signin-authenticate
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.p-cloud-signin-recover
+ section-cloud-signin-authenticate(
+ mode="recover"
+ )
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+.p-cloud-signup
+ template(
+ v-if="isFinal"
+ )
+ section-cloud-signup-final(
+ @finish="onFormFinish"
+ class="p-cloud-signup__final"
+ )
+
+ template(
+ v-else
+ )
+ section-cloud-signup-title(
+ :stage="stage"
+ class="p-cloud-signup__title"
+ )
+
+ section-cloud-signup-form(
+ @continue="onFormContinue"
+ :stage="stage"
+ class="p-cloud-signup__form"
+ )
+
+ section-cloud-signup-progress(
+ :stage="stage"
+ class="p-cloud-signup__progress"
+ )
+
+
+
+
+
+
+
+
+
+
+
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);
+});