import React, { useState, useEffect } from "react"; import { X, ShieldAlert } from "lucide-react"; import { updateAnnotation, updateHighlight, updateBookmark, sessionAtom, getUserTags, getTrendingTags, } from "../../api/client"; import type { AnnotationItem, ContentLabelValue } from "../../types"; import TagInput from "../ui/TagInput"; const SELF_LABEL_OPTIONS: { value: ContentLabelValue; label: string }[] = [ { value: "sexual", label: "Sexual" }, { value: "nudity", label: "Nudity" }, { value: "violence", label: "Violence" }, { value: "gore", label: "Gore" }, { value: "spam", label: "Spam" }, { value: "misleading", label: "Misleading" }, ]; const HIGHLIGHT_COLORS = [ { value: "yellow", bg: "bg-yellow-400", ring: "ring-yellow-500" }, { value: "green", bg: "bg-green-400", ring: "ring-green-500" }, { value: "blue", bg: "bg-blue-400", ring: "ring-blue-500" }, { value: "red", bg: "bg-red-400", ring: "ring-red-500" }, ]; interface EditItemModalProps { isOpen: boolean; onClose: () => void; item: AnnotationItem; type: "annotation" | "highlight" | "bookmark"; onSaved?: (item: AnnotationItem) => void; } export default function EditItemModal({ isOpen, onClose, item, type, onSaved, }: EditItemModalProps) { if (!isOpen) return null; return ( ); } function EditItemModalContent({ item, type, onClose, onSaved, }: Omit) { const [text, setText] = useState(item.body?.value || ""); const [tags, setTags] = useState(item.tags || []); const [tagSuggestions, setTagSuggestions] = useState([]); const [color, setColor] = useState(item.color || "yellow"); const [title, setTitle] = useState(item.title || item.target?.title || ""); const [description, setDescription] = useState(item.description || ""); const existingLabels = (item.labels || []) .filter((l) => l.src === item.author?.did) .map((l) => l.val as ContentLabelValue); const [selfLabels, setSelfLabels] = useState(existingLabels); const [showLabelPicker, setShowLabelPicker] = useState( existingLabels.length > 0, ); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); useEffect(() => { const session = sessionAtom.get(); if (session?.did) { Promise.all([ getUserTags(session.did).catch(() => [] as string[]), getTrendingTags(50) .then((tags) => tags.map((t) => t.tag)) .catch(() => [] as string[]), ]).then(([userTags, trendingTags]) => { const seen = new Set(userTags); const merged = [...userTags]; for (const t of trendingTags) { if (!seen.has(t)) { merged.push(t); seen.add(t); } } setTagSuggestions(merged); }); } }, []); const toggleLabel = (val: ContentLabelValue) => { setSelfLabels((prev) => prev.includes(val) ? prev.filter((l) => l !== val) : [...prev, val], ); }; const handleSave = async () => { setSaving(true); setError(null); let success = false; const labels = selfLabels.length > 0 ? selfLabels : []; try { if (type === "annotation") { success = await updateAnnotation( item.uri, text, tags.length > 0 ? tags : undefined, labels, ); } else if (type === "highlight") { success = await updateHighlight( item.uri, color, tags.length > 0 ? tags : undefined, labels, ); } else if (type === "bookmark") { success = await updateBookmark( item.uri, title || undefined, description || undefined, tags.length > 0 ? tags : undefined, labels, ); } } catch (e) { console.error("Edit save error:", e); setError(e instanceof Error ? e.message : "Failed to save"); setSaving(false); return; } setSaving(false); if (!success) { setError("Failed to save changes. Please try again."); return; } const updated = { ...item }; if (type === "annotation") { updated.body = { type: "TextualBody", value: text, format: "text/plain" }; } else if (type === "highlight") { updated.color = color; } else if (type === "bookmark") { updated.title = title; updated.description = description; } updated.tags = tags; const otherLabels = (item.labels || []).filter( (l) => l.src !== item.author?.did, ); const newSelfLabels = selfLabels.map((val) => ({ val, src: item.author?.did || "", scope: "content" as const, })); updated.labels = [...otherLabels, ...newSelfLabels]; onSaved?.(updated); onClose(); }; return (
e.stopPropagation()} >

Edit{" "} {type === "annotation" ? "Annotation" : type === "highlight" ? "Highlight" : "Bookmark"}

{type === "annotation" && (