fix: updated text when time/location not provided (#289)

* fix: updated text when time/location not provided

* fix(issue): fixed text when time/loc isn't provided

* chore: lint and format

* fix: created location&time component

* fix: renamed component & restructured component

* chore: fix lint

* fix: variety of issues within DisplayMeetingInfo component

* fix: fixed lint error

* fix: ran prettier

* chore: locationInfo usage

* chore: cleanup

* fix: removed periods and added online info

* fix: wrapped in div to remove space

* fix: space now shows properly

* fix: spacing fixed

* chore: remove types from jsdoc

* fix: extra arg

* chore: fix lint

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
ali v
2024-11-16 15:11:30 -06:00
committed by GitHub
parent e987fbbe8e
commit ebcc0aa76a
2 changed files with 99 additions and 35 deletions

View File

@@ -0,0 +1,96 @@
import type { Course } from '@shared/types/Course';
import type { CourseMeeting } from '@shared/types/CourseMeeting';
import Link from '@views/components/common/Link';
import Text from '@views/components/common/Text/Text';
import React from 'react';
/**
* Props for the DisplayMeetingInfo component.
*/
export interface DisplayMeetingInfoProps {
course: Course;
}
interface MeetingInfoTextProps {
meeting: CourseMeeting;
instructionMode: string;
}
/**
* Renders a single meeting's time and location info.
*
* @param meeting - The meeting to display the info for.
* @param instructionMode - The instruction mode of the course.
* @returns The JSX element for the meeting info.
*/
function MeetingInfoText({ meeting, instructionMode }: MeetingInfoTextProps): JSX.Element {
const daysString = meeting.getDaysString({ format: 'long', separator: 'long' });
const timeString = meeting.getTimeString({ separator: ' to ' });
const getBuildingUrl = (building: string) =>
`https://utdirect.utexas.edu/apps/campus/buildings/nlogon/maps/UTM/${building}`;
let locationInfo: JSX.Element | string | undefined;
if (meeting.location) {
locationInfo = (
<div className='ml-1'>
{'in '}
<Link href={getBuildingUrl(meeting.location.building)} className='link' variant='h4'>
{meeting.location.building} {meeting.location.room}
</Link>
</div>
);
} else if (instructionMode !== 'Online') {
locationInfo = (
<Text variant='h4' as='p' className='ml-1'>
(No location has been provided)
</Text>
);
} else if (instructionMode === 'Online') {
locationInfo = ', Online (Internet)';
}
return (
<div className='flex'>
<Text variant='h4' as='p'>
{daysString} {timeString}
</Text>
<Text variant='h4' as='p'>
{locationInfo}
</Text>
</div>
);
}
/**
* Render the time and location for the current class.
*
* @param course - The course to display the meeting info for.
* @returns The JSX element for the meeting info.
*/
export default function DisplayMeetingInfo({ course }: DisplayMeetingInfoProps): JSX.Element {
const { schedule, instructionMode } = course;
const noMeetings = !Array.isArray(schedule.meetings) || schedule.meetings.length === 0;
return (
<div className='mt-1 flex flex-col'>
{noMeetings ? (
<Text variant='h4' as='p'>
{instructionMode !== 'Online'
? '(No time and location has been provided)'
: '(No time has been provided), Online (Internet)'}
</Text>
) : (
schedule.meetings.map(meeting => (
<MeetingInfoText
key={`${meeting.days.join('-')}-${meeting.startTime}-${meeting.endTime}`}
meeting={meeting}
instructionMode={instructionMode}
/>
))
)}
</div>
);
}

View File

@@ -20,6 +20,8 @@ import OpenNewIcon from '~icons/material-symbols/open-in-new';
import Remove from '~icons/material-symbols/remove'; import Remove from '~icons/material-symbols/remove';
import Reviews from '~icons/material-symbols/reviews'; import Reviews from '~icons/material-symbols/reviews';
import DisplayMeetingInfo from './DisplayMeetingInfo';
const { openNewTab, addCourse, removeCourse, openCESPage } = background; const { openNewTab, addCourse, removeCourse, openCESPage } = background;
/** /**
@@ -56,9 +58,6 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
const getInstructorFullName = (instructor: Instructor) => const getInstructorFullName = (instructor: Instructor) =>
instructor.toString({ format: 'first_last', case: 'capitalize' }); instructor.toString({ format: 'first_last', case: 'capitalize' });
const getBuildingUrl = (building: string) =>
`https://utdirect.utexas.edu/apps/campus/buildings/nlogon/maps/UTM/${building}`;
const handleCopy = () => { const handleCopy = () => {
navigator.clipboard.writeText(formattedUniqueId); navigator.clipboard.writeText(formattedUniqueId);
}; };
@@ -164,38 +163,7 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
))} ))}
</div> </div>
</div> </div>
<div className='mt-1 flex flex-col'> <DisplayMeetingInfo course={course} />
{schedule.meetings.map(meeting => {
const daysString = meeting.getDaysString({ format: 'long', separator: 'long' });
const timeString = meeting.getTimeString({ separator: ' to ' });
return (
<Text
key={
daysString +
timeString +
(meeting.location?.building ?? '') +
(meeting.location?.room ?? '')
}
variant='h4'
as='p'
>
{daysString} {timeString}
{meeting.location && (
<>
{' in '}
<Link
href={getBuildingUrl(meeting.location.building)}
className='link'
variant='h4'
>
{meeting.location.building} {meeting.location.room}
</Link>
</>
)}
</Text>
);
})}
</div>
</div> </div>
<div className='my-3 flex flex-wrap items-center gap-x-3.75 gap-y-2.5'> <div className='my-3 flex flex-wrap items-center gap-x-3.75 gap-y-2.5'>
<Button <Button