177 lines
5.5 KiB
JavaScript
177 lines
5.5 KiB
JavaScript
/* assets/js/main.js */
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const notesGrid = document.getElementById('notes-grid');
|
|
const modal = document.getElementById('note-editor-modal');
|
|
const editorTextarea = document.getElementById('note-editor-textarea');
|
|
const saveNoteBtn = document.getElementById('save-note-btn');
|
|
const noteIdInput = document.getElementById('note-editor-id');
|
|
|
|
// --- Main Functions ---
|
|
|
|
const fetchAndRenderNotes = async () => {
|
|
try {
|
|
const response = await fetch('api/notes.php');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const notes = await response.json();
|
|
renderNotes(notes);
|
|
} catch (error) {
|
|
console.error("Error fetching notes:", error);
|
|
notesGrid.innerHTML = '<p style="color: var(--text-muted);">Could not load notes. Please try again later.</p>';
|
|
}
|
|
};
|
|
|
|
const renderNotes = (notes) => {
|
|
notesGrid.innerHTML = ''; // Clear existing notes
|
|
|
|
// 1. Add "New Note" Card
|
|
const addCard = createAddNoteCard();
|
|
notesGrid.appendChild(addCard);
|
|
|
|
// 2. Add Note Cards
|
|
if (Array.isArray(notes)) {
|
|
notes.forEach(note => {
|
|
const noteCard = createNoteCard(note);
|
|
notesGrid.appendChild(noteCard);
|
|
});
|
|
}
|
|
};
|
|
|
|
// --- UI Element Creation ---
|
|
|
|
const createAddNoteCard = () => {
|
|
const card = document.createElement('div');
|
|
card.className = 'note-card add-note-card';
|
|
card.innerHTML = "
|
|
<div class=\"add-note-icon\"><i class=\"fas fa-plus\"></i></div>
|
|
<div class=\"add-note-text\">Add New Note</div>
|
|
";
|
|
card.addEventListener('click', () => openEditor());
|
|
return card;
|
|
};
|
|
|
|
const createNoteCard = (note) => {
|
|
const card = document.createElement('div');
|
|
card.className = 'note-card';
|
|
card.dataset.id = note.id;
|
|
|
|
// Auto-link URLs
|
|
const linkedContent = (note.content || '').replace(/(https?:\[^\]+)/g, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>');
|
|
|
|
card.innerHTML = "
|
|
<div class=\"note-card-content">${linkedContent}</div>
|
|
<div class=\"note-card-footer\">
|
|
<span class=\"note-card-date\">${new Date(note.updated_at).toLocaleDateString()}</span>
|
|
<button class=\"delete-note-btn\"><i class=\"fas fa-trash-alt\"></i></button>
|
|
</div>
|
|
";
|
|
|
|
// Edit by clicking the card body
|
|
card.querySelector('.note-card-content').addEventListener('click', () => openEditor(note));
|
|
|
|
// Delete button
|
|
card.querySelector('.delete-note-btn').addEventListener('click', (e) => {
|
|
e.stopPropagation(); // Prevent opening editor
|
|
showDeleteConfirmation(note.id);
|
|
});
|
|
|
|
return card;
|
|
};
|
|
|
|
// --- Editor Modal Logic ---
|
|
|
|
const openEditor = (note = {}) => {
|
|
noteIdInput.value = note.id || '';
|
|
editorTextarea.value = note.content || '';
|
|
modal.classList.add('show');
|
|
editorTextarea.focus();
|
|
};
|
|
|
|
const closeEditor = () => {
|
|
modal.classList.remove('show');
|
|
noteIdInput.value = '';
|
|
editorTextarea.value = '';
|
|
};
|
|
|
|
const saveNote = async () => {
|
|
const id = noteIdInput.value;
|
|
const content = editorTextarea.value;
|
|
|
|
const url = 'api/notes.php';
|
|
const formData = new FormData();
|
|
formData.append('content', content);
|
|
if (id) {
|
|
formData.append('id', id);
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: 'POST', // Using POST for both create and update
|
|
body: formData
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('Failed to save note');
|
|
}
|
|
|
|
closeEditor();
|
|
await fetchAndRenderNotes(); // Refresh notes list
|
|
} catch (error) {
|
|
console.error("Error saving note:", error);
|
|
alert('Could not save note. Please try again.');
|
|
}
|
|
};
|
|
|
|
const showDeleteConfirmation = (id) => {
|
|
if (confirm('Are you sure you want to delete this note?')) {
|
|
deleteNote(id);
|
|
}
|
|
};
|
|
|
|
const deleteNote = async (id) => {
|
|
try {
|
|
const formData = new FormData();
|
|
formData.append('id', id);
|
|
|
|
const response = await fetch('api/notes.php', {
|
|
method: 'DELETE',
|
|
body: formData
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('Failed to delete note');
|
|
}
|
|
|
|
await fetchAndRenderNotes(); // Refresh notes list
|
|
} catch (error) {
|
|
console.error("Error deleting note:", error);
|
|
alert('Could not delete note. Please try again.');
|
|
}
|
|
};
|
|
|
|
// --- Event Listeners ---
|
|
|
|
saveNoteBtn.addEventListener('click', saveNote);
|
|
|
|
// Close modal if clicking on the background
|
|
modal.addEventListener('click', (e) => {
|
|
if (e.target === modal) {
|
|
closeEditor();
|
|
}
|
|
});
|
|
|
|
// Close with Escape key
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && modal.classList.contains('show')) {
|
|
closeEditor();
|
|
}
|
|
});
|
|
|
|
// --- Initial Load ---
|
|
if (notesGrid) { // Only run on pages with the notes grid
|
|
fetchAndRenderNotes();
|
|
}
|
|
});
|