Skip to content

Commit 1cf1590

Browse files
committed
redesigned hub managed form
1 parent 61ac400 commit 1cf1590

File tree

7 files changed

+398
-154
lines changed

7 files changed

+398
-154
lines changed

assets/css/custom.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,7 @@ ul.list-primary li::marker {
155155
@apply border-secondary;
156156
}
157157

158-
input:focus:invalid,
159158
input.show-invalid:invalid,
160-
textarea:focus:invalid,
161159
textarea.show-invalid:invalid {
162160
@apply border-red-500 ring-0;
163161
}

assets/js/hubmanaged.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"use strict";
22

33
// requires store.js
4+
// requires newsletter.js
45
const REQUEST_HUB_MANAGED_URL = STORE_API_URL + '/hub/request-managed';
6+
const VALIDATE_HUB_MANAGED_REQUEST_URL = STORE_API_URL + '/hub/validate-managed-request';
57

68
class HubManaged {
79

@@ -11,6 +13,84 @@ class HubManaged {
1113
this._submitData = submitData;
1214
}
1315

16+
validateEmail() {
17+
if (!$(this._form)[0].checkValidity()) {
18+
$(this._form).find(':input').addClass('show-invalid');
19+
this._feedbackData.errorMessage = 'Please fill in all required fields.';
20+
return;
21+
}
22+
23+
this._feedbackData.inProgress = true;
24+
this._feedbackData.errorMessage = '';
25+
$.ajax({
26+
url: VALIDATE_HUB_MANAGED_REQUEST_URL,
27+
type: 'GET',
28+
data: {
29+
email: this._submitData.email
30+
}
31+
}).done(_ => {
32+
this.onValidationSucceeded();
33+
}).fail(xhr => {
34+
this.onValidationFailed(xhr.responseJSON?.message || 'Validating email failed.');
35+
});
36+
}
37+
38+
validateSubdomainAndTeam() {
39+
if (!$(this._form)[0].checkValidity()) {
40+
$(this._form).find(':input').addClass('show-invalid');
41+
this._feedbackData.errorMessage = 'Please fill in all required fields.';
42+
return;
43+
}
44+
45+
this._feedbackData.inProgress = true;
46+
this._feedbackData.errorMessage = '';
47+
$.ajax({
48+
url: VALIDATE_HUB_MANAGED_REQUEST_URL,
49+
type: 'GET',
50+
data: {
51+
subdomain: this._submitData.subdomain,
52+
team: this._submitData.team
53+
}
54+
}).done(_ => {
55+
this.onValidationSucceeded();
56+
}).fail(xhr => {
57+
this.onValidationFailed(xhr.responseJSON?.message || 'Validating subdomain and team failed.');
58+
});
59+
}
60+
61+
validateQuantity() {
62+
if (!$(this._form)[0].checkValidity()) {
63+
$(this._form).find(':input').addClass('show-invalid');
64+
this._feedbackData.errorMessage = 'Please fill in all required fields.';
65+
return;
66+
}
67+
68+
this._feedbackData.inProgress = true;
69+
this._feedbackData.errorMessage = '';
70+
$.ajax({
71+
url: VALIDATE_HUB_MANAGED_REQUEST_URL,
72+
type: 'GET',
73+
data: {
74+
quantity: this._submitData.quantity
75+
}
76+
}).done(_ => {
77+
this.onValidationSucceeded();
78+
}).fail(xhr => {
79+
this.onValidationFailed(xhr.responseJSON?.message || 'Validating quantity failed.');
80+
});
81+
}
82+
83+
onValidationFailed(error) {
84+
this._feedbackData.inProgress = false;
85+
this._feedbackData.errorMessage = error;
86+
}
87+
88+
onValidationSucceeded() {
89+
this._feedbackData.currentStep++;
90+
this._feedbackData.inProgress = false;
91+
this._feedbackData.errorMessage = '';
92+
}
93+
1494
request() {
1595
if (!$(this._form)[0].checkValidity()) {
1696
$(this._form).find(':input').addClass('show-invalid');
@@ -27,6 +107,9 @@ class HubManaged {
27107
data: this._submitData
28108
}).done(_ => {
29109
this.onRequestSucceeded();
110+
if (this._submitData.acceptNewsletter) {
111+
subscribeToNewsletter(this._submitData.email, 7);
112+
}
30113
}).fail(xhr => {
31114
this.onRequestFailed(xhr.responseJSON?.message || 'Requesting Hub Managed failed.');
32115
});
@@ -46,3 +129,31 @@ class HubManaged {
46129
}
47130

48131
}
132+
133+
function teamToSubdomain(team) {
134+
// Convert to lowercase
135+
let subdomain = team.toLowerCase();
136+
// Replace German specific characters
137+
subdomain = subdomain.replace(/ß/g, "ss").replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue");
138+
// Normalize to decompose accented characters and remove diacritics
139+
subdomain = subdomain.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
140+
// Replace any whitespace (including spaces, tabs, etc.) with a hyphen
141+
subdomain = subdomain.replace(/\s+/g, "-");
142+
// Remove any characters that are not letters, numbers, or hyphens
143+
subdomain = subdomain.replace(/[^a-z0-9-]/g, "");
144+
// Replace multiple hyphens with a single hyphen
145+
subdomain = subdomain.replace(/-+/g, "-");
146+
// Remove any leading or trailing hyphens
147+
subdomain = subdomain.replace(/^-+/, "").replace(/-+$/, "");
148+
// Cap the subdomain at 63 characters
149+
if (subdomain.length > 63) {
150+
subdomain = subdomain.slice(0, 63);
151+
// Remove any trailing hyphen after truncation
152+
subdomain = subdomain.replace(/-+$/, "");
153+
}
154+
return subdomain;
155+
}
156+
157+
function subdomainToURL(subdomain) {
158+
return `https://${subdomain}.cryptomator.cloud`;
159+
}

i18n/de.yaml

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
translation: "Ich bin damit einverstanden, Neuigkeiten von Cryptomator zu erhalten, und akzeptiere die <a class=\"text-link\" href=\"/de/privacy/\">Datenschutzerklärung</a>."
2525
- id: accept_newsletter_optional
2626
translation: "Ich bin damit einverstanden, Neuigkeiten von Cryptomator per E-Mail zu erhalten (optional)."
27+
- id: accept_hub_newsletter_optional
28+
translation: "Ich bin damit einverstanden, Neuigkeiten von Cryptomator Hub per E-Mail zu erhalten (optional)."
2729
- id: accept_privacy
2830
translation: "Ich akzeptiere die <a class=\"text-link\" href=\"/de/privacy/\">Datenschutzerklärung</a>."
2931
- id: accept_privacy_implicitly
@@ -610,41 +612,61 @@
610612
- id: hub_managed_description
611613
translation: "Beantrage Zugang zu einer Managed-Instanz von Cryptomator Hub und hol dein Team mit der clientseitigen Verschlüsselung für deinen Cloud-Speicher an Bord."
612614

613-
- id: hub_managed_info_header_title
614-
translation: "Information"
615-
- id: hub_managed_info_header_description
616-
translation: "Auf der Grundlage deiner Eingaben wird eine neue Hub-Instanz für dich erstellt. Du wirst der erste Administrator dieser Instanz sein."
617-
- id: hub_managed_info_subdomain
618-
translation: "Subdomain"
619-
- id: hub_managed_info_subdomain_description
620-
translation: "Die URL deiner Hub-Instanz. Wenn du eine eigene Domain verwenden möchtest, teile uns dies bitte unten mit."
621-
- id: hub_managed_info_email
615+
- id: hub_managed_steps_title
616+
translation: "Schritt <span x-text=\"feedbackData.currentStep + 1\"></span> von <span x-text=\"steps.length\"></span>"
617+
- id: hub_managed_steps_next
618+
translation: "Weiter"
619+
620+
- id: hub_managed_step_1_nav_title
622621
translation: "Arbeits-E-Mail"
623-
- id: hub_managed_info_email_description
624-
translation: "Die E-Mail-Adresse der Person, die der erste Administrator deiner Hub-Instanz sein wird."
625-
- id: hub_managed_info_quantity
622+
- id: hub_managed_step_1_title
623+
translation: "Wie lautet die E-Mail-Adresse für deine Arbeit?"
624+
- id: hub_managed_step_1_email_placeholder
625+
translation: "E-Mail-Adresse für die Arbeit"
626+
627+
- id: hub_managed_step_2_nav_title
628+
translation: "Team-Name"
629+
- id: hub_managed_step_2_title
630+
translation: "Wie heißt dein Team?"
631+
- id: hub_managed_step_2_team_placeholder
632+
translation: "Name deines Teams, Unternehmens oder deiner Organisation"
633+
- id: hub_managed_step_2_subdomain_description
634+
translation: "Dies ist die URL deiner Hub-Instanz."
635+
- id: hub_managed_step_2_subdomain_placeholder
636+
translation: "Subdomain deiner Hub-Instanz"
637+
638+
- id: hub_managed_step_3_nav_title
639+
translation: "Erwartete Nutzer"
640+
- id: hub_managed_step_3_title
641+
translation: "Wie viele Nutzer erwartest du?"
642+
- id: hub_managed_step_3_quantity_description
643+
translation: "Dies kann nur eine Schätzung sein und später geändert werden."
644+
- id: hub_managed_step_3_quantity_placeholder
626645
translation: "Anzahl der erwarteten Nutzer"
627-
- id: hub_managed_info_quantity_description
628-
translation: "Die Anzahl der Nutzer, die du voraussichtlich haben wirst. Diese kann später geändert werden."
629-
- id: hub_managed_info_message
630-
translation: "Nachricht (optional)"
631-
- id: hub_managed_info_message_description
632-
translation: "Wenn du Fragen oder besondere Wünsche hast, lass sie uns bitte wissen."
633646

634-
- id: hub_managed_trial_info
635-
translation: "Keine Kreditkarte erforderlich. Starte noch heute mit deiner kostenlosen 30-Tage-Testversion."
636-
- id: hub_managed_loadcaptcha
647+
- id: hub_managed_step_4_nav_title
648+
translation: "Zusammenfassung"
649+
- id: hub_managed_step_4_title
650+
translation: "Zusammenfassung"
651+
- id: hub_managed_step_4_email
652+
translation: "E-Mail"
653+
- id: hub_managed_step_4_team
654+
translation: "Team-Name"
655+
- id: hub_managed_step_4_url
656+
translation: "URL"
657+
- id: hub_managed_step_4_quantity
658+
translation: "Anzahl der erwarteten Nutzer"
659+
- id: hub_managed_step_4_loadcaptcha
637660
translation: "Weiter…"
638-
- id: hub_managed_submit
661+
- id: hub_managed_step_4_submit
639662
translation: "Zugang anfragen"
663+
640664
- id: hub_managed_success_title
641665
translation: "Deine Anfrage wurde versendet!"
642666
- id: hub_managed_success_description
643667
translation: "Wir haben deine Anfrage erhalten und werden sie so schnell wie möglich prüfen."
644668

645-
- id: hub_managed_pricing_title
646-
translation: "Preise"
647-
- id: hub_managed_pricing_description
669+
- id: hub_managed_trial_info
648670
translation: "Keine Kreditkarte erforderlich. Starte noch heute mit deiner kostenlosen 30-Tage-Testversion."
649671

650672
- id: hub_managed_contact_us_title
@@ -662,14 +684,8 @@
662684
translation: "Lade Cryptomator ohne Hub herunter, wenn du Tresore alleine nutzen möchtest."
663685
- id: hub_managed_low_quantity_description_2
664686
translation: "Lade Cryptomator ohne Hub herunter, wenn du Tresore mit jemandem teilen möchtest. Lies die <a class=\"text-link\" href=\"https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults\" target=\"_blank\" rel=\"noopener\">Best Practices zum Teilen von Tresoren</a>."
665-
- id: hub_managed_low_quantity_description_3
666-
translation: "Lade Cryptomator ohne Hub herunter, wenn du Tresore mit einem kleinen Team teilen möchtest. Lies die <a class=\"text-link\" href=\"https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults\" target=\"_blank\" rel=\"noopener\">Best Practices zum Teilen von Tresoren</a>."
667-
- id: hub_managed_low_quantity_description_4
668-
translation: "Ansonsten kannst du gerne Zugang zu einer Managed-Instanz von Cryptomator Hub anfragen."
669-
- id: hub_managed_low_quantity_submit_1
687+
- id: hub_managed_low_quantity_submit
670688
translation: "Zu Downloads"
671-
- id: hub_managed_low_quantity_submit_2
672-
translation: "Anfrage bestätigen"
673689

674690
# Hub Setup
675691
- id: hub_setup_description

i18n/en.yaml

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
translation: "I agree to get updates from Cryptomator and accept the <a class=\"text-link\" href=\"/privacy/\">Privacy Policy</a>."
2525
- id: accept_newsletter_optional
2626
translation: "I agree to get updates from Cryptomator via email (optional)."
27+
- id: accept_hub_newsletter_optional
28+
translation: "I agree to get updates from Cryptomator Hub via email (optional)."
2729
- id: accept_privacy
2830
translation: "I accept the <a class=\"text-link\" href=\"/privacy/\">Privacy Policy</a>."
2931
- id: accept_privacy_implicitly
@@ -610,41 +612,61 @@
610612
- id: hub_managed_description
611613
translation: "Request access to a managed instance of Cryptomator Hub and get your team on board with client-side encryption for your cloud storage."
612614

613-
- id: hub_managed_info_header_title
614-
translation: "Information"
615-
- id: hub_managed_info_header_description
616-
translation: "Based on your input, a new Hub instance will be created for you. You will be the first admin of this instance."
617-
- id: hub_managed_info_subdomain
618-
translation: "Subdomain"
619-
- id: hub_managed_info_subdomain_description
620-
translation: "The URL of your Hub instance. If you'd like to use a custom domain, please let us know below."
621-
- id: hub_managed_info_email
622-
translation: "Work Email"
623-
- id: hub_managed_info_email_description
624-
translation: "The email address of the person who will be the first admin of your Hub instance."
625-
- id: hub_managed_info_quantity
626-
translation: "Number of Expected Users"
627-
- id: hub_managed_info_quantity_description
628-
translation: "The number of users you expect to have. This can be changed later."
629-
- id: hub_managed_info_message
630-
translation: "Message (optional)"
631-
- id: hub_managed_info_message_description
632-
translation: "If you have any questions or special requirements, please let us know."
615+
- id: hub_managed_steps_title
616+
translation: "Step <span x-text=\"feedbackData.currentStep + 1\"></span> of <span x-text=\"steps.length\"></span>"
617+
- id: hub_managed_steps_next
618+
translation: "Next"
633619

634-
- id: hub_managed_trial_info
635-
translation: "No credit card required. Get started today with your 30-day free trial."
636-
- id: hub_managed_loadcaptcha
620+
- id: hub_managed_step_1_nav_title
621+
translation: "Work Email"
622+
- id: hub_managed_step_1_title
623+
translation: "What's your email address for work?"
624+
- id: hub_managed_step_1_email_placeholder
625+
translation: "Email address for work"
626+
627+
- id: hub_managed_step_2_nav_title
628+
translation: "Team Name"
629+
- id: hub_managed_step_2_title
630+
translation: "What's your team's name?"
631+
- id: hub_managed_step_2_team_placeholder
632+
translation: "Name of your team, company, or organization"
633+
- id: hub_managed_step_2_subdomain_description
634+
translation: "This is the URL of your Hub instance."
635+
- id: hub_managed_step_2_subdomain_placeholder
636+
translation: "Subdomain of your Hub instance"
637+
638+
- id: hub_managed_step_3_nav_title
639+
translation: "Expected Users"
640+
- id: hub_managed_step_3_title
641+
translation: "How many users do you expect?"
642+
- id: hub_managed_step_3_quantity_description
643+
translation: "This can be just an estimate and changed later."
644+
- id: hub_managed_step_3_quantity_placeholder
645+
translation: "Number of expected users"
646+
647+
- id: hub_managed_step_4_nav_title
648+
translation: "Summary"
649+
- id: hub_managed_step_4_title
650+
translation: "Summary"
651+
- id: hub_managed_step_4_email
652+
translation: "Email"
653+
- id: hub_managed_step_4_team
654+
translation: "Team Name"
655+
- id: hub_managed_step_4_url
656+
translation: "URL"
657+
- id: hub_managed_step_4_quantity
658+
translation: "Expected Users"
659+
- id: hub_managed_step_4_loadcaptcha
637660
translation: "Continue…"
638-
- id: hub_managed_submit
661+
- id: hub_managed_step_4_submit
639662
translation: "Request Access"
663+
640664
- id: hub_managed_success_title
641665
translation: "Your request has been sent!"
642666
- id: hub_managed_success_description
643667
translation: "We have received your request and will evaluate it as soon as possible."
644668

645-
- id: hub_managed_pricing_title
646-
translation: "Pricing"
647-
- id: hub_managed_pricing_description
669+
- id: hub_managed_trial_info
648670
translation: "No credit card required. Get started today with your 30-day free trial."
649671

650672
- id: hub_managed_contact_us_title
@@ -662,14 +684,8 @@
662684
translation: "Download Cryptomator without Hub if you intend to use vaults on your own."
663685
- id: hub_managed_low_quantity_description_2
664686
translation: "Download Cryptomator without Hub if you intend to share vaults with another person. Check out the <a class=\"text-link\" href=\"https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults\" target=\"_blank\" rel=\"noopener\">best practices on how to share vaults</a>."
665-
- id: hub_managed_low_quantity_description_3
666-
translation: "Download Cryptomator without Hub if you intend to share vaults with a small team. Check out the <a class=\"text-link\" href=\"https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults\" target=\"_blank\" rel=\"noopener\">best practices on how to share vaults</a>."
667-
- id: hub_managed_low_quantity_description_4
668-
translation: "Otherwise, feel free to request access to a managed instance of Cryptomator Hub."
669-
- id: hub_managed_low_quantity_submit_1
687+
- id: hub_managed_low_quantity_submit
670688
translation: "Go to Downloads"
671-
- id: hub_managed_low_quantity_submit_2
672-
translation: "Confirm Request"
673689

674690
# Hub Setup
675691
- id: hub_setup_description

0 commit comments

Comments
 (0)