Proje Detayları

Adım Adım Geliştirme

Bu bölümde, not alma uygulamasını adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.

Adım 1: Proje Yapısını Oluşturma

İlk olarak, projemiz için gerekli dosyaları oluşturalım:

  • index.html - Ana HTML dosyası
  • style.css - CSS stil dosyası
  • script.js - JavaScript kod dosyası
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Not Alma Uygulaması</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
    <div class="notes-app">
        <div class="notes-header">
            <h2>Not Alma Uygulaması</h2>
        </div>
        
        <div class="notes-container">
            <div class="notes-sidebar">
                <div class="search-container">
                    <input type="text" class="search-input" placeholder="Notlarda ara..." id="searchInput">
                </div>
                <ul class="notes-list" id="notesList">
                    <!-- Not öğeleri buraya dinamik olarak eklenecek -->
                </ul>
            </div>
            
            <div class="notes-editor">
                <div class="editor-toolbar">
                    <div class="toolbar-left">
                        <button class="toolbar-btn" id="boldBtn"><i class="fas fa-bold"></i></button>
                        <button class="toolbar-btn" id="italicBtn"><i class="fas fa-italic"></i></button>
                        <button class="toolbar-btn" id="underlineBtn"><i class="fas fa-underline"></i></button>
                        <button class="toolbar-btn" id="listBtn"><i class="fas fa-list-ul"></i></button>
                    </div>
                    <div class="toolbar-right">
                        <button class="toolbar-btn" id="deleteNoteBtn"><i class="fas fa-trash-alt"></i></button>
                    </div>
                </div>
                <div class="editor-content">
                    <input type="text" class="note-title-input" id="noteTitleInput" placeholder="Not başlığı">
                    <textarea class="note-body-input" id="noteBodyInput" placeholder="Not içeriği..."></textarea>
                </div>
            </div>
        </div>
        
        <button class="add-note-btn" id="addNoteBtn"><i class="fas fa-plus"></i></button>
        
        <!-- Silme Onay Modalı -->
        <div class="delete-confirm-modal" id="deleteModal">
            <div class="modal-content">
                <div class="modal-title">Bu notu silmek istediğinizden emin misiniz?</div>
                <div class="modal-buttons">
                    <button class="modal-btn cancel-btn" id="cancelDeleteBtn">İptal</button>
                    <button class="modal-btn delete-btn" id="confirmDeleteBtn">Sil</button>
                </div>
            </div>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>
style.css
/* Genel Stiller */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f0f2f5;
    color: #333;
    line-height: 1.6;
    padding: 20px;
}

/* Not Alma Uygulaması Stilleri */
.notes-app {
    max-width: 1000px;
    margin: 0 auto;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    overflow: hidden;
    position: relative;
}

.notes-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 20px;
    background-color: #4caf50;
    color: white;
}

.notes-header h2 {
    margin: 0;
    font-size: 1.5rem;
}

.notes-container {
    display: flex;
    min-height: 500px;
    border-top: none;
}

.notes-sidebar {
    width: 30%;
    background-color: #f5f5f5;
    border-right: 1px solid #ddd;
    overflow-y: auto;
}

.notes-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.note-item {
    padding: 15px;
    border-bottom: 1px solid #ddd;
    cursor: pointer;
    transition: background-color 0.2s;
}

.note-item:hover {
    background-color: #eee;
}

.note-item.active {
    background-color: #e3f2fd;
    border-left: 4px solid #2196f3;
}

.note-title {
    font-weight: bold;
    margin-bottom: 5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.note-preview {
    color: #666;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.note-date {
    font-size: 0.8rem;
    color: #999;
    margin-top: 5px;
}

.notes-editor {
    width: 70%;
    display: flex;
    flex-direction: column;
}

.editor-toolbar {
    padding: 10px;
    background-color: #f9f9f9;
    border-bottom: 1px solid #ddd;
    display: flex;
    justify-content: space-between;
}

.toolbar-left {
    display: flex;
    gap: 10px;
}

.toolbar-right {
    display: flex;
    gap: 10px;
}

.toolbar-btn {
    background: none;
    border: none;
    padding: 5px 10px;
    cursor: pointer;
    border-radius: 3px;
    transition: background-color 0.2s;
}

.toolbar-btn:hover {
    background-color: #eee;
}

.toolbar-btn.active {
    background-color: #e3f2fd;
    color: #2196f3;
}

.editor-content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
}

