import { type Note, useDeleteNote, useUpdateNote } from "@/hooks/use-notes"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Pin, Archive, Trash2, Edit, History, Copy } from "lucide-react"; import { format } from "date-fns"; import { toast } from "sonner"; import { useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { NoteForm } from "./note-form"; import ReactMarkdown from "react-markdown"; import { getNoteColor } from "@/lib/constants"; import clsx from "clsx"; import remarkGfm from "remark-gfm"; import { VersionHistoryDialog } from "./version-history-dialog"; import { NoteViewDialog } from "./note-view-dialog"; import { Checkbox } from "@/components/ui/checkbox"; import { useBulkSelection } from "@/components/bulk-selection-context"; import { useTranslation } from "react-i18next"; interface NoteCardProps { note: Note; } export function NoteCard({ note }: NoteCardProps) { const { mutate: deleteNote } = useDeleteNote(); const { mutate: updateNote } = useUpdateNote(); const [editing, setEditing] = useState(false); const [historyOpen, setHistoryOpen] = useState(false); const [viewOpen, setViewOpen] = useState(false); const { t } = useTranslation(); // Bulk selection const { isSelected, toggleSelection, isBulkMode } = useBulkSelection(); const selected = isSelected(note.id); const handleCheckboxClick = (e: React.MouseEvent) => { e.stopPropagation(); toggleSelection(note.id); }; // Archive toggle const toggleArchive = (e: React.MouseEvent) => { e.stopPropagation(); updateNote({ id: note.id, is_archived: !note.is_archived }); }; // Pin toggle const togglePin = (e: React.MouseEvent) => { e.stopPropagation(); updateNote({ id: note.id, is_pinned: !note.is_pinned }); }; const handleDelete = (e: React.MouseEvent) => { e.stopPropagation(); if (confirm(t("Are you sure?"))) { deleteNote(note.id); } } const handleCopy = async (e: React.MouseEvent) => { e.stopPropagation(); try { const textToCopy = `${note.title}\n\n${note.content}`; await navigator.clipboard.writeText(textToCopy); toast.success(t("Note copied to clipboard")); } catch (err) { toast.error(t("Failed to copy note")); } } const handleEdit = (data: any) => { const tags = data.tags ? data.tags.split(",").map((t: string) => t.trim()).filter(Boolean) : []; updateNote({ id: note.id, ...data, tags, }, { onSuccess: () => { setEditing(false); toast.success(t("Note updated")); } }); } const { glass, borderClass } = getNoteColor(note.color); return ( <> !isBulkMode && setViewOpen(true)} > {/* Bulk selection checkbox */} {note.title} {note.is_pinned && } {format(new Date(note.created_at), "MMM d, yyyy")} {note.content} {note.tags.map(tag => ( {tag.name} ))} { e.stopPropagation(); setHistoryOpen(true); }} title={t("History")}> { e.stopPropagation(); setEditing(true); }}> {t("Edit Note")} t.name).join(", "), }} onSubmit={handleEdit} submitLabel={t("Update")} /> setEditing(true)} /> > ); }