Spaces:
Sleeping
Sleeping
File size: 7,403 Bytes
70e74ea 1e2a2f3 9e51bdc 70e74ea 9e51bdc 70e74ea c075953 70e74ea 9e51bdc 70e74ea 9e51bdc |
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 |
import { useState, useRef } from 'react';
import DocumentProcessor from './DocumentProcessor';
function Homepage() {
const [hasFile, setHasFile] = useState(false);
const [fileName, setFileName] = useState('');
const [selectedFile, setSelectedFile] = useState(null);
const [academicBackground, setAcademicBackground] = useState('');
const [showAbout, setShowAbout] = useState(false);
const [showDocumentProcessor, setShowDocumentProcessor] = useState(false);
const fileRef = useRef(null);
function openFilePicker() {
if (fileRef.current) fileRef.current.click();
}
function handleFileChange(event) {
const file = event.target.files?.[0];
if (file) {
setSelectedFile(file);
setHasFile(true);
setFileName(file.name);
setTimeout(() => setShowAbout(true), 250);
}
}
function handleContinue() {
setShowDocumentProcessor(true);
}
// If we're showing the document processor, render it instead of the onboarding
if (showDocumentProcessor) {
return (
<DocumentProcessor
initialFile={selectedFile}
fileName={fileName}
academicBackground={academicBackground}
/>
);
}
return (
<div className="min-h-screen w-full bg-gray-50 text-gray-900 flex items-center justify-center p-6">
<div className="max-w-4xl w-full">
<div className="mb-6 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-10 w-10 rounded-2xl bg-indigo-500 text-white flex items-center justify-center">
<svg viewBox='0 0 24 24' className='h-6 w-6'>
<path d='M12 3l7.5 4.5v9L12 21 4.5 16.5v-9L12 3z' fill='currentColor'/>
</svg>
</div>
<div>
<h1 className="text-2xl font-semibold tracking-tight">SocraticAI</h1>
<p className="text-sm text-gray-600">Guided comprehension for complex papers</p>
</div>
</div>
<div className="text-xs text-gray-500">Onboarding Flow</div>
</div>
{!hasFile && !showAbout && (
<Landing
openFilePicker={openFilePicker}
fileRef={fileRef}
handleFileChange={handleFileChange}
academicBackground={academicBackground}
setAcademicBackground={setAcademicBackground}
/>
)}
{hasFile && showAbout && (
<About
fileName={fileName}
onContinue={handleContinue}
openFilePicker={openFilePicker}
academicBackground={academicBackground}
/>
)}
</div>
</div>
);
}
function Landing({ openFilePicker, fileRef, handleFileChange, academicBackground, setAcademicBackground }) {
return (
<div className="rounded-2xl border border-gray-200 bg-white shadow-lg p-8 md:p-12">
<div>
<h2 className="text-3xl md:text-4xl font-semibold leading-tight text-gray-900">Welcome to SocraticAI</h2>
<p className="mt-3 text-gray-600">
Your mentor-like companion for mastering research papers. Upload a paper and we'll turn it into a guided
learning path — with questions, feedback, and visible progress.
</p>
<div className="mt-6">
<label htmlFor="academic-background" className="block text-sm font-medium text-gray-700 mb-2">
Describe your academic background
</label>
<p className="text-xs text-gray-500 mb-3">
This helps us adjust our tutoring AI to adapt to what you already know.
</p>
<textarea
id="academic-background"
value={academicBackground}
onChange={(e) => setAcademicBackground(e.target.value)}
placeholder="e.g., PhD in Computer Science, undergraduate in Physics, working professional in data science..."
className="w-full px-4 py-3 rounded-lg border border-gray-300 text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 resize-none"
rows="3"
/>
</div>
<div className="mt-8">
<button
onClick={openFilePicker}
className="inline-flex items-center gap-2 rounded-lg px-5 py-3 bg-indigo-500 hover:bg-indigo-600 transition text-white font-medium shadow-lg"
>
<UploadIcon /> Upload a paper (PDF)
</button>
<input
ref={fileRef}
type="file"
accept="application/pdf"
className="hidden"
onChange={handleFileChange}
/>
</div>
<p className="mt-3 text-xs text-gray-500">Your PDF will be processed locally and securely.</p>
</div>
</div>
);
}
function About({ fileName, onContinue, openFilePicker, academicBackground }) {
return (
<div className="rounded-2xl border border-gray-200 bg-white shadow-lg p-8 md:p-12">
<div className="flex items-start gap-4">
<div className="h-10 w-10 rounded-xl bg-emerald-100 border border-emerald-200 flex items-center justify-center">
<CheckIcon />
</div>
<div className="flex-1">
<h3 className="text-2xl font-semibold text-gray-900">Paper added</h3>
<p className="text-gray-600 mt-1">{fileName}</p>
{academicBackground && (
<p className="text-gray-500 mt-2 text-sm">
Background: {academicBackground}
</p>
)}
<p className="mt-4 text-gray-800">Here's how SocraticAI helps you learn deeply:</p>
<ul className="mt-3 text-gray-600 space-y-2 list-disc list-inside">
<li><span className="font-medium text-gray-800">Automatic inflection points.</span> We flag hypotheses, assumptions, method shifts, and key claims.</li>
<li><span className="font-medium text-gray-800">Guided micro-conversations.</span> Short question/answer loops validate and extend your understanding.</li>
<li><span className="font-medium text-gray-800">Visible progress.</span> Confidence builds as you complete focused checkpoints.</li>
</ul>
<div className="mt-6 flex flex-wrap gap-3">
<button
onClick={onContinue}
className="rounded-lg px-5 py-3 bg-indigo-500 hover:bg-indigo-600 transition text-white font-medium shadow-lg"
>
Continue
</button>
<button
onClick={openFilePicker}
className="rounded-lg px-5 py-3 bg-gray-100 hover:bg-gray-200 transition text-gray-700 font-medium border border-gray-300"
>
Choose another paper
</button>
</div>
</div>
</div>
</div>
);
}
function UploadIcon() {
return (
<svg viewBox="0 0 24 24" className="h-5 w-5" fill="none" stroke="currentColor" strokeWidth="1.8">
<path d="M12 16V4m0 0l-4 4m4-4l4 4"/>
<path d="M20 16v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2"/>
</svg>
);
}
function CheckIcon() {
return (
<svg viewBox="0 0 24 24" className="h-5 w-5 text-emerald-600" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M20 6L9 17l-5-5" />
</svg>
);
}
export default Homepage; |