Auto-deploy: 2026-08-05 16:17:53
This commit is contained in:
@@ -39,12 +39,18 @@ function loadSettings() {
|
||||
document.getElementById('api-key-input').value = data.apiKey;
|
||||
setKeyStatus('ok');
|
||||
}
|
||||
// A profile saved before the CV was rewritten describes a different person
|
||||
// than the PDF we now generate, so every prompt built from it would
|
||||
// contradict the attached CV. Migrate it back to the source of truth.
|
||||
const STALE_MARKERS = [
|
||||
'CTO & Technical Architect',
|
||||
'Senior Backend Engineer & Systems Architect',
|
||||
'IntaleqMaps',
|
||||
'hamzaayed.dev@gmail.com'
|
||||
];
|
||||
let profile = data.userProfile || DEFAULT_PROFILE;
|
||||
if (profile.includes('hamzaayed@intaleqapp.com') || profile.includes('hamzaayedflutter@gmail.com') || profile.includes('hamzaayed@tripz-egypt.com')) {
|
||||
profile = profile
|
||||
.replace(/hamzaayed@intaleqapp\.com/g, 'hamzaayed.dev@gmail.com')
|
||||
.replace(/hamzaayedflutter@gmail\.com/g, 'hamzaayed.dev@gmail.com')
|
||||
.replace(/hamzaayed@tripz-egypt\.com/g, 'hamzaayed.dev@gmail.com');
|
||||
if (STALE_MARKERS.some(marker => profile.includes(marker))) {
|
||||
profile = DEFAULT_PROFILE;
|
||||
chrome.storage.sync.set({ userProfile: profile });
|
||||
}
|
||||
document.getElementById('profile-textarea').value = profile;
|
||||
@@ -173,6 +179,25 @@ document.getElementById('clear-all-btn').addEventListener('click', () => {
|
||||
// ─── Autofill Functionality ──────────────────────────────────────────────────
|
||||
|
||||
function parseProfileText(text) {
|
||||
// When the textarea still holds the unmodified default, read the fields
|
||||
// straight from the structured profile instead of regex-scraping the rendered
|
||||
// text. Scraping only exists for the case where the user hand-edits it.
|
||||
if (typeof PROFILE_DATA !== 'undefined' && text === DEFAULT_PROFILE) {
|
||||
const id = PROFILE_DATA.identity;
|
||||
const nameParts = id.fullName.split(' ');
|
||||
return {
|
||||
fullName: id.fullName,
|
||||
firstName: nameParts[0] || '',
|
||||
lastName: nameParts.slice(1).join(' ') || '',
|
||||
email: id.email,
|
||||
phone: id.phone,
|
||||
linkedin: id.linkedin,
|
||||
github: '',
|
||||
summary: PROFILE_DATA.summary,
|
||||
cvText: text
|
||||
};
|
||||
}
|
||||
|
||||
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/;
|
||||
const phoneRegex = /\+?[0-9]{1,4}[ \t.-]?[0-9]{3,4}[ \t.-]?[0-9]{3,4}/;
|
||||
const linkedinRegex = /(https?:\/\/)?(www\.)?linkedin\.com\/in\/[a-zA-Z0-9_-]+/;
|
||||
@@ -199,7 +224,13 @@ function parseProfileText(text) {
|
||||
let summary = "";
|
||||
const summaryIdx = text.toLowerCase().indexOf("summary:");
|
||||
if (summaryIdx !== -1) {
|
||||
const skillsIdx = text.toLowerCase().indexOf("core skills:", summaryIdx);
|
||||
// Stop at whichever section header comes next; the rendered profile uses
|
||||
// "TARGET ROLES:", hand-written ones often use a skills header.
|
||||
const lower = text.toLowerCase();
|
||||
const candidates = ['target roles:', 'technical skills:', 'core skills:', 'skills:']
|
||||
.map(h => lower.indexOf(h, summaryIdx))
|
||||
.filter(i => i !== -1);
|
||||
const skillsIdx = candidates.length ? Math.min(...candidates) : -1;
|
||||
if (skillsIdx !== -1) {
|
||||
summary = text.substring(summaryIdx + 8, skillsIdx).trim();
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user