'use client' import { useState, useEffect, useRef } from 'react' import { Note, CheckItem, NOTE_COLORS, NoteColor } from '@/lib/types' import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { X, Plus, Palette, Image as ImageIcon, Bell, FileText, Eye } from 'lucide-react' import { updateNote } from '@/app/actions/notes' import { cn } from '@/lib/utils' import { useToast } from '@/components/ui/toast' import { MarkdownContent } from './markdown-content' import { LabelManager } from './label-manager' import { LabelBadge } from './label-badge' interface NoteEditorProps { note: Note onClose: () => void } export function NoteEditor({ note, onClose }: NoteEditorProps) { const { addToast } = useToast() const [title, setTitle] = useState(note.title || '') const [content, setContent] = useState(note.content) const [checkItems, setCheckItems] = useState(note.checkItems || []) const [labels, setLabels] = useState(note.labels || []) const [images, setImages] = useState(note.images || []) const [newLabel, setNewLabel] = useState('') const [color, setColor] = useState(note.color) const [isSaving, setIsSaving] = useState(false) const [isMarkdown, setIsMarkdown] = useState(note.isMarkdown || false) const [showMarkdownPreview, setShowMarkdownPreview] = useState(false) const fileInputRef = useRef(null) // Reminder state const [showReminderDialog, setShowReminderDialog] = useState(false) const [reminderDate, setReminderDate] = useState('') const [reminderTime, setReminderTime] = useState('') const [currentReminder, setCurrentReminder] = useState(note.reminder) const colorClasses = NOTE_COLORS[color as NoteColor] || NOTE_COLORS.default const handleImageUpload = (e: React.ChangeEvent) => { const files = e.target.files if (!files) return Array.from(files).forEach(file => { const reader = new FileReader() reader.onloadend = () => { setImages(prev => [...prev, reader.result as string]) } reader.readAsDataURL(file) }) } const handleRemoveImage = (index: number) => { setImages(images.filter((_, i) => i !== index)) } const handleReminderOpen = () => { if (currentReminder) { const date = new Date(currentReminder) setReminderDate(date.toISOString().split('T')[0]) setReminderTime(date.toTimeString().slice(0, 5)) } else { const tomorrow = new Date(Date.now() + 86400000) setReminderDate(tomorrow.toISOString().split('T')[0]) setReminderTime('09:00') } setShowReminderDialog(true) } const handleReminderSave = () => { if (!reminderDate || !reminderTime) { addToast('Please enter date and time', 'warning') return } const dateTimeString = `${reminderDate}T${reminderTime}` const date = new Date(dateTimeString) if (isNaN(date.getTime())) { addToast('Invalid date or time', 'error') return } if (date < new Date()) { addToast('Reminder must be in the future', 'error') return } setCurrentReminder(date) addToast(`Reminder set for ${date.toLocaleString()}`, 'success') setShowReminderDialog(false) } const handleRemoveReminder = () => { setCurrentReminder(null) setShowReminderDialog(false) addToast('Reminder removed', 'success') } const handleSave = async () => { setIsSaving(true) try { await updateNote(note.id, { title: title.trim() || null, content: note.type === 'text' ? content : '', checkItems: note.type === 'checklist' ? checkItems : null, labels, images, color, reminder: currentReminder, isMarkdown, }) onClose() } catch (error) { console.error('Failed to save note:', error) } finally { setIsSaving(false) } } const handleCheckItem = (id: string) => { setCheckItems(items => items.map(item => item.id === id ? { ...item, checked: !item.checked } : item ) ) } const handleUpdateCheckItem = (id: string, text: string) => { setCheckItems(items => items.map(item => (item.id === id ? { ...item, text } : item)) ) } const handleAddCheckItem = () => { setCheckItems([ ...checkItems, { id: Date.now().toString(), text: '', checked: false }, ]) } const handleRemoveCheckItem = (id: string) => { setCheckItems(items => items.filter(item => item.id !== id)) } const handleAddLabel = () => { if (newLabel.trim() && !labels.includes(newLabel.trim())) { setLabels([...labels, newLabel.trim()]) setNewLabel('') } } const handleRemoveLabel = (label: string) => { setLabels(labels.filter(l => l !== label)) } return ( Edit Note
{/* Title */} setTitle(e.target.value)} className="text-lg font-semibold border-0 focus-visible:ring-0 px-0 bg-transparent" /> {/* Images */} {images.length > 0 && (
{images.map((img, idx) => (
))}
)} {/* Content or Checklist */} {note.type === 'text' ? (
{/* Markdown controls */}
{isMarkdown && ( )}
{showMarkdownPreview && isMarkdown ? ( ) : (