mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-25 01:14:43 +00:00
331 lines
15 KiB
Plaintext
331 lines
15 KiB
Plaintext
<%= form_for(@match) do |f| %>
|
|
<% if @match.errors.any? %>
|
|
<div id="error_explanation">
|
|
<h2><%= pluralize(@match.errors.count, "error") %> prohibited this match from being saved:</h2>
|
|
|
|
<ul>
|
|
<% @match.errors.full_messages.each do |msg| %>
|
|
<li><%= msg %></li>
|
|
<% end %>
|
|
</ul>
|
|
</div>
|
|
<% end %>
|
|
<h4>Bout <strong><%= @match.bout_number %></strong></h4>
|
|
<h4>Bracket Position: <strong><%= @match.bracket_position %></strong></h4>
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name: <%= @wrestler1_name %> <select id="w1-color" onchange="changeW1Color(this)">
|
|
<option value="green">Green</option>
|
|
<option value="red">Red</option>
|
|
</select>
|
|
<br>School: <%= @wrestler1_school_name %>
|
|
<br>Last Match: <%= @wrestler1_last_match ? time_ago_in_words(@wrestler1_last_match.updated_at) : "N/A" %></th>
|
|
<th>Name: <%= @wrestler2_name %> <select id="w2-color" onchange="changeW2Color(this)">
|
|
<option value="red">Red</option>
|
|
<option value="green">Green</option>
|
|
</select>
|
|
<br>School: <%= @wrestler2_school_name %>
|
|
<br>Last Match: <%= @wrestler2_last_match ? time_ago_in_words(@wrestler2_last_match.updated_at) : "N/A" %></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><%= @wrestler1_name %> Stats: <br><%= f.text_area :w1_stat, cols: "30", rows: "10" %></td>
|
|
<td><%= @wrestler2_name %> Stats: <br><%= f.text_area :w2_stat, cols: "30", rows: "10" %></td>
|
|
</tr>
|
|
<tr>
|
|
<td><%= @wrestler1_name %> Scoring <br><button id="w1-takedown" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'T3')">T3</button>
|
|
<button id="w1-escape" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'E1')">E1</button>
|
|
<button id="w1-reversal" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'R2')">R2</button>
|
|
<button id="w1-nf2" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'N2')">N2 </button>
|
|
<button id="w1-nf3" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'N3')">N3</button>
|
|
<button id="w1-nf4" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'N4')">N4</button>
|
|
<button id="w1-nf5" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'N5')">N5</button>
|
|
<button id="w1-penalty" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'P1')">P1</button>
|
|
<button id="w1-penalty2" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'P2')">P2</button></td>
|
|
<td><%= @wrestler2_name %> Scoring <br><button id="w2-takedown" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'T3')">T3</button>
|
|
<button id="w2-escape" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'E1')">E1</button>
|
|
<button id="w2-reversal" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'R2')">R2</button>
|
|
<button id="w2-nf2" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'N2')">N2</button>
|
|
<button id="w2-nf3" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'N3')">N3</button>
|
|
<button id="w2-nf4" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'N4')">N4</button>
|
|
<button id="w2-nf5" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'N5')">N5</button>
|
|
<button id="w2-penalty" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'P1')">P1</button>
|
|
<button id="w2-penalty2" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'P2')">P2</button></td>
|
|
</tr>
|
|
<tr>
|
|
<td><%= @wrestler1_name %> Choice <br><button id="w1-top" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'|Chose Top|')">Chose Top</button>
|
|
<button id="w1-bottom" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'|Chose Bottom|')">Chose Bottom</button>
|
|
<button id="w1-neutral" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'|Chose Neutral|')">Chose Neutral</button>
|
|
<button id="w1-defer" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'|Deferred|')">Deferred</button></td>
|
|
<td><%= @wrestler2_name %> Choice <br><button id="w2-top" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'|Chose Top|')">Chose Top</button>
|
|
<button id="w2-bottom" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'|Chose Bottom|')">Chose Bottom</button>
|
|
<button id="w2-neutral" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'|Chose Neutral|')">Chose Neutral</button>
|
|
<button id="w2-defer" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'|Deferred|')">Deferred</button></td>
|
|
</tr>
|
|
<tr>
|
|
<td><%= @wrestler1_name %> Warnings <br><button id="w1-stalling" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'S')">Stalling</button>
|
|
<button id="w1-caution" type="button" class="btn btn-success btn-sm" onclick="updateStats(w1,'C')">Caution</button></td>
|
|
<td><%= @wrestler2_name %> Warnings <br><button id="w2-stalling" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'S')">Stalling</button>
|
|
<button id="w2-caution" type="button" class="btn btn-danger btn-sm" onclick="updateStats(w2,'C')">Caution</button></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Match Options <br><button type="button" class="btn btn-primary btn-sm" onclick="updateStats(w2,'|End Period|'); updateStats(w1,'|End Period|');">End Period</button></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<h5><%= @wrestler1_name %> Timer Controls</h5>
|
|
Injury Time (90 second max): <span id="w1-injury-time">0 sec</span>
|
|
<button type="button" onclick="startTimer(w1, 'injury')" class="btn btn-primary btn-sm">Start</button>
|
|
<button type="button" onclick="stopTimer(w1, 'injury')" class="btn btn-primary btn-sm">Stop</button>
|
|
<button type="button" onclick="resetTimer(w1, 'injury')" class="btn btn-primary btn-sm">Reset</button>
|
|
<br><br>
|
|
Blood Time (600 second max): <span id="w1-blood-time">0 sec</span>
|
|
<button type="button" onclick="startTimer(w1, 'blood')" class="btn btn-primary btn-sm">Start</button>
|
|
<button type="button" onclick="stopTimer(w1, 'blood')" class="btn btn-primary btn-sm">Stop</button>
|
|
<button type="button" onclick="resetTimer(w1, 'blood')" class="btn btn-primary btn-sm">Reset</button>
|
|
</td>
|
|
<td>
|
|
<h5><%= @wrestler2_name %> Timer Controls</h5>
|
|
Injury Time (90 second max): <span id="w2-injury-time">0 sec</span>
|
|
<button type="button" onclick="startTimer(w2, 'injury')" class="btn btn-primary btn-sm">Start</button>
|
|
<button type="button" onclick="stopTimer(w2, 'injury')" class="btn btn-primary btn-sm">Stop</button>
|
|
<button type="button" onclick="resetTimer(w2, 'injury')" class="btn btn-primary btn-sm">Reset</button>
|
|
<br><br>
|
|
Blood Time (600 second max): <span id="w2-blood-time">0 sec</span>
|
|
<button type="button" onclick="startTimer(w2, 'blood')" class="btn btn-primary btn-sm">Start</button>
|
|
<button type="button" onclick="stopTimer(w2, 'blood')" class="btn btn-primary btn-sm">Stop</button>
|
|
<button type="button" onclick="resetTimer(w2, 'blood')" class="btn btn-primary btn-sm">Reset</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<br>
|
|
<br>
|
|
<br>
|
|
<h4>Match Results</h4>
|
|
<br>
|
|
<div class="field">
|
|
<%= f.label "Win Type" %><br>
|
|
<%= f.select(:win_type, Match::WIN_TYPES) %>
|
|
</div>
|
|
<br>
|
|
<div class="field">
|
|
<%= f.label "Overtime Type" %> Leave blank if not overtime. For High School the 1st overtime is SV-1, second overtime is TB-1, third overtime is UTB.<br>
|
|
<%= f.select(:overtime_type, Match::OVERTIME_TYPES) %>
|
|
</div>
|
|
<br>
|
|
<div class="field">
|
|
<%= f.label "Winner" %> Please choose the winner<br>
|
|
<%= f.collection_select :winner_id, @wrestlers, :id, :name_with_school, include_blank: true %>
|
|
</div>
|
|
<br>
|
|
<% if @match.finished && @match.finished == 1 %>
|
|
<div class="field">
|
|
<%= f.label "Final Score" %> For decision, major, or tech fall put the score here in Number-Number format. If pin, put the accumulated pin time in the format MM:SS. If default, injury default, dq, bye, or forfeit, leave blank. Examples: 7-2, 17-2, 0:30, or 2:34.<br>
|
|
<%= f.text_field :score %>
|
|
</div>
|
|
<% else %>
|
|
<div class="field">
|
|
<%= f.label "Final Score" %>
|
|
<br>
|
|
<span id="score-help-text">
|
|
The input will adjust based on the selected win type.
|
|
</span>
|
|
<br>
|
|
<div id="dynamic-score-input"></div>
|
|
<p id="pin-time-tip" class="text-muted mt-2" style="display: none;">
|
|
<strong>Tip:</strong> Pin time is an accumulation over the match, not how much time was left in the current period.
|
|
<br>For example, if all 3 periods are 2 minutes and a pin happened with 1:27 left in the second period,
|
|
the pin time would be <strong>2:33</strong> (2 minutes for the first period + 33 seconds elapsed in the second period).
|
|
</p>
|
|
<div id="validation-alerts" class="text-danger mt-2"></div>
|
|
<%= f.hidden_field :score, id: "final-score-field" %>
|
|
</div>
|
|
<%= render 'matches/matchstats_variable_score_input' %>
|
|
<% end %>
|
|
<br>
|
|
|
|
<%= f.hidden_field :finished, :value => 1 %>
|
|
<%= f.hidden_field :round, :value => @match.round %>
|
|
|
|
<br>
|
|
|
|
<div class="actions">
|
|
<%= f.submit "Update Match", id: "update-match-btn", onclick: "return confirm('Is the name of the winner ' + document.getElementById('match_winner_id').options[document.getElementById('match_winner_id').selectedIndex].text + '?')", class: "btn btn-success" %>
|
|
</div>
|
|
|
|
<% end %>
|
|
|
|
<%= render 'matches/matchstats_color_change' %>
|
|
|
|
<script>
|
|
// Get variables
|
|
var tournament = <%= @match.tournament.id %>;
|
|
var bout = <%= @match.bout_number %>;
|
|
var match_finsihed = "<%= @match.finished %>";
|
|
|
|
// ############### STATS
|
|
// Create person object
|
|
function Person(stats, name) {
|
|
this.name = name;
|
|
this.stats = stats;
|
|
this.updated_at = null; // Track last updated timestamp
|
|
this.timers = {
|
|
"injury": { time: 0, startTime: null, interval: null },
|
|
"blood": { time: 0, startTime: null, interval: null },
|
|
};
|
|
}
|
|
|
|
// Declare variables
|
|
var w1 = new Person("", "w1");
|
|
var w2 = new Person("", "w2");
|
|
updateJsValues();
|
|
|
|
// Generate unique localStorage key
|
|
function generateKey(wrestler_name) {
|
|
return `${wrestler_name}-${tournament}-${bout}`;
|
|
}
|
|
|
|
// Load values from localStorage
|
|
function loadFromLocalStorage(wrestler_name) {
|
|
const key = generateKey(wrestler_name);
|
|
const data = localStorage.getItem(key);
|
|
return data ? JSON.parse(data) : null;
|
|
}
|
|
|
|
// Save values to localStorage
|
|
function saveToLocalStorage(person) {
|
|
const key = generateKey(person.name);
|
|
const data = {
|
|
stats: person.stats,
|
|
updated_at: person.updated_at,
|
|
timers: person.timers, // Save all timers
|
|
};
|
|
localStorage.setItem(key, JSON.stringify(data));
|
|
}
|
|
|
|
// Update HTML values
|
|
function updateHtmlValues() {
|
|
document.getElementById("match_w1_stat").value = w1.stats;
|
|
document.getElementById("match_w2_stat").value = w2.stats;
|
|
}
|
|
|
|
// Update JS object values from HTML
|
|
function updateJsValues() {
|
|
w1.stats = document.getElementById("match_w1_stat").value;
|
|
w2.stats = document.getElementById("match_w2_stat").value;
|
|
}
|
|
|
|
// Update stats and persist to localStorage
|
|
function updateStats(wrestler, text) {
|
|
updateJsValues();
|
|
wrestler.stats += text + " ";
|
|
wrestler.updated_at = new Date().toISOString(); // Update timestamp
|
|
updateHtmlValues();
|
|
|
|
// Save to localStorage
|
|
if (wrestler === w1) {
|
|
saveToLocalStorage(w1);
|
|
} else if (wrestler === w2) {
|
|
saveToLocalStorage(w2);
|
|
}
|
|
}
|
|
|
|
// Initialize data on page load
|
|
function initializeTimers(wrestler) {
|
|
// Iterate over each timer in the wrestler object
|
|
Object.keys(wrestler.timers).forEach((timerKey) => {
|
|
const savedData = loadFromLocalStorage(wrestler.name);
|
|
if (savedData && savedData.timers && savedData.timers[timerKey]) {
|
|
wrestler.timers[timerKey].time = savedData.timers[timerKey].time || 0;
|
|
updateTimerDisplay(wrestler, timerKey, wrestler.timers[timerKey].time);
|
|
}
|
|
});
|
|
}
|
|
|
|
function initialize() {
|
|
const localW1 = loadFromLocalStorage("w1");
|
|
const localW2 = loadFromLocalStorage("w2");
|
|
|
|
if (localW1) {
|
|
w1.stats = localW1.stats || "";
|
|
w1.updated_at = localW1.updated_at || null;
|
|
w1.timers = localW1.timers || w1.timers; // Load timer data
|
|
// set localStorage values to html
|
|
updateHtmlValues();
|
|
}
|
|
if (localW2) {
|
|
w2.stats = localW2.stats || "";
|
|
w2.updated_at = localW2.updated_at || null;
|
|
w2.timers = localW2.timers || w2.timers; // Load timer data
|
|
// set localStorage values to html
|
|
updateHtmlValues();
|
|
}
|
|
|
|
initializeTimers(w1);
|
|
initializeTimers(w2);
|
|
updateJsValues()
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
initialize();
|
|
});
|
|
|
|
// ############### Blood and Injury time timers
|
|
// Timer storage and interval references
|
|
// Start a timer for a wrestler
|
|
function startTimer(wrestler, timerKey) {
|
|
const timer = wrestler.timers[timerKey];
|
|
if (timer.interval) return; // Prevent multiple intervals
|
|
timer.startTime = Date.now(); // Record the start time
|
|
timer.interval = setInterval(() => {
|
|
const elapsedSeconds = Math.floor((Date.now() - timer.startTime) / 1000);
|
|
updateTimerDisplay(wrestler, timerKey, timer.time + elapsedSeconds); // Show total time
|
|
}, 1000);
|
|
}
|
|
|
|
// Stop a timer for a wrestler
|
|
function stopTimer(wrestler, timerKey) {
|
|
const timer = wrestler.timers[timerKey];
|
|
if (!timer.interval || !timer.startTime) return; // Timer not running
|
|
clearInterval(timer.interval);
|
|
|
|
const elapsedSeconds = Math.floor((Date.now() - timer.startTime) / 1000); // Calculate elapsed time
|
|
timer.time += elapsedSeconds; // Add elapsed time to total
|
|
timer.interval = null;
|
|
timer.startTime = null;
|
|
|
|
saveToLocalStorage(wrestler); // Save wrestler data
|
|
updateTimerDisplay(wrestler, timerKey, timer.time); // Update final display
|
|
updateStatsBox(wrestler, timerKey, elapsedSeconds); // Update wrestler stats
|
|
}
|
|
|
|
// Reset a timer for a wrestler
|
|
function resetTimer(wrestler, timerKey) {
|
|
const timer = wrestler.timers[timerKey];
|
|
stopTimer(wrestler, timerKey); // Stop if running
|
|
timer.time = 0; // Reset time
|
|
updateTimerDisplay(wrestler, timerKey, 0); // Update display
|
|
saveToLocalStorage(wrestler); // Save wrestler data
|
|
}
|
|
|
|
// Update the timer display
|
|
function updateTimerDisplay(wrestler, timerKey, totalTime) {
|
|
const elementId = `${wrestler.name}-${timerKey}-time`; // Construct element ID
|
|
const element = document.getElementById(elementId);
|
|
if (element) {
|
|
element.innerText = `${Math.floor(totalTime / 60)}m ${totalTime % 60}s`;
|
|
}
|
|
}
|
|
|
|
// Update wrestler stats box with elapsed timer information
|
|
function updateStatsBox(wrestler, timerKey, elapsedSeconds) {
|
|
const timerType = timerKey.includes("injury") ? "Injury Time" : "Blood Time";
|
|
const formattedTime = `${Math.floor(elapsedSeconds / 60)}m ${elapsedSeconds % 60}s`;
|
|
updateStats(wrestler, `${timerType}: ${formattedTime}`);
|
|
}
|
|
</script>
|