.note-title-input {
    width: 100%;
    padding: 10px;
    font-size: 1.2rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    margin-bottom: 15px;
}

.note-body-input {
    width: 100%;
    height: calc(100% - 60px);
    padding: 10px;
    font-size: 1rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    resize: none;
    font-family: inherit;
}

.add-note-btn {
    position: absolute;
    bottom: 20px;
    right: 20px;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: #4caf50;
    color: white;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
    box-shadow: 0 3px 5px rgba(0,0,0,0.2);
    transition: background-color 0.3s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.add-note-btn:hover {
    background-color: #45a049;
}

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: #666;
    padding: 20px;
    text-align: center;
}

.empty-state i {
    font-size: 3rem;
    margin-bottom: 15px;
    color: #ddd;
}

.empty-state p {
    margin-bottom: 20px;
}

.empty-state button {
    padding: 10px 15px;
    background-color: #4caf50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.empty-state button:hover {
    background-color: #45a049;
}

.search-container {
    padding: 10px;
    border-bottom: 1px solid #ddd;
}

.search-input {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 0.9rem;
}

.delete-confirm-modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0,0,0,0.5);
}

.modal-content {
    background-color: #fefefe;
    margin: 15% auto;
    padding: 20px;
    border: 1px solid #888;
    width: 80%;
    max-width: 500px;
    border-radius: 5px;
    text-align: center;
}

.modal-title {
    font-size: 1.2rem;
    margin-bottom: 15px;
}

.modal-buttons {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 20px;
}

.modal-btn {
    padding: 8px 15px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

.cancel-btn {
    background-color: #f5f5f5;
    color: #333;
}

.delete-btn {
    background-color: #f44336;
    color: white;
}

/* Responsive Tasarım */
@media (max-width: 768px) {
    .notes-container {
        flex-direction: column;
    }
    
    .notes-sidebar, .notes-editor {
        width: 100%;
    }
    
    .notes-sidebar {
        border-right: none;
        border-bottom: 1px solid #ddd;
        max-height: 300px;
    }
}

Adım 2: JavaScript Kodunu Yazma

Şimdi, uygulamanın işlevselliğini sağlayacak JavaScript kodunu yazalım:

script.js
// DOM elementlerini seçme
const notesList = document.getElementById('notesList');
const noteTitleInput = document.getElementById('noteTitleInput');
const noteBodyInput = document.getElementById('noteBodyInput');
const addNoteBtn = document.getElementById('addNoteBtn');
const deleteNoteBtn = document.getElementById('deleteNoteBtn');
const searchInput = document.getElementById('searchInput');
const deleteModal = document.getElementById('deleteModal');
const cancelDeleteBtn = document.getElementById('cancelDeleteBtn');
const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
const boldBtn = document.getElementById('boldBtn');
const italicBtn = document.getElementById('italicBtn');
const underlineBtn = document.getElementById('underlineBtn');
const listBtn = document.getElementById('listBtn');

// Not verilerini LocalStorage'dan al veya boş bir dizi oluştur
let notes = JSON.parse(localStorage.getItem('notes')) || [];
let activeNoteId = null;

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Notları listele
    renderNotes();
    
    // Yeni not ekleme butonuna tıklama olayı
    addNoteBtn.addEventListener('click', addNewNote);
    
    // Not silme butonuna tıklama olayı
    deleteNoteBtn.addEventListener('click', () => {
        if (activeNoteId) {
            openDeleteModal();
        }
    });
    
    // Silme modalı iptal butonuna tıklama olayı
    cancelDeleteBtn.addEventListener('click', closeDeleteModal);
    
    // Silme modalı onay butonuna tıklama olayı
    confirmDeleteBtn.addEventListener('click', () => {
        deleteNote(activeNoteId);
        closeDeleteModal();
    });
    
    // Not listesine tıklama olayı (event delegation)
    notesList.addEventListener('click', (event) => {
        const noteItem = event.target.closest('.note-item');
        if (noteItem) {
            const noteId = parseInt(noteItem.dataset.id);
            setActiveNote(noteId);
        }
    });
    
    // Not başlığı değişiklik olayı
    noteTitleInput.addEventListener('input', saveActiveNote);
    
    // Not içeriği değişiklik olayı
    noteBodyInput.addEventListener('input', saveActiveNote);
    
    // Arama olayı
    searchInput.addEventListener('input', searchNotes);
    
    // Biçimlendirme butonları olayları
    boldBtn.addEventListener('click', () => formatText('bold'));
    italicBtn.addEventListener('click', () => formatText('italic'));
    underlineBtn.addEventListener('click', () => formatText('underline'));
    listBtn.addEventListener('click', () => formatText('list'));
    
    // İlk not varsa, onu aktif yap
    if (notes.length > 0) {
        setActiveNote(notes[0].id);
    } else {
        // Not yoksa, boş bir not oluştur
        addNewNote();
    }
});

