mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 00:49:03 +00:00
Closes: #16018 Changes: - Updated the testimonial configuration in testimonial.yml to add two new required values: - `quoteAuthorProfileImageFilename` - The filename of the quote author's LinkedIn profile picture in the website's `assets/images/` folder - `productCategories`: An array of product categories that this quote is relevant to - Added new quotes to testimonials.yml - Updated the testimonial validation in build-static-content to throw an error if a testimonial is missing one of the new required values - Updated the `<scrollable-tweets> component to match the latest wireframes - Updated the controllers for the product category landing pages to filter testimonials by product category and sort them by the order specified in [the wireframes](https://www.figma.com/file/3he8e72251IEnF6dBafKq1/%F0%9F%9A%A7-fleetdm.com-(scratchpad)?type=design&node-id=9369-4714&mode=dev)
116 lines
4.5 KiB
JavaScript
Vendored
116 lines
4.5 KiB
JavaScript
Vendored
/**
|
|
* <scrollable-tweets>
|
|
* -----------------------------------------------------------------------------
|
|
* A horizontally scrolling row of tweets with an auto-updating page indicator
|
|
*
|
|
* @type {Component}
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
|
|
parasails.registerComponent('scrollableTweets', {
|
|
// ╔═╗╦═╗╔═╗╔═╗╔═╗
|
|
// ╠═╝╠╦╝║ ║╠═╝╚═╗
|
|
// ╩ ╩╚═╚═╝╩ ╚═╝
|
|
props: [
|
|
'testimonials'
|
|
],
|
|
|
|
// ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗
|
|
// ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣
|
|
// ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
|
|
data: function () {
|
|
return {
|
|
quotesToDisplay: [],
|
|
quotesWithVideoLinks: [],
|
|
currentTweetPage: 0,
|
|
numberOfTweetCards: 0,
|
|
numberOfTweetPages: 0,
|
|
numberOfTweetsPerPage: 0,
|
|
tweetCardWidth: 0,
|
|
tweetPageWidth: 0,
|
|
screenSize: 0,
|
|
scrolledAmount: 0,
|
|
scrollableAmount: 0,
|
|
modal: ''
|
|
};
|
|
},
|
|
|
|
// ╦ ╦╔╦╗╔╦╗╦
|
|
// ╠═╣ ║ ║║║║
|
|
// ╩ ╩ ╩ ╩ ╩╩═╝
|
|
template: `
|
|
<div class="d-flex flex-column">
|
|
<div purpose="tweets" class="d-flex flex-row flex-nowrap">
|
|
<a purpose="tweet-card" class="card" v-for="testimonial in quotesToDisplay" target="_blank" :href="testimonial.quoteLinkUrl">
|
|
<div purpose="logo" class="mb-4">
|
|
<img :height="testimonial.imageHeight" v-if="testimonial.quoteImageFilename" :src="'/images/'+testimonial.quoteImageFilename"/>
|
|
</div>
|
|
<p purpose="quote">
|
|
{{testimonial.quote}}
|
|
<a purpose="video-link" v-if="testimonial.youtubeVideoUrl" @click.prevent.self="clickOpenVideoModal(testimonial.quoteAuthorName)">See the video.</a>
|
|
</p>
|
|
<div purpose="quote-author-info" class="d-flex flex-row align-items-center">
|
|
<div purpose="profile-picture">
|
|
<img :src="'/images/'+testimonial.quoteAuthorProfileImageFilename">
|
|
</div>
|
|
<div class="d-flex flex-column align-self-top">
|
|
<p purpose="name" class="font-weight-bold m-0">{{testimonial.quoteAuthorName}}</p>
|
|
<p purpose="job-title" class="m-0">{{testimonial.quoteAuthorJobTitle}}</p>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div purpose="page-indictator-container" class="mx-auto d-flex flex-row justify-content-center">
|
|
</div>
|
|
<div v-for="video in quotesWithVideoLinks">
|
|
<modal purpose="video-modal" v-if="modal === video.modalId" @close="closeModal()" >
|
|
<iframe width="560" height="315" :src="'https://www.youtube.com/embed/'+video.embedId+'?rel=0'" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
|
</modal>
|
|
</div>
|
|
</div>
|
|
`,
|
|
|
|
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
|
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
|
|
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
|
|
beforeMount: function() {
|
|
if(!this.testimonials){
|
|
throw new Error('Incomplete usage of <scrollable-tweets>: Please pass in a `testimonials` prop (an array of testimonials from sails.config.builtStaticContent.testimonials). For example: `<scrollable-tweets :testimonials="testimonials">`');
|
|
}
|
|
if(!_.isArray(this.testimonials)){
|
|
throw new Error('Incomplete usage of <scrollable-tweets>: The `testimonials` prop provided is an invalid type. Please provide an array of testimonial values.');
|
|
}
|
|
this.quotesToDisplay = _.clone(this.testimonials);
|
|
for(let quote of this.testimonials){
|
|
if(quote.youtubeVideoUrl){
|
|
this.quotesWithVideoLinks.push({
|
|
modalId: _.kebabCase(quote.quoteAuthorName),
|
|
embedId: quote.videoIdForEmbed,
|
|
});
|
|
}
|
|
}
|
|
|
|
},
|
|
mounted: async function(){
|
|
|
|
},
|
|
beforeDestroy: function() {
|
|
|
|
},
|
|
|
|
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
|
|
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
|
|
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
|
|
methods: {
|
|
|
|
clickOpenVideoModal: function(modalName) {
|
|
this.modal = _.kebabCase(modalName);
|
|
},
|
|
|
|
closeModal: function() {
|
|
this.modal = undefined;
|
|
},
|
|
|
|
}
|
|
});
|