initial commit.
This commit is contained in:
commit
195a208b5a
6
html/live-score.html
Normal file
6
html/live-score.html
Normal file
@ -0,0 +1,6 @@
|
||||
<div id="live-score-container">
|
||||
<h3>Live Match Score</h3>
|
||||
<div id="live-score-content">
|
||||
<em>Loading live score...</em>
|
||||
</div>
|
||||
</div>
|
||||
18
html/scoreboard-controls.html
Normal file
18
html/scoreboard-controls.html
Normal file
@ -0,0 +1,18 @@
|
||||
<div id="score-controls">
|
||||
<h4>Rugby Score Controls</h4>
|
||||
<label>Minute: <input type="number" id="score-minute" value="0" min="0"></label><br>
|
||||
<label>Team:
|
||||
<select id="score-team">
|
||||
<option value="home">Home</option>
|
||||
<option value="away">Away</option>
|
||||
</select>
|
||||
</label><br>
|
||||
<button class="score-btn" data-type="start">Start Match</button>
|
||||
<button class="score-btn" data-type="half_time">Half Time</button>
|
||||
<button class="score-btn" data-type="full_time">Full Time</button>
|
||||
<button class="score-btn" data-type="try">Try</button>
|
||||
<button class="score-btn" data-type="conversion">Conversion</button>
|
||||
<button class="score-btn" data-type="penalty_kick">Penalty Kick</button>
|
||||
<button class="score-btn" data-type="yellow_card">Yellow Card</button>
|
||||
<button class="score-btn" data-type="red_card">Red Card</button>
|
||||
</div>
|
||||
4
html/scoreboard.html
Normal file
4
html/scoreboard.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div id="live-scoreboard">
|
||||
<h3>Scoreboard Timeline</h3>
|
||||
<ul id="scoreboard-list"></ul>
|
||||
</div>
|
||||
23
js/live-score.js
Normal file
23
js/live-score.js
Normal file
@ -0,0 +1,23 @@
|
||||
jQuery(document).ready(function ($) {
|
||||
fetch(LiveScoreAjax.templatesUrl + 'live-score.html')
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
const container = $(html).appendTo('[data-live-score-shortcode]');
|
||||
function fetchLiveScore() {
|
||||
$.get(LiveScoreAjax.ajaxUrl, { action: 'get_live_score' }, function (res) {
|
||||
if (res.success) {
|
||||
const score = res.data.score;
|
||||
$('#live-score-content').html(`
|
||||
<strong>${res.data.event_title}</strong><br>
|
||||
<span>Home: ${score.home} | Away: ${score.away}</span>
|
||||
`);
|
||||
} else {
|
||||
$('#live-score-content').html('<em>No live event at the moment.</em>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fetchLiveScore();
|
||||
setInterval(fetchLiveScore, 10000); // Poll every 10 seconds
|
||||
});
|
||||
});
|
||||
35
js/scoreboard-controls.js
Normal file
35
js/scoreboard-controls.js
Normal file
@ -0,0 +1,35 @@
|
||||
jQuery(document).ready(function ($) {
|
||||
if (!scoreboardData.canEdit) return;
|
||||
|
||||
fetch(scoreboardData.templatesUrl + 'scoreboard-controls.html')
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
const panel = $(html).appendTo('.entry-content');
|
||||
|
||||
panel.on('click', '.score-btn', function () {
|
||||
const type = $(this).data('type');
|
||||
const minute = parseInt($('#score-minute').val(), 10);
|
||||
const team = $('#score-team').val();
|
||||
const newEvent = { type, minute, team };
|
||||
|
||||
let timelineData = [];
|
||||
try {
|
||||
timelineData = JSON.parse(scoreboardData.timeline);
|
||||
if (!Array.isArray(timelineData)) timelineData = [];
|
||||
} catch (e) { }
|
||||
|
||||
timelineData.push(newEvent);
|
||||
|
||||
$.post(scoreboardData.ajaxUrl, {
|
||||
action: 'update_scoreboard',
|
||||
event_id: scoreboardData.eventId,
|
||||
timeline: JSON.stringify(timelineData)
|
||||
}, function (res) {
|
||||
if (res.success) {
|
||||
alert('Event added!');
|
||||
location.reload(); // optionally trigger re-render instead
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
14
js/scoreboard.js
Normal file
14
js/scoreboard.js
Normal file
@ -0,0 +1,14 @@
|
||||
jQuery(document).ready(function ($) {
|
||||
fetch(scoreboardData.templatesUrl + 'scoreboard.html')
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
const container = $(html).appendTo('.entry-content');
|
||||
const data = JSON.parse(scoreboardData.timeline);
|
||||
const list = container.find('#scoreboard-list');
|
||||
|
||||
data.forEach(ev => {
|
||||
const item = $(`<li>${ev.minute}' - ${ev.team || 'N/A'} - ${ev.type}</li>`);
|
||||
list.append(item);
|
||||
});
|
||||
});
|
||||
});
|
||||
145
scoreboard.php
Normal file
145
scoreboard.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Sportspress Scoreboard Extension
|
||||
* Description: Adds a live scoreboard with edit controls for users with permission.
|
||||
* Version: 1.0
|
||||
*/
|
||||
|
||||
add_action('init', function() {
|
||||
add_role('score_editor', 'Score Editor', ['sportspress_can_control_score' => true]);
|
||||
});
|
||||
|
||||
register_activation_hook(__FILE__, function() {
|
||||
$role = get_role('administrator');
|
||||
if ($role) {
|
||||
$role->add_cap('sportspress_can_control_score');
|
||||
}
|
||||
});
|
||||
|
||||
register_deactivation_hook(__FILE__, function() {
|
||||
$role = get_role('administrator');
|
||||
if ($role) {
|
||||
$role->remove_cap('sportspress_can_control_score');
|
||||
}
|
||||
});
|
||||
|
||||
// Add meta box for scoreboard timeline
|
||||
add_action('add_meta_boxes', function() {
|
||||
add_meta_box('scoreboard_timeline', 'Scoreboard Timeline', 'render_scoreboard_meta_box', 'sp_event');
|
||||
});
|
||||
|
||||
function render_scoreboard_meta_box($post) {
|
||||
$json = get_post_meta($post->ID, '_scoreboard_timeline', true);
|
||||
$json = $json ? esc_textarea($json) : '{}';
|
||||
echo '<textarea style="width:100%;height:200px;" name="scoreboard_timeline_json">' . $json . '</textarea>';
|
||||
}
|
||||
|
||||
// Save scoreboard meta
|
||||
add_action('save_post_sp_event', function($post_id) {
|
||||
if (isset($_POST['scoreboard_timeline_json'])) {
|
||||
update_post_meta($post_id, '_scoreboard_timeline', wp_unslash($_POST['scoreboard_timeline_json']));
|
||||
}
|
||||
});
|
||||
|
||||
add_action('wp_enqueue_scripts', function() {
|
||||
if (is_singular('sp_event')) {
|
||||
wp_enqueue_script('scoreboard-js', plugins_url('/js/scoreboard.js', __FILE__), ['jquery'], null, true);
|
||||
wp_enqueue_script('scoreboard-controls-js', plugins_url('/js/scoreboard-controls.js', __FILE__), ['jquery'], null, true);
|
||||
|
||||
wp_localize_script('scoreboard-js', 'scoreboardData', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'eventId' => get_the_ID(),
|
||||
'canEdit' => current_user_can('sportspress_can_control_score'),
|
||||
'timeline' => get_post_meta(get_the_ID(), '_scoreboard_timeline', true) ?: '{}',
|
||||
'templatesUrl' => plugins_url('/html/', __FILE__)
|
||||
]);
|
||||
}
|
||||
});
|
||||
// AJAX endpoint for saving scoreboard
|
||||
add_action('wp_ajax_update_scoreboard', function() {
|
||||
if (!current_user_can('sportspress_can_control_score')) {
|
||||
wp_send_json_error('Unauthorized');
|
||||
}
|
||||
|
||||
$event_id = intval($_POST['event_id']);
|
||||
$timeline = wp_unslash($_POST['timeline']);
|
||||
update_post_meta($event_id, '_scoreboard_timeline', $timeline);
|
||||
|
||||
wp_send_json_success();
|
||||
});
|
||||
|
||||
add_shortcode('live_score', function($atts) {
|
||||
ob_start();
|
||||
?>
|
||||
<div id="live-score-widget" data-refresh="1">
|
||||
<strong>Loading live score...</strong>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
});
|
||||
|
||||
add_action('wp_ajax_nopriv_get_live_score', 'get_live_score_callback');
|
||||
add_action('wp_ajax_get_live_score', 'get_live_score_callback');
|
||||
|
||||
function get_live_score_callback() {
|
||||
$args = [
|
||||
'post_type' => 'sp_event',
|
||||
'posts_per_page' => 1,
|
||||
'meta_query' => [
|
||||
[
|
||||
'key' => 'is_live',
|
||||
'value' => '1',
|
||||
'compare' => '='
|
||||
]
|
||||
]
|
||||
];
|
||||
$live_event = get_posts($args);
|
||||
if (!$live_event) {
|
||||
wp_send_json_error('No live event');
|
||||
}
|
||||
|
||||
$event = $live_event[0];
|
||||
$timeline = get_post_meta($event->ID, '_scoreboard_timeline', true);
|
||||
$timeline_data = json_decode($timeline, true);
|
||||
|
||||
// Simplified for display: extract latest score entry
|
||||
$latest = end($timeline_data);
|
||||
|
||||
wp_send_json_success([
|
||||
'event_id' => $event->ID,
|
||||
'event_title' => get_the_title($event),
|
||||
'score' => $latest ?? ['home' => 0, 'away' => 0]
|
||||
]);
|
||||
}
|
||||
|
||||
add_action('wp_enqueue_scripts', function() {
|
||||
wp_enqueue_script('live-score-script', plugins_url('/js/live-score.js', __FILE__), ['jquery'], null, true);
|
||||
wp_localize_script('live-score-script', 'LiveScoreAjax', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
]);
|
||||
});
|
||||
// function scoreboard_add_to_event_page($content) {
|
||||
// if (get_post_type() === 'sp_event') {
|
||||
// ob_start();
|
||||
// render_scoreboard_timeline();
|
||||
// $timeline_html = ob_get_clean();
|
||||
// return $timeline_html . $content; // Prepend it
|
||||
// }
|
||||
|
||||
// return $content;
|
||||
// }
|
||||
// add_filter('the_content', 'scoreboard_add_to_event_page');
|
||||
// // Display scoreboard on match report
|
||||
// add_action('sportspress_after_event_content', 'render_scoreboard_timeline');
|
||||
// function render_scoreboard_timeline() {
|
||||
// echo '<div style="background:#f0f0f0;padding:10px;margin-bottom:10px;">Scoreboard timeline loaded.</div>';
|
||||
|
||||
// if (current_user_can('scoreboard_can_control')) {
|
||||
// echo '<div style="background:#d1ffd1;padding:10px;margin-bottom:10px;">User CAN control scoreboard.</div>';
|
||||
// //include plugin_dir_path(__FILE__) . 'templates/scoreboard-controls.php';
|
||||
// } else {
|
||||
// echo '<div style="background:#ffe5e5;padding:10px;margin-bottom:10px;">User CANNOT control scoreboard.</div>';
|
||||
// }
|
||||
|
||||
// //include plugin_dir_path(__FILE__) . 'templates/scoreboard-timeline.php';
|
||||
// }
|
||||
Loading…
Reference in New Issue
Block a user