// Notları listeleme fonksiyonu
function renderNotes(notesToRender = notes) {
    notesList.innerHTML = ''; // Önceki notları temizle
    
    if (notesToRender.length === 0) {
        // Not yoksa, boş durum mesajı göster
        notesList.innerHTML = `
            
                
                Henüz not bulunmuyor.
            
        `;
        return;
    }
    
    // Notları tarihe göre sırala (en yeni en üstte)
    notesToRender.sort((a, b) => b.updatedAt - a.updatedAt);
    
    // Her not için bir liste öğesi oluştur
    notesToRender.forEach(note => {
        const noteItem = document.createElement('li');
        noteItem.className = `note-item${note.id === activeNoteId ? ' active' : ''}`;
        noteItem.dataset.id = note.id;
        
        // Not içeriğinden önizleme oluştur (ilk 30 karakter)
        const preview = note.body.substring(0, 30) + (note.body.length > 30 ? '...' : '');
        
        // Tarih formatını oluştur
        const date = new Date(note.updatedAt);
        const formattedDate = `${date.toLocaleDateString('tr-TR', { day: 'numeric', month: 'long', year: 'numeric' })}, ${date.toLocaleTimeString('tr-TR', { hour: '2-digit', minute: '2-digit' })}`;
        
        noteItem.innerHTML = `
            ${note.title || 'Başlıksız Not'}
            ${preview}
            ${formattedDate}
        `;
        
        notesList.appendChild(noteItem);
    });
}

// Yeni not ekleme fonksiyonu
function addNewNote() {
    // Yeni not nesnesi oluştur
    const newNote = {
        id: Date.now(), // Benzersiz ID için şu anki zaman damgasını kullan
        title: '',
        body: '',
        createdAt: Date.now(),
        updatedAt: Date.now()
    };
    
    // Notu diziye ekle
    notes.unshift(newNote);
    
    // Notları kaydet
    saveNotes();
    
    // Notları yeniden listele
    renderNotes();
    
    // Yeni notu aktif yap
    setActiveNote(newNote.id);
}

// Aktif notu ayarlama fonksiyonu
function setActiveNote(noteId) {
    // Aktif not ID'sini güncelle
    activeNoteId = noteId;
    
    // Aktif notu bul
    const activeNote = notes.find(note => note.id === noteId);
    
    if (activeNote) {
        // Not başlığı ve içeriğini editöre yükle
        noteTitleInput.value = activeNote.title;
        noteBodyInput.value = activeNote.body;
        
        // Tüm not öğelerinden 'active' sınıfını kaldır
        document.querySelectorAll('.note-item').forEach(item => {
            item.classList.remove('active');
        });
        
        // Aktif not öğesine 'active' sınıfını ekle
        const activeNoteItem = document.querySelector(`.note-item[data-id="${noteId}"]`);
        if (activeNoteItem) {
            activeNoteItem.classList.add('active');
        }
    }
}

// Aktif notu kaydetme fonksiyonu
function saveActiveNote() {
    if (!activeNoteId) return;
    
    // Aktif notu bul
    const noteIndex = notes.findIndex(note => note.id === activeNoteId);
    
    if (noteIndex !== -1) {
        // Not başlığı ve içeriğini güncelle
        notes[noteIndex].title = noteTitleInput.value;
        notes[noteIndex].body = noteBodyInput.value;
        notes[noteIndex].updatedAt = Date.now();
        
        // Notları kaydet
        saveNotes();
        
        // Notları yeniden listele
        renderNotes();
    }
}

// Not silme fonksiyonu
function deleteNote(noteId) {
    // Notu diziden kaldır
    notes = notes.filter(note => note.id !== noteId);
    
    // Notları kaydet
    saveNotes();
    
    // Notları yeniden listele
    renderNotes();
    
    // Başka not varsa, ilk notu aktif yap
    if (notes.length > 0) {
        setActiveNote(notes[0].id);
    } else {
        // Not yoksa, editörü temizle
        noteTitleInput.value = '';
        noteBodyInput.value = '';
        activeNoteId = null;
    }
}

