// Editor entry (ESNext) for Swiss Football blocks. // This registers blocks and the shortcode insertion toolbar button. import { registerBlockType } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; import { InspectorControls, useBlockProps, RawHTML } from '@wordpress/block-editor'; import { PanelBody, SelectControl, ToggleControl, RangeControl, Spinner } from '@wordpress/components'; import { useState, useEffect, createElement } from '@wordpress/element'; import { registerFormatType, applyFormat } from '@wordpress/rich-text'; import './format-shortcode'; function makeAjaxCall(action, data = {}) { const root = swiFootEditorData.rest_url.replace(/\/$/, ''); let url = root; const opts = { credentials: 'same-origin', headers: { 'X-WP-Nonce': swiFootEditorData.rest_nonce } }; if (action === 'swi_foot_get_teams_for_editor') { url += '/teams'; opts.method = 'GET'; } else if (action === 'swi_foot_get_matches_for_team') { url += '/matches?team_id=' + encodeURIComponent(data.team_id || ''); opts.method = 'GET'; } else if (action === 'swi_foot_get_commons_ids') { url += '/commons-ids'; opts.method = 'GET'; } else { return Promise.reject({ error: 'Unknown action' }); } return fetch(url, opts) .then(r => { if (!r.ok) return r.json().then(j => Promise.reject(j)); return r.json(); }) .then(data => { // Transform API response into expected format for editor blocks if (action === 'swi_foot_get_teams_for_editor') { return { success: true, data: Array.isArray(data) ? data.map(team => ({ value: team.teamId, label: team.teamName })) : [] }; } else if (action === 'swi_foot_get_matches_for_team') { return { success: true, data: Array.isArray(data) ? data.map(match => ({ value: match.matchId, label: `${match.teamNameA} vs ${match.teamNameB} (${match.matchDate})` })) : [] }; } return { success: true, data: data }; }); } function checkBlockStatus(matchId, endpoint) { if (!matchId) return Promise.resolve(null); const root = swiFootEditorData.rest_url.replace(/\/$/, ''); const url = `${root}/block-status/${matchId}/${endpoint}`; const opts = { credentials: 'same-origin', headers: { 'X-WP-Nonce': swiFootEditorData.rest_nonce } }; return fetch(url, opts) .then(r => r.json()) .catch(() => null); } // Standings block (editor UI only, server renders) // Gets team from container context, no user selection needed registerBlockType('swi-foot/standings', { apiVersion: 3, title: __('Swiss Football Standings', 'swi_foot_matchdata'), category: 'swi-football', supports: { align: true, anchor: true }, edit: ({ attributes, setAttributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); return (

{__('Team is inherited from the container context.', 'swi_foot_matchdata')}

{__('Standings', 'swi_foot_matchdata')}

{__('League standings inherited from team context. ✓ Data will render on the front-end.', 'swi_foot_matchdata')}

); }, save: () => null }); // Schedule block (editor UI only, server renders) // Gets team from container context, only allows limiting results registerBlockType('swi-foot/schedule', { apiVersion: 3, title: __('Swiss Football Schedule', 'swi_foot_matchdata'), category: 'swi-football', supports: { align: true, anchor: true }, attributes: { limit: { type: 'number', default: 10 }, matchFilter: { type: 'string', default: 'all' } }, edit: ({ attributes, setAttributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); const { limit, matchFilter } = attributes; return (

{__('Team is inherited from the container context.', 'swi_foot_matchdata')}

setAttributes({ limit: val })} min={1} max={20} /> setAttributes({ matchFilter: val })} />

{__('Schedule', 'swi_foot_matchdata')}

{__('Team and match schedule inherited from context. ✓ Data will render on the front-end.', 'swi_foot_matchdata')}

); }, save: ({ attributes }) => null }); // Match Roster // Gets match and team from container context, only allows selecting which side (home/away) and bench option registerBlockType('swi-foot/match-roster', { apiVersion: 3, title: __('Swiss Football Match Roster', 'swi_foot_matchdata'), category: 'swi-football', supports: { align: true, anchor: true }, attributes: { side: { type: 'string', default: 'home' }, showStartingSquad: { type: 'boolean', default: true }, showBench: { type: 'boolean', default: false } }, edit: ({ attributes, setAttributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); const { side, showStartingSquad, showBench } = attributes; return (

