diff --git a/handbook/company/pricing-features-table.yml b/handbook/company/pricing-features-table.yml index 829e13807d..bacf972b78 100644 --- a/handbook/company/pricing-features-table.yml +++ b/handbook/company/pricing-features-table.yml @@ -529,7 +529,7 @@ tier: Free productCategories: [Endpoint operations] pricingTableCategories: [Deployment] -- industryName: Managed Cloud +- industryName: Managed Cloud (700+ hosts) description: Have Fleet host it for you (currently only available for customers with 700+ hosts. PS. Wish we could host for you? We're working on it! Please let us know if you know of a good partner. In the meantime, join fleetdm.com/support and we're happy to help you deploy Fleet yourself.) pricingTableCategories: [Deployment] productCategories: [Endpoint operations,Device management,Vulnerability management] diff --git a/website/api/controllers/entrance/signup.js b/website/api/controllers/entrance/signup.js index dd62d799a5..df3b8853aa 100644 --- a/website/api/controllers/entrance/signup.js +++ b/website/api/controllers/entrance/signup.js @@ -61,6 +61,18 @@ the account verification message.)`, type: 'string', isIn: ['Buy a license', 'Try Fleet'], defaultsTo: 'Buy a license', + }, + + primaryBuyingSituation: { + type: 'string', + description: 'What the user will be using Fleet for.', + required: true, + isIn: [ + 'endpoint-ops-security', + 'endpoint-ops-it', + 'device-management', + 'vulnerability-management' + ], } }, @@ -84,18 +96,41 @@ the account verification message.)`, description: 'The provided email address is already in use.', }, + invalidEmailDomain: { + description: 'This email address is on a denylist of domains and cannot be used to signup for a fleetdm.com account.', + responseType: 'badRequest' + }, + }, - fn: async function ({emailAddress, password, firstName, lastName, organization, signupReason}) { + fn: async function ({emailAddress, password, firstName, lastName, organization, signupReason, primaryBuyingSituation}) { // Note: in Oct. 2023, the Fleet Sandbox related code was removed from this action. For more details, see https://github.com/fleetdm/fleet/pull/14638/files var newEmailAddress = emailAddress.toLowerCase(); - // Checking if a user with this email address exists in our database before we send a request to the cloud provisioner. if(await User.findOne({emailAddress: newEmailAddress})) { throw 'emailAlreadyInUse'; } + // Check the user's email address and return an 'invalidEmailDomain' response if the domain is in the bannedEmailDomainsForSignup array. + let emailDomain = newEmailAddress.split('@')[1]; + let bannedEmailDomainsForSignup = [ + 'gmail.com', + 'yahoo.com', + 'yahoo.co.uk', + 'hotmail.com', + 'hotmail.co.uk', + 'outlook.com', + 'icloud.com', + 'proton.me', + 'live.com', + 'yandex.ru', + 'ymail.com', + ]; + if(_.includes(bannedEmailDomainsForSignup, emailDomain)){ + throw 'invalidEmailDomain'; + } + if (!sails.config.custom.enableBillingFeatures) { throw new Error('The Stripe configuration variables (sails.config.custom.stripePublishableKey and sails.config.custom.stripeSecret) are missing!'); @@ -137,6 +172,7 @@ the account verification message.)`, lastName, organization, signupReason, + primaryBuyingSituation, webhookSecret: sails.config.custom.zapierSandboxWebhookSecret, } }) diff --git a/website/assets/images/icon-checkmark-white-10x9@2x.png b/website/assets/images/icon-checkmark-white-10x9@2x.png new file mode 100644 index 0000000000..5fb3f6ca9d Binary files /dev/null and b/website/assets/images/icon-checkmark-white-10x9@2x.png differ diff --git a/website/assets/images/icon-copy-14x14@2x.png b/website/assets/images/icon-copy-14x14@2x.png new file mode 100644 index 0000000000..c2d0efb5e6 Binary files /dev/null and b/website/assets/images/icon-copy-14x14@2x.png differ diff --git a/website/assets/images/icon-pencil-12x12@2x.png b/website/assets/images/icon-pencil-12x12@2x.png new file mode 100644 index 0000000000..99c8c16b4c Binary files /dev/null and b/website/assets/images/icon-pencil-12x12@2x.png differ diff --git a/website/assets/js/pages/customers/new-license.page.js b/website/assets/js/pages/customers/new-license.page.js index f2c7a720ce..f49312ffff 100644 --- a/website/assets/js/pages/customers/new-license.page.js +++ b/website/assets/js/pages/customers/new-license.page.js @@ -16,6 +16,7 @@ parasails.registerPage('new-license', { billingFormRules: { paymentSource: {required: true}, + selfHostedAcknowledgment: {required: true, is: true}, }, // Syncing / loading state @@ -73,13 +74,19 @@ parasails.registerPage('new-license', { this.showQuotedPrice = true; this.quotedPrice = quote.quotedPrice; this.numberOfHostsQuoted = quote.numberOfHosts; - if(quote.numberOfHosts <= 700) { + if(quote.numberOfHosts < 700) { this.formData.quoteId = quote.id; this.showBillingForm = true; } await this.forceRender(); }, + clickClearOneFormError: async function(field) { + if(this.formErrors[field]){ + this.formErrors = _.omit(this.formErrors, field); + } + }, + clickScheduleDemo: async function() { this.syncing = true; // Note: we keep loading spinner present indefinitely so that it is apparent that a new page is loading diff --git a/website/assets/js/pages/entrance/signup.page.js b/website/assets/js/pages/entrance/signup.page.js index 301f0014bc..d527b084a1 100644 --- a/website/assets/js/pages/entrance/signup.page.js +++ b/website/assets/js/pages/entrance/signup.page.js @@ -17,6 +17,7 @@ parasails.registerPage('signup', { organization: {required: true}, emailAddress: {required: true, isEmail: true}, password: {required: true, minLength: 8}, + primaryBuyingSituation: {required: true}, }, // Syncing / loading state syncing: false, diff --git a/website/assets/styles/pages/customers/dashboard.less b/website/assets/styles/pages/customers/dashboard.less index cd46a5b186..6dd2f43dff 100644 --- a/website/assets/styles/pages/customers/dashboard.less +++ b/website/assets/styles/pages/customers/dashboard.less @@ -1,5 +1,5 @@ #dashboard { - padding-top: 40px; + padding-top: 80px; h1 { font-size: 28px; @@ -7,7 +7,8 @@ } h3 { padding-bottom: 16px; - font-size: 24px; + font-size: 16px; + line-height: 120%; margin-bottom: 0px; } a { @@ -93,42 +94,60 @@ cursor: pointer; } - [purpose='slack-button'] { - font-size: 16px; + [purpose='animated-arrow-button-red'] { + display: flex; + flex-direction: row; + align-items: center; + line-height: 24px; + padding-right: 24px; + cursor: pointer; + position: relative; + width: fit-content; + font-weight: bold; + user-select: none; + transition: 0.2s ease-in-out; + -o-transition: 0.2s ease-in-out; + -ms-transition: 0.2s ease-in-out; + -moz-transition: 0.2s ease-in-out; + -webkit-transition: 0.2s ease-in-out; color: @core-fleet-black; - background-color: #fff; - border: 1px solid #C5C7D1; - border-radius: 4px; - padding: 8px 40px; - line-height: 20px; - &:hover { - background: #fff; - color: @core-fleet-black; - } - &:focus { - box-shadow: none; - } - img { - display: inline; - height: 20px; - width: auto; - padding-right: 4px; - margin-bottom: 1px; - } - a { - color: @core-fleet-black; - } text-decoration: none; + &:hover { + color: #000; + } + &:after { + content: url('/images/arrow-right-red-16x16@2x.png'); + transform: scale(0.5); + position: absolute; + top: -5px; + left: 75%; // <--- here + transition: 0.2s ease-in-out; + -o-transition: 0.2s ease-in-out; + -ms-transition: 0.2s ease-in-out; + -moz-transition: 0.2s ease-in-out; + -webkit-transition: 0.2s ease-in-out; + } + &:hover:after { + left: 82%; // <--- here + transition: 0.2s ease-in-out; + -o-transition: 0.2s ease-in-out; + -ms-transition: 0.2s ease-in-out; + -moz-transition: 0.2s ease-in-out; + -webkit-transition: 0.2s ease-in-out; + } } [purpose='deploy-button'] { - font-size: 16px; - line-height: 20px; - padding: 8px 40px; - border-radius: 4px; - color: white; + height: 48px; + padding: 16px 32px; + border-radius: 8px; + color: #FFF; text-decoration: none; + font-size: 16px; + font-weight: 700; + line-height: 16px; + margin-right: 32px; &:hover { - color: white; + color: #FFF; } } @@ -243,7 +262,7 @@ } @media (max-width: 768px) { - padding-top: 60px; + padding-top: 64px; [purpose='modal-content'] { margin-top: 50px; @@ -262,6 +281,9 @@ [purpose='billing-card'] { padding: 40px 20px; } + [purpose='deploy-button'] { + margin-right: unset; + } } diff --git a/website/assets/styles/pages/customers/new-license.less b/website/assets/styles/pages/customers/new-license.less index 484bc00789..1942c73ff6 100644 --- a/website/assets/styles/pages/customers/new-license.less +++ b/website/assets/styles/pages/customers/new-license.less @@ -25,6 +25,52 @@ input[type='number'] { -moz-appearance: textfield; } + + [purpose='self-hosted-checkbox'] { + [purpose='self-hosted-note'] { + font-size: 14px; + line-height: 150%; + margin-bottom: 0px; + margin-botom: 24px; + } + input { + display: none; + } + input + label { + position: relative; + padding-left: 24px; + cursor: pointer; + } + input + label::before { + content: ''; + position: absolute; + left: 0; + top: 2px; + width: 16px; + height: 16px; + background-color: #fff; + border: 2px solid #192147; + border-radius: 4px; + } + input:checked + label::before { + background-color: #192147; + } + input:checked + label::after { + content: url('/images/icon-checkmark-white-10x9@2x.png'); + position: absolute; + left: -1px; + top: 2px; + transform: scale(0.5); + width: 16px; + height: 16px; + } + label.is-invalid::before { + border: 2px solid #FF5C83; + } + label.is-invalid + .invalid-feedback { + display: block; + } + } [purpose='quote-input'] { max-width: 200px; } diff --git a/website/assets/styles/pages/entrance/signup.less b/website/assets/styles/pages/entrance/signup.less index 21b4acff8f..6288210bb1 100644 --- a/website/assets/styles/pages/entrance/signup.less +++ b/website/assets/styles/pages/entrance/signup.less @@ -28,6 +28,24 @@ .card-body { padding: 2em; } + .selectbox { + + position: relative; + } + .selectbox::after { + content: url('/images/chevron-12x8@2x.png'); + right: 14px; + transform: scale(0.5); + top: 14px; + position: absolute; + pointer-events: none; + } + .selectbox select { + border-radius: 6px; + height: 48px; + appearance: none; + -webkit-appearance: none; + } } [purpose='submit-button'] { diff --git a/website/views/pages/customers/dashboard.ejs b/website/views/pages/customers/dashboard.ejs index 26631ccbec..abac99d72d 100644 --- a/website/views/pages/customers/dashboard.ejs +++ b/website/views/pages/customers/dashboard.ejs @@ -42,7 +42,7 @@
{{thisSubscription.fleetLicenseKey}}
{{me.billingCardBrand}} ending in {{me.billingCardLast4}}![]()
{{me.billingCardBrand}} ending in {{me.billingCardLast4}}![]()
Contact us to change your number of devices, or to cancel your subscription.
+Contact us to change your number of devices, or to cancel your subscription.
Please confirm that you will be hosting Fleet yourself.
The billing card provided could not be used. Please use another card or contact support.
Sign in to manage your Fleet Premium subscription.
+We just need a few details in order to get started.
Minimum length is 8 characters
This email is already linked to a Fleet account.
Please sign in with your email and password.
Please enter a valid work email address
+By signing up you agree to our privacy policy and terms of service.