Created
February 10, 2020 12:31
-
-
Save saltcod/7d15f78746e50b4b37e4de396c234365 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable */ | |
/* globals wp */ | |
// @TODO: Need to change markup once it is finalized on FE. | |
const { __ } = wp.i18n; | |
const { InspectorControls, RichText } = wp.blockEditor; | |
const { PanelBody, RadioControl } = wp.components; | |
const { apiFetch } = wp; | |
const { Component } = wp.element; | |
const { addQueryArgs } = wp.url; | |
import { isEmpty } from "lodash"; | |
/** | |
* Render post markup. | |
* | |
* @param page | |
* @param linkText | |
* @param linkURL | |
* | |
* @returns {*} | |
*/ | |
function renderPost(post) { | |
// Later hook up proper post.thumbnails | |
const thumbnails = { | |
full: "https://placeimg.com/640/480/any" | |
}; | |
return ( | |
<article className="post-card"> | |
<a | |
className="post-card__link" | |
href="javascript:;" | |
title={post.title.rendered} | |
aria-label={post.title.rendered} | |
> | |
{!isEmpty(thumbnails) && !isEmpty(thumbnails.full) && ( | |
<div class="post-card__image-wrap"> | |
<img | |
class="post-card__image" | |
src={thumbnails.full} | |
alt="placeholder image" | |
/> | |
</div> | |
)} | |
<div class="post-card__content"> | |
<h2 class="post-card__title">{post.title.rendered}</h2> | |
</div> | |
<div class="post-card__date" itemprop="datePublished"> | |
<time datetime={getFormattedDate(post.date)}> | |
{getFormattedDate(post.date)} | |
</time> | |
</div> | |
</a> | |
</article> | |
); | |
} | |
/** | |
* Get a properly formatted date from the post.date that WP gives | |
* | |
* @param {*} date the UTC string WP provides | |
*/ | |
function getFormattedDate(date) { | |
const formattedDate = new Date(date); | |
const month = formattedDate.toLocaleString("default", { month: "long" }); | |
const day = formattedDate.toLocaleString("default", { day: "numeric" }); | |
const year = formattedDate.getFullYear(); | |
return `${month} ${day}, ${year}`; | |
} | |
/** | |
* Editing interface in the admin | |
* | |
* @param attributes | |
* @param setAttributes | |
* @returns {*} | |
*/ | |
class LatestPostsEdit extends Component { | |
constructor() { | |
super(...arguments); | |
this.state = { | |
categoriesList: [], | |
contentTypesList: [], | |
selectedPosts: [], | |
selectedContentType: "", | |
selectedCategory: "" | |
}; | |
} | |
componentDidMount() { | |
this.termFetch(); | |
// this.postFetch(); | |
} | |
/** | |
* Fetch a list of categories and content types | |
* to populate our <select> dropdowns | |
* | |
* Urls: | |
* http://newbeauty.test/wp-json/wp/v2/posts?per_page=15&nb_content_type=7&category=2 | |
* http://newbeauty.test/wp-json/wp/v2/categories | |
* http://newbeauty.test/wp-json/wp/v2/nb_content_type | |
* | |
*/ | |
termFetch() { | |
const categoryRequest = apiFetch({ | |
path: addQueryArgs("/wp/v2/categories", { | |
per_page: 20, // eslint-disable-line camelcase | |
type: "post" | |
}) | |
}); | |
categoryRequest.then(categories => { | |
this.setState({ categoriesList: categories }); | |
}); | |
const contentTypeRequest = apiFetch({ | |
path: addQueryArgs("/wp/v2/nb_content_type", { | |
per_page: 20, // eslint-disable-line camelcase | |
type: "post" | |
}) | |
}); | |
contentTypeRequest.then(contentTypes => { | |
this.setState({ contentTypesList: contentTypes }); | |
}); | |
} | |
postFetch = () => { | |
// wp/v2/posts?per_page=15&nb_content_type=7&category=2 | |
const postsRequest = apiFetch({ | |
path: addQueryArgs("/wp/v2/posts", { | |
per_page: 3, // eslint-disable-line camelcase | |
type: "post", | |
category: this.state.selectedCategory, | |
nb_content_type: this.state.selectedContentType | |
}) | |
}); | |
postsRequest.then(posts => { | |
this.setState({ selectedPosts: posts }); | |
setAttributes({ latestPosts: posts }); | |
}); | |
}; | |
onCategoryChange = e => { | |
//this.setState({ selectedCategory: e.target.value }, {} => this.postFetch()); | |
this.setState({ selectedCategory: e.target.value }, () => this.postFetch()); | |
}; | |
onContentTypeChange = e => { | |
this.setState({ selectedContentType: e.target.value }, () => | |
this.postFetch() | |
); | |
}; | |
render() { | |
const { | |
attributes: { title, latestPosts, layout }, | |
setAttributes | |
} = this.props; | |
return ( | |
<> | |
<InspectorControls> | |
<PanelBody title={__("Sorting and filtering")}> | |
<h3> | |
Select a content type and category to pull in the latest 3 posts | |
</h3> | |
<div className="components-base-control"> | |
<p>Content type:</p> | |
<select onChange={this.onContentTypeChange}> | |
<option value selected disabled> | |
Select a type of content | |
</option> | |
{this.state.contentTypesList.map((type, index) => ( | |
<option value={type.id} key={index}> | |
{type.name} | |
</option> | |
))} | |
</select> | |
</div> | |
<div className="components-base-control"> | |
<p>Category:</p> | |
<select onChange={this.onCategoryChange}> | |
<option value selected disabled> | |
Select a category | |
</option> | |
{this.state.categoriesList.map((category, index) => ( | |
<option value={category.id} key={index}> | |
{category.name} | |
</option> | |
))} | |
</select> | |
</div> | |
<RadioControl | |
label={__("Layout", "nu-alumni")} | |
selected={layout} | |
options={[ | |
{ label: "Left aligned", value: "left" }, | |
{ label: "Centered", value: "centered" } | |
]} | |
onChange={layout => { | |
setAttributes({ layout }); | |
}} | |
/> | |
</PanelBody> | |
</InspectorControls> | |
<div> | |
<RichText | |
className="heading-accented -giant" | |
tagName="h2" | |
multiline={false} | |
placeholder={__("Title", "newbeauty")} | |
keepPlaceholderOnFocus="true" | |
value={title} | |
onChange={title => setAttributes({ title })} | |
/> | |
<div | |
className={ | |
"category-articles__list " + | |
(layout == "left" ? "-left-align" : "-center-align") | |
} | |
> | |
<div className="category-articles__main"> | |
{this.state.selectedPosts.length ? ( | |
this.state.selectedPosts | |
.slice(0, 1) | |
.map(post => renderPost(post)) | |
) : ( | |
<p> | |
Select a content type and category in the sidebar on the | |
right. | |
</p> | |
)} | |
</div> | |
<div className="category-articles__norm"> | |
{this.state.selectedPosts | |
.slice(1, 3) | |
.map(post => renderPost(post))} | |
</div> | |
</div> | |
</div> | |
</> | |
); | |
} | |
} | |
export default LatestPostsEdit; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment