// Swiss Football Gutenberg Blocks - Refactored User Flow (function (blocks, element, editor, components, i18n, data) { 'use strict'; const { registerBlockType } = blocks; const { createElement: el, useState, useEffect } = element; const { InspectorControls } = editor; const { PanelBody, SelectControl, TextControl, ToggleControl, Spinner, RangeControl } = components; const { __ } = i18n; // Helper function to make AJAX calls function makeAjaxCall(action, data = {}) { return new Promise((resolve, reject) => { jQuery.post(swiFootEditorData.ajax_url, { action: action, nonce: swiFootEditorData.nonce, ...data }, function (response) { if (response && response.success) { resolve(response); } else { reject(response); } }).fail(reject); }); } // Main Swiss Football Block - Refactored Logic registerBlockType('swi-foot/team-data', { title: __('Swiss Football Team Data', 'swi_foot_matchdata'), description: __('Display team standings or match data with guided selection', 'swi_foot_matchdata'), icon: 'universal-access-alt', category: 'widgets', keywords: [ __('football', 'swi_foot_matchdata'), __('soccer', 'swi_foot_matchdata'), __('team', 'swi_foot_matchdata'), __('swiss', 'swi_foot_matchdata'), ], attributes: { selectedTeam: { type: 'string', default: '' }, dataType: { type: 'string', default: '' // 'match' or 'stats' }, selectedMatch: { type: 'string', default: '' }, shortcodeType: { type: 'string', default: 'match' }, format: { type: 'string', default: '' }, separator: { type: 'string', default: ':' } }, edit: function (props) { const { attributes, setAttributes } = props; const { selectedTeam, dataType, selectedMatch, shortcodeType, format, separator } = attributes; // State for dynamic data const [teams, setTeams] = useState([]); const [matches, setMatches] = useState([]); const [loadingTeams, setLoadingTeams] = useState(true); const [loadingMatches, setLoadingMatches] = useState(false); // Load teams on component mount useEffect(() => { makeAjaxCall('swi_foot_get_teams_for_editor') .then(response => { if (response.success && response.data) { setTeams(response.data); } setLoadingTeams(false); }) .catch(() => { setLoadingTeams(false); }); }, []); // Load matches when team is selected and dataType is 'match' useEffect(() => { if (selectedTeam && dataType === 'match') { setLoadingMatches(true); makeAjaxCall('swi_foot_get_matches_for_team', { team_id: selectedTeam }) .then(response => { if (response.success && response.data) { setMatches(response.data); } setLoadingMatches(false); }) .catch(() => { setLoadingMatches(false); }); } else { setMatches([]); } }, [selectedTeam, dataType]); // Build shortcode/content preview let content = ''; if (selectedTeam && dataType === 'stats') { content = '[swi_foot_standings team_id="' + selectedTeam + '"]'; } else if (selectedTeam && dataType === 'match' && selectedMatch) { if (selectedMatch === 'current') { content = '[swi_foot_' + shortcodeType + ' team_id="' + selectedTeam + '" show_current="true"'; } else { content = '[swi_foot_' + shortcodeType + ' match_id="' + selectedMatch + '"'; } if (format && (shortcodeType === 'match_date' || shortcodeType === 'match_time')) { content += ' format="' + format + '"'; } if (separator !== ':' && shortcodeType === 'match_score') { content += ' separator="' + separator + '"'; } content += ']'; } // Data type options const dataTypeOptions = [ { value: '', label: __('Choose what to display...', 'swi_foot_matchdata') }, { value: 'stats', label: __('Team Statistics (Standings/Ranking)', 'swi_foot_matchdata') }, { value: 'match', label: __('Match Data', 'swi_foot_matchdata') } ]; // Match data type options const matchDataOptions = [ { value: 'match', label: __('Complete Match Information', 'swi_foot_matchdata') }, { value: 'match_home_team', label: __('Home Team Name Only', 'swi_foot_matchdata') }, { value: 'match_away_team', label: __('Away Team Name Only', 'swi_foot_matchdata') }, { value: 'match_date', label: __('Match Date Only', 'swi_foot_matchdata') }, { value: 'match_time', label: __('Match Time Only', 'swi_foot_matchdata') }, { value: 'match_venue', label: __('Venue/Location Only', 'swi_foot_matchdata') }, { value: 'match_score', label: __('Score Only', 'swi_foot_matchdata') }, { value: 'match_status', label: __('Match Status Only', 'swi_foot_matchdata') }, { value: 'match_league', label: __('League Name Only', 'swi_foot_matchdata') }, { value: 'match_round', label: __('Round Number Only', 'swi_foot_matchdata') } ]; return el('div', { className: 'swi-foot-team-data-block' }, el(InspectorControls, {}, el(PanelBody, { title: __('Team Selection', 'swi_foot_matchdata') }, // Step 1: Team selection loadingTeams ? el(Spinner) : el(SelectControl, { label: __('1. Select Team', 'swi_foot_matchdata'), value: selectedTeam, options: [{ value: '', label: __('Choose a team...', 'swi_foot_matchdata') }].concat( teams.map(team => ({ value: team.value, label: team.label })) ), onChange: function (value) { setAttributes({ selectedTeam: value, dataType: '', // Reset when team changes selectedMatch: '' }); } }), // Step 2: Data type selection (only show if team is selected) selectedTeam && el(SelectControl, { label: __('2. What would you like to display?', 'swi_foot_matchdata'), value: dataType, options: dataTypeOptions, onChange: function (value) { setAttributes({ dataType: value, selectedMatch: '' // Reset match when data type changes }); } }) ), // Match-specific settings dataType === 'match' && el(PanelBody, { title: __('Match Settings', 'swi_foot_matchdata') }, // Match selection loadingMatches ? el(Spinner) : el(SelectControl, { label: __('3. Select Match', 'swi_foot_matchdata'), value: selectedMatch, options: [{ value: '', label: __('Choose a match...', 'swi_foot_matchdata') }].concat( [{ value: 'current', label: __('Current Match (Next upcoming or recent)', 'swi_foot_matchdata') }], matches.map(match => ({ value: match.value, label: match.label })) ), onChange: function (value) { setAttributes({ selectedMatch: value }); } }), // Match data type (what part of match to show) selectedMatch && el(SelectControl, { label: __('4. What match information to display?', 'swi_foot_matchdata'), value: shortcodeType, options: matchDataOptions, onChange: function (value) { setAttributes({ shortcodeType: value }); } }) ), // Advanced options for match data dataType === 'match' && selectedMatch && el(PanelBody, { title: __('Advanced Options', 'swi_foot_matchdata'), initialOpen: false }, (shortcodeType === 'match_date' || shortcodeType === 'match_time') && el(SelectControl, { label: __('Date/Time Format', 'swi_foot_matchdata'), value: format, options: shortcodeType === 'match_date' ? [ { value: '', label: __('Default (WordPress setting)', 'swi_foot_matchdata') }, { value: 'd.m.Y', label: '31.12.2024 (European)' }, { value: 'm/d/Y', label: '12/31/2024 (US)' }, { value: 'F j, Y', label: 'December 31, 2024' }, { value: 'D, M j', label: 'Tue, Dec 31' } ] : [ { value: '', label: __('Default (WordPress setting)', 'swi_foot_matchdata') }, { value: 'H:i', label: '14:30 (24-hour)' }, { value: 'g:i A', label: '2:30 PM (12-hour)' }, { value: 'g:i', label: '2:30 (12-hour no AM/PM)' } ], onChange: function (value) { setAttributes({ format: value }); } }), shortcodeType === 'match_score' && el(SelectControl, { label: __('Score Separator', 'swi_foot_matchdata'), value: separator, options: [ { value: ':', label: '2 : 1 (colon with spaces)' }, { value: '-', label: '2 - 1 (dash with spaces)' }, { value: ' vs ', label: '2 vs 1 (versus)' }, { value: '|', label: '2 | 1 (pipe)' } ], onChange: function (value) { setAttributes({ separator: value }); } }) ) ), // Main preview area el('div', { className: 'swi-foot-preview' }, el('div', { style: { padding: '30px', textAlign: 'center', background: '#f8f9fa', border: '2px dashed #ddd', borderRadius: '8px' } }, el('h4', { style: { marginTop: 0 } }, __('Swiss Football Team Data', 'swi_foot_matchdata')), !selectedTeam && el('p', { style: { color: '#666' } }, __('1. Please select a team to get started', 'swi_foot_matchdata') ), selectedTeam && !dataType && el('p', { style: { color: '#666' } }, __('2. Please choose what you want to display', 'swi_foot_matchdata') ), selectedTeam && dataType === 'stats' && el('p', { style: { color: '#28a745' } }, '✓ ' + __('Will display team standings/ranking', 'swi_foot_matchdata') ), selectedTeam && dataType === 'match' && !selectedMatch && el('p', { style: { color: '#666' } }, __('3. Please select a match', 'swi_foot_matchdata') ), selectedTeam && dataType === 'match' && selectedMatch && el('div', {}, el('p', { style: { color: '#28a745' } }, '✓ ' + __('Ready to display match data', 'swi_foot_matchdata') ), el('p', { style: { fontSize: '14px', color: '#666' } }, __('Generated shortcode:', 'swi_foot_matchdata') ), el('code', { style: { display: 'block', padding: '10px', background: '#fff', border: '1px solid #ddd', borderRadius: '4px', fontFamily: 'Monaco, Menlo, monospace', fontSize: '12px', wordBreak: 'break-all' } }, content) ) ) ) ); }, save: function (props) { const { attributes } = props; const { selectedTeam, dataType, selectedMatch, shortcodeType, format, separator } = attributes; // Build shortcode for saving let shortcode = ''; if (selectedTeam && dataType === 'stats') { shortcode = '[swi_foot_standings team_id="' + selectedTeam + '"]'; } else if (selectedTeam && dataType === 'match' && selectedMatch) { if (selectedMatch === 'current') { shortcode = '[swi_foot_' + shortcodeType + ' team_id="' + selectedTeam + '" show_current="true"'; } else { shortcode = '[swi_foot_' + shortcodeType + ' match_id="' + selectedMatch + '"'; } if (format && (shortcodeType === 'match_date' || shortcodeType === 'match_time')) { shortcode += ' format="' + format + '"'; } if (separator !== ':' && shortcodeType === 'match_score') { shortcode += ' separator="' + separator + '"'; } shortcode += ']'; } return shortcode; } }); // Match Roster Block with Side Selector and Bench Option registerBlockType('swi-foot/match-roster', { title: __('Swiss Football Match Roster', 'swi_foot_matchdata'), description: __('Display match roster for home or away team, with optional bench players', 'swi_foot_matchdata'), icon: 'groups', category: 'widgets', keywords: [ __('roster', 'swi_foot_matchdata'), __('players', 'swi_foot_matchdata'), __('lineup', 'swi_foot_matchdata'), __('team', 'swi_foot_matchdata'), ], attributes: { selectedTeam: { type: 'string', default: '' }, selectedMatch: { type: 'string', default: '' }, side: { type: 'string', default: 'home' // home or away }, withBench: { type: 'boolean', default: false } }, edit: function (props) { const { attributes, setAttributes } = props; const { selectedTeam, selectedMatch, side, withBench } = attributes; const [teams, setTeams] = wp.element.useState([]); const [matches, setMatches] = wp.element.useState([]); const [loadingTeams, setLoadingTeams] = wp.element.useState(true); const [loadingMatches, setLoadingMatches] = wp.element.useState(false); // Helper AJAX call function makeAjaxCall(action, data = {}) { return new Promise((resolve, reject) => { jQuery.post(swiFootEditorData.ajax_url, { action: action, nonce: swiFootEditorData.nonce, ...data }, function (response) { if (response && response.success) { resolve(response); } else { reject(response); } }).fail(reject); }); } // Load teams wp.element.useEffect(() => { setLoadingTeams(true); makeAjaxCall('swi_foot_get_teams_for_editor') .then(response => { if (Array.isArray(response.data)) { setTeams(response.data); } setLoadingTeams(false); }) .catch(() => setLoadingTeams(false)); }, []); // Load matches when team changes wp.element.useEffect(() => { if (selectedTeam) { setLoadingMatches(true); makeAjaxCall('swi_foot_get_matches_for_team', { team_id: selectedTeam }) .then(response => { if (Array.isArray(response.data)) { setMatches(response.data); } setLoadingMatches(false); }) .catch(() => setLoadingMatches(false)); } }, [selectedTeam]); return el('div', { className: 'swi-foot-roster-block' }, el(InspectorControls, {}, el(PanelBody, { title: __('Match Selection', 'swi_foot_matchdata') }, // Team selector loadingTeams ? el(Spinner) : el(SelectControl, { label: __('Select Team', 'swi_foot_matchdata'), value: selectedTeam, options: [{ value: '', label: __('Choose a team...', 'swi_foot_matchdata') }].concat( teams.map(team => ({ value: team.value, label: team.label })) ), onChange: function (value) { setAttributes({ selectedTeam: value, selectedMatch: '' }); } }), // Match selector (shows after team is selected) selectedTeam && (loadingMatches ? el(Spinner) : el(SelectControl, { label: __('Select Match', 'swi_foot_matchdata'), value: selectedMatch, options: [{ value: '', label: __('Choose a match...', 'swi_foot_matchdata') }].concat( [{ value: 'current', label: __('Current Match', 'swi_foot_matchdata') }], matches.map(match => ({ value: match.value, label: match.label })) ), onChange: function (value) { setAttributes({ selectedMatch: value }); } })), // Side selector (Home/Away) selectedMatch && el(SelectControl, { label: __('Select Side', 'swi_foot_matchdata'), value: side, options: [ { value: 'home', label: __('Home Team', 'swi_foot_matchdata') }, { value: 'away', label: __('Away Team', 'swi_foot_matchdata') } ], onChange: function (value) { setAttributes({ side: value }); } }), // Include bench toggle selectedMatch && el(ToggleControl, { label: __('Include Bench Players', 'swi_foot_matchdata'), help: __('When enabled, bench players will also be displayed', 'swi_foot_matchdata'), checked: withBench, onChange: function (value) { setAttributes({ withBench: value }); } }) ) ), // Block preview el('div', { style: { padding: '30px', textAlign: 'center', background: '#f8f9fa', border: '2px dashed #ddd', borderRadius: '8px' } }, el('h4', { style: { marginTop: 0 } }, __('Match Roster', 'swi_foot_matchdata')), (!selectedTeam || !selectedMatch) ? el('p', { style: { color: '#666' } }, __('Please select team, match, side, and bench option', 'swi_foot_matchdata') ) : el('p', { style: { color: '#28a745' } }, '✓ ' + __('Roster will be displayed for ' + side + ' team' + (withBench ? ' (with bench)' : ''), 'swi_foot_matchdata') ) ) ); }, save: function (props) { const { selectedTeam, selectedMatch, side, withBench } = props.attributes; if (!selectedTeam || !selectedMatch || !side) return ''; let shortcode = '[swi_foot_roster '; if (selectedMatch === 'current') { shortcode += 'team_id="' + selectedTeam + '" show_current="true"'; } else { shortcode += 'match_id="' + selectedMatch + '"'; } shortcode += ' side="' + side + '"'; if (withBench) { shortcode += ' with_bench="true"'; } shortcode += ']'; return shortcode; } }); // Match Events Block registerBlockType('swi-foot/match-events', { title: __('Swiss Football Match Events', 'swi_foot_matchdata'), description: __('Display live match events with auto-refresh', 'swi_foot_matchdata'), icon: 'list-view', category: 'widgets', keywords: [ __('events', 'swi_foot_matchdata'), __('live', 'swi_foot_matchdata'), __('timeline', 'swi_foot_matchdata'), __('match', 'swi_foot_matchdata'), ], attributes: { selectedTeam: { type: 'string', default: '' }, selectedMatch: { type: 'string', default: '' }, refreshInterval: { type: 'number', default: 30 } }, edit: function (props) { const { attributes, setAttributes } = props; const { selectedTeam, selectedMatch, refreshInterval } = attributes; const [teams, setTeams] = useState([]); const [matches, setMatches] = useState([]); const [loadingTeams, setLoadingTeams] = useState(true); const [loadingMatches, setLoadingMatches] = useState(false); // Load teams useEffect(() => { makeAjaxCall('swi_foot_get_teams_for_editor') .then(response => { if (response.success && response.data) { setTeams(response.data); } setLoadingTeams(false); }) .catch(() => setLoadingTeams(false)); }, []); // Load matches when team changes useEffect(() => { if (selectedTeam) { setLoadingMatches(true); makeAjaxCall('swi_foot_get_matches_for_team', { team_id: selectedTeam }) .then(response => { if (response.success && response.data) { setMatches(response.data); } setLoadingMatches(false); }) .catch(() => setLoadingMatches(false)); } }, [selectedTeam]); return el('div', { className: 'swi-foot-events-block' }, el(InspectorControls, {}, el(PanelBody, { title: __('Match Selection', 'swi_foot_matchdata') }, loadingTeams ? el(Spinner) : el(SelectControl, { label: __('Select Team', 'swi_foot_matchdata'), value: selectedTeam, options: [{ value: '', label: __('Choose a team...', 'swi_foot_matchdata') }].concat( teams.map(team => ({ value: team.value, label: team.label })) ), onChange: function (value) { setAttributes({ selectedTeam: value, selectedMatch: '' }); } }), selectedTeam && (loadingMatches ? el(Spinner) : el(SelectControl, { label: __('Select Match', 'swi_foot_matchdata'), value: selectedMatch, options: [{ value: '', label: __('Choose a match...', 'swi_foot_matchdata') }].concat( [{ value: 'current', label: __('Current Match', 'swi_foot_matchdata') }], matches.map(match => ({ value: match.value, label: match.label })) ), onChange: function (value) { setAttributes({ selectedMatch: value }); } })) ), el(PanelBody, { title: __('Auto-Refresh Settings', 'swi_foot_matchdata') }, el(RangeControl, { label: __('Refresh Interval (seconds)', 'swi_foot_matchdata'), value: refreshInterval, onChange: function (value) { setAttributes({ refreshInterval: value }); }, min: 10, max: 300, step: 10 }) ) ), el('div', { style: { padding: '30px', textAlign: 'center', background: '#f8f9fa', border: '2px dashed #ddd', borderRadius: '8px' } }, el('h4', { style: { marginTop: 0 } }, __('Live Match Events', 'swi_foot_matchdata')), (!selectedTeam || !selectedMatch) ? el('p', { style: { color: '#666' } }, __('Please select team and match', 'swi_foot_matchdata')) : el('div', {}, el('p', { style: { color: '#28a745' } }, '✓ ' + __('Will display live match events', 'swi_foot_matchdata')), el('p', { style: { fontSize: '12px', color: '#666' } }, __('Auto-refresh every', 'swi_foot_matchdata') + ' ' + refreshInterval + ' ' + __('seconds', 'swi_foot_matchdata')) ) ) ); }, save: function (props) { const { attributes } = props; const { selectedTeam, selectedMatch, refreshInterval } = attributes; if (!selectedTeam || !selectedMatch) return ''; let shortcode = '[swi_foot_events '; if (selectedMatch === 'current') { shortcode += 'team_id="' + selectedTeam + '" show_current="true"'; } else { shortcode += 'match_id="' + selectedMatch + '"'; } shortcode += ' refresh_interval="' + refreshInterval + '"]'; return shortcode; } }); })( window.wp.blocks, window.wp.element, window.wp.blockEditor, window.wp.components, window.wp.i18n, window.wp.data );