wp-plugin-swiss-football-ma.../assets/editor-blocks.js
2026-03-27 13:59:28 +01:00

654 lines
30 KiB
JavaScript

// 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
);