registerPage('employees', async (content, params = {}) => { document.getElementById('topbar-title').textContent = 'Employees'; let clients = []; async function loadClients() { const r = await api('clients.php', { action: 'list' }); if (r.success) clients = r.clients; } async function render(search = '', clientFilter = '') { const r = await api('employees.php', { action: 'list', search, clients_id: clientFilter }); if (!r.success) { document.getElementById('emp-table').innerHTML = emptyHTML('Error: ' + (r.error || 'unknown')); return; } if (r.prompt) { document.getElementById('emp-table').innerHTML = `
Select a client or enter a search term to load employees.
Showing first ${r.limit} results — use search or client filter to narrow down.
` : ''; document.getElementById('emp-table').innerHTML = rows.length === 0 ? emptyHTML('No employees found') : limitNote + `| Name | Surname | ID/Passport | Client | Occupation | Company # | Actions |
|---|---|---|---|---|---|---|
| ${e.client_employees_name} | ${e.surname} | ${e.i_doc_passport || '—'} | ${e.clients_name || '—'} | ${e.occupation || '—'} | ${e.company_number || '—'} |
No assessment or test results found.
`; return; } const assRows = assessments.map(a => { const passed = a.results === 'COMPETENT' || a.results === 'C'; return `Assessments (${assessments.length})
Tests (${tests.length})
${a.assesses_name || '—'}
${a.results || '—'}
${a.client_employees_name || ''} ${a.surname || ''}
${a.i_doc_passport || '—'}
${a.company_number || '—'}
${a.clients_name || '—'}
${a.assessor_name || a.assessor_username || '—'}
${a.assessor_number || '—'}
${a.date || '—'}
${a.current_mark || '—'} / ${a.passmark || '—'}
${a.nqf_level || '—'}
${a.credits || '—'}
${a.vehicle_model}
${a.notes}
No section data.
'}`; document.getElementById('result-view-footer').innerHTML = ` ${a.booking ? `` : ''} `; openModal('result-view-modal'); }; // ── View Test popup ──────────────────────────────────────────────────────── window.viewTest = async (id) => { const r = await api('results.php', { action: 'get_test', id }); if (!r.success) { toast('Failed to load', 'error'); return; } const t = r.test; document.getElementById('result-view-title').textContent = t.test_name || 'Test'; const passed = t.results === 'COMPETENT' || t.results === 'C'; const qHtml = (t.questions || []).map(q => { const parts = (q.subtotal || '').split('-'); const total = parts[0] || '?', score = parts[1] || '?'; const ansRows = (q.answers || []).map(a => `${t.test_name || '—'}
${t.results || '—'}
${t.client_employees_name || ''} ${t.surname || ''}
${t.i_doc_passport || '—'}
${t.clients_name || '—'}
${t.assessor_name || t.assessor_username || '—'}
${t.date || '—'}
${t.current_mark || '—'} / ${t.passmark || '—'}
No question data.
'}`; document.getElementById('result-view-footer').innerHTML = ` ${t.booking ? `` : ''} `; openModal('result-view-modal'); }; // ── Assessment PDF — matches old system layout ───────────────────────────── window.pdfAssessment = async (id) => { const r = await api('results.php', { action: 'get_assessment', id }); if (!r.success) { toast('Failed', 'error'); return; } const a = r.assessment; const passed = a.results === 'COMPETENT' || a.results === 'C'; const sigBase = window.location.origin + window.location.pathname.replace('index.php', '').replace(/\/[^/]*$/, '/'); const sectionsHtml = (a.sections || []).map(sec => { const parts = (sec.subtotal || '0-0').split('-'); const total = parts[0] || '0', score = parts[1] || '0'; const qRows = (sec.questions || []).map(q => `${q.question}
${sec.section_name} Score: ${score}/${total} | ||||
| CRITERIA | C | NYC | COMMENT | |
|---|---|---|---|---|
SAFETY & TRAINING PRACTITIONERS | |
${a.assesses_info || ''} | |
NQF LEVEL: ${a.nqf_level || ''} |
Credits: ${a.credits || ''} |
${a.assesses_name || ''} |
Vehicle Model: ${a.vehicle_model || ''} |
CANDIDATE NAME | ${a.client_employees_name || ''} ${a.surname || ''} |
COY NO | ${a.company_number || ''} |
ID NO. | ${a.i_doc_passport || ''} |
MINE | ${a.clients_name || ''} |
ASSESSOR | ${a.assessor_name || a.assessor_username || ''} |
ASSESSOR NO | ${a.assessor_number || ''} |
ASSESSMENT DATE | ${a.date || ''} |
COMPETENT / NYC | ${a.results || ''} |
CAND. SIGNATURE |
|
ASSESSOR SIGNATURE |
|
DATE | ${a.date || ''} |
SAFETY & TRAINING PRACTITIONERS | |
${a.assesses_info || ''} | |
NQF LEVEL: ${a.nqf_level || ''} |
Credits: ${a.credits || ''} |
${a.assesses_name || ''} | |
I fully understand the above and was under no pressure or obligation to sign this document.
Signed on ${a.date || new Date().toLocaleDateString('en-ZA')}
| Candidate Signature. |
|
Assessor Signature. |
|
I, ${a.client_employees_name || ''} ${a.surname || ''}, hereby confirm that I have received training in theory and practical on ${a.assesses_name || ''}. I confirm that I have been given the opportunity to ask questions and that answers given have been satisfactory. I have signed every section of this training evaluation. I furthermore undertake to carry out my appointed duties applicable to this equipment in a safe manner and to adhere to all safety aspects as required by Codes of Practice and Safe Working Procedures.
Signature of Candidate |
|
Signature of Assessor; |
|
Date: |
${a.date || ''} |
Photo of Candidate: |