// Notları LocalStorage'a kaydetme fonksiyonu
function saveNotes() {
    localStorage.setItem('notes', JSON.stringify(notes));
}

// Notlarda arama fonksiyonu
function searchNotes() {
    const searchTerm = searchInput.value.toLowerCase();
    
    if (searchTerm === '') {
        // Arama terimi yoksa, tüm notları göster
        renderNotes();
    } else {
        // Arama terimine göre notları filtrele
        const filteredNotes = notes.filter(note => {
            return (
                note.title.toLowerCase().includes(searchTerm) ||
                note.body.toLowerCase().includes(searchTerm)
            );
        });
        
        // Filtrelenmiş notları göster
        renderNotes(filteredNotes);
    }
}

// Silme modalını açma fonksiyonu
function openDeleteModal() {
    deleteModal.style.display = 'block';
}

// Silme modalını kapatma fonksiyonu
function closeDeleteModal() {
    deleteModal.style.display = 'none';
}

// Metin biçimlendirme fonksiyonu
function formatText(format) {
    // Seçili metni al
    const textarea = noteBodyInput;
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const selectedText = textarea.value.substring(start, end);
    
    let formattedText = '';
    let cursorPosition = 0;
    
    switch (format) {
        case 'bold':
            formattedText = `**${selectedText}**`;
            cursorPosition = start + formattedText.length;
            break;
        case 'italic':
            formattedText = `*${selectedText}*`;
            cursorPosition = start + formattedText.length;
            break;
        case 'underline':
            formattedText = `_${selectedText}_`;
            cursorPosition = start + formattedText.length;
            break;
        case 'list':
            // Seçili metin satırlarını al
            const lines = selectedText.split('\n');
            // Her satırın başına '- ' ekle
            formattedText = lines.map(line => `- ${line}`).join('\n');
            cursorPosition = start + formattedText.length;
            break;
    }
    
    // Metni değiştir
    textarea.value = textarea.value.substring(0, start) + formattedText + textarea.value.substring(end);
    
    // İmleci uygun konuma getir
    textarea.selectionStart = cursorPosition;
    textarea.selectionEnd = cursorPosition;
    
    // Textarea'ya odaklan
    textarea.focus();
    
    // Aktif notu kaydet
    saveActiveNote();
}

Adım 3: Uygulamayı Test Etme

Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:

  1. Tüm dosyaları (index.htmlstyle.cssscript.js) aynı klasöre kaydedin.
  2. HTML dosyasını bir web tarayıcısında açın.
  3. Uygulama ilk açıldığında otomatik olarak boş bir not oluşturulacaktır.
  4. Not başlığı ve içeriğini düzenleyin.
  5. Yeni not ekleme butonuna tıklayarak başka notlar oluşturun.
  6. Notlar arasında geçiş yapın ve içeriklerini düzenleyin.
  7. Arama kutusunu kullanarak notlar arasında arama yapın.
  8. Biçimlendirme butonlarını kullanarak metni biçimlendirin.
  9. Silme butonunu kullanarak bir notu silin.
  10. Sayfayı yenileyin ve notların LocalStorage sayesinde korunduğunu doğrulayın.

İpucu: Tarayıcınızın geliştirici araçlarını (genellikle F12 tuşu ile açılır) kullanarak LocalStorage içeriğini inceleyebilir ve JavaScript hatalarını ayıklayabilirsiniz.

Projeyi Geliştirme

Temel not alma uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:

1. Markdown Desteği

Notları Markdown formatında yazabilme ve önizleme yapabilme özelliği ekleyin:

markdown.js
// HTML'e Markdown önizleme butonu ve alanı ekleyin
// <button class="toolbar-btn" id="previewBtn"><i class="fas fa-eye"></i></button>
// <div class="markdown-preview" id="markdownPreview"></div>

// Markdown önizleme butonunu seç
const previewBtn = document.getElementById('previewBtn');
const markdownPreview = document.getElementById('markdownPreview');
let isPreviewMode = false;

// Önizleme butonuna tıklama olayı
previewBtn.addEventListener('click', togglePreview);

// Önizleme modunu değiştirme fonksiyonu
function togglePreview() {
    isPreviewMode = !isPreviewMode;
    
    if (isPreviewMode) {
        // Önizleme modunu etkinleştir
        noteBodyInput.style.display = 'none';
        markdownPreview.style.display = 'block';
        previewBtn.classList.add('active');
        
        // Markdown'ı HTML'e dönüştür
        const markdown = noteBodyInput.value;
        const html = convertMarkdownToHtml(markdown);
        markdownPreview.innerHTML = html;
    } else {
        // Düzenleme modunu etkinleştir
        noteBodyInput.style.display = 'block';
        markdownPreview.style.display = 'none';
        previewBtn.classList.remove('active');
    }
}

