Skip to content

Commit

Permalink
More progress on saving status in RSVP V2 block.
Browse files Browse the repository at this point in the history
  • Loading branch information
mauteri committed Dec 8, 2024
1 parent f28ec61 commit 8037221
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 97 deletions.
2 changes: 1 addition & 1 deletion build/blocks/rsvp-status/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '980c9982f495280b9cf9');
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '647c9e73475f1342072f');
2 changes: 1 addition & 1 deletion build/blocks/rsvp-status/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 2 additions & 14 deletions build/blocks/rsvp-v2/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,9 @@
"example": {},
"description": "Enables members to easily confirm their attendance for an event.",
"attributes": {
"noStatusLabel": {
"serializedInnerBlocks": {
"type": "string",
"default": "RSVP"
},
"attendingLabel": {
"type": "string",
"default": "Edit RSVP"
},
"waitingListLabel": {
"type": "string",
"default": "Edit RSVP"
},
"notAttendingLabel": {
"type": "string",
"default": "Edit RSVP"
"default": "[]"
}
},
"supports": {
Expand Down
2 changes: 1 addition & 1 deletion build/blocks/rsvp-v2/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => 'e342b20ef97f7ae4fc71');
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '9da56d3f11ea2a058a0c');
2 changes: 1 addition & 1 deletion build/blocks/rsvp-v2/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions includes/core/classes/class-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@ protected function unregister_blocks(): array {
'gatherpress/event-date',
'gatherpress/online-event',
'gatherpress/rsvp',
'gatherpress/rsvp-v2',
'gatherpress/rsvp-response',
'gatherpress/rsvp-response-v2',
'gatherpress/rsvp-status',
);
break;
Expand Down
3 changes: 1 addition & 2 deletions src/blocks/rsvp-status/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { useBlockProps } from '@wordpress/block-editor';
import metadata from './block.json';
import Edit from './edit';

