feat: Add CMD+K command palette with ninja-keys integration

Implement a command palette accessible via CMD+K/Ctrl+K using the ninja-keys
web component. Features include:

- New /api/cmd-k endpoint serving dynamic CV entries (experiences, projects, courses)
- Language-aware responses with 1-hour cache headers
- Scroll-to-section functionality for quick navigation
- Enhanced keyboard shortcuts modal with CMD+K documentation
- Comprehensive test coverage for API and UI interactions

Also includes cleanup of deprecated debug test files and various UI polish
improvements to contact form, themes, and action bar components.
This commit is contained in:
juanatsap
2025-12-01 13:03:06 +00:00
parent 976b8ae2e2
commit 9a848e8c53
45 changed files with 3070 additions and 1587 deletions
+52 -20
View File
@@ -1,7 +1,21 @@
{{define "contact-modal"}}
<!-- Contact Form Modal - Native Dialog -->
<dialog id="contact-modal" class="info-modal no-print"
_="on click call closeOnBackdrop(me, event)">
_="on click call closeOnBackdrop(me, event)
on show
-- Reset form state when modal opens
set form to getElementById('contact-form')
if form
call form.reset()
set formFields to querySelectorAll('.form-group') in form
repeat for field in formFields
remove .hidden from field
end
remove .hidden from querySelector('.form-actions') in form
remove .hidden from querySelector('.form-note') in form
set responseDiv to getElementById('contact-response')
if responseDiv set responseDiv.innerHTML to ''
end">
<div class="info-modal-content">
<button class="info-modal-close" onclick="document.getElementById('contact-modal').close()" aria-label="{{.UI.ContactModal.Close}}">
<iconify-icon icon="mdi:close" width="24" height="24"></iconify-icon>
@@ -25,11 +39,21 @@
hx-target="#contact-response"
hx-swap="innerHTML"
hx-indicator="#contact-spinner"
hx-headers='{"X-Requested-With": "htmx"}'
hx-headers='{"X-Requested-With": "XMLHttpRequest"}'
_="on htmx:afterRequest
if event.detail.successful
wait 2s then call document.getElementById('contact-modal').close()
end">
-- Check if response contains success message (not validation error)
set responseDiv to document.getElementById('contact-response')
if responseDiv is not null and responseDiv.querySelector('.contact-success') is not null
-- Hide all form fields and show only success message
set formFields to me.querySelectorAll('.form-group')
repeat for field in formFields
add .hidden to field
end
add .hidden to me.querySelector('.form-actions')
add .hidden to me.querySelector('.form-note')
-- Close modal after 3 seconds
wait 3s then call document.getElementById('contact-modal').close()
end">
<!-- Honeypot field - hidden, should be empty -->
<div style="position: absolute; left: -9999px;" aria-hidden="true">
@@ -134,29 +158,37 @@
</div>
</dialog>
<!-- Initialize form timestamp on page load -->
<!-- Initialize form timestamp on page load and modal open -->
<script>
(function() {
'use strict';
document.addEventListener('DOMContentLoaded', function() {
function resetContactFormTimestamp() {
const timestampField = document.getElementById('contact-form-loaded-at');
if (timestampField) {
timestampField.value = Date.now();
}
});
// Reset timestamp when modal opens
const contactModal = document.getElementById('contact-modal');
if (contactModal) {
contactModal.addEventListener('click', function(e) {
if (e.target === contactModal && contactModal.open) {
const timestampField = document.getElementById('contact-form-loaded-at');
if (timestampField) {
timestampField.value = Date.now();
}
}
});
}
// Set initial timestamp on page load
document.addEventListener('DOMContentLoaded', resetContactFormTimestamp);
// Reset timestamp when modal opens (using MutationObserver to catch dialog open)
document.addEventListener('DOMContentLoaded', function() {
const contactModal = document.getElementById('contact-modal');
if (contactModal) {
// Observer watches for the 'open' attribute being added
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'open' && contactModal.hasAttribute('open')) {
resetContactFormTimestamp();
}
});
});
observer.observe(contactModal, { attributes: true });
}
});
})();
</script>
{{end}}