Skip to content
This repository has been archived by the owner on Jan 10, 2023. It is now read-only.

[Gutenberg] Add "Featured Destinations" homepage block #34

Merged
merged 16 commits into from
Apr 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 59 additions & 66 deletions assets/js/editor-blocks.js

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions assets/js/term-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* global wp */

/**
* JS functions for terms in admin UI.
*/

( function( $ ) {
'use strict';

let component = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice structure of the file.


/**
* Init.
*/
component.init = function init() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the selected image is persisting even after saving a new "Location"

  1. Go to /wp-admin/edit-tags.php?taxonomy=location
  2. Fill in all of the fields, and select an image

adding-new-location

  1. Click "Add New Location"
  2. Expected: the selected image doesn't display anymore, as the rest of the fields are empty
  3. Actual: the selected image still displays:

image-still-appears

But the workflow looks fine when editing a location:

edit-location

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this.

_.extend( component, {
fileFrame: [],
uploadButton: $( '#location-cover-image' ),
removeButton: $( '#location-cover-image-remove' ),
imgContainer: $( '#location-cover-image-preview' ),
imgIdInput: $( '#location-cover-image-value' ),
saveNewTermButton: $( '#addtag #submit' )
} );

component.setupLocationMediaUploader();
component.setupAddTerm();
};

/**
* Add media uploader for location cover image.
*/
component.setupLocationMediaUploader = function() {
component.uploadButton.on( 'click', function ( event ) {

event.preventDefault();

let self = $( this ),
id = self.attr( 'id' );

// If the media frame already exists, reopen it.
if ( component.fileFrame[ id ] ) {
component.fileFrame[ id ].open();

return;
}

// Create the media frame.
component.fileFrame[ id ] = wp.media.frames.fileFrame = wp.media( {
title: wp.i18n.__( 'Select Location Cover Image' ),
button: {
text: wp.i18n.__( 'Select Image' )
},
multiple: false
} );

// When an image is selected, run a callback.
component.fileFrame[ id ].on( 'select', function() {
let attachment = component.fileFrame[ id ].state().get( 'selection' ).first().toJSON();

// Set input value.
component.imgIdInput.val( attachment.id );
component.imgContainer.html( '<img src="' + attachment.url + '" style="max-width: 100%;" />' );
component.removeButton.removeClass( 'hidden' );

} );

// Finally, open the modal
component.fileFrame[ id ].open();

} );

component.removeButton.on( 'click', function( event ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have time, could you display this component.removeButton only if there's no selected image? But I'd call this a "nice to have."

It could be confusing to have a "Remove" button if there's no image to remove.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making this change, @miina. This works well.

event.preventDefault();
component.imgIdInput.val( '' );
component.imgContainer.html( '' );
component.removeButton.addClass( 'hidden' );

} );
};

/**
* Set up events when adding new term.
*/
component.setupAddTerm = function() {
component.saveNewTermButton.on( 'click', function() {

if ( ! validateForm( $( this ).parents( 'form' ) ) ) {
return;
}

// Wait for ajax save stopping.
$( document ).ajaxStop( function() {
if ( 0 === $( '#ajax-response .error' ).length ) {
component.imgIdInput.val( '' );
component.imgContainer.html( '' );
component.removeButton.addClass( 'hidden' );
$( '.location-is-featured-wrap input[type="checkbox"]' ).prop( 'checked', false );
}
} );
} );
};

$( document ).ready( function() {
component.init();
} );

})( jQuery );
194 changes: 119 additions & 75 deletions blocks/featured/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,85 +6,15 @@
*/
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;

import { deamplify } from '../amp-transformer';

/**
* Render the featured block.
*
* @return {wp.element.Component} Rendered component.
*/
const renderStaticFeaturedBlock = () => {
return (
<section className='travel-featured pt3 relative clearfix'>
<header className='max-width-2 mx-auto px1 md-px2 relative'>
<h3 className='travel-featured-heading h1 bold line-height-2 mb2 center'>Featured Destinations</h3>
</header>
<div className='max-width-3 mx-auto relative'>
<div className='travel-featured-grid flex flex-wrap items-stretch'>
<div className='col-12 md-col-6 flex items-stretch flex-auto'>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-blue' on="tap:AMP.setState({fields_query: 'New York', query_query: 'New York'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='336' height='507' src={travelGlobals.themeUrl + '/img/new-york.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>New York</div>
<div className='h5'>379 adventures</div>
</div>
</a>
<div className='flex flex-column items-stretch flex-auto'>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-cyan' on="tap:AMP.setState({fields_query: 'Barcelona', query_query: 'Barcelona'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='246' src={travelGlobals.themeUrl + '/img/barcelona.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>Barcelona</div>
<div className='h5'>68 adventures</div>
</div>
</a>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-orange' on="tap:AMP.setState({fields_query: 'Paris', query_query: 'Paris'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='264' src={travelGlobals.themeUrl + '/img/paris.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>Paris</div>
<div className='h5'>221 adventures</div>
</div>
</a>
</div>
</div>
<div className='col-12 md-col-6 flex items-stretch flex-auto'>
<div className='flex flex-column items-stretch flex-auto'>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-purple' on="tap:AMP.setState({fields_query: 'Tokyo', query_query: 'Tokyo'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='276' height='207' src={travelGlobals.themeUrl + '/img/tokyo.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>Tokyo</div>
<div className='h5'>500+ adventures</div>
</div>
</a>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-cornflower' on="tap:AMP.setState({fields_query: 'Chicago', query_query: 'Chicago'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='264' height='286' src={travelGlobals.themeUrl + '/img/chicago.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>Chicago</div>
<div className='h5'>143 adventures</div>
</div>
</a>
</div>
<a href='travel-results.amp' className='travel-featured-tile flex flex-auto relative travel-featured-color-teal' on="tap:AMP.setState({fields_query: 'Reykjavik', query_query: 'Reykjavik'})">
<amp-img class='travel-object-cover flex-auto' layout='responsive' width='312' height='507' src={travelGlobals.themeUrl + '/img/reykjavik.jpg'}></amp-img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold h3'>Reykjavik</div>
<div className='h5'>87 adventures</div>
</div>
</a>
</div>
</div>
</div>
</section>
);
};
const { Placeholder, withAPIData } = wp.components;

