14 Ekim 2026 Çarşamba

HTML5 Not Defteri

HTML5 Not Defteri yapalım.

Özellikler:

  1. 9:16 Mobil Uyumlu Çerçeve: Masaüstünde şık bir telefon görünümünde (9:16), mobilde ise tam ekran uyumlu çalışır.

  2. Çevrimdışı ve Yerel Depolama: Harici sunucu gerektirmez, tüm notlar tarayıcınızın localStorage alanında güvenle saklanır.

  3. Değiştirilebilir Temalar: Modern Karanlık, Pastel Aydınlık, Cyberpunk Neon ve Pastel Pembe olmak üzere 4 farklı tema seçeneğine sahiptir.

  4. Anlık Arama: Başlık, içerik veya etiketlerde eş zamanlı (real-time) arama yapabilirsiniz.

  5. Resim ve Sembol Desteği: Notlarınıza cihazınızdan görsel ekleyebilir (Base64 olarak kaydedilir) veya hızlı sembol/emoji çubuğunu kullanabilirsiniz.

  6. Görünüm Modu Toggle Butonu: Header kısmında en üst sağda görünüm değiştirici simgesi.

  7. Liste (Kompakt) Görünümü: Notlar tek satır halinde minimal özet, başlık, etiket ve ikonuyla listelenir.

  8. Ayrıntılı Görünüm: Not metinlerinin tamamı, eklenen büyük görseller, kategoriler ve detaylı tarihler görünür.

  9. Tercih Hatırlama: Seçtiğiniz görünüm modu localStorage üzerine kaydedilir, sayfayı yenilediğinizde aynı görünümle devam eder.


Cepten Notlar - Mobil Not Defteri

Cepten Notlar

0 Not

Not Düzenle

İşlem başarılı

<!DOCTYPE html>
<html lang="tr" class="h-full">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cepten Notlar - Mobil Not Defteri</title>
    <!-- Tailwind CSS CDN -->
    <script src="https://cdn.tailwindcss.com"></script>
    <script>
        tailwind.config = {
            darkMode: 'class',
            theme: {
                extend: {
                    colors: {
                        themeDark: { bg: '#0f172a', card: '#1e293b', text: '#f8fafc', primary: '#3b82f6', border: '#334155' },
                        themeLight: { bg: '#f1f5f9', card: '#ffffff', text: '#0f172a', primary: '#2563eb', border: '#e2e8f0' },
                        themeCyber: { bg: '#05050a', card: '#121124', text: '#00ffcc', primary: '#ff007f', border: '#2a265f' },
                        themePastel: { bg: '#fdf4f5', card: '#ffffff', text: '#4a4046', primary: '#d97706', border: '#f5d0d6' }
                    }
                }
            }
        }
    </script>
    <style>
        /* 9:16 Responsive Container Constraints for desktop, full screen on mobile */
        @media (min-width: 640px) {
            .phone-frame {
                width: 100%;
                max-width: 420px;
                height: 85vh;
                max-height: 840px;
                box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
                border-radius: 2.5rem;
                border: 8px solid #1e293b;
                overflow: hidden;
            }
        }
        @media (max-width: 639px) {
            .phone-frame {
                width: 100vw;
                height: 100vh;
                border-radius: 0;
            }
        }
        /* Custom Scrollbar */
        ::-webkit-scrollbar { width: 5px; height: 5px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(150,150,150,0.3); border-radius: 10px; }
    </style>
