diff --git a/website/api/controllers/view-testimonials.js b/website/api/controllers/view-testimonials.js new file mode 100644 index 000000000000..dfd040ccf569 --- /dev/null +++ b/website/api/controllers/view-testimonials.js @@ -0,0 +1,51 @@ +module.exports = { + + + friendlyName: 'View testimonials', + + + description: 'Display "Testimonials" page.', + + + exits: { + + success: { + viewTemplatePath: 'pages/testimonials' + } + + }, + + + fn: async function () { + + if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.testimonials) || !sails.config.builtStaticContent.compiledPagePartialsAppPath) { + throw {badConfig: 'builtStaticContent.testimonials'}; + } + // Get testimonials for the component. + let testimonials = _.clone(sails.config.builtStaticContent.testimonials); + + // Filter the testimonials by product category + let testimonialsForMdm = _.filter(testimonials, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Device management'); + }); + let testimonialsForSecurityEngineering = _.filter(testimonials, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Vulnerability management'); + }); + let testimonialsForItEngineering = _.filter(testimonials, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Endpoint operations'); + }); + let testimonialsWithVideoLinks = _.filter(testimonials, (testimonial)=>{ + return testimonial.youtubeVideoUrl; + }); + + return { + testimonialsForMdm, + testimonialsForSecurityEngineering, + testimonialsForItEngineering, + testimonialsWithVideoLinks, + }; + + } + + +}; diff --git a/website/assets/js/pages/testimonials.page.js b/website/assets/js/pages/testimonials.page.js new file mode 100644 index 000000000000..ed6c2ef49fb3 --- /dev/null +++ b/website/assets/js/pages/testimonials.page.js @@ -0,0 +1,44 @@ +parasails.registerPage('testimonials', { + // ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗ + // ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣ + // ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝ + data: { + selectedContent: 'mdm', + modal: '', + quotesWithVideoLinks: [], + }, + + // ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗ + // ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣ + // ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝ + beforeMount: function() { + for(let quote of this.testimonialsWithVideoLinks) { + if(quote.youtubeVideoUrl){ + this.quotesWithVideoLinks.push({ + modalId: _.kebabCase(quote.quoteAuthorName), + embedId: quote.videoIdForEmbed, + }); + } + } + }, + mounted: async function() { + //… + }, + + // ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗ + // ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗ + // ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ + methods: { + clickChangePageContent: function(option) { + this.selectedContent = option; + }, + clickOpenVideoModal: function(modalName) { + console.log(modalName); + this.modal = _.kebabCase(modalName); + }, + + closeModal: function() { + this.modal = undefined; + }, + } +}); diff --git a/website/assets/styles/importer.less b/website/assets/styles/importer.less index c57c29f48d8f..f68370a395a9 100644 --- a/website/assets/styles/importer.less +++ b/website/assets/styles/importer.less @@ -77,4 +77,5 @@ @import 'pages/integrations.less'; @import 'pages/start.less'; @import 'pages/deals.less'; +@import 'pages/testimonials.less'; diff --git a/website/assets/styles/pages/testimonials.less b/website/assets/styles/pages/testimonials.less new file mode 100644 index 000000000000..7a1f24e14ab4 --- /dev/null +++ b/website/assets/styles/pages/testimonials.less @@ -0,0 +1,441 @@ +#testimonials { + + h4 { + color: #515774; + font-feature-settings: 'salt' on, 'ss01' on, 'ss02' on; + font-family: 'Roboto Mono'; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 150%; + text-transform: uppercase; + } + h1 { + color: #192147; + font-family: Inter; + font-size: 48px; + font-style: normal; + font-weight: 800; + line-height: 120%; + } + [purpose='page-container'] { + padding: 64px; + } + [purpose='page-content'] { + max-width: 1072px; + margin-left: auto; + margin-right: auto; + } + [purpose='hero-quote'] { + margin-top: 32px; + margin-botom: 32px; + [purpose='quote-author-info'] { + display: inline-flex; + padding: 4px 16px 4px 4px; + border-radius: 28px; + width: fit-content; + margin-top: 8px; + margin-bottom: 48px; + [purpose='job-title'] { + color: var(--UI-Fleet-Black-75, #515774); + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; + } + [purpose='name'] { + color: var(--UI-Fleet-Black-75, #515774); + + /* Body XS (bold) */ + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 700; + line-height: 18px; /* 150% */ + } + [purpose='profile-picture'] { + margin-right: 16px; + img { + height: 48px; + width: 48px; + } + } + } + [purpose='quote-text'] { + color: var(--UI-Fleet-Black-75, #515774); + font-family: Inter; + font-size: 20px; + font-style: italic; + font-weight: 400; + line-height: 30px; /* 150% */ + max-width: 616px; + } + } + [purpose='context-switch'] { + border-bottom: 1px solid var(--border-border-primary, #E2E4EA); + margin-bottom: 64px; + [purpose='switch-option'] { + p { + margin-bottom: 0px; + } + cursor: pointer; + display: flex; + padding: 16px; + justify-content: center; + align-items: center; + width: 33%; + color: var(--Core-Fleet-Black, #192147); + text-align: center; + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; /* 150% */ + white-space: nowrap; + &.selected { + font-weight: 700; + border-bottom: 2px solid var(--text-text-brand, #192147); + } + } + } + + [purpose='testimonials-container'] { + columns: 3; + margin-bottom: 32px; + } + + [purpose='testimonial-card'] { + display: inline-block; + padding: var(--spacing-3, 24px); + flex-direction: column; + justify-content: center; + align-items: flex-start; + align-self: stretch; + border-radius: 16px; + border: 1px solid var(--UI-Fleet-Black-10, #E2E4EA); + background: var(--Core-White, #FFF); + height: min-content; + [purpose='logo'] { + img { + max-height: 32px; + max-width: 100%; + } + min-height: 0; + // margin-bottom: 24px; + } + [purpose='quote'] { + color: var(--UI-Fleet-Black-75, #515774); + + /* Body SM (FKA Card text) */ + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 21px; /* 150% */ + margin-bottom: 16px; + } + [purpose='video-link'] { + cursor: pointer; + text-decoration: underline; + } + [purpose='quote-author-info'] { + [purpose='job-title'] { + font-size: 12px; + line-height: 18px; + } + [purpose='name'] { + color: @core-fleet-black; + } + [purpose='profile-picture'] { + margin-right: 16px; + img { + height: 48px; + width: 48px; + border-radius: 50%; + } + } + } + } + + [purpose='share-button'] { + display: flex; + padding: var(--spacing-spacing-xs, 8px) var(--spacing-spacing-sm, 16px); + justify-content: center; + align-items: center; + gap: var(--spacing-spacing-xxs, 4px); + border-radius: var(--spacing-spacing-sm, 16px); + background: var(--surface-surface-secondary, #F9FAFC); + color: var(--text-text-primary, #515774); + text-align: center; + + /* Body SM (bold) */ + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 21px; /* 150% */ + &:hover { + text-decoration: none; + } + } + [parasails-component='logo-carousel'] { + margin-bottom: 64px; + } + [purpose='statistics'] { + display: flex; + flex-direction: row; + justify-content: center; + margin-top: 64px; + margin-bottom: 64px; + h4 { + color: #515774; + text-align: center; + + /* Body LG (bold) */ + font-family: Inter; + font-size: 18px; + font-style: normal; + font-weight: 700; + line-height: 27px; + } + p { + color: var(--text-text-primary, #515774); + text-align: center; + text-wrap: nowrap; + + /* Body XS (FKA p small) */ + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; /* 150% */ + margin-bottom: 0px; + } + [purpose='customers'] { + border-right: 1px solid #E2E4EA; + display: flex; + padding: 8px 64px; + flex-direction: column; + align-items: center; + } + [purpose='devices'] { + border-right: 1px solid #E2E4EA; + display: flex; + padding: 8px 64px; + flex-direction: column; + align-items: center; + } + [purpose='countries'] { + display: flex; + padding: 8px 64px; + flex-direction: column; + align-items: center; + + } + + } + + [purpose='bottom-gradient'] { + background: linear-gradient(180deg, #FFFFFF 0%, #E9F4F4 100%); + } + + [purpose='bottom-cta'] { + h2 { + color: var(--Fleet-Black-100, #192147); + text-align: center; + + /* Title L (FKA h2) */ + font-family: Inter; + font-size: 32px; + font-style: normal; + font-weight: 800; + line-height: 38.4px; /* 120% */ + } + [purpose='button-row'] { + a { + font-weight: 700; + font-size: 16px; + text-decoration: none; + } + [purpose='cta-button'] { + display: flex; + height: 36px; + padding: 16px; + justify-content: center; + align-items: center; + gap: 4px; + border-radius: 8px; + background: var(--color-brand-vibrant-red, #FF5C83); + color: var(--Core-White, #FFF); + text-align: center; + + /* Body MD (bold) */ + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 700; + line-height: 24px; /* 150% */ + margin-right: 24px; + position: relative; + } + [purpose='cta-button']::before { + background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%); + opacity: 1; + content: ''; + position: absolute; + top: 0; + left: -5px; + width: 50%; + height: 100%; + transform: skew(-10deg); + transition: left 0.5s ease-in, opacity 0.50s ease-in, width 0.5s ease-in; + } + [purpose='cta-button']:hover:before { + left: 160px; + width: 110%; + } + [parasails-component='animated-arrow-button'] { + width: fit-content; + display: flex; + align-items: center; + padding: 6px 0px; + text-decoration: none; + font-weight: 700; + [purpose='button-text'] { + color: var(--Core-Fleet-Black, #192147); + text-align: center; + font-family: Inter; + font-size: 15px; + font-style: normal; + font-weight: 600; + line-height: 24px; /* 160% */ + } + } + } + } + + + + + + + [purpose='video-modal'] { + [purpose='modal-dialog'] { + width: 100%; + max-width: 100%; + } + [purpose='modal-content'] { + max-width: 1140px; + height: 641px; + background-color: transparent; + box-shadow: none; + border: none; + padding: 0px; + margin-top: 150px; + margin-left: auto; + margin-right: auto; + [purpose='modal-close-button'] { + top: -40px; + right: 0px; + border-radius: 50%; + width: 32px; + height: 32px; + padding: 0px 0px 4px 0px; + background-color: #192147; + color: #FFF; + opacity: 1; + } + } + iframe { + width: 1140px; + height: 641px; + } + } + + + @media (max-width: 991px) { + + [purpose='testimonials-container'] { + columns: 2; + } + [purpose='page-container'] { + padding: 64px 32px; + } + } + @media (max-width: 776px) { + [purpose='page-container'] { + padding: 48px 24px; + } + [purpose='testimonials-container'] { + columns: 2; + } + + } + @media (max-width: 576px) { + [purpose='page-container'] { + padding: 32px 24px; + } + [purpose='testimonials-container'] { + columns: 1; + } + [purpose='statistics'] { + flex-direction: column; + max-width: fit-content; + margin-left: auto; + margin-right: auto; + margin-top: 32px; + h4 { + margin-bottom: 0px; + } + [purpose='customers'] { + padding: 0px 64px 24px 64px; + border-right: none; + } + [purpose='devices'] { + border-top: 1px solid #E2E4EA; + border-bottom: 1px solid #E2E4EA; + padding: 24px; + border-right: none; + } + + [purpose='countries'] { + padding: 24px 64px 0px 64px; + border-right: none; + } + + + } + [purpose='testimonial-card'] { + width: 100%; + } + [purpose='context-switch'] { + border-left: 1px solid var(--border-border-primary, #E2E4EA); + border-bottom: none; + margin-bottom: 64px; + [purpose='switch-option'] { + cursor: pointer; + display: flex; + padding: 12px; + justify-content: center; + align-items: center; + width: 100%; + color: var(--Core-Fleet-Black, #192147); + text-align: center; + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; /* 150% */ + white-space: nowrap; + &.selected { + font-weight: 700; + border-left: 2px solid var(--text-text-brand, #192147); + border-bottom: none; + } + } + } + + + } +} diff --git a/website/config/policies.js b/website/config/policies.js index 7721df8194ea..befa1d166c0a 100644 --- a/website/config/policies.js +++ b/website/config/policies.js @@ -57,4 +57,5 @@ module.exports.policies = { 'view-deals': true, 'deliver-deal-registration-submission': true, 'get-est-device-certificate': true, + 'view-testimonials': true, }; diff --git a/website/config/routes.js b/website/config/routes.js index 9e9d7005ed6f..d73683ded0d1 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -292,6 +292,14 @@ module.exports.routes = { } }, + 'GET /customer-stories': { + action: 'view-testimonials', + locals: { + pageTitleForMeta: 'Customer stories', + pageDescriptionForMeta: 'See what people are saying about Fleet' + } + }, + // ╦ ╔═╗╔═╗╔═╗╔═╗╦ ╦ ╦═╗╔═╗╔╦╗╦╦═╗╔═╗╔═╗╔╦╗╔═╗ // ║ ║╣ ║ ╦╠═╣║ ╚╦╝ ╠╦╝║╣ ║║║╠╦╝║╣ ║ ║ ╚═╗ // ╩═╝╚═╝╚═╝╩ ╩╚═╝ ╩ ╩╚═╚═╝═╩╝╩╩╚═╚═╝╚═╝ ╩ ╚═╝ @@ -500,7 +508,7 @@ module.exports.routes = { // // For example, a clever user might try to visit fleetdm.com/documentation, not knowing that Fleet's website // puts this kind of thing under /docs, NOT /documentation. These "convenience" redirects are to help them out. - 'GET /testimonials': 'https://github.com/fleetdm/fleet/blob/28cd420b086c23a6606ba17c4f3821ed267c6bbb/handbook/company/testimonials.yml#L190', + 'GET /testimonials': '/customer-stories', 'GET /admin': '/admin/email-preview', 'GET /renew': 'https://calendly.com/zayhanlon/fleet-renewal-discussion', 'GET /documentation': '/docs', diff --git a/website/views/layouts/layout.ejs b/website/views/layouts/layout.ejs index 7c2bf7ee1e18..0338df7a7bc7 100644 --- a/website/views/layouts/layout.ejs +++ b/website/views/layouts/layout.ejs @@ -183,7 +183,7 @@
- What people are saying + What people are saying News Ask around COMPANY @@ -243,7 +243,7 @@
Stories
diff --git a/website/views/pages/testimonials.ejs b/website/views/pages/testimonials.ejs new file mode 100644 index 000000000000..4f3b38c54a52 --- /dev/null +++ b/website/views/pages/testimonials.ejs @@ -0,0 +1,147 @@ +
+
+
+
+

