import { apiGet, apiPost } from '../api.js'; import { showToast } from '../app.js'; import { isDevTestClientCode, isDevTestUsername, testDataRowClassForClient } from '../test-data.js'; let coaches = []; let clients = []; let selectedCoachID = null; export async function assignmentsPage() { selectedCoachID = null; const app = document.getElementById('app'); app.innerHTML = `
`; try { const data = await apiGet('assignments.php'); coaches = data.coaches || []; clients = data.clients || []; renderAssignments(); } catch (e) { showToast(e.message, 'error'); document.getElementById('assignContent').innerHTML = `

${esc(e.message)}

`; } } function renderAssignments() { const container = document.getElementById('assignContent'); if (!coaches.length) { container.innerHTML = `

No coaches found

Create coaches first before assigning clients.

`; return; } // Group clients by coachID for the filter badge counts const clientsByCoach = {}; const unassigned = []; clients.forEach(c => { if (c.coachID) { (clientsByCoach[c.coachID] = clientsByCoach[c.coachID] || []).push(c); } else { unassigned.push(c); } }); container.innerHTML = `

Coaches

Clients

Client Code Current Coach
`; // Wire coach list click → filter clients document.querySelectorAll('.coach-list-item').forEach(li => { li.addEventListener('click', () => { document.querySelectorAll('.coach-list-item').forEach(x => x.classList.remove('active')); li.classList.add('active'); selectedCoachID = li.dataset.id; document.getElementById('filterByCoach').value = selectedCoachID; renderClientRows(); }); }); // Wire filters document.getElementById('filterByCoach').addEventListener('change', renderClientRows); document.getElementById('clientSearch').addEventListener('input', renderClientRows); document.getElementById('clientTestFilter').addEventListener('change', renderClientRows); // Wire select all / clear document.getElementById('selectAllBtn').addEventListener('click', () => { document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => cb.checked = true); updateSelectionInfo(); }); document.getElementById('clearSelBtn').addEventListener('click', () => { document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => cb.checked = false); updateSelectionInfo(); }); document.getElementById('selectAllCb').addEventListener('change', (e) => { document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => cb.checked = e.target.checked); updateSelectionInfo(); }); // Wire assign button document.getElementById('assignBtn').addEventListener('click', doAssign); renderClientRows(); } function renderClientRows() { const body = document.getElementById('clientTableBody'); const coachFilter = document.getElementById('filterByCoach').value; const search = document.getElementById('clientSearch').value.trim().toLowerCase(); const testMode = document.getElementById('clientTestFilter')?.value || ''; let visible = clients; if (coachFilter === '__unassigned__') { visible = clients.filter(c => !c.coachID); } else if (coachFilter) { visible = clients.filter(c => c.coachID === coachFilter); } if (search) { visible = visible.filter(c => c.clientCode.toLowerCase().includes(search)); } if (testMode === 'test') { visible = visible.filter(c => isDevTestClientCode(c.clientCode)); } else if (testMode === 'hide-test') { visible = visible.filter(c => !isDevTestClientCode(c.clientCode)); } if (!visible.length) { body.innerHTML = `No clients match the current filter`; updateSelectionInfo(); return; } body.innerHTML = visible.map(c => ` ${esc(c.clientCode)} ${c.coachUsername ? esc(c.coachUsername) : 'Unassigned'} `).join(''); body.querySelectorAll('.client-cb').forEach(cb => { cb.addEventListener('change', updateSelectionInfo); }); updateSelectionInfo(); } function getSelectedCodes() { return [...document.querySelectorAll('#clientTableBody .client-cb:checked')] .map(cb => cb.value); } function updateSelectionInfo() { const selected = getSelectedCodes(); const info = document.getElementById('selectionInfo'); const card = document.getElementById('assignActionCard'); if (!selected.length) { info.style.display = 'none'; card.style.display = 'none'; return; } info.style.display = ''; info.innerHTML = `${selected.length} client${selected.length === 1 ? '' : 's'} selected`; card.style.display = ''; } async function doAssign() { const selected = getSelectedCodes(); const coachID = document.getElementById('targetCoachSelect').value; if (!selected.length) { showToast('Select at least one client', 'error'); return; } if (!coachID) { showToast('Select a target coach', 'error'); return; } const coachName = coaches.find(c => c.coachID === coachID)?.username || coachID; if (!confirm(`Assign ${selected.length} client(s) to ${coachName}?`)) return; const btn = document.getElementById('assignBtn'); btn.disabled = true; btn.textContent = 'Assigning...'; try { const data = await apiPost('assignments.php', { clientCodes: selected, coachID }); if (data.success) { // Update local data selected.forEach(code => { const c = clients.find(x => x.clientCode === code); if (c) { c.coachID = coachID; c.coachUsername = coachName; } }); showToast(`${data.assigned} client(s) assigned to ${coachName}`, 'success'); renderAssignments(); } } catch (e) { showToast(e.message, 'error'); btn.disabled = false; btn.textContent = 'Assign'; } } function esc(s) { const d = document.createElement('div'); d.textContent = s ?? ''; return d.innerHTML; }