</head>
<body class="h-full flex items-center justify-center transition-colors duration-300" id="bodyTag">

    <!-- Ana Çerçeve (9:16 Oranı / Mobil Görünüm) -->
    <div id="appContainer" class="phone-frame flex flex-col relative transition-colors duration-300 shadow-2xl">
        
        <!-- Üst Bilgi Çubuğu (Header) -->
        <header class="px-5 py-4 flex items-center justify-between border-b transition-colors duration-300 z-10" id="headerEl">
            <div class="flex items-center space-x-2">
                <div class="w-8 h-8 rounded-xl flex items-center justify-center font-bold text-lg shadow-md" id="appLogo">📝</div>
                <div>
                    <h1 class="font-bold text-base leading-tight tracking-tight" id="appTitle">Cepten Notlar</h1>
                    <span class="text-xs opacity-75" id="noteCountBadge">0 Not</span>
                </div>
            </div>
            
            <div class="flex items-center space-x-2">
                <!-- Tema Değiştirme Butonu -->
                <button onclick="toggleThemeModal()" class="p-2 rounded-xl transition hover:scale-105 active:scale-95 shadow-sm" id="themeBtn" title="Tema Değiştir">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
                </button>
                <!-- Yeni Not Ekleme Butonu -->
                <button onclick="openEditor()" class="p-2 rounded-xl text-white transition hover:scale-105 active:scale-95 shadow-md flex items-center justify-center" id="addBtn" title="Yeni Not">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 4v16m8-8H4"></path></svg>
                </button>
            </div>
        </header>

        <!-- Arama ve Filtreleme Alanı -->
        <div class="px-4 py-3 border-b transition-colors duration-300" id="searchBarEl">
            <div class="relative">
                <span class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none opacity-50">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
                </span>
                <input type="text" id="searchInput" oninput="filterNotes()" placeholder="Notlarda ara (başlık, içerik, etiket)..." 
                    class="w-full pl-9 pr-4 py-2 rounded-xl text-sm border outline-none transition duration-200 bg-opacity-50">
            </div>
        </div>

        <!-- Not Listesi Ekranı -->
        <div class="flex-1 overflow-y-auto p-4 space-y-3" id="notesListContainer">
            <!-- Dinamik Notlar Buraya Gelecek -->
        </div>

        <!-- Boş Durum Görseli -->
        <div id="emptyState" class="hidden flex-1 flex flex-col items-center justify-center p-8 text-center opacity-60">
            <div class="text-5xl mb-3">📭</div>
            <p class="text-sm font-medium">Henüz not bulunmuyor.</p>
            <p class="text-xs mt-1">Sağ üstteki "+" butonuna basarak ilk notunuzu ekleyin!</p>
        </div>

        <!-- Not Düzenleme / Ekleme Modal / Ekranı -->
        <div id="editorScreen" class="absolute inset-0 z-20 flex flex-col transform translate-y-full transition-transform duration-300 ease-in-out shadow-2xl" style="background: inherit;">
            <div class="px-5 py-4 flex items-center justify-between border-b" id="editorHeader">
                <button onclick="closeEditor()" class="px-3 py-1.5 rounded-xl text-sm font-medium transition hover:opacity-75 flex items-center space-x-1">
                    <span>← Geri</span>
                </button>
                <h2 class="font-bold text-sm" id="editorTitleText">Not Düzenle</h2>
                <button onclick="saveNote()" class="px-4 py-1.5 rounded-xl text-sm font-semibold text-white transition shadow-sm" id="saveNoteBtn">Kaydet</button>
            </div>

            <div class="flex-1 overflow-y-auto p-5 space-y-4">
                <!-- Başlık -->
                <div>
                    <label class="block text-xs font-semibold mb-1 opacity-80 uppercase tracking-wider">Başlık</label>
                    <input type="text" id="noteTitleInput" placeholder="Not başlığı girin..." class="w-full px-3 py-2.5 rounded-xl text-sm border outline-none bg-opacity-30">
                </div>

                <!-- Kategori / Etiket -->
                <div>
                    <label class="block text-xs font-semibold mb-1 opacity-80 uppercase tracking-wider">Etiket / Kategori</label>
                    <input type="text" id="noteCategoryInput" placeholder="Örn: İş, Kişisel, Alışveriş..." class="w-full px-3 py-2.5 rounded-xl text-sm border outline-none bg-opacity-30">
                </div>

                <!-- Hızlı Sembol & Emoji Çubuğu -->
                <div>
                    <label class="block text-xs font-semibold mb-1 opacity-80 uppercase tracking-wider">Hızlı Sembol & Emoji Ekle</label>
                    <div class="flex flex-wrap gap-1.5 p-2 rounded-xl border bg-black bg-opacity-5">
                        <button type="button" onclick="insertSymbol('⭐')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">⭐</button>
                        <button type="button" onclick="insertSymbol('🔥')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">🔥</button>
                        <button type="button" onclick="insertSymbol('💡')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">💡</button>
                        <button type="button" onclick="insertSymbol('✅')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">✅</button>
                        <button type="button" onclick="insertSymbol('📌')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">📌</button>
                        <button type="button" onclick="insertSymbol('❤️')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">❤️</button>
                        <button type="button" onclick="insertSymbol('🎯')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">🎯</button>
                        <button type="button" onclick="insertSymbol('📅')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">📅</button>
                        <button type="button" onclick="insertSymbol('💰')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">💰</button>
                        <button type="button" onclick="insertSymbol('⚡')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">⚡</button>
                        <button type="button" onclick="insertSymbol('✓')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">✓</button>
                        <button type="button" onclick="insertSymbol('✗')" class="p-1.5 rounded hover:bg-black hover:bg-opacity-10 text-sm">✗</button>
                    </div>
                </div>

                <!-- İçerik Alanı -->
                <div class="flex-1 flex flex-col">
                    <label class="block text-xs font-semibold mb-1 opacity-80 uppercase tracking-wider">Not İçeriği</label>
                    <textarea id="noteContentInput" rows="6" placeholder="Notunuzu buraya yazın..." class="w-full flex-1 px-3 py-2.5 rounded-xl text-sm border outline-none bg-opacity-30 resize-none"></textarea>
                </div>

                <!-- Resim Yükleme Alanı -->
                <div>
                    <label class="block text-xs font-semibold mb-1 opacity-80 uppercase tracking-wider">Görsel Ekle</label>
                    <input type="file" id="imageUploadInput" accept="image/*" onchange="handleImageUpload(event)" class="block w-full text-xs file:mr-4 file:py-2 file:px-4 file:rounded-xl file:border-0 file:text-xs file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 cursor-pointer">
                    
                    <!-- Yüklenen Resim Önizleme -->
                    <div id="imagePreviewContainer" class="mt-2 relative hidden">
                        <img id="noteImagePreview" src="" alt="Önizleme" class="w-full h-32 object-cover rounded-xl border">
                        <button type="button" onclick="removeImage()" class="absolute top-2 right-2 bg-red-600 text-white rounded-full p-1 text-xs shadow hover:bg-red-700">❌</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Tema Seçim Paneli / Modal -->
        <div id="themeModal" class="absolute inset-0 z-30 bg-black bg-opacity-60 backdrop-blur-sm hidden flex items-center justify-center p-4">
            <div class="w-full max-w-xs rounded-2xl p-5 shadow-2xl border transition-all" id="themeModalContent">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="font-bold text-sm">Tema Seçin</h3>
                    <button onclick="toggleThemeModal()" class="text-xs opacity-70 hover:opacity-100 font-bold px-2 py-1">✕ Kapat</button>
                </div>
                <div class="space-y-2">
                    <button onclick="setTheme('dark')" class="w-full flex items-center justify-between p-3 rounded-xl border text-sm font-medium transition hover:scale-[1.02]">
                        <span class="flex items-center space-x-2"><span>🌙</span><span>Modern Karanlık</span></span>
                        <span class="w-4 h-4 rounded-full bg-slate-900 border border-slate-700"></span>
                    </button>
                    <button onclick="setTheme('light')" class="w-full flex items-center justify-between p-3 rounded-xl border text-sm font-medium transition hover:scale-[1.02]">
                        <span class="flex items-center space-x-2"><span>☀️</span><span>Pastel Aydınlık</span></span>
                        <span class="w-4 h-4 rounded-full bg-white border border-slate-300"></span>
                    </button>
                    <button onclick="setTheme('cyber')" class="w-full flex items-center justify-between p-3 rounded-xl border text-sm font-medium transition hover:scale-[1.02]">
                        <span class="flex items-center space-x-2"><span>⚡</span><span>Cyberpunk Neon</span></span>
                        <span class="w-4 h-4 rounded-full bg-[#05050a] border border-[#ff007f]"></span>
                    </button>
                    <button onclick="setTheme('pastel')" class="w-full flex items-center justify-between p-3 rounded-xl border text-sm font-medium transition hover:scale-[1.02]">
                        <span class="flex items-center space-x-2"><span>🌸</span><span>Pastel Pembe</span></span>
                        <span class="w-4 h-4 rounded-full bg-[#fdf4f5] border border-[#d97706]"></span>
                    </button>
                </div>
            </div>
        </div>

        <!-- Bildirim / Mesaj Kutusu -->
        <div id="toast" class="absolute bottom-5 left-1/2 transform -translate-x-1/2 px-4 py-2 rounded-xl text-xs font-semibold shadow-lg transition-all duration-300 opacity-0 pointer-events-none z-40 bg-black text-white">
            İşlem başarılı
        </div>

    </div>

    <!-- JavaScript Uygulama Mantığı -->
    <script>
        // Uygulama Durumu (State)
        let notes = JSON.parse(localStorage.getItem('cepten_notes') || '[]');
        let currentTheme = localStorage.getItem('cepten_theme') || 'dark';
        let editingNoteId = null;
        let currentImageBase64 = '';

        // Sayfa Yüklendiğinde Çalışacaklar
        window.onload = function() {
            setTheme(currentTheme);
            renderNotes();
        };

        // Tema Yönetimi
        function setTheme(themeName) {
            currentTheme = themeName;
            localStorage.setItem('cepten_theme', themeName);

            const body = document.getElementById('bodyTag');
            const container = document.getElementById('appContainer');
            const header = document.getElementById('headerEl');
            const searchBar = document.getElementById('searchBarEl');
            const searchInput = document.getElementById('searchInput');
            const editorScreen = document.getElementById('editorScreen');
            const editorHeader = document.getElementById('editorHeader');
            const noteTitleInput = document.getElementById('noteTitleInput');
            const noteCategoryInput = document.getElementById('noteCategoryInput');
            const noteContentInput = document.getElementById('noteContentInput');
            const themeModalContent = document.getElementById('themeModalContent');
            const addBtn = document.getElementById('addBtn');
            const saveNoteBtn = document.getElementById('saveNoteBtn');

            // Sınıfları Temizle
            container.className = "phone-frame flex flex-col relative transition-colors duration-300 shadow-2xl";
            
            let themeConfig = {};
            if (themeName === 'dark') {
                themeConfig = { bg: '#0f172a', card: '#1e293b', text: '#f8fafc', primary: '#3b82f6', border: '#334155', inputBg: '#0f172a' };
            } else if (themeName === 'light') {
                themeConfig = { bg: '#e2e8f0', card: '#f8fafc', text: '#0f172a', primary: '#2563eb', border: '#cbd5e1', inputBg: '#ffffff' };
            } else if (themeName === 'cyber') {
                themeConfig = { bg: '#05050a', card: '#121124', text: '#00ffcc', primary: '#ff007f', border: '#2a265f', inputBg: '#05050a' };
            } else if (themeName === 'pastel') {
                themeConfig = { bg: '#fce7f0', card: '#ffffff', text: '#4a4046', primary: '#d97706', border: '#f5d0d6', inputBg: '#fff5f7' };
            }

            container.style.backgroundColor = themeConfig.bg;
            container.style.color = themeConfig.text;
            editorScreen.style.backgroundColor = themeConfig.bg;
            editorScreen.style.color = themeConfig.text;
            header.style.borderColor = themeConfig.border;
            searchBar.style.borderColor = themeConfig.border;
            editorHeader.style.borderColor = themeConfig.border;
            themeModalContent.style.backgroundColor = themeConfig.card;
            themeModalContent.style.borderColor = themeConfig.border;

            searchInput.style.backgroundColor = themeConfig.inputBg;
            searchInput.style.borderColor = themeConfig.border;
            searchInput.style.color = themeConfig.text;

            noteTitleInput.style.backgroundColor = themeConfig.inputBg;
            noteTitleInput.style.borderColor = themeConfig.border;
            noteTitleInput.style.color = themeConfig.text;

            noteCategoryInput.style.backgroundColor = themeConfig.inputBg;
            noteCategoryInput.style.borderColor = themeConfig.border;
            noteCategoryInput.style.color = themeConfig.text;

            noteContentInput.style.backgroundColor = themeConfig.inputBg;
            noteContentInput.style.borderColor = themeConfig.border;
            noteContentInput.style.color = themeConfig.text;

            addBtn.style.backgroundColor = themeConfig.primary;
            saveNoteBtn.style.backgroundColor = themeConfig.primary;

            document.getElementById('themeModal').classList.add('hidden');
            renderNotes();
        }

        function toggleThemeModal() {
            const modal = document.getElementById('themeModal');
            modal.classList.toggle('hidden');
        }

        // Not Listeleme & Filtreleme
        function renderNotes(filterText = '') {
            const container = document.getElementById('notesListContainer');
            const emptyState = document.getElementById('emptyState');
            const countBadge = document.getElementById('noteCountBadge');
            
            container.innerHTML = '';

            const filtered = notes.filter(n => {
                const text = filterText.toLowerCase();
                return n.title.toLowerCase().includes(text) || 
                       n.content.toLowerCase().includes(text) || 
                       (n.category && n.category.toLowerCase().includes(text));
            });

            countBadge.innerText = `${notes.length} Not`;

            if (filtered.length === 0) {
                emptyState.classList.remove('hidden');
                return;
            } else {
                emptyState.classList.add('hidden');
            }

            // Kart stilleri temaya göre ayarlanır
            let cardBg = '#1e293b', cardBorder = '#334155', badgeBg = '#334155';
            if (currentTheme === 'light') { cardBg = '#ffffff'; cardBorder = '#e2e8f0'; badgeBg = '#e2e8f0'; }
            else if (currentTheme === 'cyber') { cardBg = '#121124'; cardBorder = '#2a265f'; badgeBg = '#2a265f'; }
            else if (currentTheme === 'pastel') { cardBg = '#ffffff'; cardBorder = '#f5d0d6'; badgeBg = '#fae1e6'; }

            filtered.sort((a, b) => b.date - a.date).forEach(note => {
                const dateStr = new Date(note.date).toLocaleDateString('tr-TR', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
                
                const card = document.createElement('div');
                card.className = "p-4 rounded-2xl border transition-all duration-200 hover:scale-[1.01] shadow-sm flex flex-col space-y-2 relative group";
                card.style.backgroundColor = cardBg;
                card.style.borderColor = cardBorder;

                let imageHtml = '';
                if (note.image) {
                    imageHtml = `<div class="mt-2"><img src="${note.image}" class="w-full h-28 object-cover rounded-xl border opacity-90" alt="Not Görseli"></div>`;
                }

                card.innerHTML = `
                    <div class="flex items-start justify-between">
                        <h3 class="font-bold text-sm line-clamp-1 pr-6">${escapeHtml(note.title || 'Başlıksız Not')}</h3>
                        <div class="absolute top-3 right-3 flex items-center space-x-1 opacity-80 group-hover:opacity-100">
                            <button onclick="editNote('${note.id}')" class="p-1 rounded hover:bg-black hover:bg-opacity-10 text-xs" title="Düzenle">✏️</button>
                            <button onclick="deleteNote('${note.id}')" class="p-1 rounded hover:bg-black hover:bg-opacity-10 text-xs" title="Sil">🗑️</button>
                        </div>
                    </div>
                    ${note.category ? `<span class="self-start px-2 py-0.5 rounded-md text-[10px] font-semibold uppercase tracking-wider" style="background-color: ${badgeBg}; opacity: 0.9;">${escapeHtml(note.category)}</span>` : ''}
                    <p class="text-xs opacity-80 line-clamp-2 whitespace-pre-wrap">${escapeHtml(note.content)}</p>
                    ${imageHtml}
                    <div class="flex justify-between items-center pt-1 text-[10px] opacity-60">
                        <span>${dateStr}</span>
                    </div>
                `;
                container.appendChild(card);
            });
        }

        function filterNotes() {
            const query = document.getElementById('searchInput').value;
            renderNotes(query);
        }

        // CRUD İşlemleri
        function openEditor(noteId = null) {
            editingNoteId = noteId;
            currentImageBase64 = '';
            document.getElementById('imagePreviewContainer').classList.add('hidden');
            document.getElementById('imageUploadInput').value = '';

            const titleInput = document.getElementById('noteTitleInput');
            const categoryInput = document.getElementById('noteCategoryInput');
            const contentInput = document.getElementById('noteContentInput');
            const editorTitleText = document.getElementById('editorTitleText');

            if (noteId) {
                const note = notes.find(n => n.id === noteId);
                if (note) {
                    titleInput.value = note.title;
                    categoryInput.value = note.category || '';
                    contentInput.value = note.content;
                    if (note.image) {
                        currentImageBase64 = note.image;
                        document.getElementById('noteImagePreview').src = note.image;
                        document.getElementById('imagePreviewContainer').classList.remove('hidden');
                    }
                    editorTitleText.innerText = 'Notu Düzenle';
                }
            } else {
                titleInput.value = '';
                categoryInput.value = '';
                contentInput.value = '';
                editorTitleText.innerText = 'Yeni Not Ekle';
            }

            document.getElementById('editorScreen').style.transform = 'translateY(0)';
        }

        function closeEditor() {
            document.getElementById('editorScreen').style.transform = 'translateY(100%)';
            editingNoteId = null;
        }

        function saveNote() {
            const title = document.getElementById('noteTitleInput').value.trim();
            const category = document.getElementById('noteCategoryInput').value.trim();
            const content = document.getElementById('noteContentInput').value.trim();

            if (!title && !content) {
                showToast('Lütfen en az başlık veya içerik girin!');
                return;
            }

            if (editingNoteId) {
                const index = notes.findIndex(n => n.id === editingNoteId);
                if (index !== -1) {
                    notes[index].title = title;
                    notes[index].category = category;
                    notes[index].content = content;
                    notes[index].image = currentImageBase64;
                    notes[index].date = Date.now();
                }
                showToast('Not güncellendi!');
            } else {
                const newNote = {
                    id: '_' + Math.random().toString(36).substr(2, 9),
                    title: title,
                    category: category,
                    content: content,
                    image: currentImageBase64,
                    date: Date.now()
                };
                notes.push(newNote);
                showToast('Not eklendi!');
            }

            localStorage.setItem('cepten_notes', JSON.stringify(notes));
            closeEditor();
            renderNotes();
        }

        function editNote(id) {
            openEditor(id);
        }

        function deleteNote(id) {
            if (confirm('Bu notu silmek istediğinize emin misiniz?')) {
                notes = notes.filter(n => n.id !== id);
                localStorage.setItem('cepten_notes', JSON.stringify(notes));
                renderNotes();
                showToast('Not silindi.');
            }
        }

        // Resim Yükleme (Base64)
        function handleImageUpload(event) {
            const file = event.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = function(e) {
                currentImageBase64 = e.target.result;
                document.getElementById('noteImagePreview').src = currentImageBase64;
                document.getElementById('imagePreviewContainer').classList.remove('hidden');
            };
            reader.readAsDataURL(file);
        }

        function removeImage() {
            currentImageBase64 = '';
            document.getElementById('imageUploadInput').value = '';
            document.getElementById('imagePreviewContainer').classList.add('hidden');
        }

        // Sembol / Emoji Ekleme
        function insertSymbol(symbol) {
            const textarea = document.getElementById('noteContentInput');
            const start = textarea.selectionStart;
            const end = textarea.selectionEnd;
            const text = textarea.value;
            textarea.value = text.substring(0, start) + symbol + text.substring(end);
            textarea.selectionStart = textarea.selectionEnd = start + symbol.length;
            textarea.focus();
        }

        // Bildirim Kutusu (Toast)
        function showToast(message) {
            const toast = document.getElementById('toast');
            toast.innerText = message;
            toast.classList.remove('opacity-0');
            toast.classList.add('opacity-100');
            setTimeout(() => {
                toast.classList.remove('opacity-100');
                toast.classList.add('opacity-0');
            }, 2000);
        }

        // Güvenlik / XSS Engelleyici
        function escapeHtml(str) {
            return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
        }
    </script>
</body>
</html>


ÖNEMLİ NOT:

Kodun  en üst tarafında yer alan:
<script src="https://cdn.tailwindcss.com"></script>  
satırı internete bağımlı çalışır. 
tailwindcss.js
dosyasını internetten indirip html dosyasının yanına koyup satırı şu şekilde değiştirirseniz:
<script src="tailwindcss.js"></script>   
tamamen localde çalışırsınız.


Hiç yorum yok:

Yorum Gönder