Kontrol Scoreboard Futsal

Timer

00:00

Tim HOME

Logo HOME
0
0
0
0

Tim AWAY

Logo AWAY
0
0
0
0

Instruksi Penggunaan:

1. Gunakan panel kontrol ini untuk mengatur skor, foul, kartu, nama tim, dan babak pertandingan.

2. Atur timer dengan tombol Start, Pause, dan Reset. Anda juga dapat mengatur waktu spesifik.

3. Upload logo tim dengan mengklik tombol "Choose File" di bagian Logo Tim.

4. Klik tombol "Perbarui Tampilan" untuk mengirim perubahan ke database.

5. Untuk menampilkan scoreboard di OBS, gunakan URL berikut:

http://localhost/panel/scoreboard-display.html
// URL API const apiUrl = "http://localhost/panel/"; // Ganti dengan URL server Anda // Variabel untuk menyimpan data let homeScore = 0; let awayScore = 0; let homeFoul = 0; let awayFoul = 0; let homeYellow = 0; let awayYellow = 0; let homeRed = 0; let awayRed = 0; let period = 1; let homeName = "HOME"; let awayName = "AWAY"; let homeLogo = "default_logo.png"; let awayLogo = "default_logo.png"; let timerSeconds = 0; let timerRunning = false; let timerInterval = null; // Elemen DOM const homeScoreEl = document.getElementById('homeScore'); const awayScoreEl = document.getElementById('awayScore'); const homeFoulEl = document.getElementById('homeFoul'); const awayFoulEl = document.getElementById('awayFoul'); const homeYellowEl = document.getElementById('homeYellow'); const awayYellowEl = document.getElementById('awayYellow'); const homeRedEl = document.getElementById('homeRed'); const awayRedEl = document.getElementById('awayRed'); const homeNameInput = document.getElementById('homeName'); const awayNameInput = document.getElementById('awayName'); const periodSelect = document.getElementById('period'); const statusEl = document.getElementById('status'); const obsUrlEl = document.getElementById('obsUrl'); const timerDisplayEl = document.getElementById('timerDisplay'); const homeLogoInput = document.getElementById('homeLogo'); const awayLogoInput = document.getElementById('awayLogo'); const homeLogoPreview = document.getElementById('homeLogoPreview'); const awayLogoPreview = document.getElementById('awayLogoPreview'); // Tampilkan URL OBS yang benar obsUrlEl.textContent = apiUrl + "scoreboard-display.html"; // Fungsi untuk menampilkan status function showStatus(message, isSuccess = true) { statusEl.textContent = message; statusEl.className = isSuccess ? "status success" : "status error"; statusEl.style.display = "block"; // Sembunyikan status setelah 3 detik setTimeout(() => { statusEl.style.display = "none"; }, 3000); } // Fungsi untuk memformat waktu function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const secs = seconds % 60; return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; } // Fungsi untuk memulai timer function startTimer() { if (!timerRunning) { timerRunning = true; // Hentikan interval sebelumnya jika ada if (timerInterval) { clearInterval(timerInterval); } // Mulai interval baru timerInterval = setInterval(() => { if (timerSeconds > 0) { timerSeconds--; timerDisplayEl.textContent = formatTime(timerSeconds); // Perbarui data ke server setiap 5 detik untuk mengurangi beban if (timerSeconds % 5 === 0) { updateData(false); // false berarti tidak menampilkan pesan sukses } } else { clearInterval(timerInterval); timerRunning = false; updateData(false); } }, 1000); // Perbarui status timer di database segera updateData(false); } } // Fungsi untuk menghentikan timer function pauseTimer() { if (timerRunning) { clearInterval(timerInterval); timerRunning = false; updateData(false); // Perbarui status timer di database } } // Fungsi untuk mereset timer function resetTimer() { clearInterval(timerInterval); timerRunning = false; timerSeconds = 0; timerDisplayEl.textContent = formatTime(timerSeconds); updateData(false); // Perbarui status timer di database } // Fungsi untuk mengatur timer ke waktu tertentu function setTimer(minutes) { clearInterval(timerInterval); timerRunning = false; timerSeconds = minutes * 60; timerDisplayEl.textContent = formatTime(timerSeconds); updateData(false); // Perbarui status timer di database } // Fungsi untuk upload logo async function uploadLogo(fileInput, isHome) { const file = fileInput.files[0]; if (!file) return; const formData = new FormData(); formData.append('logo', file); try { const response = await fetch(apiUrl + "upload_logo.php", { method: "POST", body: formData }); const result = await response.json(); if (result.success) { if (isHome) { homeLogo = result.filename; homeLogoPreview.src = apiUrl + "logos/" + result.filename; } else { awayLogo = result.filename; awayLogoPreview.src = apiUrl + "logos/" + result.filename; } showStatus("Logo berhasil diupload!"); updateData(); } else { showStatus("Gagal mengupload logo: " + result.message, false); } } catch (error) { showStatus("Gagal mengupload logo: " + error.message, false); } } // Fungsi untuk memuat data dari server async function loadData() { try { const response = await fetch(apiUrl + "get_data.php"); const data = await response.json(); if (data.home_score !== undefined) { homeScore = parseInt(data.home_score); awayScore = parseInt(data.away_score); homeFoul = parseInt(data.home_foul); awayFoul = parseInt(data.away_foul); homeYellow = parseInt(data.home_yellow || 0); awayYellow = parseInt(data.away_yellow || 0); homeRed = parseInt(data.home_red || 0); awayRed = parseInt(data.away_red || 0); period = parseInt(data.period); homeName = data.home_name; awayName = data.away_name; // Timer data timerSeconds = parseInt(data.timer_seconds || 0); timerRunning = data.timer_running == 1; timerDisplayEl.textContent = formatTime(timerSeconds); // Logo data homeLogo = data.home_logo || "default_logo.png"; awayLogo = data.away_logo || "default_logo.png"; homeLogoPreview.src = apiUrl + "logos/" + homeLogo; awayLogoPreview.src = apiUrl + "logos/" + awayLogo; // Perbarui tampilan homeScoreEl.textContent = homeScore; awayScoreEl.textContent = awayScore; homeFoulEl.textContent = homeFoul; awayFoulEl.textContent = awayFoul; homeYellowEl.textContent = homeYellow; awayYellowEl.textContent = awayYellow; homeRedEl.textContent = homeRed; awayRedEl.textContent = awayRed; homeNameInput.value = homeName; awayNameInput.value = awayName; periodSelect.value = period; // Jika timer sedang berjalan, mulai timer if (timerRunning) { // Hentikan interval yang ada jika ada if (timerInterval) { clearInterval(timerInterval); } // Mulai interval baru timerInterval = setInterval(() => { if (timerSeconds > 0) { timerSeconds--; timerDisplayEl.textContent = formatTime(timerSeconds); // Perbarui data ke server setiap 5 detik if (timerSeconds % 5 === 0) { updateData(false); } } else { clearInterval(timerInterval); timerRunning = false; updateData(false); } }, 1000); } } } catch (error) { showStatus("Gagal memuat data: " + error.message, false); } } // Fungsi untuk memperbarui data ke server async function updateData(showMessage = true) { try { // Ambil nilai terbaru dari input homeName = homeNameInput.value || "HOME"; awayName = awayNameInput.value || "AWAY"; period = parseInt(periodSelect.value); const data = { home_name: homeName, away_name: awayName, home_score: homeScore, away_score: awayScore, home_foul: homeFoul, away_foul: awayFoul, home_yellow: homeYellow, away_yellow: awayYellow, home_red: homeRed, away_red: awayRed, period: period, timer_seconds: timerSeconds, timer_running: timerRunning, home_logo: homeLogo, away_logo: awayLogo }; const response = await fetch(apiUrl + "update_data.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); const result = await response.json(); if (result.success && showMessage) { showStatus("Data berhasil diperbarui!"); } else if (!result.success) { if (showMessage) { showStatus("Gagal memperbarui data: " + result.message, false); } } } catch (error) { if (showMessage) { showStatus("Gagal memperbarui data: " + error.message, false); } } } // Fungsi untuk memperbarui tampilan lokal function updateDisplay() { homeScoreEl.textContent = homeScore; awayScoreEl.textContent = awayScore; homeFoulEl.textContent = homeFoul; awayFoulEl.textContent = awayFoul; homeYellowEl.textContent = homeYellow; awayYellowEl.textContent = awayYellow; homeRedEl.textContent = homeRed; awayRedEl.textContent = awayRed; timerDisplayEl.textContent = formatTime(timerSeconds); } // Event listeners untuk tombol skor document.getElementById('homeScoreUp').addEventListener('click', () => { homeScore++; updateDisplay(); }); document.getElementById('homeScoreDown').addEventListener('click', () => { if (homeScore > 0) homeScore--; updateDisplay(); }); document.getElementById('awayScoreUp').addEventListener('click', () => { awayScore++; updateDisplay(); }); document.getElementById('awayScoreDown').addEventListener('click', () => { if (awayScore > 0) awayScore--; updateDisplay(); }); // Event listeners untuk tombol foul document.getElementById('homeFoulUp').addEventListener('click', () => { homeFoul++; updateDisplay(); }); document.getElementById('homeFoulDown').addEventListener('click', () => { if (homeFoul > 0) homeFoul--; updateDisplay(); }); document.getElementById('awayFoulUp').addEventListener('click', () => { awayFoul++; updateDisplay(); }); document.getElementById('awayFoulDown').addEventListener('click', () => { if (awayFoul > 0) awayFoul--; updateDisplay(); }); // Event listeners untuk tombol kartu kuning document.getElementById('homeYellowUp').addEventListener('click', () => { homeYellow++; updateDisplay(); }); document.getElementById('homeYellowDown').addEventListener('click', () => { if (homeYellow > 0) homeYellow--; updateDisplay(); }); document.getElementById('awayYellowUp').addEventListener('click', () => { awayYellow++; updateDisplay(); }); document.getElementById('awayYellowDown').addEventListener('click', () => { if (awayYellow > 0) awayYellow--; updateDisplay(); }); // Event listeners untuk tombol kartu merah document.getElementById('homeRedUp').addEventListener('click', () => { homeRed++; updateDisplay(); }); document.getElementById('homeRedDown').addEventListener('click', () => { if (homeRed > 0) homeRed--; updateDisplay(); }); document.getElementById('awayRedUp').addEventListener('click', () => { awayRed++; updateDisplay(); }); document.getElementById('awayRedDown').addEventListener('click', () => { if (awayRed > 0) awayRed--; updateDisplay(); }); // Event listeners untuk tombol timer document.getElementById('startTimer').addEventListener('click', startTimer); document.getElementById('pauseTimer').addEventListener('click', pauseTimer); document.getElementById('resetTimer').addEventListener('click', resetTimer); document.getElementById('set5min').addEventListener('click', () => setTimer(5)); document.getElementById('set10min').addEventListener('click', () => setTimer(10)); document.getElementById('set20min').addEventListener('click', () => setTimer(20)); document.getElementById('addMin').addEventListener('click', () => { timerSeconds += 60; timerDisplayEl.textContent = formatTime(timerSeconds); updateData(false); }); document.getElementById('subMin').addEventListener('click', () => { if (timerSeconds >= 60) timerSeconds -= 60; timerDisplayEl.textContent = formatTime(timerSeconds); updateData(false); }); // Event listeners untuk upload logo homeLogoInput.addEventListener('change', () => uploadLogo(homeLogoInput, true)); awayLogoInput.addEventListener('change', () => uploadLogo(awayLogoInput, false)); // Event listeners untuk tombol reset document.getElementById('resetScores').addEventListener('click', () => { homeScore = 0; awayScore = 0; updateDisplay(); }); document.getElementById('resetFouls').addEventListener('click', () => { homeFoul = 0; awayFoul = 0; updateDisplay(); }); document.getElementById('resetCards').addEventListener('click', () => { homeYellow = 0; awayYellow = 0; homeRed = 0; awayRed = 0; updateDisplay(); }); document.getElementById('resetAll').addEventListener('click', () => { homeScore = 0; awayScore = 0; homeFoul = 0; awayFoul = 0; homeYellow = 0; awayYellow = 0; homeRed = 0; awayRed = 0; period = 1; timerSeconds = 0; timerRunning = false; clearInterval(timerInterval); homeName = 'HOME'; awayName = 'AWAY'; homeNameInput.value = 'HOME'; awayNameInput.value = 'AWAY'; periodSelect.value = '1'; timerDisplayEl.textContent = formatTime(timerSeconds); updateDisplay(); updateData(); }); // Event listener untuk tombol update document.getElementById('updateDisplay').addEventListener('click', updateData); // Muat data saat halaman dimuat window.addEventListener('load', loadData);