Customer stories

+

What people are saying

+ +
+ an opening quotation mark +

+ We wanted an open-source MDM to easily use configuration-as-code, deliver the best possible experience for our employees, and make security happy. +

+
+
+ Wes Whetstone +
+
+

Kenny Botelho

+

Lead Client Platform Engineer

+
+
+ +
+
+
+

Device Managment

+

IT Engineering

+

Security Engineering

+
+
+
+
+
+ logo +
+

+ {{testimonial.quote}} + See the video. +

+
+
+ Profile picture +
+
+

{{testimonial.quoteAuthorName}}

+

{{testimonial.quoteAuthorJobTitle}}

+
+
+
+
+
+
+
+
+
+ logo +
+

+ {{testimonial.quote}} + See the video. +

+
+
+ Profile picture +
+
+

{{testimonial.quoteAuthorName}}

+

{{testimonial.quoteAuthorJobTitle}}

+
+
+
+
+
+
+
+
+
+ logo +
+

+ {{testimonial.quote}} + See the video. +

+
+
+ Profile picture +
+
+

{{testimonial.quoteAuthorName}}

+

{{testimonial.quoteAuthorJobTitle}}

+
+
+
+
+
+
+ +
+
+
+

100+

+

customers

+
+
+

2,000,000+

+

computing devices

+
+
+

90+

+

countries

+
+
+ +
+
+
<%// page content%> +
<%// page container%> + <%/* Bottom gradient */%> +
+
+
+

Open-source vulnerability reporting

+

For teams with lots of computing devices

+

Open-source device management for everyone

+

Untangle your endpoints

+

Check vulnerabilities anywhere

+
+ Try it yourself + Talk to us +
+
+
+ +
+ <%/* Cloud city banner */%> + + + +
+ + + +
+
+<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>