Seniority

NAD Employee Seniority & Promotion Management

Checking access…
// Parse the MM/YYYY, M/YYYY, YYYY, or DD/MM/YYYY date formats used in the sheet. function parseSeniorityDate(str) { if (!str) return null; str = String(str).trim(); let m = str.match(/^(\d{1,2})\/(\d{4})$/); // MM/YYYY if (m) return new Date(+m[2], +m[1] - 1, 1); m = str.match(/^(\d{4})$/); // YYYY if (m) return new Date(+m[1], 0, 1); m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/); // DD/MM/YYYY if (m) return new Date(+m[3], +m[2] - 1, +m[1]); return null; } function dateValue(str) { const d = parseSeniorityDate(str); return d ? d.getTime() : 0; } function yearOf(str) { const d = parseSeniorityDate(str); return d ? d.getFullYear() : null; } // Robust CSV parser function parseCSV(text) { const rows = []; let row = []; let cell = ""; let insideQuote = false; for (let i = 0; i < text.length; i++) { const char = text[i]; if (char === '"') { if (insideQuote && text[i + 1] === '"') { cell += '"'; i++; } else { insideQuote = !insideQuote; } } else if (char === ',' && !insideQuote) { row.push(cell); cell = ""; } else if ((char === '\n' || char === '\r') && !insideQuote) { if (cell || row.length) { row.push(cell); rows.push(row); row = []; cell = ""; } } else { cell += char; } } if (cell || row.length) row.push(cell), rows.push(row); return rows; } // Load both sheets async function loadData() { try { // Sheet1 const res1 = await fetch(sheet1URL); const text1 = await res1.text(); const rows1 = parseCSV(text1); headers1 = rows1[0]; employees = rows1.slice(1).map(r => { let obj = {}; headers1.forEach((h, i) => obj[h] = r[i] || ""); return obj; }); // Sheet2 const res2 = await fetch(sheet2URL); const text2 = await res2.text(); const rows2 = parseCSV(text2); headers2 = rows2[0]; sanctionedPosts = rows2.slice(1).map(r => { let obj = {}; headers2.forEach((h, i) => obj[h] = r[i] || ""); return obj; }); } catch (err) { console.error("Error loading sheets", err); } } // Autocomplete Suggestions function showSuggestions() { const input = document.getElementById("tokenInput").value.trim().toLowerCase(); const suggestionsDiv = document.getElementById("suggestions"); suggestionsDiv.innerHTML = ""; if (input.length < 2) { suggestionsDiv.style.display = "none"; return; } const matches = employees.filter(e => (e["Tokan No."] || "").toLowerCase().includes(input)).slice(0, 5); matches.forEach(emp => { const div = document.createElement("div"); div.textContent = `${emp["Tokan No."]} - ${emp["Name"]}`; div.style.cursor = "pointer"; div.onclick = () => { document.getElementById("tokenInput").value = emp["Tokan No."]; suggestionsDiv.style.display = "none"; searchEmployee(); }; suggestionsDiv.appendChild(div); }); suggestionsDiv.style.display = matches.length > 0 ? "block" : "none"; } // Search Employee function searchEmployee() { const token = document.getElementById("tokenInput").value.trim(); const div = document.getElementById("employeeDetails"); div.innerHTML = ""; const emp = employees.find(e => e["Tokan No."] === token); if (!emp) { div.innerHTML = `

No employee found with token: ${token}

`; return; } div.innerHTML = `

Employee Details

${headers1.map(h => ``).join("")}
${h}${emp[h]}

Promotion Timeline

${promotionTimeline(emp)}

Seniority List

${showSeniority(emp)} `; } // Promotion Timeline (improved) function promotionTimeline(emp) { const rankOrder = ["USL","SSK","Tradesman Mate","SK","HSK II","HSK I","MCM"]; const idx = rankOrder.indexOf(emp["Rank"]); if (idx === -1) return "

Rank not in promotion ladder

"; const retirementYear = yearOf(emp["Date of Retirement"]); let html = ""; return html; } // Seniority List function showSeniority(emp) { const peers = employees.filter(e => e["Post"] === emp["Post"] && e["Rank"] === emp["Rank"]); peers.sort((a, b) => dateValue(a[`Date of ${emp["Rank"]}`]) - dateValue(b[`Date of ${emp["Rank"]}`])); let html = "
    "; peers.forEach(p => { const highlight = p["Tokan No."] === emp["Tokan No."] ? "style='background:yellow;'" : ""; html += `
  1. ${p["Tokan No."]} - ${p["Name"]}
  2. `; }); html += "
"; return html; } window.onload = loadData;

Get in Touch

Need help or have suggestions for Seniority Manager? We're here to assist.