| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Advanced Note Taking App</title> |
| <link href="https://cdn.tailwindcss.com" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| |
| .modal { |
| display: none; |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| background-color: rgba(0, 0, 0, 0.5); |
| z-index: 1000; |
| justify-content: center; |
| align-items: center; |
| } |
| |
| .modal.active { |
| display: flex; |
| } |
| |
| .modal-content { |
| background-color: white; |
| border-radius: 0.5rem; |
| width: 90%; |
| max-width: 500px; |
| max-height: 90vh; |
| overflow-y: auto; |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); |
| animation: modalFadeIn 0.3s ease-out; |
| } |
| |
| @keyframes modalFadeIn { |
| from { |
| opacity: 0; |
| transform: translateY(-20px); |
| } |
| to { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| } |
| |
| .note-card { |
| transition: all 0.2s ease; |
| } |
| |
| .note-card:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| |
| .tag { |
| transition: all 0.2s ease; |
| } |
| |
| .tag:hover { |
| transform: scale(1.05); |
| } |
| |
| .search-bar:focus { |
| outline: none; |
| box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); |
| } |
| |
| |
| ::-webkit-scrollbar { |
| width: 8px; |
| } |
| |
| ::-webkit-scrollbar-track { |
| background: #f1f1f1; |
| border-radius: 10px; |
| } |
| |
| ::-webkit-scrollbar-thumb { |
| background: #888; |
| border-radius: 10px; |
| } |
| |
| ::-webkit-scrollbar-thumb:hover { |
| background: #555; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-100 min-h-screen"> |
| |
| <header class="bg-indigo-600 text-white shadow-lg"> |
| <div class="container mx-auto px-4 py-6"> |
| <div class="flex justify-between items-center"> |
| <div class="flex items-center space-x-2"> |
| <i class="fas fa-book text-2xl"></i> |
| <h1 class="text-2xl font-bold">NoteMaster</h1> |
| </div> |
| <div class="flex items-center space-x-4"> |
| <button id="theme-toggle" class="p-2 rounded-full hover:bg-indigo-700 transition"> |
| <i class="fas fa-moon"></i> |
| </button> |
| <button id="user-menu" class="p-2 rounded-full hover:bg-indigo-700 transition"> |
| <i class="fas fa-user"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <main class="container mx-auto px-4 py-8"> |
| |
| <div class="mb-8"> |
| <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4"> |
| <div class="relative flex-grow"> |
| <input type="text" id="search" placeholder="Search notes..." |
| class="w-full px-4 py-2 pl-10 rounded-lg border border-gray-300 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition"> |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
| </div> |
| <div class="flex space-x-2"> |
| <select id="filter-tag" class="px-4 py-2 rounded-lg border border-gray-300 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition"> |
| <option value="">All Tags</option> |
| <option value="work">Work</option> |
| <option value="personal">Personal</option> |
| <option value="ideas">Ideas</option> |
| <option value="important">Important</option> |
| </select> |
| <button id="new-note-btn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition flex items-center space-x-2"> |
| <i class="fas fa-plus"></i> |
| <span>New Note</span> |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="notes-container" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> |
| |
| </div> |
|
|
| |
| <div id="empty-state" class="text-center py-16 hidden"> |
| <i class="fas fa-sticky-note text-6xl text-gray-300 mb-4"></i> |
| <h2 class="text-2xl font-semibold text-gray-600">No notes found</h2> |
| <p class="text-gray-500 mt-2">Create your first note by clicking the "New Note" button</p> |
| </div> |
| </main> |
|
|
| |
| <div id="note-modal" class="modal"> |
| <div class="modal-content"> |
| <div class="p-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-semibold" id="modal-title">New Note</h3> |
| <button id="close-modal" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="mb-4"> |
| <input type="text" id="note-title" placeholder="Title" |
| class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition mb-2"> |
| <textarea id="note-content" placeholder="Write your note here..." rows="8" |
| class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition"></textarea> |
| </div> |
| |
| <div class="mb-4"> |
| <label class="block text-sm font-medium text-gray-700 mb-2">Tags</label> |
| <div class="flex flex-wrap gap-2 mb-2" id="tags-container"> |
| |
| </div> |
| <div class="flex"> |
| <input type="text" id="new-tag" placeholder="Add tag..." |
| class="flex-grow px-4 py-2 rounded-l-lg border border-gray-300 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition"> |
| <button id="add-tag" class="px-4 py-2 bg-indigo-600 text-white rounded-r-lg hover:bg-indigo-700 transition"> |
| <i class="fas fa-plus"></i> |
| </button> |
| </div> |
| </div> |
| |
| <div class="flex justify-between"> |
| <div> |
| <label class="inline-flex items-center"> |
| <input type="checkbox" id="note-pinned" class="rounded text-indigo-600 focus:ring-indigo-500"> |
| <span class="ml-2 text-sm text-gray-700">Pin note</span> |
| </label> |
| </div> |
| <div class="flex space-x-2"> |
| <button id="cancel-note" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100 transition"> |
| Cancel |
| </button> |
| <button id="save-note" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition"> |
| Save |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="delete-modal" class="modal"> |
| <div class="modal-content"> |
| <div class="p-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h3 class="text-xl font-semibold">Delete Note</h3> |
| <button id="close-delete-modal" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <p class="mb-6 text-gray-700">Are you sure you want to delete this note? This action cannot be undone.</p> |
| |
| <div class="flex justify-end space-x-2"> |
| <button id="cancel-delete" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100 transition"> |
| Cancel |
| </button> |
| <button id="confirm-delete" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition"> |
| Delete |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| const notesContainer = document.getElementById('notes-container'); |
| const emptyState = document.getElementById('empty-state'); |
| const searchInput = document.getElementById('search'); |
| const filterTag = document.getElementById('filter-tag'); |
| const newNoteBtn = document.getElementById('new-note-btn'); |
| const noteModal = document.getElementById('note-modal'); |
| const closeModal = document.getElementById('close-modal'); |
| const cancelNote = document.getElementById('cancel-note'); |
| const saveNote = document.getElementById('save-note'); |
| const noteTitle = document.getElementById('note-title'); |
| const noteContent = document.getElementById('note-content'); |
| const tagsContainer = document.getElementById('tags-container'); |
| const newTagInput = document.getElementById('new-tag'); |
| const addTagBtn = document.getElementById('add-tag'); |
| const notePinned = document.getElementById('note-pinned'); |
| const deleteModal = document.getElementById('delete-modal'); |
| const closeDeleteModal = document.getElementById('close-delete-modal'); |
| const cancelDelete = document.getElementById('cancel-delete'); |
| const confirmDelete = document.getElementById('confirm-delete'); |
| const themeToggle = document.getElementById('theme-toggle'); |
| |
| |
| let notes = JSON.parse(localStorage.getItem('notes')) || []; |
| let currentNoteId = null; |
| let tags = []; |
| let noteToDeleteId = null; |
| |
| |
| function init() { |
| renderNotes(); |
| setupEventListeners(); |
| checkEmptyState(); |
| } |
| |
| |
| function setupEventListeners() { |
| |
| newNoteBtn.addEventListener('click', openNewNoteModal); |
| closeModal.addEventListener('click', closeNoteModal); |
| cancelNote.addEventListener('click', closeNoteModal); |
| saveNote.addEventListener('click', saveCurrentNote); |
| |
| |
| addTagBtn.addEventListener('click', addTag |
| </html> |