/* ============================================================
jobboard.js — Job Posting Center: publish + track performance
============================================================ */
window.Views = window.Views || {};
window.JobBoard = {};
Views.jobboard = function () {
const totals = DB.publishings.reduce((a, p) => ({ views: a.views + p.views, clicks: a.clicks + p.clicks, apps: a.apps + p.apps }), { views: 0, clicks: 0, apps: 0 });
const conv = totals.views ? ((totals.apps / totals.views) * 100).toFixed(1) : 0;
const statCard = (label, val, icn, cls, sub) => `
Job Board
Publish requisitions across channels and track performance
${statCard('Total Views', totals.views.toLocaleString(), 'eye', 'i-blue', 'across all platforms')}
${statCard('Total Clicks', totals.clicks.toLocaleString(), 'target', 'i-purple', ((totals.clicks / totals.views) * 100).toFixed(1) + '% CTR')}
${statCard('Applications', totals.apps.toLocaleString(), 'users', 'i-green', 'from job boards')}
${statCard('Conversion Rate', conv + '%', 'trending-up', 'i-teal', 'view → application')}
Platform Performance
Applications by channel
${DB.publishPlatforms.map(p => `
${UI.icon(p.icon)}
${p.name}
${p.cost === 'Free' ? 'Free posting' : 'Paid · ' + p.cost}
${p.connected ? UI.badge('Connected', 'b-green') : `
`}
`).join('')}
Active Postings
${DB.publishings.length} live postings across ${platRows.length} platforms
${table.html}
`;
return {
html,
onMount() {
table.mount();
Charts.horizontalBar(document.getElementById('jbChart'), {
labels: platRows.map(p => p[0]), data: platRows.map(p => p[1].apps)
});
}
};
};
// ---------------- Publish flow (stepper modal) ----------------
JobBoard.publishFlow = function (jobId) {
const state = { step: 1, jobId: jobId || DB.jobs.filter(j => j.status === 'Open')[0].id, platforms: ['Career Portal'] };
JobBoard._state = state;
JobBoard._renderFlow();
};
JobBoard._renderFlow = function () {
const state = JobBoard._state;
const steps = ['Select Job', 'Approval', 'Platforms', 'Publish'];
const stepper = `${steps.map((s, i) => {
const n = i + 1;
const cls = n < state.step ? 'done' : n === state.step ? 'active' : '';
return `
${n < state.step ? '✓' : n}
${s}
${i < steps.length - 1 ? `
` : ''}`;
}).join('')}
`;
let body = stepper;
if (state.step === 1) {
const opts = DB.jobs.filter(j => j.status !== 'Draft').map(j => `
${UI.icon('check-circle')}
Published Successfully
${DB.getJob(state.jobId).title} is now live on ${state.platforms.length} platform${state.platforms.length > 1 ? 's' : ''}
${state.platforms.map(p => { const pl = DB.publishPlatforms.find(x => x.name === p); return `${pl.name}`; }).join('')}
`;
}
let footer;
if (state.step === 4) footer = `