registerBlockType(metadata.name, {
...metadata,
registerBlockType(metadata, {
edit: Edit,
save: () => {
// Use blockProps to ensure proper WordPress class handling
Expand Down
16 changes: 2 additions & 14 deletions src/blocks/rsvp-v2/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,9 @@
"example": {},
"description": "Enables members to easily confirm their attendance for an event.",
"attributes": {
"noStatusLabel": {
"serializedInnerBlocks": {
"type": "string",
"default": "RSVP"
},
"attendingLabel": {
"type": "string",
"default": "Edit RSVP"
},
"waitingListLabel": {
"type": "string",
"default": "Edit RSVP"
},
"notAttendingLabel": {
"type": "string",
"default": "Edit RSVP"
"default": "[]"
}
},
"supports": {
Expand Down
109 changes: 48 additions & 61 deletions src/blocks/rsvp-v2/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,95 +5,81 @@ import {
InnerBlocks,
InspectorControls,
useBlockProps,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { PanelBody, SelectControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useEffect } from '@wordpress/element';
import { useEffect, useState, useCallback } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';

/**
* Internal dependencies.
*/
import { useDispatch, useSelect } from '@wordpress/data';
import TEMPLATE from './template';

/**
* Edit component for the GatherPress RSVP block.
*
* This component defines the edit interface for the GatherPress RSVP block in the block editor.
* It dynamically manages and updates block attributes based on user input and the status of
* nested blocks. The component includes:
* - `InspectorControls` for managing RSVP statuses via a dropdown.
* - Logic to locate and update text labels of nested `core/button` blocks based on the current RSVP status.
* - `InnerBlocks` to allow nested content within the RSVP block.
*
* The `useEffect` hook ensures that changes to the RSVP status or inner blocks dynamically update
* the block attributes, ensuring consistent behavior and text labels.
*
* @param {Object} props The props passed to the component.
* @param {Object} props.attributes Block attributes.
* @param {Function} props.setAttributes Function to update block attributes.
* @param {string} props.clientId The unique ID of the block instance.
*
* @since 1.0.0
*
* @return {JSX.Element} The rendered edit interface for the RSVP block.
*/
const Edit = ({ setAttributes }) => {
const Edit = ({ attributes, setAttributes, clientId }) => {
const { serializedInnerBlocks = '{}' } = attributes;
const [status, setStatus] = useState('no_status');
const blockProps = useBlockProps();
const dispatch = useDispatch();
const { setStatus } = dispatch('gatherpress/rsvp-status');
const { status } = useSelect(
(select) => ({
status: select('gatherpress/rsvp-status').getStatus(),
}),
[]
);

const clientId = useSelect(
(select) => select('core/block-editor').getSelectedBlock()?.clientId,
[]
);
const { replaceInnerBlocks } = useDispatch(blockEditorStore);

// Get the current inner blocks
const innerBlocks = useSelect(
(select) =>
clientId ? select('core/block-editor').getBlocks(clientId) : [],
(select) => select(blockEditorStore).getBlocks(clientId),
[clientId]
);

const locateButtonBlock = (blocks) => {
for (const block of blocks) {
if (block.name === 'core/button') {
return block;
}
if (block.innerBlocks.length > 0) {
const found = locateButtonBlock(block.innerBlocks);
if (found) {
return found;
}
// Save the provided inner blocks to the serializedInnerBlocks attribute
const saveInnerBlocks = (state, blocks) => {
const currentSerializedBlocks = JSON.parse(
serializedInnerBlocks || '{}'
);
const updatedBlocks = {
...currentSerializedBlocks,
[state]: blocks,
};

setAttributes({
serializedInnerBlocks: JSON.stringify(updatedBlocks),
});
};

// Load inner blocks for a given state
const loadInnerBlocksForState = useCallback(
(state) => {
const savedBlocks = JSON.parse(serializedInnerBlocks || '{}')[
state
];
if (savedBlocks && savedBlocks.length > 0) {
replaceInnerBlocks(clientId, savedBlocks);
}
}
return null;
},
[clientId, replaceInnerBlocks, serializedInnerBlocks]
);

// Handle status change: save current inner blocks and load new ones
const handleStatusChange = (newStatus) => {
saveInnerBlocks(status, innerBlocks); // Save current inner blocks before switching state
setStatus(newStatus); // Update the state
loadInnerBlocksForState(newStatus); // Load blocks for the new state
};

const buttonBlock = locateButtonBlock(innerBlocks);
// On initial render, ensure correct blocks are loaded
useEffect(() => {
if (buttonBlock) {
const buttonText = buttonBlock.attributes.text;

switch (status) {
case 'no_status':
setAttributes({ noStatusLabel: buttonText });
break;
case 'attending':
setAttributes({ attendingLabel: buttonText });
break;
case 'waiting_list':
setAttributes({ waitingListLabel: buttonText });
break;
case 'not_attending':
setAttributes({ notAttendingLabel: buttonText });
break;
}
}
}, [buttonBlock, setAttributes, status]);
loadInnerBlocksForState(status);
}, [status, loadInnerBlocksForState]);

return (
<>
Expand Down Expand Up @@ -132,7 +118,7 @@ const Edit = ({ setAttributes }) => {
value: 'not_attending',
},
]}
onChange={(newStatus) => setStatus(newStatus)}
onChange={handleStatusChange}
/>
</PanelBody>
</InspectorControls>
Expand All @@ -142,4 +128,5 @@ const Edit = ({ setAttributes }) => {
</>
);
};

export default Edit;
10 changes: 8 additions & 2 deletions src/blocks/rsvp-v2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ import './style.scss';
*/
registerBlockType(metadata, {
edit,
save: () => {
save: ({ attributes }) => {
const blockProps = useBlockProps.save();
const { serializedInnerBlocks } = attributes;

return (
<div {...useBlockProps.save()}>
<div
{...blockProps}
data-serialized-inner-blocks={serializedInnerBlocks}
>
<InnerBlocks.Content />
</div>
);
Expand Down

0 comments on commit 8037221

Please sign in to comment.