File size: 7,050 Bytes
c075953
4a6c290
c075953
a706099
 
 
 
02158b8
a706099
 
 
 
f444dc0
e79fdda
a706099
4a6c290
 
8066d07
 
4a6c290
a706099
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d0b379
f444dc0
a706099
 
 
 
 
8d0b379
 
 
f444dc0
 
 
 
 
 
 
98d2bd7
a706099
 
 
 
 
 
9ded9e1
a706099
4a6c290
 
 
 
 
 
 
 
 
 
98d2bd7
a706099
9ded9e1
c075953
 
a706099
c075953
 
e79fdda
 
 
 
 
 
 
 
 
 
 
 
 
 
c075953
 
 
 
 
 
e79fdda
 
c075953
 
e79fdda
c075953
e79fdda
c075953
 
 
e79fdda
c075953
e79fdda
c075953
 
 
 
 
 
a706099
c075953
e79fdda
 
 
 
 
 
f444dc0
 
 
 
 
 
 
 
 
 
 
c075953
b1e57e4
e79fdda
 
 
 
 
 
 
a706099
 
 
 
 
e79fdda
 
 
 
 
 
 
f444dc0
 
 
 
 
 
 
 
 
e79fdda
a706099
 
 
 
8d0b379
f444dc0
 
 
 
 
 
 
 
8066d07
 
 
f444dc0
a706099
e79fdda
b1e57e4
a706099
c075953
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import 'katex/dist/katex.min.css';
import { useState, useEffect } from 'react';

// Import custom hooks
import { useDocumentProcessor } from '../hooks/useDocumentProcessor';
import { useChunkNavigation } from '../hooks/useChunkNavigation';
import { usePanelResize } from '../hooks/usePanelResize';

// Import components
import LoadingAnimation from './LoadingAnimation';
import DocumentViewer from './DocumentViewer';
import ChunkPanel from './ChunkPanel';
import ProgressBar from './ProgressBar';

function DocumentProcessor() {
    // State for PDF navigation
    const [pdfNavigation, setPdfNavigation] = useState(null);
    // State for first LLM response loading
    const [waitingForFirstResponse, setWaitingForFirstResponse] = useState(false);
    
    // Custom hooks
    const {
        fileInputRef,
        selectedFile,
        processing,
        uploadProgress,
        documentData,
        handleFileChange,
        processDocument,
        setSelectedFile
    } = useDocumentProcessor();

    const {
        chunkStates,
        currentChunkIndex,
        chunkExpanded,
        showChat,
        isTransitioning,
        goToNextChunk,
        goToPrevChunk,
        skipChunk,
        markChunkUnderstood,
        startInteractiveLesson,
        setChunkExpanded,
        setShowChat,
        setChunkAsInteractive,
        updateGlobalChatHistory,
        getGlobalChatHistory,
        addMessageToChunk,
        getCurrentChunkMessages,
        hasChunkMessages,
        isChunkCompleted,
        canEditChunk
    } = useChunkNavigation(documentData, null);

    const {
        leftPanelWidth,
        isDragging,
        containerRef,
        handleMouseDown
    } = usePanelResize(50);

    // Sync PDF page navigation with chunk switching
    useEffect(() => {
        if (pdfNavigation && documentData && documentData.chunks[currentChunkIndex]) {
            const currentChunk = documentData.chunks[currentChunkIndex];
            if (currentChunk.page && pdfNavigation.goToPage) {
                pdfNavigation.goToPage(currentChunk.page);
            }
        }
    }, [currentChunkIndex, pdfNavigation, documentData]);

    // Simplified startInteractiveLesson
    const handleStartInteractiveLesson = () => {
        startInteractiveLesson();
    };

    // Early returns for different states
    if (!selectedFile) {
        return (
            <div className="h-screen bg-gray-50 flex items-center justify-center">
                <input
                    ref={fileInputRef}
                    type="file"
                    accept=".pdf"
                    className="hidden"
                    onChange={handleFileChange}
                />
                <button
                    onClick={() => fileInputRef.current.click()}
                    className="px-6 py-3 bg-white shadow-md hover:shadow-lg text-gray-700 font-medium rounded-lg transition-all"
                >
                    Select PDF
                </button>
            </div>
        );
    }

    if (!documentData) {
        return (
            <div className="h-screen bg-gray-50 flex items-center justify-center">
                <div className="flex gap-4">
                    <button
                        onClick={processDocument}
                        className="px-6 py-3 bg-white shadow-md hover:shadow-lg text-gray-700 font-medium rounded-lg transition-all"
                    >
                        Process
                    </button>
                    <button
                        onClick={() => setSelectedFile(null)}
                        className="px-6 py-3 bg-white shadow-md hover:shadow-lg text-gray-700 font-medium rounded-lg transition-all"
                    >
                        ← Back
                    </button>
                </div>
            </div>
        );
    }

    // Main render
    return (
        <div 
            ref={containerRef}
            className="h-screen bg-gray-100 flex gap-2 p-6 overflow-hidden"
            style={{ cursor: isDragging ? 'col-resize' : 'default' }}
        >
            {/* Left Panel - Document */}
            <div style={{ width: `${leftPanelWidth}%`, height: '100%' }} className="flex flex-col">

                
                {/* Document Viewer */}
                <div className="flex-1 min-h-0">
                    <DocumentViewer
                        selectedFile={selectedFile}
                        documentData={documentData}
                        onPageChange={setPdfNavigation}
                    />
                </div>
            </div>

            {/* Resizable Divider */}
            <div 
                className="flex items-center justify-center cursor-col-resize group transition-all duration-200"
                style={{ width: '8px' }}
                onMouseDown={handleMouseDown}
            >
                <div
                    className="w-px h-full rounded-full transition-all duration-200 group-hover:shadow-lg"
                    style={{
                        backgroundColor: isDragging ? 'rgba(59, 130, 246, 0.8)' : 'transparent',
                        boxShadow: isDragging ? '0 0 8px rgba(59, 130, 246, 0.8)' : 'none'
                    }}
                ></div>
            </div>

            {/* Right Panel Container */}
            <div 
                className="flex flex-col"
                style={{ width: `${100 - leftPanelWidth}%` }}
            >                {/* Progress Bar */}
                <div className="mb-4 flex-shrink-0">
                    <ProgressBar 
                        currentChunkIndex={currentChunkIndex}
                        totalChunks={documentData?.chunks?.length || 0}
                        onChunkClick={null} // Start with linear progression only
                    />
                </div>
                
                {/* Chunk Panel */}
                <div className="flex-1 flex flex-col min-h-0 bg-white rounded-lg shadow-sm">
                    <ChunkPanel
                        documentData={documentData}
                        currentChunkIndex={currentChunkIndex}
                        showChat={showChat}
                        isTransitioning={isTransitioning}
                        updateGlobalChatHistory={updateGlobalChatHistory}
                        getGlobalChatHistory={getGlobalChatHistory}
                        addMessageToChunk={addMessageToChunk}
                        getCurrentChunkMessages={getCurrentChunkMessages}
                        hasChunkMessages={hasChunkMessages}
                        isChunkCompleted={isChunkCompleted}
                        canEditChunk={canEditChunk}
                        setWaitingForFirstResponse={setWaitingForFirstResponse}
                        markChunkUnderstood={markChunkUnderstood}
                        skipChunk={skipChunk}
                        goToPrevChunk={goToPrevChunk}
                    />
                </div>
            </div>
        </div>
    );
}

export default DocumentProcessor;