import React, { useState, useEffect } from 'react'; import { ChevronLeft, Pin, Clock, Archive, Trash2, Plus, Palette, Type, MoreVertical, Search, Tag, X, Bell, Check } from 'lucide-react'; export default function GoogleKeepApp() { const [view, setView] = useState('home'); // home, note-view, archive, trash const [notes, setNotes] = useState([]); const [selectedNote, setSelectedNote] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [showColorPicker, setShowColorPicker] = useState(false); const [showLabelPicker, setShowLabelPicker] = useState(false); const [editTitle, setEditTitle] = useState(''); const [editContent, setEditContent] = useState(''); const [editColor, setEditColor] = useState('dark-brown'); const [editLabels, setEditLabels] = useState([]); const [newLabel, setNewLabel] = useState(''); const [reminder, setReminder] = useState({ date: '', time: '' }); const [allLabels, setAllLabels] = useState([]); const [selectedLabelFilter, setSelectedLabelFilter] = useState(null); const themes = { 'dark-brown': { name: 'Dark Brown', bg: 'linear-gradient(135deg, #5d4e37 0%, #3d2817 100%)', text: '#fff', card: '#4a3f33', }, black: { name: 'Black', bg: 'linear-gradient(135deg, #1a1a1a 0%, #0d0d0d 100%)', text: '#fff', card: '#2d2d2d', }, white: { name: 'White', bg: 'linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%)', text: '#000', card: '#fff', }, 'light-yellow': { name: 'Light Yellow', bg: 'linear-gradient(135deg, #fff8dc 0%, #ffeaa7 100%)', text: '#333', card: '#fffaf0', }, 'sky-blue': { name: 'Sky Blue', bg: 'linear-gradient(135deg, #87ceeb 0%, #4da6d6 100%)', text: '#fff', card: '#b0e0e6', }, pink: { name: 'Pink', bg: 'linear-gradient(135deg, #ffb6c1 0%, #ff69b4 100%)', text: '#fff', card: '#ffc0cb', }, purple: { name: 'Purple', bg: 'linear-gradient(135deg, #9370db 0%, #6a4c93 100%)', text: '#fff', card: '#b19cd9', }, green: { name: 'Green', bg: 'linear-gradient(135deg, #90ee90 0%, #3cb371 100%)', text: '#fff', card: '#a8e6a1', }, orange: { name: 'Orange', bg: 'linear-gradient(135deg, #ffa500 0%, #ff8c00 100%)', text: '#fff', card: '#ffb84d', }, red: { name: 'Red', bg: 'linear-gradient(135deg, #ff6b6b 0%, #c92a2a 100%)', text: '#fff', card: '#ff8787', }, 'sunset': { name: 'Gradient Sunset', bg: 'linear-gradient(135deg, #ff6b6b 0%, #ffa94d 50%, #ffd93d 100%)', text: '#fff', card: '#ffb366', }, 'ocean': { name: 'Gradient Ocean', bg: 'linear-gradient(135deg, #0ea5e9 0%, #06b6d4 50%, #10b981 100%)', text: '#fff', card: '#38bdf8', }, 'dark-purple': { name: 'Gradient Dark Purple', bg: 'linear-gradient(135deg, #7c3aed 0%, #6d28d9 50%, #3f0f5c 100%)', text: '#fff', card: '#a78bfa', }, 'glassmorphism': { name: 'Glassmorphism', bg: 'rgba(255, 255, 255, 0.1)', text: '#fff', card: 'rgba(255, 255, 255, 0.15)', backdrop: 'blur(10px)', }, 'neon': { name: 'Blur Neon', bg: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)', text: '#00ff88', card: '#0f3460', neon: true, }, }; // Load notes from localStorage useEffect(() => { const savedNotes = localStorage.getItem('googleKeepNotes'); if (savedNotes) { try { const parsed = JSON.parse(savedNotes); setNotes(parsed); // Extract all labels const labels = new Set(); parsed.forEach(note => { note.labels?.forEach(label => labels.add(label)); }); setAllLabels(Array.from(labels)); } catch (e) { console.error('Error loading notes:', e); } } }, []); // Save notes to localStorage useEffect(() => { localStorage.setItem('googleKeepNotes', JSON.stringify(notes)); }, [notes]); // Check reminders useEffect(() => { const interval = setInterval(() => { notes.forEach(note => { if (note.reminder && !note.reminderShown) { const reminderDate = new Date(note.reminder); const now = new Date(); if (reminderDate <= now && reminderDate > new Date(now.getTime() - 60000)) { if ('Notification' in window && Notification.permission === 'granted') { new Notification('Note Reminder', { body: note.title || 'Untitled Note', tag: note.id, }); } setNotes(notes.map(n => n.id === note.id ? { ...n, reminderShown: true } : n)); } } }); }, 10000); return () => clearInterval(interval); }, [notes]); const createNote = () => { const newNote = { id: Date.now(), title: '', content: '', color: 'dark-brown', pinned: false, archived: false, deleted: false, labels: [], reminder: null, reminderShown: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; setNotes([newNote, ...notes]); setSelectedNote(newNote); setEditTitle(''); setEditContent(''); setEditColor('dark-brown'); setEditLabels([]); setReminder({ date: '', time: '' }); setView('note-view'); }; const updateNote = (id, updates) => { setNotes(notes.map(n => n.id === id ? { ...n, ...updates, updatedAt: new Date().toISOString() } : n )); }; const deleteNote = (id) => { updateNote(id, { deleted: true, archived: false }); }; const archiveNote = (id) => { updateNote(id, { archived: !notes.find(n => n.id === id)?.archived }); }; const pinNote = (id) => { updateNote(id, { pinned: !notes.find(n => n.id === id)?.pinned }); }; const permanentlyDelete = (id) => { setNotes(notes.filter(n => n.id !== id)); }; const restoreNote = (id) => { updateNote(id, { deleted: false }); }; const openNote = (note) => { setSelectedNote(note); setEditTitle(note.title); setEditContent(note.content); setEditColor(note.color); setEditLabels(note.labels || []); setReminder(note.reminder ? { date: note.reminder.split('T')[0], time: note.reminder.split('T')[1]?.substring(0, 5) || '' } : { date: '', time: '' }); setView('note-view'); }; const saveNote = () => { if (selectedNote) { const reminderDateTime = reminder.date && reminder.time ? `${reminder.date}T${reminder.time}` : null; updateNote(selectedNote.id, { title: editTitle || 'Untitled Note', content: editContent, color: editColor, labels: editLabels, reminder: reminderDateTime, reminderShown: false, }); } }; const closeNote = () => { saveNote(); setView('home'); setSelectedNote(null); }; const getFilteredNotes = () => { let filtered = notes.filter(n => { if (view === 'archive') return n.archived && !n.deleted; if (view === 'trash') return n.deleted; return !n.archived && !n.deleted; }); // Filter by selected label if (selectedLabelFilter) { filtered = filtered.filter(n => n.labels?.includes(selectedLabelFilter)); } // Filter by search if (searchQuery) { const query = searchQuery.toLowerCase(); filtered = filtered.filter(n => n.title.toLowerCase().includes(query) || n.content.toLowerCase().includes(query) ); } // Sort by pinned and date return filtered.sort((a, b) => { if (a.pinned !== b.pinned) return a.pinned ? -1 : 1; return new Date(b.updatedAt) - new Date(a.updatedAt); }); }; const pinnedNotes = getFilteredNotes().filter(n => n.pinned); const unpinnedNotes = getFilteredNotes().filter(n => !n.pinned); const archivedNotesCount = notes.filter(n => n.archived && !n.deleted).length; const trashedNotesCount = notes.filter(n => n.deleted).length; const currentTheme = themes[editColor] || themes['dark-brown']; return (
{/* Note View */} {view === 'note-view' && selectedNote && (
{/* Header */}
{/* Content Area */}
{ setEditTitle(e.target.value); saveNote(); }} placeholder="Title" style={{ background: 'transparent', border: 'none', color: currentTheme.text, fontSize: '28px', fontWeight: 'bold', outline: 'none', marginBottom: '12px', textShadow: currentTheme.neon ? '0 0 10px rgba(0, 255, 136, 0.5)' : 'none', }} />