Online Smart Note-Taking App

Online Smart Note-Taking App

Your Smart Notebook

Select a note to edit or create a new one to get started.

No notes found.

'; return; } filteredNotes.forEach(note => { const item = document.createElement('div'); item.className = `p-3 rounded-lg cursor-pointer hover:bg-gray-100 ${note.id === currentNoteId ? 'bg-blue-100' : ''}`; item.dataset.id = note.id; item.innerHTML = `

${note.title || 'Untitled Note'}

${note.content.substring(0, 40) || 'No content'}

${new Date(note.lastModified).toLocaleString('en-US')}

`; item.addEventListener('click', () => selectNote(note.id)); noteList.appendChild(item); }); } function displayEditor(show = true) { welcomePanel.classList.toggle('hidden', show); editorPanel.classList.toggle('hidden', !show); editorActions.classList.toggle('hidden', !show); } function selectNote(id) { const note = notes.find(n => n.id === id); if (!note) return; currentNoteId = id; noteIdInput.value = note.id; noteTitleInput.value = note.title; noteContentInput.value = note.content; displayEditor(true); renderNoteList(searchInput.value); } // --- DATA MANIPULATION (CRUD) --- function saveNotes() { localStorage.setItem('smartNotes', JSON.stringify(notes)); } function createNewNote() { const newNote = { id: Date.now(), title: '', content: '', lastModified: new Date().toISOString() }; notes.push(newNote); saveNotes(); selectNote(newNote.id); } function updateNote() { if (!currentNoteId) return; const note = notes.find(n => n.id === currentNoteId); if (note) { note.title = noteTitleInput.value; note.content = noteContentInput.value; note.lastModified = new Date().toISOString(); clearTimeout(saveTimeout); saveTimeout = setTimeout(() => { saveNotes(); renderNoteList(searchInput.value); }, 500); // Debounce saving } } function deleteNote() { if (!currentNoteId) return; notes = notes.filter(n => n.id !== currentNoteId); saveNotes(); currentNoteId = null; displayEditor(false); renderNoteList(searchInput.value); } // --- EVENT LISTENERS --- newNoteBtn.addEventListener('click', createNewNote); deleteNoteBtn.addEventListener('click', deleteNote); searchInput.addEventListener('input', () => renderNoteList(searchInput.value)); noteTitleInput.addEventListener('input', updateNote); noteContentInput.addEventListener('input', updateNote); // --- AI SUMMARY LOGIC --- summarizeBtn.addEventListener('click', async () => { const content = noteContentInput.value; if (content.trim().length < 50) { summaryContent.innerHTML = '

Please write more content (at least 50 characters) to generate a summary.

'; summaryModal.classList.remove('hidden'); return; } summaryModal.classList.remove('hidden'); summaryContent.innerHTML = '
'; try { const summary = await callGeminiAPI(content); summaryContent.innerHTML = `

${summary}

`; } catch (error) { console.error("Summarization failed:", error); summaryContent.innerHTML = '

Failed to generate summary. Please try again later.

'; } }); closeModalBtn.addEventListener('click', () => summaryModal.classList.add('hidden')); async function callGeminiAPI(text) { const apiKey = ""; // API key handled by environment const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const prompt = `Summarize the following note into a few key bullet points:\n\n---\n${text}\n---`; const payload = { contents: [{ parts: [{ text: prompt }] }] }; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) throw new Error(`API request failed with status ${response.status}`); const result = await response.json(); return result.candidates[0].content.parts[0].text; } // --- PDF DOWNLOAD LOGIC --- downloadPdfBtn.addEventListener('click', () => { if (!currentNoteId) return; const note = notes.find(n => n.id === currentNoteId); const { jsPDF } = window.jspdf; const tempDiv = document.createElement('div'); tempDiv.innerHTML = `

${note.title}

${note.content}

`; document.body.appendChild(tempDiv); html2canvas(document.getElementById('pdf-content'), { scale: 2 }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const widthInPdf = pdfWidth - 80; const heightInPdf = widthInPdf / ratio; pdf.addImage(imgData, 'PNG', 40, 40, widthInPdf, heightInPdf); pdf.save(`${note.title.replace(/\s/g, '-') || 'note'}.pdf`); document.body.removeChild(tempDiv); }); }); // --- INITIALIZATION --- renderNoteList(); displayEditor(false); lucide.createIcons(); });
Scroll to Top