Spaces:
Sleeping
Sleeping
Upload 51 files
Browse files- App.tsx +2 -2
- components/Sidebar.tsx +10 -3
- pages/CourseList.tsx +3 -3
App.tsx
CHANGED
|
@@ -159,7 +159,7 @@ const AppContent: React.FC = () => {
|
|
| 159 |
<Sidebar
|
| 160 |
currentView={currentView}
|
| 161 |
onChangeView={(view) => { setCurrentView(view); setSidebarOpen(false); }}
|
| 162 |
-
userRole={currentUser?.role || UserRole.USER}
|
| 163 |
onLogout={handleLogout}
|
| 164 |
isOpen={sidebarOpen}
|
| 165 |
onClose={() => setSidebarOpen(false)}
|
|
@@ -185,4 +185,4 @@ const App: React.FC = () => {
|
|
| 185 |
);
|
| 186 |
};
|
| 187 |
|
| 188 |
-
export default App;
|
|
|
|
| 159 |
<Sidebar
|
| 160 |
currentView={currentView}
|
| 161 |
onChangeView={(view) => { setCurrentView(view); setSidebarOpen(false); }}
|
| 162 |
+
userRole={(currentUser?.role as UserRole) || UserRole.USER}
|
| 163 |
onLogout={handleLogout}
|
| 164 |
isOpen={sidebarOpen}
|
| 165 |
onClose={() => setSidebarOpen(false)}
|
|
|
|
| 185 |
);
|
| 186 |
};
|
| 187 |
|
| 188 |
+
export default App;
|
components/Sidebar.tsx
CHANGED
|
@@ -13,12 +13,19 @@ interface SidebarProps {
|
|
| 13 |
onClose: () => void;
|
| 14 |
}
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
export const Sidebar: React.FC<SidebarProps> = ({ currentView, onChangeView, userRole, onLogout, isOpen, onClose }) => {
|
| 17 |
const currentUser = api.auth.getCurrentUser();
|
| 18 |
const canSeeAI = userRole === UserRole.ADMIN || (userRole === UserRole.TEACHER && currentUser?.aiAccess);
|
| 19 |
|
| 20 |
// Default Items
|
| 21 |
-
const defaultItems = [
|
| 22 |
{ id: 'dashboard', label: '工作台', icon: LayoutDashboard, roles: [UserRole.ADMIN, UserRole.PRINCIPAL, UserRole.TEACHER, UserRole.STUDENT] },
|
| 23 |
{ id: 'ai-assistant', label: 'AI 智能助教', icon: Bot, roles: canSeeAI ? [UserRole.ADMIN, UserRole.TEACHER] : [] },
|
| 24 |
{ id: 'attendance', label: '考勤管理', icon: CalendarCheck, roles: [UserRole.TEACHER, UserRole.PRINCIPAL] },
|
|
@@ -36,13 +43,13 @@ export const Sidebar: React.FC<SidebarProps> = ({ currentView, onChangeView, use
|
|
| 36 |
{ id: 'settings', label: '系统设置', icon: Settings, roles: [UserRole.ADMIN, UserRole.PRINCIPAL] },
|
| 37 |
];
|
| 38 |
|
| 39 |
-
const [menuItems, setMenuItems] = useState(defaultItems);
|
| 40 |
const [isEditing, setIsEditing] = useState(false);
|
| 41 |
|
| 42 |
useEffect(() => {
|
| 43 |
// Load saved order
|
| 44 |
if (currentUser?.menuOrder && currentUser.menuOrder.length > 0) {
|
| 45 |
-
const ordered = [];
|
| 46 |
const map = new Map(defaultItems.map(i => [i.id, i]));
|
| 47 |
// Add saved items in order
|
| 48 |
currentUser.menuOrder.forEach(id => {
|
|
|
|
| 13 |
onClose: () => void;
|
| 14 |
}
|
| 15 |
|
| 16 |
+
interface MenuItem {
|
| 17 |
+
id: string;
|
| 18 |
+
label: string;
|
| 19 |
+
icon: React.ElementType;
|
| 20 |
+
roles: UserRole[];
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
export const Sidebar: React.FC<SidebarProps> = ({ currentView, onChangeView, userRole, onLogout, isOpen, onClose }) => {
|
| 24 |
const currentUser = api.auth.getCurrentUser();
|
| 25 |
const canSeeAI = userRole === UserRole.ADMIN || (userRole === UserRole.TEACHER && currentUser?.aiAccess);
|
| 26 |
|
| 27 |
// Default Items
|
| 28 |
+
const defaultItems: MenuItem[] = [
|
| 29 |
{ id: 'dashboard', label: '工作台', icon: LayoutDashboard, roles: [UserRole.ADMIN, UserRole.PRINCIPAL, UserRole.TEACHER, UserRole.STUDENT] },
|
| 30 |
{ id: 'ai-assistant', label: 'AI 智能助教', icon: Bot, roles: canSeeAI ? [UserRole.ADMIN, UserRole.TEACHER] : [] },
|
| 31 |
{ id: 'attendance', label: '考勤管理', icon: CalendarCheck, roles: [UserRole.TEACHER, UserRole.PRINCIPAL] },
|
|
|
|
| 43 |
{ id: 'settings', label: '系统设置', icon: Settings, roles: [UserRole.ADMIN, UserRole.PRINCIPAL] },
|
| 44 |
];
|
| 45 |
|
| 46 |
+
const [menuItems, setMenuItems] = useState<MenuItem[]>(defaultItems);
|
| 47 |
const [isEditing, setIsEditing] = useState(false);
|
| 48 |
|
| 49 |
useEffect(() => {
|
| 50 |
// Load saved order
|
| 51 |
if (currentUser?.menuOrder && currentUser.menuOrder.length > 0) {
|
| 52 |
+
const ordered: MenuItem[] = [];
|
| 53 |
const map = new Map(defaultItems.map(i => [i.id, i]));
|
| 54 |
// Add saved items in order
|
| 55 |
currentUser.menuOrder.forEach(id => {
|
pages/CourseList.tsx
CHANGED
|
@@ -169,13 +169,13 @@ export const CourseList: React.FC = () => {
|
|
| 169 |
<div className="flex gap-2 pt-2 border-t border-gray-50">
|
| 170 |
<button onClick={() => {
|
| 171 |
setFormData({
|
| 172 |
-
courseCode: c.courseCode,
|
| 173 |
courseName: c.courseName,
|
| 174 |
teacherName: c.teacherName,
|
| 175 |
teacherId: c.teacherId || '',
|
| 176 |
className: c.className,
|
| 177 |
-
credits: c.credits,
|
| 178 |
-
capacity: c.capacity
|
| 179 |
});
|
| 180 |
setEditId(c._id || String(c.id));
|
| 181 |
setIsModalOpen(true);
|
|
|
|
| 169 |
<div className="flex gap-2 pt-2 border-t border-gray-50">
|
| 170 |
<button onClick={() => {
|
| 171 |
setFormData({
|
| 172 |
+
courseCode: c.courseCode || '',
|
| 173 |
courseName: c.courseName,
|
| 174 |
teacherName: c.teacherName,
|
| 175 |
teacherId: c.teacherId || '',
|
| 176 |
className: c.className,
|
| 177 |
+
credits: c.credits || 2,
|
| 178 |
+
capacity: c.capacity || 45
|
| 179 |
});
|
| 180 |
setEditId(c._id || String(c.id));
|
| 181 |
setIsModalOpen(true);
|