ELNOR REPO READER TEXT MIRROR Original path: Design Mockups/DOC20 Mockups/Q_NOTES_FULL.jsx Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- import { useState, useRef, useCallback, useEffect } from "react"; const font={sans:"'Söhne','Helvetica Neue',-apple-system,BlinkMacSystemFont,sans-serif"}; const R={sm:"6px",md:"10px",full:"9999px"}; const c={bgApp:"#F8F8F6",bgPanel:"#FFFFFF",bgPanelAlt:"#F9FAFB",bgCard:"#FFFFFF",bgInput:"#EFF1F3",textPri:"#1A1D21",textSec:"#5E6570",textTer:"#8B919A",accentBtn:"#31588c",warn:"#D97706",error:"#B04040",border:"#E0E2E5",borderLight:"#ECEEF0",green:"#2E8B57",agentAv:"#a1a7aa"}; const Ic=({d,size=18,color,sw=1.75})=>; const I={Plus:p=>,X:p=>,Check:p=>,Pin:p=>,Spark:p=>,MsgCircle:p=>,ChevD:p=>,ChevR:p=>,Search:p=>,Maximize:p=>,Save:p=>,Copy:p=>,Link:p=>,Eye:p=>,Edit:p=>,Undo:p=>,Redo:p=>,Folder:p=>,FileText:p=>,Trash:p=>,Archive:p=>,}; const Dot=({color,size=8})=>; const Btn=({children,primary,ghost,small,onClick,disabled,style:s})=>; const Av=({letter,color,size=20})=>
{letter}
; const TBtn=({icon,title,active,onClick,label,dropdown})=>; const Sep=()=>
; const Toast=({msg,onDone})=>{useEffect(()=>{const t=setTimeout(onDone,2200);return()=>clearTimeout(t)},[onDone]);return
{msg}
}; const DItem=({children,onClick,active})=>; const Radio=({selected,label,desc,onClick})=>; const tcColors={You:{del:c.accentBtn,ins:c.accentBtn},Elnor:{del:"#B04040",ins:"#2E8B57"},Scout:{del:"#8B5E00",ins:"#2563EB"}}; const agents=[{name:"Elnor",color:c.agentAv,letter:"E"},{name:"Scout",color:"#5B5F97",letter:"S"}]; const chats=[{name:"Henderson discovery",color:c.accentBtn,origin:true},{name:"Quark patent search",color:c.green},{name:"New chat",color:c.textTer}]; const initFolders=[{id:"nf1",title:"Henderson Case",parent:null},{id:"nf2",title:"Privilege Issues",parent:"nf1"},{id:"nf3",title:"Motion Practice",parent:"nf1"},{id:"nf4",title:"Quark Patents",parent:null},{id:"nf5",title:"Expert Depositions",parent:"nf3"},{id:"nf6",title:"Summary Judgment",parent:"nf3"}]; const initNotes=[ {id:"n1",title:"Henderson Discovery Priorities",folder:"nf2",mod:"2h",comments:3,pinned:true,pending:true,proj:"Henderson",projColor:"#31588c",status:"active"}, {id:"n2",title:"Weekly Task List",folder:null,mod:"4h",comments:0,pinned:true,proj:"Henderson",projColor:"#31588c",status:"active"}, {id:"n3",title:"Judge Chen Conference Notes",folder:"nf3",mod:"3d",comments:2,proj:"Henderson",projColor:"#31588c",status:"active"}, {id:"n4",title:"Privilege Review Checklist",folder:"nf2",mod:"1d",comments:0,proj:"Henderson",projColor:"#31588c",status:"active"}, {id:"n5",title:"Quark Patent Analysis",folder:"nf4",mod:"1d",comments:1,proj:"Quark",projColor:"#2E8B57",status:"active"}, {id:"n6",title:"AI in Legal Discovery",folder:null,mod:"5d",comments:0,status:"active"}, {id:"n7",title:"Old Case Research",folder:null,mod:"2w",comments:0,status:"archived"}, {id:"n8",title:"Expert Depo Prep — Dr. Smith",folder:"nf5",mod:"1w",comments:0,proj:"Henderson",projColor:"#31588c",status:"active"}, ]; const segs=[{id:"s1",t:"p",v:"Key documents to review from discovery batch #4."},{id:"s2",t:"h2",v:"Priority Items"},{id:"s3",t:"li",v:"Email chain: Henderson → Outside Counsel (March 12-15) — 23 messages, 8 flagged"},{id:"s4",t:"li",v:"Privileged strategy memo (March 18) discussing litigation posture and settlement authority"},{id:"s5",t:"li",v:"Board minutes from Q1 2024 executive session"},{id:"s6",t:"h2",v:"Timeline Conflicts"},{id:"s7",t:"p",v:"Deposition transcript (Feb 12): initial contact January 5, but metadata suggests January 8."},{id:"s8",t:"p",v:"Cross-reference calendar, email timestamps, phone records Jan 5-8."},{id:"s9",t:"h2",v:"Next Steps"},{id:"s10",t:"p",v:"Prepare updated privilege log with all newly identified documents."}]; const initChanges=[{id:"tc1",segId:"s4",author:"Elnor",oldText:"discussing litigation posture and settlement authority",newText:"discussing litigation posture, settlement authority, and insurance coverage implications",status:"pending"},{id:"tc2",segId:"s7",author:"Elnor",oldText:"initial contact January 5, but metadata suggests January 8",newText:"initial contact January 5, but metadata and email headers suggest January 8",status:"pending"},{id:"tc3",segId:"s10",author:"You",oldText:"Prepare updated privilege log with all newly identified documents.",newText:"Prepare updated privilege log with all newly identified documents. Include Bates-stamp cross-references.",status:"pending"}]; const initComments=[{id:"c1",author:"You",color:c.accentBtn,body:"Follow up on March 2024 emails — may be privileged.",time:"2h ago",status:"open",segId:"s3",anchor:"Email chain: Henderson",replies:[{id:"r1",author:"Elnor",color:c.agentAv,body:"Flagged 8. Add to privilege log?",time:"1h ago"}]},{id:"c2",author:"Elnor",color:c.agentAv,body:"Timeline conflict vs deposition. Cross-check.",time:"4h ago",status:"open",segId:"s7",anchor:"Deposition transcript (Feb 12)",replies:[]},{id:"c3",author:"Scout",color:"#5B5F97",body:"Judge Chen 5-day rule applies retroactively.",time:"1d ago",status:"resolved",segId:"s9",anchor:"Next Steps",replies:[]}]; const noteSortOpts=["Modified","Alphabetical","Created"]; const timeVal=t=>{if(!t)return 99999;if(t.includes("m"))return parseInt(t);if(t.includes("h"))return parseInt(t)*60;if(t.includes("d"))return parseInt(t)*1440;if(t.includes("w"))return parseInt(t)*10080;return 99999}; export default function NotesV5(){ const idC=useRef(300);const nid=()=>"x"+(++idC.current); const [notes,setNotes]=useState(initNotes); const [comments,setComments]=useState(initComments);const [changes,setChanges]=useState(initChanges); const [activeComment,setActiveComment]=useState(null);const [bubbleMenu,setBubbleMenu]=useState(null); const [noteListOpen,setNoteListOpen]=useState(true);const [folderView,setFolderView]=useState(true); const [selectedNote,setSelectedNote]=useState("n1");const [noteFolders,setNoteFolders]=useState(initFolders); const [expandedFolders,setExpandedFolders]=useState(new Set(["nf1","nf3"])); const [rightOpen,setRightOpen]=useState(true);const [rightTab,setRightTab]=useState("comments"); const [showMarkup,setShowMarkup]=useState(true);const [findBar,setFindBar]=useState(false); const [fullScreen,setFullScreen]=useState(false);const [toast,setToast]=useState(null);const [openDrop,setOpenDrop]=useState(null); const [newFolderMode,setNewFolderMode]=useState(null);const [newFolderName,setNewFolderName]=useState("");const [hoverFolder,setHoverFolder]=useState(null); // Note list controls const [noteSearch,setNoteSearch]=useState("");const [noteSort,setNoteSort]=useState("Modified");const [noteSortDrop,setNoteSortDrop]=useState(false); const [showArchived,setShowArchived]=useState(false); const [contextMenu,setContextMenu]=useState(null); // {x,y,noteId} const [deletingNote,setDeletingNote]=useState(null); // Comment editing const [replyingTo,setReplyingTo]=useState(null);const [replyText,setReplyText]=useState(""); const [editingId,setEditingId]=useState(null);const [editText,setEditText]=useState("");const [deletingId,setDeletingId]=useState(null); const [newCm,setNewCm]=useState(null);const [newCmText,setNewCmText]=useState(""); // Send drawer const [agentIdx,setAgentIdx]=useState(0);const [agentDrop,setAgentDrop]=useState(false); const [chatIdx,setChatIdx]=useState(0);const [chatDrop,setChatDrop]=useState(false); const [sendScope,setSendScope]=useState("full");const [selectedCmIds,setSelectedCmIds]=useState(new Set()); const [outputMode,setOutputMode]=useState("respond_in_chat");const [subMode,setSubMode]=useState("tracked_changes"); const [instruction,setInstruction]=useState(""); const editorRef=useRef(null);const cmRef=useRef(null);const nfRef=useRef(null); const agent=agents[agentIdx];const openC=comments.filter(x=>x.status==="open");const resolvedC=comments.filter(x=>x.status==="resolved"); const pendingChanges=changes.filter(x=>x.status==="pending");const flash=msg=>setToast(msg); // Filtered & sorted notes const activeNotes=notes.filter(n=>n.status==="active"); const archivedNotes=notes.filter(n=>n.status==="archived"); const filteredNotes=(noteSearch?activeNotes.filter(n=>n.title.toLowerCase().includes(noteSearch.toLowerCase())):activeNotes).sort((a,b)=>{ if(a.pinned&&!b.pinned)return -1;if(!a.pinned&&b.pinned)return 1; if(noteSort==="Alphabetical")return a.title.localeCompare(b.title); return timeVal(a.mod)-timeVal(b.mod); }); const archiveNote=id=>{setNotes(p=>p.map(n=>n.id===id?{...n,status:"archived"}:n));setContextMenu(null);flash("Archived")}; const unarchiveNote=id=>{setNotes(p=>p.map(n=>n.id===id?{...n,status:"active"}:n));flash("Restored")}; const deleteNote=id=>{setNotes(p=>p.filter(n=>n.id!==id));setDeletingNote(null);setContextMenu(null);flash("Permanently deleted")}; const handleMouseUp=useCallback(e=>{if(e.target.closest("[data-bubble]"))return;const sel=window.getSelection();if(!sel||sel.isCollapsed||!sel.toString().trim()){setBubbleMenu(null);return}const text=sel.toString().trim();if(text.length<3)return;const rect=sel.getRangeAt(0).getBoundingClientRect();const er=editorRef.current?.getBoundingClientRect();if(!er)return;setBubbleMenu({x:rect.left-er.left+rect.width/2,y:rect.top-er.top-8,text})},[]); const dismissBubble=()=>{setBubbleMenu(null);window.getSelection()?.removeAllRanges()}; const startComment=()=>{if(!bubbleMenu)return;setNewCm({text:bubbleMenu.text});setBubbleMenu(null);setRightOpen(true);setRightTab("comments");setTimeout(()=>cmRef.current?.focus(),100)}; const addComment=()=>{if(!newCmText.trim())return;const cm={id:nid(),author:"You",color:c.accentBtn,body:newCmText.trim(),time:"just now",status:"open",segId:null,anchor:newCm?.text||null,replies:[]};setComments(p=>[...p,cm]);setNewCm(null);setNewCmText("");setActiveComment(cm.id)}; const addReply=cmId=>{if(!replyText.trim())return;setComments(p=>p.map(cm=>cm.id===cmId?{...cm,replies:[...cm.replies,{id:nid(),author:"You",color:c.accentBtn,body:replyText.trim(),time:"just now"}]}:cm));setReplyingTo(null);setReplyText("")}; const saveEdit=id=>{if(!editText.trim())return;setComments(p=>p.map(cm=>cm.id===id?{...cm,body:editText.trim()}:cm));setEditingId(null)}; const doDelete=id=>{setComments(p=>p.filter(cm=>cm.id!==id));setDeletingId(null)}; const resolveComment=id=>{setComments(p=>p.map(cm=>cm.id===id?{...cm,status:"resolved"}:cm));if(activeComment===id)setActiveComment(null)}; const reopenComment=id=>setComments(p=>p.map(cm=>cm.id===id?{...cm,status:"open"}:cm)); const acceptChange=id=>setChanges(p=>p.map(x=>x.id===id?{...x,status:"accepted"}:x)); const rejectChange=id=>setChanges(p=>p.map(x=>x.id===id?{...x,status:"rejected"}:x)); const acceptAll=()=>{setChanges(p=>p.map(x=>x.status==="pending"?{...x,status:"accepted"}:x));flash("All accepted")}; const rejectAll=()=>{setChanges(p=>p.map(x=>x.status==="pending"?{...x,status:"rejected"}:x));flash("All rejected")}; const toggleCmSelect=id=>{const s=new Set(selectedCmIds);s.has(id)?s.delete(id):s.add(id);setSelectedCmIds(s)}; const createFolder=parent=>{if(!newFolderName.trim())return;setNoteFolders(p=>[...p,{id:"nf"+(p.length+10),title:newFolderName.trim(),parent}]);if(parent){const s=new Set(expandedFolders);s.add(parent);setExpandedFolders(s)}setNewFolderMode(null);setNewFolderName("");flash("Folder created")}; const handleSend=()=>{if(outputMode==="respond_in_chat"){flash(`Opening "${chats[chatIdx].name}" (ref:note:n1)…`)}else{if(!instruction.trim())return;flash(`${agent.name}: ${subMode} (ref:note:n1)…`)}}; const renderText=seg=>{const tc=changes.find(x=>x.segId===seg.id&&x.status==="pending");const tca=changes.find(x=>x.segId===seg.id&&x.status==="accepted");if(tca)return {seg.v.replace(tca.oldText,tca.newText)};if(!tc||!showMarkup){if(tc&&!showMarkup)return {seg.v.replace(tc.oldText,tc.newText)};return {seg.v}}const idx=seg.v.indexOf(tc.oldText);if(idx===-1)return {seg.v};const ac=tcColors[tc.author]||tcColors.Elnor;return {seg.v.slice(0,idx)}{tc.oldText}{tc.newText}{" "}{tc.author}{seg.v.slice(idx+tc.oldText.length)}}; const renderSeg=seg=>{const hasCm=openC.some(cm=>cm.segId===seg.id);const isAct=activeComment&&comments.find(cm=>cm.id===activeComment)?.segId===seg.id;const hl=isAct?{backgroundColor:c.accentBtn+"18",borderRadius:3,padding:"2px 4px",margin:"-2px -4px",boxShadow:`inset 0 0 0 1.5px ${c.accentBtn}40`}:hasCm?{backgroundColor:c.accentBtn+"08",borderRadius:3,padding:"1px 3px",margin:"-1px -3px"}:{};const cnt=openC.filter(cm=>cm.segId===seg.id).length;if(seg.t==="h2")return

{seg.v}

;if(seg.t==="li")return
  • {renderText(seg)}{cnt>0&&{const cm=openC.find(x=>x.segId===seg.id);if(cm)setActiveComment(cm.id)}}>💬{cnt}}
  • ;return

    {renderText(seg)}{cnt>0&&{const cm=openC.find(x=>x.segId===seg.id);if(cm)setActiveComment(cm.id)}}>💬{cnt}}

    }; const CmCard=({cm,resolved})=>{const isAct=activeComment===cm.id;return
    setActiveComment(isAct?null:cm.id)}>
    {cm.anchor&&
    "{cm.anchor.slice(0,55)}"
    }
    {cm.author}{cm.time}
    {editingId===cm.id?
    e.stopPropagation()}>