Zulassen von Anonymen RFID updates verlinkung der UUID wenn spieler angelegt wurde

This commit is contained in:
2025-09-11 16:33:22 +02:00
parent d2a1bb16ea
commit 28616b3b0c
14 changed files with 2676 additions and 241 deletions

View File

@@ -242,6 +242,53 @@ async function showRFIDSettings() {
openModal('rfidModal');
// Reset scanner state
stopQRScanner();
// Check if user is already linked and hide/show create player section
await updateCreatePlayerSectionVisibility();
}
// Update visibility of create player section based on link status
async function updateCreatePlayerSectionVisibility() {
const createPlayerSection = document.getElementById('createPlayerSection');
if (!currentUser) {
// No user logged in - hide create player section
if (createPlayerSection) {
createPlayerSection.style.display = 'none';
}
return;
}
try {
// Check if user has a linked player
const response = await fetch(`/api/v1/public/user-player/${currentUser.id}?t=${Date.now()}`);
if (response.ok) {
const result = await response.json();
if (result.success && result.data && result.data.id) {
// User is already linked - hide create player section
if (createPlayerSection) {
createPlayerSection.style.display = 'none';
}
} else {
// User is not linked - show create player section
if (createPlayerSection) {
createPlayerSection.style.display = 'block';
}
}
} else {
// Error checking link status - show create player section as fallback
if (createPlayerSection) {
createPlayerSection.style.display = 'block';
}
}
} catch (error) {
console.error('Error checking link status:', error);
// Error occurred - show create player section as fallback
if (createPlayerSection) {
createPlayerSection.style.display = 'block';
}
}
}
// Check link status and load times
@@ -448,6 +495,117 @@ async function linkManualRfid() {
}
}
// Create new RFID player record
async function createRfidPlayerRecord() {
const rawUid = document.getElementById('manualRfidInput').value.trim();
const firstname = document.getElementById('playerFirstname').value.trim();
const lastname = document.getElementById('playerLastname').value.trim();
const birthdate = document.getElementById('playerBirthdate').value;
// Validation
if (!rawUid) {
const inputErrorMsg = currentLanguage === 'de' ?
'Bitte gib eine RFID UID ein' :
'Please enter a RFID UID';
showMessage('rfidMessage', inputErrorMsg, 'error');
return;
}
if (!firstname) {
const inputErrorMsg = currentLanguage === 'de' ?
'Bitte gib einen Vornamen ein' :
'Please enter a first name';
showMessage('rfidMessage', inputErrorMsg, 'error');
return;
}
if (!lastname) {
const inputErrorMsg = currentLanguage === 'de' ?
'Bitte gib einen Nachnamen ein' :
'Please enter a last name';
showMessage('rfidMessage', inputErrorMsg, 'error');
return;
}
if (!birthdate) {
const inputErrorMsg = currentLanguage === 'de' ?
'Bitte gib ein Geburtsdatum ein' :
'Please enter a birth date';
showMessage('rfidMessage', inputErrorMsg, 'error');
return;
}
try {
// Format the UID to match database format
const formattedUid = formatRfidUid(rawUid);
const formattedMsg = currentLanguage === 'de' ?
`Erstelle Spieler: ${firstname} ${lastname} (${formattedUid})` :
`Creating player: ${firstname} ${lastname} (${formattedUid})`;
showMessage('rfidMessage', formattedMsg, 'info');
// Create player record
const response = await fetch('/api/v1/public/players/create-with-rfid', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
rfiduid: formattedUid,
firstname: firstname,
lastname: lastname,
birthdate: birthdate,
supabase_user_id: currentUser?.id || null
})
});
const result = await response.json();
if (result.success) {
const successMsg = currentLanguage === 'de' ?
`Spieler erfolgreich erstellt: ${result.data.firstname} ${result.data.lastname}` :
`Player successfully created: ${result.data.firstname} ${result.data.lastname}`;
showMessage('rfidMessage', successMsg, 'success');
// Clear form
document.getElementById('manualRfidInput').value = '';
document.getElementById('playerFirstname').value = '';
document.getElementById('playerLastname').value = '';
document.getElementById('playerBirthdate').value = '';
// Hide create player section since user is now linked
const createPlayerSection = document.getElementById('createPlayerSection');
if (createPlayerSection) {
createPlayerSection.style.display = 'none';
}
// Refresh times if user is linked
if (currentUser) {
await checkLinkStatusAndLoadTimes();
}
} else {
let errorMsg = result.message;
// Erweitere Fehlermeldung um Levenshtein-Details falls vorhanden
if (result.details) {
if (result.details.matchType === 'similar') {
const similarityPercent = Math.round((1 - result.details.similarity) * 100);
errorMsg += `\n\nÄhnlichkeit: ${similarityPercent}% (Distanz: ${result.details.levenshteinDistance})`;
}
}
showMessage('rfidMessage', errorMsg, 'error');
}
} catch (error) {
console.error('Error creating RFID player record:', error);
const errorMsg = currentLanguage === 'de' ?
`Fehler beim Erstellen: ${error.message}` :
`Error creating: ${error.message}`;
showMessage('rfidMessage', errorMsg, 'error');
}
}
// Link user by RFID UID (core function)
async function linkUserByRfidUid(rfidUid) {
if (!currentUser) {
@@ -549,6 +707,51 @@ function showTimesNotLinked() {
}
}
// Show RFID linked info with help button
function showRFIDLinkedInfo(playerData) {
// Find the RFID card and update it
const rfidCard = document.querySelector('.card[onclick="showRFIDSettings()"]');
if (rfidCard) {
const isGerman = currentLanguage === 'de';
rfidCard.innerHTML = `
<h3>${isGerman ? '🏷️ RFID Verknüpft' : '🏷️ RFID Linked'}</h3>
<div style="background: rgba(16, 185, 129, 0.1); border: 1px solid rgba(16, 185, 129, 0.3); border-radius: 0.5rem; padding: 1rem; margin: 1rem 0;">
<div style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;">
<span style="color: #10b981; font-weight: 600;">✅</span>
<span style="color: #10b981; font-weight: 600;">
${isGerman ? 'Erfolgreich verknüpft' : 'Successfully linked'}
</span>
</div>
<div style="font-size: 0.9rem; color: #8892b0;">
<div><strong>${isGerman ? 'Spieler:' : 'Player:'}</strong> ${playerData.firstname} ${playerData.lastname}</div>
<div><strong>RFID:</strong> <code style="background: rgba(255,255,255,0.1); padding: 0.2rem 0.4rem; border-radius: 0.25rem; font-family: monospace;">${playerData.rfiduid}</code></div>
</div>
</div>
<button class="btn btn-secondary" onclick="requestRFIDHelp()" style="margin-top: 1rem; font-size: 0.9rem; padding: 0.5rem 1rem;">
${isGerman ? '❓ Hilfe anfordern' : '❓ Request Help'}
</button>
`;
// Remove the onclick from the card since we don't want it to open the modal
rfidCard.removeAttribute('onclick');
rfidCard.style.cursor = 'default';
}
}
// Request RFID help
function requestRFIDHelp() {
const isGerman = currentLanguage === 'de';
const message = isGerman ?
'Hilfe-Anfrage gesendet! Ein Administrator wird sich bei dir melden, um bei der RFID-Änderung zu helfen.' :
'Help request sent! An administrator will contact you to help with the RFID change.';
alert(message);
// Here you could send a notification to admins or log the help request
console.log('RFID help requested by user:', currentUser?.email);
}
// Show loading state
function showTimesLoading() {
document.getElementById('timesLoading').style.display = 'block';
@@ -584,6 +787,9 @@ async function loadUserTimesSection(playerData) {
// Display times
displayUserTimes(times);
// Show RFID info and help button
showRFIDLinkedInfo(playerData);
// Show the times display
document.getElementById('timesLoading').style.display = 'none';
document.getElementById('timesNotLinked').style.display = 'none';