// Markdown'ı HTML'e dönüştürme fonksiyonu
function convertMarkdownToHtml(markdown) {
    // Basit bir Markdown dönüştürücü
    // Gerçek bir uygulamada marked.js gibi bir kütüphane kullanabilirsiniz
    
    let html = markdown;
    
    // Başlıklar
    html = html.replace(/^# (.*$)/gm, '<h1>$1</h1>');
    html = html.replace(/^## (.*$)/gm, '<h2>$1</h2>');
    html = html.replace(/^### (.*$)/gm, '<h3>$1</h3>');
    
    // Kalın
    html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
    
    // İtalik
    html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
    
    // Altı çizili
    html = html.replace(/_(.*?)_/g, '<u>$1</u>');
    
    // Listeler
    html = html.replace(/^\- (.*$)/gm, '<li>$1</li>');
    html = html.replace(/(<li>.*<\/li>)/gm, '<ul>$1</ul>');
    
    // Satır sonları
    html = html.replace(/\n/g, '<br>');
    
    return html;
}

2. Kategori Sistemi

Notları kategorilere ayırabilme özelliği ekleyin:

categories.js
// HTML'e kategori seçimi ekleyin
// <div class="category-selector">
//     <select id="categorySelect">
//         <option value="">Tüm Kategoriler</option>
//     </select>
//     <button id="addCategoryBtn"><i class="fas fa-plus"></i></button>
// </div>

// Kategori verilerini LocalStorage'dan al veya boş bir dizi oluştur
let categories = JSON.parse(localStorage.getItem('categories')) || [];

// DOM elementlerini seç
const categorySelect = document.getElementById('categorySelect');
const addCategoryBtn = document.getElementById('addCategoryBtn');

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Kategorileri yükle
    loadCategories();
    
    // Kategori ekleme butonuna tıklama olayı
    addCategoryBtn.addEventListener('click', addNewCategory);
    
    // Kategori seçimi değişiklik olayı
    categorySelect.addEventListener('change', filterNotesByCategory);
});

// Kategorileri yükleme fonksiyonu
function loadCategories() {
    // Kategori seçimini temizle
    categorySelect.innerHTML = '<option value="">Tüm Kategoriler</option>';
    
    // Kategorileri ekle
    categories.forEach(category => {
        const option = document.createElement('option');
        option.value = category.id;
        option.textContent = category.name;
        categorySelect.appendChild(option);
    });
}

// Yeni kategori ekleme fonksiyonu
function addNewCategory() {
    const categoryName = prompt('Yeni kategori adı:');
    
    if (categoryName && categoryName.trim() !== '') {
        // Yeni kategori nesnesi oluştur
        const newCategory = {
            id: Date.now(),
            name: categoryName.trim()
        };
        
        // Kategoriyi diziye ekle
        categories.push(newCategory);
        
        // Kategorileri kaydet
        saveCategories();
        
        // Kategorileri yeniden yükle
        loadCategories();
    }
}

// Kategorileri LocalStorage'a kaydetme fonksiyonu
function saveCategories() {
    localStorage.setItem('categories', JSON.stringify(categories));
}

// Kategoriye göre notları filtreleme fonksiyonu
function filterNotesByCategory() {
    const selectedCategoryId = categorySelect.value;
    
    if (selectedCategoryId === '') {
        // Tüm kategoriler seçiliyse, tüm notları göster
        renderNotes();
    } else {
        // Seçili kategoriye göre notları filtrele
        const filteredNotes = notes.filter(note => note.categoryId === parseInt(selectedCategoryId));
        
        // Filtrelenmiş notları göster
        renderNotes(filteredNotes);
    }
}

// Not nesnesine kategori alanı ekleyin
function addNewNote() {
    const selectedCategoryId = categorySelect.value !== '' ? parseInt(categorySelect.value) : null;
    
    // Yeni not nesnesi oluştur
    const newNote = {
        id: Date.now(),
        title: '',
        body: '',
        categoryId: selectedCategoryId,
        createdAt: Date.now(),
        updatedAt: Date.now()
    };
    
    // ... diğer kodlar ...
}

3. Dışa/İçe Aktarma

Notları dışa aktarma ve içe aktarma özelliği ekleyin:

export-import.js
// HTML'e dışa/içe aktarma butonları ekleyin
// <button id="exportBtn">Dışa Aktar</button>
// <button id="importBtn">İçe Aktar</button>
// <input type="file" id="importFile" style="display: none;">

// DOM elementlerini seç
const exportBtn = document.getElementById('exportBtn');
const importBtn = document.getElementById('importBtn');
const importFile = document.getElementById('importFile');

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Dışa aktarma butonuna tıklama olayı
    exportBtn.addEventListener('click', exportNotes);
    
    // İçe aktarma butonuna tıklama olayı
    importBtn.addEventListener('click', () => {
        importFile.click();
    });
    
    // Dosya seçimi değişiklik olayı
    importFile.addEventListener('change', importNotes);
});

