Transaction

2dcf8dd26f2a2208af9ed0612798617e1f6f4687eaa0ca3d38d9f05ac71b0c76
2024-10-29 06:59:04
0.00022123 BSV
(
0.02700128 BSV
-
0.02678005 BSV
)
499.6 sat/KB
1
42,150
44,268 B

2 Outputs

Total Output:
0.02678005 BSV
  • jM¬<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="chrome-extension://lbjapbcmmceacocpimbpbidpgmlmoaao/content.js"></script> <title>Golf Scorecard with Signatures</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 5; display: flex; justify-content: center; background-color: #f4f4f4; height: 100vh; overflow-y: auto; } /* Ensure .framed-page is responsive and allows flexbox to work */ .framed-page { width: 100%; /* Ensure it is responsive */ max-width: 1200px; padding: 20px; border: 3px solid #2a9d8f; border-radius: 10px; background-color: #fff; box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2); margin: 20px 0; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; height: 300px; /* Allow height to adjust based on content */ /*overflow-x: visible; /* Ensure no hidden overflow */ } /* Ensure scrolling behavior for smaller screens */ @media (max-width: 768px) { .scoring-array { flex-wrap: nowrap; /* Prevent wrapping on smaller screens */ overflow-x: auto; /* Ensure horizontal scrolling */ padding: 0 10px; /* Ensure padding on mobile */ } .scoring-array input { flex: 0 0 50px; /* Fixed width for input fields on smaller screens */ } } /* Scoreboard section below the scorecard */ #scoreboardSection { margin-top: 20px; /* Space between scorecard and scoreboard */ padding: 20px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); } /* Table styling for both the scorecard and scoreboard */ table { width: 100%; border-collapse: collapse; margin-bottom: 20px; } th, td { padding: 1px; text-align: center; border: 1px solid #ccc; } th { background-color: #005f5f; color: white; } td { background-color: #f4f4f4; } /* Input fields inside scorecard */ input[type="text"], input[type="date"] { width: 15%; padding: 12px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 8px; } input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } /* Remove arrows from number inputs in Firefox */ input[type="number"] { -moz-appearance: textfield; } /* Set the width of the number input */ input[type="number"] { width: 25px; /* Adjust width as needed */ } /* Hide the difficulty row if needed */ #difficultyRow { display: none; } /* Styling for the scoreboard table */ #leaderboardTable { width: 100%; border-collapse: collapse; margin-top: 10px; } #leaderboardTable th, #leaderboardTable td { padding: 8px; text-align: center; border-bottom: 1px solid #ddd; } #leaderboardTable th { background-color: #005f5f; color: white; } #scoreboardSection { display: none; /* Initially hidden */ margin-top: 20px; padding: 15px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); } .action-bar { display: flex; align-items: center; /* Vertically aligns elements */ gap: 10px; /* Space between elements */ } button { padding: 5px 10px; /* Adjust the padding to make the buttons smaller */ } label, select { margin-left: 10px; /* Add space between the label/select and buttons */ } select { padding: 5px; /* Adjust padding to reduce size */ } </style> </head> <body> <div class="framed-page"> <header> <div style="display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; width: 100%;"> <header> <div style="display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; width: 100%;"> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="playerName" placeholder="Player Name" style="width: 100%;"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="memberNum" placeholder="Member Num" maxlength="7" style="width: 100%;"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="competitionInput" value="TOUR" placeholder="Competition" style="width: 100%; max-width: 100px; text-align: left; box-sizing: border-box;"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="number" id="handicap" placeholder="Handicap" style="width: 100%;" value="0"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="countryCode" placeholder="Country Code (e.g., 064)" style="width: 100%;"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="clubCode" placeholder="Club Code (e.g., 271)" style="width: 100%;"> </div> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="teeInput" placeholder="Tee Type (e.g., whitetee)" style="width: 100%;"> </div> <!-- New Team Input Field --> <div style="flex: 1; margin-right: 10px;"> <input type="text" id="teamInput" placeholder="Team Name" style="width: 100%;"> </div> </div> </header> </div> </header> <table> <thead> <tr> <th>Hole</th> <!-- Hole numbers --> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> <th>7</th> <th>8</th> <th>9</th> <th>ST</th> <th>10</th> <th>11</th> <th>12</th> <th>13</th> <th>14</th> <th>15</th> <th>16</th> <th>17</th> <th>18</th> <th>ST</th> </tr> </thead> <tbody> <tr id="difficultyRow"> <th>Stroke</th> <!-- Stroke values (empty for now) --> <td id="diff1"></td> <td id="diff2"></td> <td id="diff3"></td> <td id="diff4"></td> <td id="diff5"></td> <td id="diff6"></td> <td id="diff7"></td> <td id="diff8"></td> <td id="diff9"></td> <td></td> <td id="diff10"></td> <td id="diff11"></td> <td id="diff12"></td> <td id="diff13"></td> <td id="diff14"></td> <td id="diff15"></td> <td id="diff16"></td> <td id="diff17"></td> <td id="diff18"></td> <td></td> </tr> <!-- Row for Par values --> <tr id="parRow"> <th>Par</th> <td id="par1"></td> <td id="par2"></td> <td id="par3"></td> <td id="par4"></td> <td id="par5"></td> <td id="par6"></td> <td id="par7"></td> <td id="par8"></td> <td id="par9"></td> <td></td> <td id="par10"></td> <td id="par11"></td> <td id="par12"></td> <td id="par13"></td> <td id="par14"></td> <td id="par15"></td> <td id="par16"></td> <td id="par17"></td> <td id="par18"></td> <td></td> </tr> <!-- Row for Scores input --> <tr class="input-row"> <th>Score</th> <td><input type="number" id="hole1" oninput="calculateTotals()"></td> <td><input type="number" id="hole2" oninput="calculateTotals()"></td> <td><input type="number" id="hole3" oninput="calculateTotals()"></td> <td><input type="number" id="hole4" oninput="calculateTotals()"></td> <td><input type="number" id="hole5" oninput="calculateTotals()"></td> <td><input type="number" id="hole6" oninput="calculateTotals()"></td> <td><input type="number" id="hole7" oninput="calculateTotals()"></td> <td><input type="number" id="hole8" oninput="calculateTotals()"></td> <td><input type="number" id="hole9" oninput="calculateTotals()"></td> <td><input type="number" id="st1" readonly></td> <td><input type="number" id="hole10" oninput="calculateTotals()"></td> <td><input type="number" id="hole11" oninput="calculateTotals()"></td> <td><input type="number" id="hole12" oninput="calculateTotals()"></td> <td><input type="number" id="hole13" oninput="calculateTotals()"></td> <td><input type="number" id="hole14" oninput="calculateTotals()"></td> <td><input type="number" id="hole15" oninput="calculateTotals()"></td> <td><input type="number" id="hole16" oninput="calculateTotals()"></td> <td><input type="number" id="hole17" oninput="calculateTotals()"></td> <td><input type="number" id="hole18" oninput="calculateTotals()"></td> <td><input type="number" id="st2" readonly></td> </tr> <!-- Row for Stableford scores --> <tr> <th>Sford</th> <td><input type="number" id="sford1" readonly></td> <td><input type="number" id="sford2" readonly></td> <td><input type="number" id="sford3" readonly></td> <td><input type="number" id="sford4" readonly></td> <td><input type="number" id="sford5" readonly></td> <td><input type="number" id="sford6" readonly></td> <td><input type="number" id="sford7" readonly></td> <td><input type="number" id="sford8" readonly></td> <td><input type="number" id="sford9" readonly></td> <td><input type="number" id="sf1" readonly></td> <td><input type="number" id="sford10" readonly></td> <td><input type="number" id="sford11" readonly></td> <td><input type="number" id="sford12" readonly></td> <td><input type="number" id="sford13" readonly></td> <td><input type="number" id="sford14" readonly></td> <td><input type="number" id="sford15" readonly></td> <td><input type="number" id="sford16" readonly></td> <td><input type="number" id="sford17" readonly></td> <td><input type="number" id="sford18" readonly></td> <td><input type="number" id="sf2" readonly></td> </tr> </tbody> </table> <!-- Totals and Buttons Section --> <div style="display: flex; justify-content: space-between; align-items: center; width: 100%; margin-bottom: 20px;"> <div>Gross: <span id="gross">0</span></div> <div>Nett: <span id="net">0</span></div> <div>Stableford: <span id="stablefordTotal">0</span></div> <button id="startGameButton">Start Game</button> <button id="saveButton">Save</button> <button id="loadButton">Load</button><input type="file" id="fileInput" style="display: none;"> <button id="clearButton">Clear</button> <button id="updateButton">Update</button> <button id="scoreboardButton">Scoreboard</button> </div> <!-- Add the text area for both sending and displaying messages --> <div style="width: 100%; margin-bottom: 20px;"> <textarea id="messageTextArea" rows="3" style="width: 100%;" placeholder="Enter your message here..."></textarea> </div> <div class="action-bar"> <button id="sendToAllButton">Send to All</button> <button id="sendToRecipientButton" disabled>Send to Selected Recipient</button> <label for="recipientSelect">Recipient:</label> <select id="recipientSelect" disabled> <option value="">--No recipient selected--</option> <!-- The selected recipient will be dynamically populated here --> </select> <button id="getMessageButton">Get Message</button> </div> <!-- Scoreboard Section --> <div id="scoreboardSection"> <h2>Scoreboard</h2> <table id="leaderboardTable" style="width: 100%;"> <thead> <tr> <th>Player</th> <th>Handicap</th> <th id="sortByGross">Gross</th> <!-- ID for Gross --> <th id="sortByNett">Nett</th> <!-- ID for Nett --> <th id="sortBySford">Stableford</th> <!-- ID for Stableford --> <th>Action</th> </tr> </thead> <tbody id="leaderboardBody"> <!-- Player rows will be dynamically inserted here --> </tbody> </table> </div> <script> // Function to update the scorecard with fetched par, stroke, and distance data function updateScorecard(parArray, strokeArray, distanceArray) { // Update the par, stroke, and distance rows in the table for (let i = 1; i <= 18; i++) { document.getElementById(`par${i}`).innerText = parArray[i - 1]; document.getElementById(`diff${i}`).innerText = strokeArray[i - 1]; // You can update distance if required on the UI } } // Function to reset the array based on fetched data and display intermediate arrays function resetArray(handicap) { const parArray = JSON.parse(sessionStorage.getItem('ParArray')) || []; const strokeArray = JSON.parse(sessionStorage.getItem('StrokeArray')) || []; const distanceArray = JSON.parse(sessionStorage.getItem('DistanceArray')) || []; const resetArray = Array(18).fill(0); const PParArray = []; const Hdp1 = Array(18).fill(0); const Hdp2 = Array(18).fill(0); const Hdp3 = Array(18).fill(0); // Reorder based on difficulty const reorderedHoles = parArray.map((par, index) => ({ holeNumber: index + 1, difficulty: strokeArray[index], par: par, distance: distanceArray[index] })).sort((a, b) => a.difficulty - b.difficulty); // Apply positive or negative handicap distribution logic if (handicap < 0) { let numNegativeStrokes = Math.min(-handicap, 6); reorderedHoles.forEach((hole, index) => { if (index < 18 - numNegativeStrokes) { PParArray.push(hole.par); } else { PParArray.push(hole.par - 1); } }); } else { for (let i = 0; i < handicap; i++) { if (i < 18) Hdp1[i % 18]++; else if (i < 36) Hdp2[i % 18]++; else Hdp3[i % 18]++; } reorderedHoles.forEach((hole, index) => { PParArray.push(hole.par + Hdp1[index] + Hdp2[index] + Hdp3[index]); }); } strokeArray.forEach((difficulty, index) => { resetArray[index] = PParArray[difficulty - 1]; }); sessionStorage.setItem('ResetArray', JSON.stringify(resetArray)); return resetArray; } // Function to calculate and display gross, nett, and stableford totals along with subtotals function calculateTotals() { const resetArray = JSON.parse(sessionStorage.getItem('ResetArray')) || []; const parArray = JSON.parse(sessionStorage.getItem('ParArray')) || []; // Use fetched ParArray from session let totalGross = 0, totalNett = 0, totalStableford = 0; let front9Gross = 0, back9Gross = 0; let front9Nett = 0, back9Nett = 0; let front9Stableford = 0, back9Stableford = 0; for (let i = 1; i <= 18; i++) { const grossScore = parseInt(document.getElementById(`hole${i}`).value) || 0; totalGross += grossScore; const personalPar = resetArray[i - 1]; // Adjusted personal par (Reset Par) const coursePar = parArray[i - 1]; // Standard par fetched from JSON // Nett score logic: Nett = Gross - (Reset Par - Course Par) const nettScore = grossScore - (personalPar - coursePar); totalNett += nettScore; // Stableford logic: Only calculate if gross score is entered const stablefordScore = grossScore > 0 ? Math.max(personalPar - grossScore + 2, 0) : 0; document.getElementById(`sford${i}`).value = stablefordScore; totalStableford += stablefordScore; // Subtotals for front 9 (holes 1-9) and back 9 (holes 10-18) if (i <= 9) { front9Gross += grossScore; front9Nett += nettScore; front9Stableford += stablefordScore; } else { back9Gross += grossScore; back9Nett += nettScore; back9Stableford += stablefordScore; } } // Log calculated totals console.log('Total Gross:', totalGross); console.log('Total Nett:', totalNett); console.log('Total Stableford:', totalStableford); // Save totals in session storage sessionStorage.setItem('totalGross', totalGross); sessionStorage.setItem('totalNett', totalNett); sessionStorage.setItem('totalStableford', totalStableford); // Update total values in the UI document.getElementById('gross').innerText = totalGross; document.getElementById('net').innerText = totalNett; document.getElementById('stablefordTotal').innerText = totalStableford; // Update subtotals for front 9 and back 9 document.getElementById('st1').value = front9Gross; document.getElementById('sf1').value = front9Stableford; document.getElementById('st2').value = back9Gross; document.getElementById('sf2').value = back9Stableford; // Log subtotals for front 9 and back 9 console.log('Front 9 Gross:', front9Gross); console.log('Back 9 Gross:', back9Gross); } // Function to save the scorecard data to a JSON file function saveCollectedData(data) { const dataStr = JSON.stringify(data, null, 2); // Format the JSON data with indentation const dataBlob = new Blob([dataStr], { type: 'application/json' }); const url = window.URL.createObjectURL(dataBlob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = `${data.playerName}_scorecard.json`; // File name based on player name document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); } // Function to save the collected data as a JSON file function saveCollectedData(data) { // Convert the scoreData object to JSON const scoreDataJson = JSON.stringify(data, null, 2); // Create a blob object for the data const blob = new Blob([scoreDataJson], { type: 'application/json' }); // Clean up the player's name for the filename (remove spaces and special characters) const cleanPlayerName = data.playerName.replace(/[^a-zA-Z0-9]/g, '_'); const fileName = `${cleanPlayerName}_${data.date}.json`; // Create a link element to trigger the download const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = fileName; // The file name for the download based on name and date // Trigger the download by clicking the link a.click(); } // Function to populate the form with loaded data Done function populateFormWithData(data) { // Populate header information document.getElementById('playerName').value = data.playerName || ''; document.getElementById('memberNum').value = data.memberNum || ''; document.getElementById('competitionInput').value = data.competition || ''; // Add competition input document.getElementById('handicap').value = data.handicap || ''; document.getElementById('countryCode').value = data.countryCode || ''; document.getElementById('clubCode').value = data.clubCode || ''; document.getElementById('teeInput').value = data.teeType || ''; document.getElementById('gameDate').value = data.date || ''; // Populate scores for (let i = 1; i <= 18; i++) { document.getElementById(`hole${i}`).value = data.scores[i - 1] || ''; } // Populate Gross, Nett, and Stableford totals document.getElementById('gross').innerText = data.totalGross || 0; document.getElementById('net').innerText = data.totalNett || 0; document.getElementById('stablefordTotal').innerText = data.totalStableford || 0; // Store loaded data in sessionStorage for further use sessionStorage.setItem('playerName', data.playerName); sessionStorage.setItem('memberNum', data.memberNum); sessionStorage.setItem('competition', data.competition); // Store competition input sessionStorage.setItem('handicap', data.handicap); sessionStorage.setItem('countryCode', data.countryCode); sessionStorage.setItem('clubCode', data.clubCode); sessionStorage.setItem('teeType', data.teeType); sessionStorage.setItem('gameDate', data.date); sessionStorage.setItem('scores', JSON.stringify(data.scores)); // Save totals in sessionStorage sessionStorage.setItem('totalGross', data.totalGross || 0); sessionStorage.setItem('totalNett', data.totalNett || 0); sessionStorage.setItem('totalStableford', data.totalStableford || 0); } // Add the event listener for the "Scoreboard" button document.getElementById('scoreboardButton').addEventListener('click', function() { const scoreboardSection = document.getElementById('scoreboardSection'); // Toggle the display of the scoreboard section if (scoreboardSection.style.display === 'none' || scoreboardSection.style.display === '') { scoreboardSection.style.display = 'block'; // Show the scoreboard fetchPlayerTotals(); // Fetch and display the player data } else { scoreboardSection.style.display = 'none'; // Hide the scoreboard } }); // Add event listeners to the column headers for sorting document.getElementById('sortByGross').addEventListener('click', sortByGross); document.getElementById('sortByNett').addEventListener('click', sortByNett); document.getElementById('sortBySford').addEventListener('click', sortBySford); // Declare global variable to store player data let playersData = []; // Function to fetch player totals and store in playersData, then display leaderboard function fetchPlayerTotals() { fetch('https://bsvgolf.com/fetch-totals') // Replace this URL with your actual API endpoint .then(response => response.json()) .then(playerTotals => { if (playerTotals && playerTotals.length) { playersData = playerTotals; // Assign the fetched data to playersData displayLeaderboard(playersData); // Display the leaderboard with totals } else { console.error('No player data received.'); } }) .catch(error => { console.error('Error fetching player totals:', error); }); } // Function to handle selecting a recipient from the scoreboard function selectRecipient(playerID, playerName) { // Set the recipient dropdown to show the selected player const recipientSelect = document.getElementById('recipientSelect'); recipientSelect.innerHTML = `<option value="${playerID}">${playerName}</option>`; // Dynamically populate the dropdown recipientSelect.disabled = false; // Enable the dropdown to show selection document.getElementById('sendToRecipientButton').disabled = false; // Enable the "Send to Selected Recipient" button } // Example of the scoreboard HTML structure (Make sure you populate the buttons with this function) function displayLeaderboard(players) { let html = ''; players.forEach(player => { html += `<tr> <td>${player.playerName}</td> <td>${player.handicap}</td> <td>${player.totalGross}</td> <td>${player.totalNett}</td> <td>${player.totalStableford}</td> <td> <button onclick="selectRecipient(${player.playerID}, '${player.playerName}')">Send To</button> </td> </tr>`; }); document.getElementById('leaderboardBody').innerHTML = html; } // Sorting by Gross function sortByGross() { if (playersData && Array.isArray(playersData)) { playersData.sort((a, b) => a.totalGross - b.totalGross); displayLeaderboard(playersData); // Re-populate the table after sorting } else { console.error('playersData is not available for sorting.'); } } // Sorting by Nett function sortByNett() { if (playersData && Array.isArray(playersData)) { playersData.sort((a, b) => a.totalNett - b.totalNett); displayLeaderboard(playersData); // Re-populate the table after sorting } else { console.error('playersData is not available for sorting.'); } } // Sorting by Stableford in descending order (highest to lowest) function sortBySford() { if (playersData && Array.isArray(playersData)) { playersData.sort((a, b) => b.totalStableford - a.totalStableford); // Sort in descending order displayLeaderboard(playersData); // Re-populate the table after sorting } else { console.error('playersData is not available for sorting.'); } } // Function to send a message to the server (memory) and save to the directory (file storage) function sendMessageToServer(message, recipient = 'all', countryCode = '064', clubCode = '271') { // First, send the message to in-memory storage (send-message endpoint) fetch('https://bsvgolf.com/send-message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: message, recipient: recipient }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { console.log('Message sent to memory successfully:', data); // After sending the message to memory, save the message to the directory return fetch('https://bsvgolf.com/save-to-dir', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: message, recipient: recipient, countryCode: countryCode, // Pass countryCode for directory structure clubCode: clubCode // Pass clubCode for directory structure }) }); }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { console.log('Message saved to directory successfully:', data); // Clear the textarea only after the message is successfully sent to both const messageTextArea = document.getElementById('messageTextArea'); if (messageTextArea) { messageTextArea.value = ''; // Clear the textarea after successful send } }) .catch(error => { console.error('Error sending or saving message:', error); }); } // Function to handle recipient selection and enable/disable the send button function handleRecipientSelection() { const recipientSelect = document.getElementById('recipientSelect'); const sendToRecipientButton = document.getElementById('sendToRecipientButton'); // Enable the "Send to Selected Recipient" button if a recipient is selected if (recipientSelect.value !== '') { sendToRecipientButton.disabled = false; } else { sendToRecipientButton.disabled = true; } } // Function to fetch and display the latest message from the server in the text area function receiveMessagesFromServer() { fetch('https://bsvgolf.com/receive-message') .then(response => response.json()) .then(data => { const messageTextArea = document.getElementById('messageTextArea'); if (messageTextArea && data.text) { // Only update if data.text is non-empty messageTextArea.value = data.text; // Update the text area with the received message console.log('Updated message text area with:', data.text); } else { console.log('No new message received'); } }) .catch(error => { console.error('Error receiving message:', error); }); } // Function to fetch and display the latest message from the server in the text area function receiveMessagesFromServer() { fetch('https://bsvgolf.com/receive-message') .then(response => response.json()) .then(data => { const messageTextArea = document.getElementById('messageTextArea'); if (messageTextArea && data.text) { // Only update if data.text is non-empty messageTextArea.value = data.text; // Update the text area with the received message console.log('Updated message text area with:', data.text); } else { console.log('No new message received'); } }) .catch(error => { console.error('Error receiving message:', error); }); } // Add the event listener for the "Get Message" button document.getElementById('getMessageButton').addEventListener('click', function() { receiveMessagesFromServer(); // Manually fetch messages when the button is clicked }); // The DOMContentLoaded event listener document.addEventListener('DOMContentLoaded', function() { // Poll every 60 seconds for new messages setInterval(receiveMessagesFromServer, 60000); const sendToAllButton = document.getElementById('sendToAllButton'); const sendToRecipientButton = document.getElementById('sendToRecipientButton'); const messageTextArea = document.getElementById('messageTextArea'); const recipientSelect = document.getElementById('recipientSelect'); // Send to "All" when the "Send to All" button is clicked sendToAllButton.addEventListener('click', () => { const message = messageTextArea.value; if (message.trim()) { sendMessageToServer(message); // Send to all (default recipient = 'all') messageTextArea.value = ''; // Clear the text area after sending } else { alert("Please enter a message."); } }); document.getElementById('sendToRecipientButton').addEventListener('click', () => { const message = messageTextArea.value; const recipient = recipientSelect.value; if (message.trim() && recipient) { sendMessageToServer(message, recipient); // Send to the selected recipient messageTextArea.value = ''; // Clear the text area after sending } else { alert("Please enter a message and select a recipient."); } }); document.getElementById('startGameButton').addEventListener('click', function() { // Get user inputs const countryCode = document.getElementById('countryCode').value.trim(); const courseCode = document.getElementById('clubCode').value.trim(); const teeType = document.getElementById('teeInput').value.trim(); // Input validation if (!countryCode || !courseCode || !teeType) { alert('Please provide valid inputs for Country Code, Club Code, and Tee Type.'); return; // Stop the function if inputs are invalid } // Construct the URL and add .json to tee type const teeUrl = `https://bsvgolf.com/${countryCode}/${courseCode}/${teeType}.json`; // Check if the .json file exists by sending a HEAD request fetch(teeUrl, { method: 'HEAD' }) .then(response => { if (!response.ok) { throw new Error(`Tee file does not exist: ${teeType}.json`); } // Proceed with fetching the data if the file exists return fetch(teeUrl); }) .then(response => { if (!response.ok) { throw new Error(`Unable to fetch tee data. Status: ${response.status}`); } return response.json(); }) .then(data => { const parArray = data.Par; // Fetch the par values from the JSON const strokeArray = data.Difficulty; // Fetch the difficulty values from the JSON const distanceArray = data.Distance; // Fetch the distance values from the JSON // Store fetched data in session for further calculations sessionStorage.setItem('ParArray', JSON.stringify(parArray)); sessionStorage.setItem('StrokeArray', JSON.stringify(strokeArray)); sessionStorage.setItem('DistanceArray', JSON.stringify(distanceArray)); // Update the scorecard with the fetched data updateScorecard(parArray, strokeArray, distanceArray); // Call resetArray function to calculate intermediate arrays resetArray(parseInt(document.getElementById('handicap').value)); }) .catch(error => { console.error('Error:', error); alert(`Error fetching tee data: ${error.message}`); }); }); // Handle file input change (when a file is selected) document.getElementById('fileInput').addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { const fileContent = e.target.result; const loadedData = JSON.parse(fileContent); populateFormWithData(loadedData); // Populate the form with the loaded data }; reader.readAsText(file); } }); // Function to update player scores function updatePlayerScores() { // Gather the necessary data from session storage const playerName = sessionStorage.getItem('playerName') || 'Unknown_Player'; const playerNumber = sessionStorage.getItem('playerNumber') || ''; // Retrieve player number const memberNum = sessionStorage.getItem('memberNum') || ''; const handicap = sessionStorage.getItem('handicap') || ''; const countryCode = sessionStorage.getItem('countryCode') || ''; const clubCode = sessionStorage.getItem('clubCode') || ''; const teeType = sessionStorage.getItem('teeType') || ''; const competition = sessionStorage.getItem('competition') || 'Unknown_Competition'; // Include competition const teamName = document.getElementById('teamInput').value || 'No Team'; // New team field const tournamentType = "Stroke Play"; // System-generated Tournament Type (you can update this logic as needed) const gameDate = new Date().toISOString().split('T')[0]; // System-generated current date const scores = JSON.parse(sessionStorage.getItem('scores')) || []; // Read totals from session storage const totalGross = sessionStorage.getItem('totalGross') || 0; const totalNett = sessionStorage.getItem('totalNett') || 0; const totalStableford = sessionStorage.getItem('totalStableford') || 0; // Create a data object to send, now including Tournament Type and Team const scoreData = { playerName, playerNumber, // Include player number memberNum, competition, // Include competition in the data object handicap, countryCode, clubCode, teeType, tournamentType, // Include the system-generated Tournament Type teamName, // Include the Team Name date: gameDate, // System-generated current date scores, totalGross, totalNett, totalStableford }; // Send the data to the server fetch('https://bsvgolf.com/update', { // Replace with your domain name and endpoint method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(scoreData) }) .then(response => { if (response.ok) { console.log('Player score updated successfully!'); } else { console.error('Failed to update the score. Please try again.'); } }) .catch(error => { console.error('Error updating the score:', error); }); } // Add the event listener for the "Update" button document.getElementById('updateButton').addEventListener('click', function() { updatePlayerScores(); // Call the function when the button is clicked }); // Automatically update every 15 minutes (900,000 milliseconds) setInterval(function() { updatePlayerScores(); // Call the function every 15 minutes }, 900000); // 900000 milliseconds = 15 minutes // Save scores, stablefords, and nett arrays to session storage for (let i = 1; i <= 18; i++) { // Event listener for score inputs document.getElementById(`hole${i}`).addEventListener('input', function() { const scores = JSON.parse(sessionStorage.getItem('scores')) || []; scores[i - 1] = this.value; sessionStorage.setItem('scores', JSON.stringify(scores)); }); // Event listener for Stableford inputs document.getElementById(`sford${i}`).addEventListener('input', function() { const stablefords = JSON.parse(sessionStorage.getItem('stablefords')) || []; stablefords[i - 1] = this.value; sessionStorage.setItem('stablefords', JSON.stringify(stablefords)); }); // You can similarly handle the Nett array if needed. } // Function to save the collected data as a JSON file document.getElementById('saveButton').addEventListener('click', function() { // Read necessary data from session storage const playerName = sessionStorage.getItem('playerName') || 'Unknown_Player'; const memberNum = sessionStorage.getItem('memberNum') || 'Unknown_Member'; // Default to 'Unknown_Member' if not provided const competition = sessionStorage.getItem('competition') || 'Unknown_Competition'; // Use competition for the file name const handicap = sessionStorage.getItem('handicap') || ''; const countryCode = sessionStorage.getItem('countryCode') || ''; const clubCode = sessionStorage.getItem('clubCode') || ''; const teeType = sessionStorage.getItem('teeType') || ''; const teamName = document.getElementById('teamInput').value || 'No Team'; // Default to "No Team" if not provided // System-generated tournament type const tournamentType = "Stroke Play"; // Example system-generated value; replace with your logic const scores = JSON.parse(sessionStorage.getItem('scores')) || []; // Read Gross, Nett, and Stableford totals from session storage const totalGross = sessionStorage.getItem('totalGross') || 0; const totalNett = sessionStorage.getItem('totalNett') || 0; const totalStableford = sessionStorage.getItem('totalStableford') || 0; // Construct the JSON object, now including the system-generated tournament type const scoreData = { playerName, memberNum, competition, // Use competition for the filename handicap, countryCode, clubCode, teeType, tournamentType, // Include system-generated Tournament Type teamName, // Include the new team field scores, totalGross, totalNett, totalStableford }; // Create the filename using CompetitionName_PlayerName_MemberNumber.json format const competitionName = competition.replace(/\s+/g, '_'); // Replace spaces with underscores in competition name const fileName = `${competitionName}_${playerName.replace(/\s+/g, '_')}_${memberNum}.json`; // Convert the scoreData object to JSON const scoreDataJson = JSON.stringify(scoreData, null, 2); // Create a blob object for the data const blob = new Blob([scoreDataJson], { type: 'application/json' }); // Create a link element to trigger the download const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = fileName; // Use the generated file name for the download // Trigger the download by clicking the link a.click(); console.log(`Player data saved as ${fileName}`); }); // Load button event listener document.getElementById('loadButton').addEventListener('click', function() { // Trigger the file input to open document.getElementById('fileInput').click(); }); // Save header info to session storage document.getElementById('playerName').addEventListener('input', function() { sessionStorage.setItem('playerName', this.value); }); document.getElementById('memberNum').addEventListener('input', function() { sessionStorage.setItem('memberNum', this.value); }); document.getElementById('competitionInput').addEventListener('input', function() { sessionStorage.setItem('competition', this.value); }); document.getElementById('handicap').addEventListener('input', function() { sessionStorage.setItem('handicap', this.value); }); document.getElementById('countryCode').addEventListener('input', function() { sessionStorage.setItem('countryCode', this.value); }); document.getElementById('clubCode').addEventListener('input', function() { sessionStorage.setItem('clubCode', this.value); }); document.getElementById('teeInput').addEventListener('input', function() { sessionStorage.setItem('teeType', this.value); }); document.getElementById('gameDate').addEventListener('input', function() { sessionStorage.setItem('gameDate', this.value); }); // Clear button event listener with confirmation document.getElementById('clearButton').addEventListener('click', function() { // Provide a warning before clearing the scorecard const confirmClear = confirm("Are you sure you want to clear the scorecard? This action cannot be undone."); if (confirmClear) { // Clear all header input fields document.getElementById('playerName').value = ''; document.getElementById('memberNum').value = ''; document.getElementById('competitionInput').value = ''; // Clear competition input field document.getElementById('handicap').value = ''; document.getElementById('countryCode').value = ''; document.getElementById('clubCode').value = ''; document.getElementById('teeInput').value = ''; document.getElementById('teamInput').value = ''; // Clear team input field // Clear score, Stableford, and Nett inputs for all 18 holes for (let i = 1; i <= 18; i++) { let holeInput = document.getElementById(`hole${i}`); let sfordInput = document.getElementById(`sford${i}`); let nettInput = document.getElementById(`nett${i}`); // Ensure the input fields exist before trying to clear them if (holeInput) { holeInput.value = ''; } if (sfordInput) { sfordInput.value = ''; } if (nettInput) { nettInput.value = ''; } } // Clear session storage, including new fields like competition and team sessionStorage.clear(); console.log('Scorecard cleared and ready for a new game.'); } else { // If user cancels, log that clearing was cancelled console.log('Scorecard clearing cancelled by user.'); } }); // Initialization code setInterval(receiveMessagesFromServer, 60000); }); </script> </body> </html>
    https://whatsonchain.com/tx/2dcf8dd26f2a2208af9ed0612798617e1f6f4687eaa0ca3d38d9f05ac71b0c76