import React, { useMemo } from "react"; import { Separator } from "../ui/separator"; import type { Workspace, SpaceType } from "../../App"; import type { CourseDirectoryItem } from "../../lib/courseDirectory"; function gmailComposeLink(email: string, subject?: string, body?: string) { const to = `to=${encodeURIComponent(email)}`; const su = subject ? `&su=${encodeURIComponent(subject)}` : ""; const bd = body ? `&body=${encodeURIComponent(body)}` : ""; return `https://mail.google.com/mail/?view=cm&fs=1&${to}${su}${bd}`; } function norm(s: any) { return String(s ?? "").trim().toLowerCase(); } function pickAny(obj: any, keys: string[]) { for (const k of keys) { const v = obj?.[k]; if (v !== undefined && v !== null && String(v).trim() !== "") return v; } return undefined; } function toIntOrFallback(v: any, fb: number) { const n = Number(v); if (Number.isFinite(n) && n > 0) return Math.floor(n); return fb; } export function CourseInfoSection({ currentWorkspaceId, workspaces, selectedCourse, availableCourses, }: { currentWorkspaceId: string; workspaces: Workspace[]; selectedCourse: string; availableCourses: CourseDirectoryItem[]; }) { const currentWorkspace = useMemo( () => workspaces.find((w) => w.id === currentWorkspaceId), [workspaces, currentWorkspaceId] ); // 判断当前是否是 Group/Team(用于决定是否展示 Group Name/Number) const isTeamSpace = useMemo(() => { const ws: any = currentWorkspace as any; const st = String((ws?.type as SpaceType) || "").toLowerCase(); return st === "group" || st === "team"; }, [currentWorkspace]); // --------- CourseInfo resolution --------- const courseInfo = useMemo((): CourseDirectoryItem | null => { const list = Array.isArray(availableCourses) ? availableCourses : []; // 1) selectedCourse: 可能是 id / name(大小写/空格不一致也能匹配) const selRaw = (selectedCourse || "").trim(); const sel = norm(selRaw); if (sel) { const hit = list.find((c: any) => norm(c.id) === sel) || list.find((c: any) => norm(c.name) === sel); if (hit) return hit as any; } // 2) workspace.courseInfo: group workspace 的 courseInfo 可能只带 id/name const wsCourse = (currentWorkspace as any)?.courseInfo as | { id?: string; name?: string; instructor?: any; teachingAssistant?: any } | undefined; const wsId = norm(wsCourse?.id); if (wsId) return (list.find((c: any) => norm(c.id) === wsId) ?? (wsCourse as any)) as any; const wsName = norm(wsCourse?.name); if (wsName) return (list.find((c: any) => norm(c.name) === wsName) ?? (wsCourse as any)) as any; return null; }, [availableCourses, currentWorkspace, selectedCourse]); // ---------- Display fields ---------- const courseName = useMemo(() => { return (courseInfo as any)?.name ?? (selectedCourse || "Course"); }, [courseInfo, selectedCourse]); // --------- Group fields (read-only) --------- const groupName = useMemo(() => { const ws: any = currentWorkspace as any; // 优先 groupName,否则退回 workspace 的 name/title return String(pickAny(ws, ["groupName", "name", "title"]) || "My Group"); }, [currentWorkspace]); const groupNo = useMemo(() => { const ws: any = currentWorkspace as any; const raw = ws?.groupNo ?? ws?.groupNumber ?? ws?.groupIndex ?? ws?.group_id ?? ws?.groupId ?? 1; return toIntOrFallback(raw, 1); }, [currentWorkspace]); // ---------- Fallback:不要静默消失 ---------- if (!courseInfo) { return (
COURSEINFO ACTIVE (fallback)
No course matched
selectedCourse: {String(selectedCourse || "")}
availableCourses: {availableCourses?.length ?? 0}
currentWorkspaceId: {String(currentWorkspaceId)}
); } const instructorName = (courseInfo as any)?.instructor?.name ?? "N/A"; const instructorEmail = String((courseInfo as any)?.instructor?.email ?? "").trim(); const taName = (courseInfo as any)?.teachingAssistant?.name ?? "N/A"; const taEmail = String((courseInfo as any)?.teachingAssistant?.email ?? "").trim(); return (
{/* Course Title */}
{courseName}
{/* Group fields (read-only, no pencil) */} {isTeamSpace && (
Group Name: {groupName}
Group Number: {groupNo}
)} {/* Instructor */}
Instructor:  {instructorEmail ? ( {instructorName} ) : ( {instructorName} )}
{/* TA */}
TA:  {taEmail ? ( {taName} ) : ( {taName} )}
); }