AI_Agent_Final / web /src /components /sidebar /CourseInfoSection.tsx
SarahXia0405's picture
Update web/src/components/sidebar/CourseInfoSection.tsx
6170d99 verified
import React, { useMemo } from "react";
import { Separator } from "../ui/separator";
import type { Workspace } 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();
}
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]
);
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) => norm(c.id) === sel) ||
list.find((c) => norm(c.name) === sel);
if (hit) return hit;
}
// 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) => norm(c.id) === wsId) ?? (wsCourse as any);
}
const wsName = norm(wsCourse?.name);
if (wsName) {
return list.find((c) => norm(c.name) === wsName) ?? (wsCourse as any);
}
return null;
}, [availableCourses, currentWorkspace, selectedCourse]);
// ---------- Fallback:不要静默消失 ----------
if (!courseInfo) {
return (
<div className="w-full">
<div className="px-4 pt-4 pb-3 space-y-2">
<div className="text-xs text-red-600">COURSEINFO ACTIVE (fallback)</div>
<div className="font-semibold text-base">No course matched</div>
<div className="text-xs text-muted-foreground space-y-1">
<div>selectedCourse: <span className="font-medium">{String(selectedCourse || "")}</span></div>
<div>availableCourses: <span className="font-medium">{availableCourses?.length ?? 0}</span></div>
<div>currentWorkspaceId: <span className="font-medium">{String(currentWorkspaceId)}</span></div>
</div>
</div>
<Separator className="bg-[#ECECF1]" />
</div>
);
}
// ---------- Display fields ----------
const courseName = courseInfo.name ?? (selectedCourse || "Course");
const instructorName = courseInfo?.instructor?.name ?? "N/A";
const instructorEmail = (courseInfo?.instructor?.email || "").trim();
const taName = courseInfo?.teachingAssistant?.name ?? "N/A";
const taEmail = (courseInfo?.teachingAssistant?.email || "").trim();
return (
<div className="w-full">
<div className="px-4 pt-4 pb-3 space-y-2">
<div className="font-semibold text-base">{courseName}</div>
<div className="text-sm text-muted-foreground">
Instructor:&nbsp;
{instructorEmail ? (
<a
href={gmailComposeLink(
instructorEmail,
`[Clare] Question about ${courseName}`,
`Hi ${instructorName},\n\nI have a question about ${courseName}:\n\n(Write your question here)\n\nThanks,\n`
)}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{instructorName}
</a>
) : (
<span className="text-muted-foreground/60">{instructorName}</span>
)}
</div>
<div className="text-sm text-muted-foreground">
TA:&nbsp;
{taEmail ? (
<a
href={gmailComposeLink(
taEmail,
`[Clare] Help request for ${courseName}`,
`Hi ${taName},\n\nI need help with ${courseName}:\n\n(Write your question here)\n\nThanks,\n`
)}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{taName}
</a>
) : (
<span className="text-muted-foreground/60">{taName}</span>
)}
</div>
</div>
<Separator className="bg-[#ECECF1]" />
</div>
);
}