Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Job Data block #1286

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be replaced with WordPress' presets:

https://github.com/WordPress/gutenberg/blob/master/package.json#L99-L102

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice!

"presets": [ "@wordpress/default" ]
}
4 changes: 3 additions & 1 deletion .gitignore
@@ -1,6 +1,5 @@
/nbproject/private/
/node_modules/
package-lock.json
project.xml
project.properties
.DS_Store
Expand All @@ -21,3 +20,6 @@ tmp/mt
# Ignore all log files except for .htaccess
/logs/*
!/logs/.htaccess

# Ignore compiled blocks.
/includes/blocks/*/build
14 changes: 13 additions & 1 deletion includes/admin/class-wp-job-manager-writepanels.php
Expand Up @@ -157,7 +157,19 @@ protected function sort_by_priority( $a, $b ) {
public function add_meta_boxes() {
global $wp_post_types;

add_meta_box( 'job_listing_data', sprintf( __( '%s Data', 'wp-job-manager' ), $wp_post_types['job_listing']->labels->singular_name ), array( $this, 'job_listing_data' ), 'job_listing', 'normal', 'high' );
add_meta_box(
'job_listing_data',
sprintf( __( '%s Data', 'wp-job-manager' ), $wp_post_types['job_listing']->labels->singular_name ),
array( $this, 'job_listing_data' ),
'job_listing',
'normal',
'high',
array(
'__back_compat_meta_box' => true,
'__block_editor_compatible_meta_box' => true,
)
);

if ( ! get_option( 'job_manager_enable_types' ) || wp_count_terms( 'job_listing_type' ) == 0 ) {
remove_meta_box( 'job_listing_typediv', 'job_listing', 'side');
} elseif ( false == job_manager_multi_job_type() ) {
Expand Down
15 changes: 15 additions & 0 deletions includes/blocks/job-data/briefcase-icon.jsx
@@ -0,0 +1,15 @@
const BriefcaseIcon = () => (
<svg
aria-hidden
className="job-data__briefcase-icon"
role="img"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 1792 1792">
<path d="M640 256h512v-128h-512v128zm1152 640v480q0 66-47 113t-113 47h-1472q-66 0-113-47t-47-113v-480h672v160q0 26 19 45t45 19h320q26 0 45-19t19-45v-160h672zm-768 0v128h-256v-128h256zm768-480v384h-1792v-384q0-66 47-113t113-47h352v-160q0-40 28-68t68-28h576q40 0 68 28t28 68v160h352q66 0 113 47t47 113z" />
</svg>
);

export default BriefcaseIcon;
53 changes: 53 additions & 0 deletions includes/blocks/job-data/class-wp-job-manager-block-job-data.php
@@ -0,0 +1,53 @@
<?php
/**
* Job Data Block
*/

class WP_Job_Manager_Block_Job_Data {
private static $_instance = null;

public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}

return self::$_instance;
}

public function __construct() {
add_action( 'init', array( $this, 'register_block' ) );
}

public function register_block() {
if ( function_exists( 'register_block_type' ) ) {
wp_register_script(
'wpjm-job-data',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-i18n' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);

wp_register_style(
'wpjm-job-data-editor',
plugins_url( 'build/editor.css', __FILE__ ),
array( 'wp-edit-blocks' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/editor.css' )
);

wp_register_style(
'wpjm-job-data',
plugins_url( 'build/style.css', __FILE__ ),
array( 'wp-edit-blocks' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/style.css' )
);

register_block_type( 'wpjm/job-data', array(
'editor_script' => 'wpjm-job-data',
'editor_style' => 'wpjm-job-data-editor',
'style' => 'wpjm-job-data',
) );
}
}
}

WP_Job_Manager_Block_Job_Data::instance();
8 changes: 8 additions & 0 deletions includes/blocks/job-data/editor.scss
@@ -0,0 +1,8 @@
.wp-block-wpjm-job-data .job-data__upload-button.button {
margin-right: 5px;
}

.wp-block-wpjm-job-data .job-data__upload-button.button .dashicon {
vertical-align: middle;
margin-bottom: 3px;
}
166 changes: 166 additions & 0 deletions includes/blocks/job-data/index.jsx
@@ -0,0 +1,166 @@
/**
* WordPress Dependencies
*/
const { __ } = wp.i18n;
const {
registerBlockType,
InspectorControls,
RichText,
} = wp.blocks;
const {
withState,
PanelBody,
TextControl,
ToggleControl,
} = wp.components;

/**
* Internal dependencies
*/
import './editor.scss';
import './style.scss';
import BriefcaseIcon from './briefcase-icon';

registerBlockType( 'wpjm/job-data', {
title: __( 'Job Data' ),
category: 'widgets',
description: __( 'Shows additional information about a job listing.' ),
icon: BriefcaseIcon,
attributes: {
alt: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'alt',
},
id: {
type: 'number',
},
url: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
},
edit: withState( {
editable: 'location',
} )( ( { attributes, className, editable, isSelected, setAttributes, setState } ) => {
const {
alt,
application,
company,
expiryDate,
featuredListing,
id,
location,
positionFilled,
tagline,
twitter,
url,
} = attributes;

const onSetActiveEditable = newEditable => () => setState( { editable: newEditable } );
const updateLogo = ( { alt, id, url } ) => setAttributes( { alt, id, url } );
const updateToggle = field => () => setAttributes( { [ field ]: ! attributes[ field ] } );
const updateValue = field => value => setAttributes( { [ field ]: value } );

return (
<div className={ className }>
{ isSelected && (
<InspectorControls key="inspector">
<PanelBody title={ __( 'Job Data Settings' ) }>
<ToggleControl
checked={ positionFilled }
label={ __( 'Position Filled' ) }
onChange={ updateToggle( 'positionFilled' ) } />

<ToggleControl
checked={ featuredListing }
label={ __( 'Featured Listing' ) }
onChange={ updateToggle( 'featuredListing' ) } />

<TextControl
label={ __( 'Application Email or URL' ) }
onChange={ updateValue( 'application' ) }
value={ application } />

<TextControl
label={ __( 'Expiry Date' ) }
onChange={ updateValue( 'expiryDate' ) }
value={ expiryDate } />
</PanelBody>
</InspectorControls>
) }

<div className="job-data__details">
{ /* TODO: Show when at least one job type is selected. */ }
{ false && (
<ul className="job-data__type-list">
{ /* TODO: Dynamically add list item when job type is selected. */ }
<li className="job-data__type is-full-time">
{ __( 'Full Time' ) }
</li>
<li className="job-data__type is-freelance">
{ __( 'Freelance' ) }
</li>
</ul>
) }

<div className="job-data__meta">
<RichText
isSelected={ isSelected && editable === 'location' }
onChange={ updateValue( 'location' ) }
onFocus={ onSetActiveEditable( 'location' ) }
placeholder={ __( 'Enter job location…' ) }
tagName="span"
wrapperClassName="job-data__location"
value={ location }
keepPlaceholderOnFocus />

{ /* TODO: Show once job is saved. */ }
{ false && (
<span className="job-data__date-posted">
<time dateTime="2017-08-31">
{ __( 'Posted 1 minute ago' ) }
</time>
</span>
) }
</div>

<div className="job-data__company-details">
<RichText
isSelected={ isSelected && editable === 'company' }
onChange={ updateValue( 'company' ) }
onFocus={ onSetActiveEditable( 'company' ) }
placeholder={ __( 'Enter company name…' ) }
tagName="span"
value={ company }
keepPlaceholderOnFocus />
<RichText
isSelected={ isSelected && editable === 'tagline' }
onChange={ updateValue( 'tagline' ) }
onFocus={ onSetActiveEditable( 'tagline' ) }
placeholder={ __( 'Enter company tagline…' ) }
tagName="span"
value={ tagline }
keepPlaceholderOnFocus />
<RichText
isSelected={ isSelected && editable === 'twitter' }
onChange={ updateValue( 'twitter' ) }
onFocus={ onSetActiveEditable( 'twitter' ) }
placeholder={ __( 'Enter company Twitter account…' ) }
tagName="span"
value={ twitter }
wrapperClassName="job-data__twitter"
keepPlaceholderOnFocus />
</div>
</div>
</div>
);
} ),
save: () => {
// TODO
return null;
}
} );
103 changes: 103 additions & 0 deletions includes/blocks/job-data/style.scss
@@ -0,0 +1,103 @@
$full-time: #90da36;
$freelance: #3399cc;

%display-icon {
display: inline-block;
width: 16px;
height: 16px;
-webkit-font-smoothing: antialiased;
font-size: 16px;
font-family: "job-manager" !important;
text-decoration: none;
font-weight: normal;
font-style: normal;
vertical-align: top;
margin: 0 2px 0 0;
}

.wp-block-wpjm-job-data .job-data__details {
margin-top: 1em;
}

.wp-block-wpjm-job-data .job-data__type-list {
list-style: none;
margin: 0 0 .5em;
padding: 0;
}

.wp-block-wpjm-job-data .job-data__type {
display: inline-block;
padding: .5em;
margin: 0 1em 0 0;
line-height: 1em;
color: #fff;

&.is-freelance {
background-color: $freelance;
}

&.is-full-time {
background-color: $full-time;
}
}

.wp-block-wpjm-job-data .job-data__meta {
margin-bottom: 1em;
}

.wp-block-wpjm-job-data .job-data__location {
display: inline-block;
}

.wp-block-wpjm-job-data .job-data__location,
.wp-block-wpjm-job-data .job-data__date-posted {
margin-right: 1em;
color: #999;
}

.wp-block-wpjm-job-data .job-data__location:before {
@extend %display-icon;
content: '\e81d';
}

.wp-block-wpjm-job-data .job-data__date-posted:before {
@extend %display-icon;
content: '\e80f';
}

.wp-block-wpjm-job-data .job-data__twitter:before {
@extend %display-icon;
content: '\e80a';
}

.wp-block-wpjm-job-data .job-data__company-details {
border: 1px solid #eee;
padding: 1em;
margin: 0 0 2em;
min-height: 3em;
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
}

.wp-block-wpjm-job-data .job-data__application-wrapper {
margin: 0 0 1em;
}

.wp-block-wpjm-job-data .job-data__application {
display: inline-block;
margin: 0 .5em 0 0;
padding: 1em 2em;
text-align: center;
font-size: 1.1em;
line-height: 1em;
outline: 0;
}

/**
* Small devices (landscape phones, 576px and up)
*/
@media screen and (min-width: 576px) {
.wp-block-wpjm-job-data .job-data__type-list,
.wp-block-wpjm-job-data .job-data__meta {
display: inline-block;
}
}