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

Feature: Add event tickets block, field template #7217

Merged
merged 19 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7e26e7d
feature: add EventTicketsBlock scaffold
pauloiankoski Jan 30, 2024
48bf7a9
feature: implement inspector settings and update placeholders structure
pauloiankoski Jan 31, 2024
bced04d
feature: set types and fix visibility logic issues
pauloiankoski Jan 31, 2024
f5547d3
feature: implement placeholder when having no events
pauloiankoski Jan 31, 2024
52f1de3
feature: implement placeholder to select an event
pauloiankoski Jan 31, 2024
18f746e
refactor: move block labels to localized array
pauloiankoski Feb 1, 2024
d54de3a
refactor: replace name attribute with title
pauloiankoski Feb 1, 2024
d77eb4e
feature: implement block placeholder with hardcoded content
pauloiankoski Feb 1, 2024
0defed4
refactor: replace placeholder hardcoded content with dynamic
pauloiankoski Feb 1, 2024
07c4d59
feature: add field template scaffold
pauloiankoski Feb 5, 2024
6ad0fbf
feature: make shared components reusable
pauloiankoski Feb 5, 2024
e16b44b
fix: set correct import path
pauloiankoski Feb 5, 2024
3ee9543
refactor: rename variables and set different styles
pauloiankoski Feb 6, 2024
354abed
fix: remove duplicated function definition
pauloiankoski Feb 6, 2024
2eac02b
refactor: restrict to only allow one EventTickets block per form
pauloiankoski Feb 9, 2024
059fd69
refactor: extract conditional responsibilities to a HOC
pauloiankoski Feb 9, 2024
949cea3
doc: type dates as Date objects
pauloiankoski Feb 9, 2024
7977748
refactor: replace string parsing with separated assignments
pauloiankoski Feb 9, 2024
3e4fc15
refactor: move import to top
pauloiankoski Feb 9, 2024
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
19 changes: 18 additions & 1 deletion src/EventTickets/Actions/EnqueueDonationFormScripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,30 @@

namespace Give\EventTickets\Actions;

use Give\Framework\EnqueueScript;

/**
* @unreleased
*/
class EnqueueDonationFormScripts
{
public function __invoke()
{
//
$scriptAsset = require GIVE_PLUGIN_DIR . 'build/eventTicketsTemplate.asset.php';

(new EnqueueScript(
'givewp-event-tickets-template',
'build/eventTicketsTemplate.js',
GIVE_PLUGIN_DIR,
GIVE_PLUGIN_URL,
'give'
))->enqueue();

wp_enqueue_style(
'givewp-event-tickets-template',
GIVE_PLUGIN_URL . 'build/eventTicketsTemplate.css',
[],
$scriptAsset['version']
);
}
}
66 changes: 65 additions & 1 deletion src/EventTickets/Actions/EnqueueFormBuilderScripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,77 @@

namespace Give\EventTickets\Actions;

use Give\Framework\EnqueueScript;

