feat: Cmd+K search — rich keywords, real logos, category icons
- Projects searchable by technologies, "open source", category (cli/app/web) - Experience searchable by technologies, shows company logo + position - Courses show institution logos - Project logos used as icons instead of generic mdi:web - Category-specific fallback icons (console, apple, puzzle, etc.)
This commit is contained in:
@@ -111,50 +111,54 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert API experience entries to ninja-keys actions
|
||||
* @param {Array} experiences - Experience entries from API
|
||||
* @returns {Array} ninja-keys actions
|
||||
*/
|
||||
/** Category icon mapping */
|
||||
const categoryIcons = {
|
||||
cli: 'mdi:console',
|
||||
app: 'mdi:apple',
|
||||
web: 'mdi:web',
|
||||
webapp: 'mdi:web',
|
||||
plugin: 'mdi:puzzle',
|
||||
sdk: 'mdi:package-variant',
|
||||
contrib: 'mdi:source-pull'
|
||||
};
|
||||
|
||||
/** Build icon HTML — use project logo if available, fallback to iconify */
|
||||
function makeIcon(logoFile, folder, fallbackIcon) {
|
||||
if (logoFile) {
|
||||
return `<img src="/static/images/${folder}/${logoFile}" style="width:20px;height:20px;object-fit:contain;border-radius:3px" alt="">`;
|
||||
}
|
||||
return `<iconify-icon icon="${fallbackIcon}" width="20"></iconify-icon>`;
|
||||
}
|
||||
|
||||
function mapExperienceActions(experiences) {
|
||||
return experiences.map(exp => ({
|
||||
id: exp.id,
|
||||
title: exp.title,
|
||||
section: exp.section,
|
||||
keywords: `${exp.keywords} work job career`.toLowerCase(),
|
||||
icon: '<iconify-icon icon="mdi:office-building" width="20"></iconify-icon>',
|
||||
keywords: exp.keywords.toLowerCase(),
|
||||
icon: makeIcon(exp.icon, 'companies', 'mdi:office-building'),
|
||||
handler: () => scrollToSection(exp.id)
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert API project entries to ninja-keys actions
|
||||
* @param {Array} projects - Project entries from API
|
||||
* @returns {Array} ninja-keys actions
|
||||
*/
|
||||
function mapProjectActions(projects) {
|
||||
return projects.map(proj => ({
|
||||
id: proj.id,
|
||||
title: proj.title,
|
||||
section: proj.section,
|
||||
keywords: `${proj.keywords} project website app`.toLowerCase(),
|
||||
icon: '<iconify-icon icon="mdi:web" width="20"></iconify-icon>',
|
||||
keywords: proj.keywords.toLowerCase(),
|
||||
icon: makeIcon(proj.icon, 'projects', categoryIcons[proj.category] || 'mdi:web'),
|
||||
handler: () => scrollToSection(proj.id)
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert API course entries to ninja-keys actions
|
||||
* @param {Array} courses - Course entries from API
|
||||
* @returns {Array} ninja-keys actions
|
||||
*/
|
||||
function mapCourseActions(courses) {
|
||||
return courses.map(course => ({
|
||||
id: course.id,
|
||||
title: course.title,
|
||||
section: course.section,
|
||||
keywords: `${course.keywords} course training certification`.toLowerCase(),
|
||||
icon: '<iconify-icon icon="mdi:school" width="20"></iconify-icon>',
|
||||
keywords: course.keywords.toLowerCase(),
|
||||
icon: makeIcon(course.icon, 'courses', 'mdi:school'),
|
||||
handler: () => scrollToSection(course.id)
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user