import { background } from '@shared/messages'; import type { Course } from '@shared/types/Course'; import type Instructor from '@shared/types/Instructor'; import type { UserSchedule } from '@shared/types/UserSchedule'; import { Button } from '@views/components/common/Button'; import { Chip, flagMap } from '@views/components/common/Chip'; import Divider from '@views/components/common/Divider'; import Link from '@views/components/common/Link'; import Text from '@views/components/common/Text/Text'; import { useCalendar } from '@views/contexts/CalendarContext'; import React from 'react'; import Add from '~icons/material-symbols/add'; import CalendarMonth from '~icons/material-symbols/calendar-month'; import CloseIcon from '~icons/material-symbols/close'; import Copy from '~icons/material-symbols/content-copy'; import Description from '~icons/material-symbols/description'; import Mood from '~icons/material-symbols/mood'; import OpenNewIcon from '~icons/material-symbols/open-in-new'; import Remove from '~icons/material-symbols/remove'; import Reviews from '~icons/material-symbols/reviews'; const { openNewTab, addCourse, removeCourse, openCESPage } = background; interface HeadingAndActionProps { /* The course to display */ course: Course; /* The active schedule */ activeSchedule: UserSchedule; /* The function to call when the popup should be closed */ onClose: () => void; } /** * Capitalizes the first letter of a string and converts the rest of the letters to lowercase. * * @param str - The string to be capitalized. * @returns The capitalized string. */ const capitalizeString = (str: string) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); /** * Renders the heading component for the CoursePopup component. * * @param {HeadingAndActionProps} props - The component props. * @param {Course} props.course - The course object containing course details. * @param {Schedule} props.activeSchedule - The active schedule object. * @param {Function} props.onClose - The function to close the popup. * @returns {JSX.Element} The rendered component. */ export default function HeadingAndActions({ course, activeSchedule, onClose }: HeadingAndActionProps): JSX.Element { const { courseName, department, number: courseNumber, uniqueId, instructors, flags, schedule } = course; const courseAdded = activeSchedule.courses.some(ourCourse => ourCourse.uniqueId === uniqueId); const formattedUniqueId = uniqueId.toString().padStart(5, '0'); const isInCalendar = useCalendar(); const getInstructorFullName = (instructor: Instructor) => { const { firstName = '', lastName = '' } = instructor; if (firstName === '') return capitalizeString(lastName); return `${capitalizeString(firstName)} ${capitalizeString(lastName)}`; }; const getBuildingUrl = (building: string) => `https://utdirect.utexas.edu/apps/campus/buildings/nlogon/maps/UTM/${building}`; const handleCopy = () => { navigator.clipboard.writeText(formattedUniqueId); }; const handleOpenRateMyProf = async () => { const openTabs = instructors.map(instructor => { const instructorSearchTerm = getInstructorFullName(instructor); instructorSearchTerm.replace(' ', '+'); const url = `https://www.ratemyprofessors.com/search/professors/1255?q=${instructorSearchTerm}`; return openNewTab({ url }); }); await Promise.all(openTabs); }; const handleOpenCES = async () => { const openTabs = instructors.map(instructor => { let { firstName = '', lastName = '' } = instructor; firstName = capitalizeString(firstName); lastName = capitalizeString(lastName); return openCESPage({ instructorFirstName: firstName, instructorLastName: lastName }); }); await Promise.all(openTabs); }; const handleOpenPastSyllabi = async () => { for (const instructor of instructors) { let { firstName = '', lastName = '' } = instructor; firstName = capitalizeString(firstName); lastName = capitalizeString(lastName); const url = `https://utdirect.utexas.edu/apps/student/coursedocs/nlogon/?year=&semester=&department=${department}&course_number=${courseNumber}&course_title=&unique=&instructor_first=${firstName}&instructor_last=${lastName}&course_type=In+Residence&search=Search`; openNewTab({ url }); } }; const handleAddOrRemoveCourse = async () => { if (!activeSchedule) return; if (!courseAdded) { addCourse({ course, scheduleId: activeSchedule.id }); } else { removeCourse({ course, scheduleId: activeSchedule.id }); } }; return (