/**
* Register block.
*/
export default registerBlockType(
'amp-travel/featured',
{
title: __( 'Featured' ),
title: __( 'Featured Destinations' ),
category: 'common',
icon: 'wordpress-alt',
keywords: [
Expand All @@ -93,11 +23,125 @@ export default registerBlockType(
__( 'Travel' )
],

edit() {
Copy link
Contributor

@kienstra kienstra Apr 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is outside of this PR's diff. But could the title of this block be 'Featured Destinations,' instead of 'Featured'? Or something that's descriptive.

title: __( 'Featured Destinations' ),
category: 'common',
icon: 'wordpress-alt',

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making this change.

return deamplify( renderStaticFeaturedBlock() );
attributes: {
heading: {
selector: '.travel-featured-heading',
source: 'children',
type: 'array'
}
},

edit: withAPIData( () => {
return {
featuredLocations: '/wp/v2/locations?per_page=6&meta_value=1&meta_key=amp_travel_featured'
};
} )( ( { featuredLocations } ) => { // eslint-disable-line
const hasLocations = Array.isArray( featuredLocations.data ) && 6 <= featuredLocations.data.length;
if ( ! hasLocations ) {
return (
<Placeholder key="placeholder"
icon="admin-post"
label={ __( 'Locations' ) }
>
{ __( 'Not enough featured locations found. Please add at least six "Locations" terms, select an image, and check "Featured destination."' ) }
</Placeholder>
);
}

const locations = featuredLocations.data;
const imgStyles = [
{
width: 336,
height: 507
},
{
width: 264,
height: 246
},
{
width: 264,
height: 264
},
{
width: 276,
height: 207
},
{
width: 264,
height: 286
},
{
width: 312,
height: 507
}
];

return (
<section className='travel-featured pt3 relative clearfix'>
<header className='max-width-2 mx-auto px1 md-px2 relative'>
<h3 className='travel-featured-heading h1 bold line-height-2 mb2 center'>{ __( 'Featured Destinations' ) }</h3>
</header>
<div className='max-width-3 mx-auto relative'>
<div className='travel-featured-grid flex flex-wrap items-stretch'>
<div className='col-12 md-col-6 flex items-stretch flex-auto'>
<a href={ locations[0].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-blue'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[0] } width='336' height='507' src={ locations[0].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[0].name }</div>
<div className='h5'>{ locations[0].count + __( ' adventures' ) }</div>
</div>
</a>
<div className='flex flex-column items-stretch flex-auto'>
<a href={ locations[1].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-cyan'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[1] } width='264' height='246' src={ locations[1].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>{ locations[1].name }</div>
<div className='h5'>{ locations[1].count + __( ' adventures' ) }</div>
</div>
</a>
<a href={ locations[2].link } className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-orange'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[2] } width='264' height='264' src={ locations[2].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading bold caps line-height-2 h3'>{ locations[2].name }</div>
<div className='h5'>{ locations[2].count + __( ' adventures' ) }</div>
</div>
</a>
</div>
</div>
<div className='col-12 md-col-6 flex items-stretch flex-auto'>
<div className='flex flex-column items-stretch flex-auto'>
<a href={ locations[3].link } className='travel-featured-tile flex flex-auto pointer relative travel-featured-color-purple'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[3] } width='276' height='207' src={ locations[3].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[3].name }</div>
<div className='h5'>{ locations[3].count + __( ' adventures' ) }</div>
</div>
</a>
<a href={ locations[4].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-cornflower'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[4] } width='264' height='286' src={ locations[4].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold line-height-2 h3'>{ locations[4].name }</div>
<div className='h5'>{ locations[4].count + __( ' adventures' ) }</div>
</div>
</a>
</div>
<a href={ locations[5].link } className='travel-featured-tile flex flex-auto relative travel-featured-color-teal'>
<img className='travel-object-cover flex-auto' layout='responsive' style={ imgStyles[5] } width='312' height='507' src={ locations[5].meta.amp_travel_location_img }></img>
<div className='travel-featured-overlay absolute z1 center top-0 right-0 bottom-0 left-0 white p2'>
<div className='travel-featured-tile-heading caps bold h3'>{ locations[5].name }</div>
<div className='h5'>{ locations[5].count + __( ' adventures' ) }</div>
</div>
</a>
</div>
</div>
</div>
</section>
);
} ), // eslint-disable-line
save() {
return renderStaticFeaturedBlock();

// Render in PHP.
return null;
}
}
);
Loading