import React, { useState, useMemo, useCallback } from "react"; import { TextSelect, Combine, WholeWord, Highlighter, Atom, Mic2, ChevronRight, CheckCircle2, } from "lucide-react"; // Define granularity levels const GRANULARITY_LEVELS = [ { id: "text", name: "Text", icon: TextSelect }, { id: "paragraph", name: "Paragraph", icon: Combine }, { id: "sentence", name: "Sentence", icon: Highlighter }, { id: "clause", name: "Clause", icon: Highlighter }, // Simplified { id: "word", name: "Word", icon: WholeWord }, { id: "syllable", name: "Syllable", icon: Mic2 }, // Conceptual { id: "phoneme", name: "Phoneme", icon: Atom }, // Conceptual ] as const; type GranularityId = (typeof GRANULARITY_LEVELS)[number]["id"]; // Granularity Menu Component interface GranularityMenuProps { selectedGranularity: GranularityId; onSelectGranularity: (granularity: GranularityId) => void; } const GranularityMenu: React.FC = ({ selectedGranularity, onSelectGranularity, }) => { return ( ); }; // Text Viewer Component interface TextViewerProps { document: TextDocument; granularity: GranularityId; onElementSelect: (elementType: GranularityId, element: any) => void; // element type can be more specific } const TextViewer: React.FC = ({ document, granularity, onElementSelect, }) => { const handleElementClick = (type: GranularityId, data: any) => { // For syllable/phoneme, pass the parent word data for now if ((type === "syllable" || type === "phoneme") && data.type === "word") { onElementSelect(type, { ...data, originalClickType: type }); } else { onElementSelect(type, data); } }; const renderContent = () => { if (granularity === "text") { return (
handleElementClick("text", document)} > {document.paragraphs.map((p) => (

{p.text}

))}
); } return document.paragraphs.map((paragraph) => (
handleElementClick("paragraph", paragraph) : undefined } > {paragraph.sentences.map((sentence) => ( handleElementClick(granularity, sentence) : undefined } > {granularity === "word" || granularity === "syllable" || granularity === "phoneme" ? sentence.words .map((word, wordIndex) => ( handleElementClick(granularity, word)} // Syllable/Phoneme click conceptually targets word > {word.text} )) .reduce( (prev, curr, idx) => ( <> {prev} {idx > 0 && " "} {curr} ), <>, ) // Add spaces between words : sentence.text} ))}
)); }; return (
{renderContent()}
); }; // Main Application Component export default function TextAnalysisScreen() { const [selectedGranularity, setSelectedGranularity] = useState("word"); const [currentDocument, setCurrentDocument] = useState(sampleTextDocument); const [selectedElementInfo, setSelectedElementInfo] = useState( null, ); const handleGranularityChange = useCallback((granularity: GranularityId) => { setSelectedGranularity(granularity); setSelectedElementInfo(null); // Clear selection when granularity changes }, []); const handleElementSelect = useCallback( (elementType: GranularityId, elementData: any) => { let info = `Selected: ${elementType.toUpperCase()}\n`; if (elementData.text) { info += `Text: "${elementData.text.substring(0, 100)}${elementData.text.length > 100 ? "..." : ""}"\n`; } info += `ID: ${elementData.id}`; if ( elementData.originalClickType && elementData.originalClickType !== elementType ) { info += `\n(Clicked as ${elementData.originalClickType}, showing parent Word)`; } setSelectedElementInfo(info); // Here you would typically navigate to a detail view or open a modal // For example: router.push(`/details/${elementType}/${elementData.id}`); console.log("Selected Element:", elementType, elementData); }, [], ); return (

Text Analyzer

{/* Sticky container for the menu */}
{" "} {/* Ensure menu is sticky on larger screens */} {selectedElementInfo && (

Selection Details:

                {selectedElementInfo}
              
)}
{" "} {/* min-w-0 for flex child */}
); }