import { useState, useEffect } from "react"; import { Header } from "./components/Header"; import { Hero } from "./components/Hero"; import { AuthStatus } from "./components/AuthStatus"; import { ExamAnalyzer } from "./components/ExamAnalyzer"; import { Features } from "./components/Features"; import { SimpleChatPanel } from "./components/SimpleChatPanel"; import { CLASSLENS_ICON } from "./lib/icon"; const VALID_INVITE_CODE = "taboola-npo-cz"; function InviteCodeGate({ onSuccess }: { onSuccess: () => void }) { const [code, setCode] = useState(""); const [error, setError] = useState(false); const [isShaking, setIsShaking] = useState(false); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (code.trim().toLowerCase() === VALID_INVITE_CODE) { // Save to localStorage so user doesn't need to enter again localStorage.setItem("classlens_access", "granted"); onSuccess(); } else { setError(true); setIsShaking(true); setTimeout(() => setIsShaking(false), 500); } }; return (
{/* Decorative background elements */}
{/* Logo */}
ClassLens

ClassLens

AI 驅動的考試分析

{/* Invite code form */}
{ setCode(e.target.value); setError(false); }} placeholder="請輸入您的邀請碼..." className={`w-full px-4 py-3 bg-[var(--color-background)] border rounded-xl text-[var(--color-text)] placeholder-[var(--color-text-muted)] focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] transition-all ${ error ? "border-red-500 focus:ring-red-500" : "border-[var(--color-border)]" }`} autoFocus /> {error && (

邀請碼無效,請重試。

)}
{/* Footer */}

Don't have an invite code?{" "} Contact us

{/* Add shake animation */}
); } export default function App() { const [hasAccess, setHasAccess] = useState(null); const [teacherEmail, setTeacherEmail] = useState(""); const [isAuthenticated, setIsAuthenticated] = useState(false); const [showAnalyzer, setShowAnalyzer] = useState(false); const [testMode, setTestMode] = useState(false); // Check for existing access on mount useEffect(() => { const access = localStorage.getItem("classlens_access"); setHasAccess(access === "granted"); }, []); // Check URL params for auth callback and test mode useEffect(() => { const params = new URLSearchParams(window.location.search); const authSuccess = params.get("auth_success"); const email = params.get("email"); const authError = params.get("auth_error"); const test = params.get("test"); if (test === "chat") { setTestMode(true); return; } if (authSuccess === "true" && email) { setTeacherEmail(email); setIsAuthenticated(true); setShowAnalyzer(true); // Clean URL window.history.replaceState({}, "", window.location.pathname); } else if (authError) { console.error("Auth error:", authError); window.history.replaceState({}, "", window.location.pathname); } }, []); const handleStartAnalysis = () => { if (isAuthenticated) { setShowAnalyzer(true); } }; // Loading state if (hasAccess === null) { return (
); } // Invite code gate if (!hasAccess) { return setHasAccess(true)} />; } // Test mode - show simple chat panel if (testMode) { return (

ChatKit Test Mode

Testing basic ChatKit functionality

← Back to app
); } return (
{!showAnalyzer ? ( <> ) : ( setShowAnalyzer(false)} /> )}
); }