Removed all job category aggregation, display dates job posted and minor fixes
This commit is contained in:
@@ -1,18 +1,42 @@
|
||||
// popup.js
|
||||
|
||||
var TITLE_ORDER = [
|
||||
'Full-Stack Engineer',
|
||||
'AI Engineer',
|
||||
'Data Scientist',
|
||||
'Front-End Engineer',
|
||||
];
|
||||
|
||||
var PROFESSION_BADGES = {
|
||||
'Full-Stack Engineer': { label: 'FS', color: '#4C6EF5' },
|
||||
'AI Engineer': { label: 'AI', color: '#9C36B5' },
|
||||
'Data Scientist': { label: 'DS', color: '#0CA678' },
|
||||
'Front-End Engineer': { label: 'FE', color: '#E8590C' },
|
||||
var PROFESSION_COLORS = {
|
||||
'Full-Stack Engineer': '#4C6EF5',
|
||||
'AI Engineer': '#9C36B5',
|
||||
'Data Scientist': '#0CA678',
|
||||
'Front-End Engineer': '#E8590C',
|
||||
};
|
||||
var DEFAULT_PROFESSION_COLOR = '#C9971C';
|
||||
|
||||
// Recomputes "X ago" fresh every render from the stored absolute timestamp,
|
||||
// so it's always accurate instead of a stale cached string.
|
||||
function formatTimeAgo(timestamp) {
|
||||
if (!timestamp) return '';
|
||||
var diffMs = Date.now() - timestamp;
|
||||
if (diffMs < 0) diffMs = 0;
|
||||
|
||||
var minutes = Math.floor(diffMs / (60 * 1000));
|
||||
var hours = Math.floor(diffMs / (60 * 60 * 1000));
|
||||
var days = Math.floor(diffMs / (24 * 60 * 60 * 1000));
|
||||
var weeks = Math.floor(days / 7);
|
||||
var months = Math.floor(days / 30);
|
||||
|
||||
if (minutes < 60)
|
||||
return (
|
||||
'Posted ' +
|
||||
Math.max(minutes, 1) +
|
||||
' minute' +
|
||||
(minutes === 1 ? '' : 's') +
|
||||
' ago'
|
||||
);
|
||||
if (hours < 24)
|
||||
return 'Posted ' + hours + ' hour' + (hours === 1 ? '' : 's') + ' ago';
|
||||
if (days < 7)
|
||||
return 'Posted ' + days + ' day' + (days === 1 ? '' : 's') + ' ago';
|
||||
if (weeks < 5)
|
||||
return 'Posted ' + weeks + ' week' + (weeks === 1 ? '' : 's') + ' ago';
|
||||
return 'Posted ' + months + ' month' + (months === 1 ? '' : 's') + ' ago';
|
||||
}
|
||||
|
||||
function sortJobsById(jobs) {
|
||||
return jobs.slice().sort(function (a, b) {
|
||||
@@ -20,58 +44,6 @@ function sortJobsById(jobs) {
|
||||
});
|
||||
}
|
||||
|
||||
function renderJob(jobList, job, newBadgeUntil, now) {
|
||||
var jobElement = document.createElement('div');
|
||||
jobElement.className = 'job-item';
|
||||
|
||||
var startInfo = job.posted_date || '';
|
||||
var postedAgo = job.posted_ago || '';
|
||||
var companyName =
|
||||
typeof job.company === 'object'
|
||||
? (job.company && job.company.name) || 'Company'
|
||||
: job.company || 'Company';
|
||||
|
||||
var isNew =
|
||||
newBadgeUntil && newBadgeUntil[job.id] && newBadgeUntil[job.id] > now;
|
||||
var badgeHtml = '';
|
||||
if (isNew) {
|
||||
var profession = job.professionalTitle || 'Full-Stack Engineer';
|
||||
var badgeInfo = PROFESSION_BADGES[profession] || {
|
||||
label: 'NEW',
|
||||
color: '#555555',
|
||||
};
|
||||
badgeHtml =
|
||||
'<span class="new-badge" style="background-color:' +
|
||||
badgeInfo.color +
|
||||
'">' +
|
||||
badgeInfo.label +
|
||||
' \u00B7 NEW</span>';
|
||||
}
|
||||
|
||||
jobElement.innerHTML =
|
||||
'<div class="job-title">' +
|
||||
badgeHtml +
|
||||
job.title +
|
||||
'</div>' +
|
||||
'<div class="job-company">' +
|
||||
companyName +
|
||||
'</div>' +
|
||||
'<div class="job-location">' +
|
||||
(job.location || 'Remote') +
|
||||
'</div>' +
|
||||
'<div class="job-posted">' +
|
||||
startInfo +
|
||||
(postedAgo ? ' - ' + postedAgo : '') +
|
||||
'</div>';
|
||||
|
||||
jobElement.addEventListener('click', function () {
|
||||
var url = job.url || 'https://app.andela.com/job-postings/' + job.id;
|
||||
chrome.tabs.create({ url: url });
|
||||
});
|
||||
|
||||
jobList.appendChild(jobElement);
|
||||
}
|
||||
|
||||
function sortWithNewFirst(jobs, newBadgeUntil, now) {
|
||||
return jobs.slice().sort(function (a, b) {
|
||||
var aNew =
|
||||
@@ -83,6 +55,55 @@ function sortWithNewFirst(jobs, newBadgeUntil, now) {
|
||||
});
|
||||
}
|
||||
|
||||
function renderJob(jobList, job, newBadgeUntil, now) {
|
||||
var jobElement = document.createElement('div');
|
||||
jobElement.className = 'job-item';
|
||||
|
||||
var startInfo = job.posted_date || '';
|
||||
var postedAgo = formatTimeAgo(job.posted_timestamp);
|
||||
var companyName =
|
||||
typeof job.company === 'object'
|
||||
? (job.company && job.company.name) || 'Company'
|
||||
: job.company || 'Company';
|
||||
|
||||
var profession = job.professionalTitle || 'Full-Stack Engineer';
|
||||
var professionColor =
|
||||
PROFESSION_COLORS[profession] || DEFAULT_PROFESSION_COLOR;
|
||||
|
||||
var isNew =
|
||||
newBadgeUntil && newBadgeUntil[job.id] && newBadgeUntil[job.id] > now;
|
||||
var newBadgeHtml = isNew ? '<span class="new-badge">NEW</span>' : '';
|
||||
|
||||
jobElement.innerHTML =
|
||||
'<div class="job-title">' +
|
||||
newBadgeHtml +
|
||||
job.title +
|
||||
'</div>' +
|
||||
'<div class="job-company">' +
|
||||
companyName +
|
||||
'</div>' +
|
||||
'<div class="job-location">' +
|
||||
(job.location || 'Remote') +
|
||||
'</div>' +
|
||||
'<div class="job-posted-row"><span>' +
|
||||
startInfo +
|
||||
'</span><span>' +
|
||||
postedAgo +
|
||||
'</span></div>' +
|
||||
'<div class="profession-tag" style="color:' +
|
||||
professionColor +
|
||||
'">' +
|
||||
profession +
|
||||
'</div>';
|
||||
|
||||
jobElement.addEventListener('click', function () {
|
||||
var url = job.url || 'https://app.andela.com/job-postings/' + job.id;
|
||||
chrome.tabs.create({ url: url });
|
||||
});
|
||||
|
||||
jobList.appendChild(jobElement);
|
||||
}
|
||||
|
||||
function updateUI(data) {
|
||||
var lastAndelaJobs = data.lastAndelaJobs || [];
|
||||
var lastAndelaUpdated = data.lastAndelaUpdated;
|
||||
@@ -106,9 +127,13 @@ function updateUI(data) {
|
||||
return;
|
||||
}
|
||||
|
||||
var opportunities = lastAndelaJobs.filter(function (j) {
|
||||
return j.kind === 'opportunity';
|
||||
});
|
||||
var opportunities = sortWithNewFirst(
|
||||
lastAndelaJobs.filter(function (j) {
|
||||
return j.kind === 'opportunity';
|
||||
}),
|
||||
newBadgeUntil,
|
||||
now,
|
||||
);
|
||||
var applied = sortJobsById(
|
||||
lastAndelaJobs.filter(function (j) {
|
||||
return j.kind !== 'opportunity';
|
||||
@@ -121,29 +146,8 @@ function updateUI(data) {
|
||||
oppHeading.textContent = 'Open Opportunities';
|
||||
jobList.appendChild(oppHeading);
|
||||
|
||||
TITLE_ORDER.forEach(function (title) {
|
||||
var group = sortWithNewFirst(
|
||||
opportunities.filter(function (j) {
|
||||
return (j.professionalTitle || 'Full-Stack Engineer') === title;
|
||||
}),
|
||||
newBadgeUntil,
|
||||
now,
|
||||
);
|
||||
if (!group.length) return;
|
||||
|
||||
var badgeInfo = PROFESSION_BADGES[title] || { color: '#C9971C' };
|
||||
var titleHeading = document.createElement('h3');
|
||||
titleHeading.className = 'profession-heading';
|
||||
titleHeading.innerHTML =
|
||||
'<span class="profession-dot" style="background-color:' +
|
||||
badgeInfo.color +
|
||||
'"></span>' +
|
||||
title;
|
||||
jobList.appendChild(titleHeading);
|
||||
|
||||
group.slice(0, 10).forEach(function (job) {
|
||||
renderJob(jobList, job, newBadgeUntil, now);
|
||||
});
|
||||
opportunities.slice(0, 30).forEach(function (job) {
|
||||
renderJob(jobList, job, newBadgeUntil, now);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user