// Notları dışa aktarma fonksiyonu
function exportNotes() {
    // Notları JSON formatına dönüştür
    const notesData = JSON.stringify(notes, null, 2);
    
    // Dosya adı oluştur
    const fileName = `notes_${new Date().toISOString().slice(0, 10)}.json`;
    
    // Dosya indirme bağlantısı oluştur
    const blob = new Blob([notesData], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    
    // Bağlantıya tıkla ve dosyayı indir
    document.body.appendChild(a);
    a.click();
    
    // Bağlantıyı temizle
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

// Notları içe aktarma fonksiyonu
function importNotes(event) {
    const file = event.target.files[0];
    
    if (file) {
        const reader = new FileReader();
        
        reader.onload = function(e) {
            try {
                // Dosya içeriğini JSON olarak ayrıştır
                const importedNotes = JSON.parse(e.target.result);
                
                // Geçerli bir notlar dizisi mi kontrol et
                if (Array.isArray(importedNotes)) {
                    // Kullanıcıya onay sor
                    const confirmImport = confirm(`${importedNotes.length} not içe aktarılacak. Mevcut notlar korunacak. Devam etmek istiyor musunuz?`);
                    
                    if (confirmImport) {
                        // İçe aktarılan notları mevcut notlara ekle
                        notes = [...notes, ...importedNotes];
                        
                        // Notları kaydet
                        saveNotes();
                        
                        // Notları yeniden listele
                        renderNotes();
                        
                        // Kullanıcıya bilgi ver
                        alert(`${importedNotes.length} not başarıyla içe aktarıldı.`);
                    }
                } else {
                    throw new Error('Geçersiz not formatı');
                }
            } catch (error) {
                alert('Dosya içe aktarılamadı. Geçersiz format.');
                console.error('İçe aktarma hatası:', error);
            }
        };
        
        reader.readAsText(file);
    }
    
    // Dosya seçimini sıfırla
    event.target.value = '';
}

Geliştirme Zorlukları

Not alma uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:

  1. Zengin Metin Editörü: Tam özellikli bir zengin metin editörü ekleyin (örneğin, TinyMCE veya Quill.js kullanarak).
  2. Resim Ekleme: Notlara resim ekleyebilme özelliği ekleyin.
  3. Senkronizasyon: Notları bir bulut hizmetiyle senkronize etme özelliği ekleyin (örneğin, Firebase kullanarak).
  4. Paylaşım: Notları e-posta veya bağlantı olarak paylaşabilme özelliği ekleyin.
  5. Hatırlatıcılar: Notlara hatırlatıcı ekleyebilme ve bildirim alabilme özelliği ekleyin.

Sonuç ve Öğrenilen Dersler

Bu projede, JavaScript kullanarak bir not alma uygulaması geliştirdik. Bu süreçte şunları öğrendik:

  • Notları oluşturma, düzenleme ve silme işlevselliği geliştirmeyi
  • Notları LocalStorage kullanarak kalıcı hale getirmeyi
  • Arama fonksiyonu ile notlar arasında filtreleme yapmayı
  • Dinamik kullanıcı arayüzü oluşturmayı
  • Tarih ve zaman işlemlerini JavaScript ile yönetmeyi
  • Olay yetkilendirme (event delegation) tekniğini kullanmayı
  • Responsive tasarım ilkelerini uygulamayı

Bu proje, modern web geliştirme becerilerinizi geliştirmenize ve gerçek dünya uygulamaları oluşturmanıza yardımcı olacak temel bilgileri sağlamıştır. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve tam özellikli not alma uygulamaları geliştirebilirsiniz.