{__('Match and team are inherited from the container context.', 'swi_foot_matchdata')}

setAttributes({side:v})} __next40pxDefaultSize={true} __nextHasNoMarginBottom={true} /> setAttributes({showStartingSquad:v})} __nextHasNoMarginBottom={true} /> setAttributes({showBench:v})} __nextHasNoMarginBottom={true} />

{__('Match Roster', 'swi_foot_matchdata')}

{__('Team and match are inherited from the container context. ✓ Data will render on the front-end.', 'swi_foot_matchdata')}

); }, save: ({ attributes }) => { const { side, showStartingSquad, showBench } = attributes; let shortcode = '[swi_foot_roster side="' + side + '"'; if (showStartingSquad) shortcode += ' starting_squad="true"'; if (showBench) shortcode += ' bench="true"'; shortcode += ']'; return createElement(RawHTML, null, shortcode); } }); // Match Events // Gets match and team from container context, only allows setting refresh interval registerBlockType('swi-foot/match-events', { apiVersion: 3, title: __('Swiss Football Match Events', 'swi_foot_matchdata'), category: 'swi-football', supports: { align: true, anchor: true }, attributes: { refreshInterval: { type: 'number', default: 30 }, eventOrder: { type: 'string', default: 'dynamic' } }, edit: ({ attributes, setAttributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); const { refreshInterval, eventOrder } = attributes; return (

{__('Match and team are inherited from the container context.', 'swi_foot_matchdata')}

setAttributes({refreshInterval:v})} min={10} max={300} step={10} /> setAttributes({eventOrder:v})} options={[ { label: __('Dynamic (Newest first while live, chronological after)', 'swi_foot_matchdata'), value: 'dynamic' }, { label: __('Newest First', 'swi_foot_matchdata'), value: 'newest_first' }, { label: __('Oldest First', 'swi_foot_matchdata'), value: 'oldest_first' } ]} help={__('Dynamic: newest events at top while match is ongoing, chronological (oldest first) after match ends', 'swi_foot_matchdata')} __next40pxDefaultSize={true} __nextHasNoMarginBottom={true} />

{__('Match Events', 'swi_foot_matchdata')}

{__('Live match events inherited from context. ✓ Will update during match.', 'swi_foot_matchdata')}

); }, save: ({ attributes }) => { const { refreshInterval, eventOrder } = attributes; let shortcode = '[swi_foot_events refresh_interval="' + (refreshInterval || 30) + '"'; if (eventOrder && eventOrder !== 'dynamic') { shortcode += ' event_order="' + eventOrder + '"'; } shortcode += ']'; return createElement(RawHTML, null, shortcode); } }); // Match Bench // Gets match from container context, displays team staff and bench players registerBlockType('swi-foot/match-bench', { apiVersion: 3, title: __('Swiss Football Match Bench', 'swi_foot_matchdata'), icon: 'clipboard-user', category: 'swi-football', supports: { align: true, anchor: true }, attributes: { side: { type: 'string', default: 'home' } }, edit: ({ attributes, setAttributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); const { side } = attributes; return (

{__('Match is inherited from the container context.', 'swi_foot_matchdata')}

setAttributes({side:v})} __next40pxDefaultSize={true} __nextHasNoMarginBottom={true} />

{__('Match Bench', 'swi_foot_matchdata')}

{__('Team bench and substitutes inherited from context. ✓ Data will render on the front-end.', 'swi_foot_matchdata')}

); }, save: ({ attributes }) => { const { side } = attributes; let shortcode = '[swi_foot_bench side="' + side + '"]'; return createElement(RawHTML, null, shortcode); } }); // Match Referees // Gets match from container context, displays match officials and referees registerBlockType('swi-foot/match-referees', { apiVersion: 3, title: __('Swiss Football Match Referees', 'swi_foot_matchdata'), icon: 'whistle', category: 'swi-football', supports: { align: true, anchor: true }, edit: ({ attributes, isSelected }) => { const blockProps = useBlockProps({ style: isSelected ? {outline: '2px solid #0073aa'} : {} }); return (

{__('Match is inherited from the container context.', 'swi_foot_matchdata')}

{__('Match Referees', 'swi_foot_matchdata')}

{__('Match officials and referees inherited from context. ✓ Data will render on the front-end.', 'swi_foot_matchdata')}

); }, save: () => null });