/**
* @unreleased
*/
class EnqueueFormBuilderScripts
{
public function __invoke()
{
//
$scriptAsset = require GIVE_PLUGIN_DIR . 'build/eventTicketsBlock.asset.php';

(new EnqueueScript(
'givewp-event-tickets-block',
'build/eventTicketsBlock.js',
GIVE_PLUGIN_DIR,
GIVE_PLUGIN_URL,
'give'
))->enqueue();

wp_localize_script(
'givewp-event-tickets-block',
'eventTicketsBlockSettings',
[
'events' => [
[
'id' => 1,
'title' => 'Event 1',
'date' => '2024-01-10 10:00',
'description' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
'tickets' => [
[
'id' => 1,
'name' => 'Standard',
'price' => 50,
'quantity' => 5,
'description' => 'Standard ticket description goes here',
],
[
'id' => 2,
'name' => 'VIP',
'price' => 100,
'quantity' => 5,
'description' => 'VIP ticket description goes here',
],
],
],
],
// TODO: Update this to fetch events from the database
'createEventUrl' => admin_url('edit.php?post_type=give_forms&page=give-event-tickets&action=new'),
//TODO: Update this with the correct URL
'listEventsUrl' => admin_url('edit.php?post_type=give_forms&page=give-event-tickets'),
//TODO: Update this with the correct URL
'ticketsLabel' => apply_filters(
'givewp_event_tickets_block/tickets_label',
__('Select Tickets', 'give')
),
'soldOutMessage' => apply_filters(
'givewp_event_tickets_block/sold_out_message',
__(
'Thank you for supporting our cause. Our fundraising event tickets are officially sold out. You can still contribute by making a donation.',
'give'
)
),
]
);

wp_enqueue_style(
'givewp-event-tickets-block',
GIVE_PLUGIN_URL . 'build/eventTicketsBlock.css',
[],
$scriptAsset['version']
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {InspectorControls} from '@wordpress/block-editor';
import {PanelBody, PanelRow, SelectControl} from '@wordpress/components';
import {createInterpolateElement} from '@wordpress/element';
import {__} from '@wordpress/i18n';
import CreateEventNotice from './components/CreateEventNotice';

/**
* @unreleased
*/
export default function BlockInspectorControls({attributes, setAttributes}) {
const {events} = window.eventTicketsBlockSettings;
const {eventId} = attributes;

const eventOptions =
events.map((event) => {
return {label: event.title, value: `${event.id}`};
}) ?? [];

return (
<InspectorControls>
<PanelBody title={__('Event', 'give')} initialOpen={true}>
{events.length === 0 ? (
<CreateEventNotice />
) : (
<PanelRow>
<SelectControl
label={__('Event Name', 'give')}
help={createInterpolateElement(
__('Add or edit an event in the <a>events page</a>.', 'give'),
{
a: <a href={window.eventTicketsBlockSettings.listEventsUrl} target="_blank" />,
}
)}
value={`${eventId}`}
options={[{label: 'Select', value: ''}, ...eventOptions]}
onChange={(value: string) => setAttributes({eventId: Number(value)})}
/>
</PanelRow>
)}
</PanelBody>
</InspectorControls>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import EventTicketsHeader from '../../../components/EventTicketsHeader';
import EventTicketsDescription from '../../../components/EventTicketsDescription';
import EventTicketsList from '../../../components/EventTicketsList';
import {getWindowData} from '@givewp/form-builder/common';

/**
* @unreleased
*/
export default function BlockPlaceholder({attributes}) {
const {events, ticketsLabel, soldOutMessage} = window.eventTicketsBlockSettings;
const event = events.find((event) => event.id === attributes.eventId);
const {currency} = getWindowData();

if (!event || !event.tickets.length) {
return null;
}

return (
<div className={'givewp-event-tickets-block__placeholder'}>
<div className={'givewp-event-tickets'}>
<EventTicketsHeader title={event.title} date={event.date} />

{event.description && <EventTicketsDescription description={event.description} />}

<EventTicketsList
tickets={event.tickets}
ticketsLabel={ticketsLabel}
soldOutMessage={soldOutMessage}
currency={currency}
/>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {__} from '@wordpress/i18n';
import {createInterpolateElement} from '@wordpress/element';

/**
* @unreleased
*/
export default function BlockPlaceholderNoEvents() {
return (
<div className={'givewp-event-tickets-block__placeholder--no-events'}>
<p>
{createInterpolateElement(
__(
'No events created yet. Go to the <a>events page</a> to create and manage your own event.',
'give'
),
{
a: <a href={window.eventTicketsBlockSettings.listEventsUrl} target="_blank" />,
}
)}
</p>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {__} from '@wordpress/i18n';
import {SelectControl} from '@wordpress/components';

/**
* @unreleased
*/
export default function BlockPlaceholderSelectEvent({attributes, setAttributes}) {
const {events} = window.eventTicketsBlockSettings;
const eventOptions =
events.map((event) => {
return {label: event.title, value: `${event.id}`};
}) ?? [];

return (
<div className={'givewp-event-tickets-block__placeholder--select-event'}>
<p>
<strong>{__('No event selected yet', 'give')}</strong>
</p>
<SelectControl
label={__('Select your preferred event for this donation form', 'give')}
value={`${attributes.eventId}`}
options={[{label: 'Select', value: ''}, ...eventOptions]}
onChange={(value: string) => setAttributes({eventId: Number(value)})}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {__} from '@wordpress/i18n';
import {Notice} from '@wordpress/components';
import {createInterpolateElement} from '@wordpress/element';

import './styles.scss';

/**
* @unreleased
*/
export default function CreateEventNotice() {
return (
<div className={`givewp-event-tickets-block__create-event-notice`}>
<Notice isDismissible={false} status="warning">
<h4>{__('No event created yet', 'give')}</h4>
<p>{__('Donors will not be able to see any event on this form', 'give')}</p>
<p>{createInterpolateElement(
__('<a>Create an event</a>', 'give'),
{
a: <a href={window.eventTicketsBlockSettings.createEventUrl} target="_blank" />,
}
)}</p>
</Notice>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.givewp-event-tickets-block__create-event-notice {
margin-bottom: var(--givewp-spacing-4);

.components-notice {
margin: 0;
padding: var(--givewp-spacing-3) var(--givewp-spacing-4);

&__content {
margin: 0;

h4, p {
font-size: 0.75rem;
line-height: 1.5;
margin: 0;
}

p {
color: var(--givewp-grey-700);
margin-top: var(--givewp-spacing-2);

a {
color: var(--givewp-grey-900);

&:hover {
text-decoration: none;
}
}
}
}
}
}
32 changes: 32 additions & 0 deletions src/EventTickets/resources/blocks/EventTicketsBlock/Edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import BlockInspectorControls from './BlockInspectorControls';
import BlockPlaceholderNoEvents from './BlockPlaceholderNoEvents';
import BlockPlaceholder from './BlockPlaceholder';
import BlockPlaceholderSelectEvent from './BlockPlaceholderSelectEvent';

import './styles.scss';

/**
* @unreleased
*/
export default function Edit(props) {
const {events} = window.eventTicketsBlockSettings;
const {
attributes: {eventId},
} = props;

const eventIds = events.map((event) => event.id);

return (
<>
{events.length === 0 ? (
<BlockPlaceholderNoEvents />
) : !eventId || !eventIds.includes(eventId) ? (
<BlockPlaceholderSelectEvent {...props} />
) : (
<BlockPlaceholder {...props} />
)}

<BlockInspectorControls {...props} />
</>
);
}
Loading
Loading