// web/src/App.tsx - 教师专用版本(ClareCourseWare)
import React, { useState, useEffect, ErrorInfo, Component } from "react";
import { LoginScreen } from "./components/LoginScreen";
import { TeacherDashboard } from "./components/TeacherDashboard";
import { Toaster } from "./components/ui/sonner";
export interface User {
name: string;
email: string;
}
// ✅ Error Boundary for catching React errors
class ErrorBoundary extends Component<
{ children: React.ReactNode },
{ hasError: boolean; error: Error | null }
> {
constructor(props: { children: React.ReactNode }) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error("React Error:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
应用错误
{this.state.error?.message || "未知错误"}
);
}
return this.props.children;
}
}
// ✅ localStorage helpers for user profile
function profileStorageKey(email: string) {
return `teacher_profile::${email}`;
}
function hydrateUserFromStorage(base: User): User {
try {
const raw = localStorage.getItem(profileStorageKey(base.email));
if (!raw) return base;
const saved = JSON.parse(raw) as Partial;
return { ...base, ...saved };
} catch {
return base;
}
}
function App() {
const [user, setUser] = useState(null);
// ✅ persist user profile whenever it changes (per-email)
useEffect(() => {
if (!user?.email) return;
try {
localStorage.setItem(profileStorageKey(user.email), JSON.stringify(user));
} catch {
// ignore
}
}, [user]);
// ✅ 教师专用:登录后直接进入 TeacherDashboard
const handleLogin = (newUser: User) => {
const hydrated = hydrateUserFromStorage(newUser);
setUser(hydrated);
};
if (!user) return ;
// ✅ 教师专用:只显示 TeacherDashboard,移除所有学生界面
return (
setUser(null)} />
);
}
export default App;