- Implemented QTTR values screen in the member area with data fetching and display. - Added new API endpoint for QTTR values retrieval. - Created a new view model for managing QTTR data state. - Updated navigation to include QTTR section. - Enhanced error handling and loading states for QTTR data. - Adjusted server-side logic to import QTTR values from external source. - Updated Android app version and adjusted build configurations. - Added necessary UI components and styling for QTTR display.
90 lines
2.4 KiB
JavaScript
90 lines
2.4 KiB
JavaScript
import { readFile } from 'fs/promises'
|
||
import { getServerDataPath } from '../../utils/paths.js'
|
||
import { getUserFromToken, verifyToken } from '../../utils/auth.js'
|
||
import { readMembers } from '../../utils/members.js'
|
||
import { readUsers } from '../../utils/auth.js'
|
||
|
||
const QTTR_FILE = getServerDataPath('qttr-values.json')
|
||
|
||
function normalizeName(value) {
|
||
return String(value || '')
|
||
.trim()
|
||
.toLowerCase()
|
||
.normalize('NFKD')
|
||
.replace(/[\u0300-\u036f]/g, '')
|
||
.replace(/\s+/g, ' ')
|
||
.replace(/[’'`]/g, '')
|
||
}
|
||
|
||
function buildBirthdateLookup(entries) {
|
||
const lookup = new Map()
|
||
|
||
for (const entry of entries || []) {
|
||
const candidates = [
|
||
entry?.name,
|
||
`${entry?.firstName || ''} ${entry?.lastName || ''}`.trim(),
|
||
]
|
||
|
||
const birthdate = entry?.geburtsdatum || entry?.birthday || entry?.birthDate || ''
|
||
if (!birthdate) continue
|
||
|
||
for (const candidate of candidates) {
|
||
const normalized = normalizeName(candidate)
|
||
if (!normalized || lookup.has(normalized)) continue
|
||
lookup.set(normalized, birthdate)
|
||
}
|
||
}
|
||
|
||
return lookup
|
||
}
|
||
|
||
export default defineEventHandler(async (event) => {
|
||
const token = getCookie(event, 'auth_token') || getHeader(event, 'authorization')?.replace(/^Bearer\s+/i, '')
|
||
if (!token || !verifyToken(token)) {
|
||
throw createError({
|
||
statusCode: 401,
|
||
message: 'Nicht authentifiziert.'
|
||
})
|
||
}
|
||
|
||
const currentUser = await getUserFromToken(token)
|
||
if (!currentUser) {
|
||
throw createError({
|
||
statusCode: 401,
|
||
message: 'Ungültiges Token.'
|
||
})
|
||
}
|
||
|
||
try {
|
||
const content = await readFile(QTTR_FILE, 'utf8')
|
||
const payload = JSON.parse(content)
|
||
const [manualMembers, registeredUsers] = await Promise.all([
|
||
readMembers(),
|
||
readUsers()
|
||
])
|
||
const birthdateLookup = buildBirthdateLookup([...manualMembers, ...registeredUsers])
|
||
|
||
return {
|
||
...payload,
|
||
rows: Array.isArray(payload.rows)
|
||
? payload.rows.map((row) => ({
|
||
...row,
|
||
birthdate: birthdateLookup.get(normalizeName(row.playerName)) || row.birthdate || ''
|
||
}))
|
||
: []
|
||
}
|
||
} catch (error) {
|
||
if (error?.code === 'ENOENT') {
|
||
throw createError({
|
||
statusCode: 404,
|
||
message: 'QTTR-Datei nicht gefunden.'
|
||
})
|
||
}
|
||
|
||
console.error('Fehler beim Laden der QTTR-Werte:', error)
|
||
throw createError({
|
||
statusCode: 500,
|
||
message: 'Fehler beim Laden der QTTR-Werte.'
|
||
})
|
||
}
|
||
}) |