some work on course popup
update the stories and create the header component
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import { Course, Status } from 'src/shared/types/Course';
|
import { Course, Status } from 'src/shared/types/Course';
|
||||||
import { CourseMeeting } from 'src/shared/types/CourseMeeting';
|
import { CourseMeeting } from 'src/shared/types/CourseMeeting';
|
||||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||||
import CoursePopup from 'src/views/components/injected/CoursePopup/CoursePopup';
|
import CoursePopup from 'src/views/components/injected/CoursePopup/CoursePopup';
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
const exampleCourse: Course = new Course({
|
const exampleCourse: Course = new Course({
|
||||||
courseName: 'ELEMS OF COMPTRS/PROGRAMMNG-WB',
|
courseName: 'ELEMS OF COMPTRS/PROGRAMMNG-WB',
|
||||||
|
|||||||
@@ -1,16 +1,67 @@
|
|||||||
import { Meta } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import { Course } from 'src/shared/types/Course';
|
import { Course, Status } from 'src/shared/types/Course';
|
||||||
|
import { CourseMeeting, DAY_MAP } from 'src/shared/types/CourseMeeting';
|
||||||
|
import { CourseSchedule } from 'src/shared/types/CourseSchedule';
|
||||||
|
import Instructor from 'src/shared/types/Instructor';
|
||||||
|
|
||||||
const testCourse: Course = {
|
import CoursePopup2 from 'src/views/components/injected/CoursePopup2/CoursePopup2';
|
||||||
|
|
||||||
}
|
const exampleCourse: Course = new Course({
|
||||||
|
uniqueId: 47280,
|
||||||
|
number: '331C',
|
||||||
|
fullName: "BVO 331C Bevo's Seminar Longhorn Care",
|
||||||
|
courseName: "Bevo's Seminar Longhorn Care",
|
||||||
|
department: 'BVO',
|
||||||
|
creditHours: 3,
|
||||||
|
status: Status.OPEN,
|
||||||
|
instructors: [new Instructor({ fullName: "Hook'em", firstName: '', lastName: "Hook'em" })],
|
||||||
|
isReserved: true,
|
||||||
|
description: [
|
||||||
|
'Restricted to Students in the School of Longhorn Enthusiasts',
|
||||||
|
'Immerse yourself in the daily routine of a longhorn—sunrise pasture walks and the best shady spots for a midday siesta. Understand the behavioral science behind our mascot’s stoic demeanor during games.',
|
||||||
|
'BVO 311C and 312H may not both be counted.',
|
||||||
|
'Prerequisite: Grazing 311 or 311H.',
|
||||||
|
'May be counted toward the Independent Inquiry flag requirement. May be counted toward the Writing flag requirement.',
|
||||||
|
'Offered on the letter-grade basis only.',
|
||||||
|
],
|
||||||
|
schedule: new CourseSchedule({
|
||||||
|
meetings: [
|
||||||
|
new CourseMeeting({
|
||||||
|
days: [DAY_MAP.T, DAY_MAP.TH],
|
||||||
|
startTime: 480,
|
||||||
|
endTime: 570,
|
||||||
|
location: { building: 'UTC', room: '123' },
|
||||||
|
}),
|
||||||
|
new CourseMeeting({
|
||||||
|
days: [DAY_MAP.TH],
|
||||||
|
startTime: 570,
|
||||||
|
endTime: 630,
|
||||||
|
location: { building: 'JES', room: '123' },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/',
|
||||||
|
flags: ['Writing', 'Independent Inquiry'],
|
||||||
|
instructionMode: 'In Person',
|
||||||
|
semester: {
|
||||||
|
year: 2024,
|
||||||
|
season: 'Spring',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const meta: Meta<typeof CoursePopup2> = {
|
const meta: Meta<typeof CoursePopup2> = {
|
||||||
|
title: 'Components/Injected/CoursePopup2',
|
||||||
component: CoursePopup2,
|
component: CoursePopup2,
|
||||||
|
argTypes: {
|
||||||
|
onClose: { action: 'onClose' },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof CoursePopup2>;
|
||||||
export const Open: Story = {
|
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args: {
|
||||||
|
course: exampleCourse,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,75 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Course } from 'src/shared/types/Course';
|
import { Course } from 'src/shared/types/Course';
|
||||||
import Text from '../../common/Text/Text';
|
|
||||||
import { Button } from '../../common/Button/Button';
|
import { Button } from '../../common/Button/Button';
|
||||||
|
import Icon from '../../common/Icon/Icon';
|
||||||
|
import Text from '../../common/Text/Text';
|
||||||
|
|
||||||
interface CourseHeadingAndActionsProps {
|
interface CourseHeadingAndActionsProps {
|
||||||
course: Course;
|
course: Course;
|
||||||
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CourseHeadingAndActions = ({ course }: CourseHeadingAndActionsProps) => {
|
const CourseHeadingAndActions = ({ course, onClose }: CourseHeadingAndActionsProps) => {
|
||||||
const { courseName, department, number, uniqueId } = course;
|
const { courseName, department, number, uniqueId, instructors, flags, schedule } = course;
|
||||||
|
const instructorString = instructors
|
||||||
|
.map(instructor => {
|
||||||
|
const firstInitial = instructor.firstName.length > 0 ? `${instructor.firstName.charAt(0)}. ` : '';
|
||||||
|
return `${firstInitial}${instructor.lastName}`;
|
||||||
|
})
|
||||||
|
.join(', ');
|
||||||
return (
|
return (
|
||||||
<div className='w-full pb-3 pt-6'>
|
<div className='w-full pb-3 pt-6'>
|
||||||
<div className='flex gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
<Text variant='h1'>
|
<div className='flex justify-center gap-1'>
|
||||||
|
<Text variant='h1' className='flex items-center'>
|
||||||
{courseName} ({department} {number})
|
{courseName} ({department} {number})
|
||||||
</Text>
|
</Text>
|
||||||
|
{/* TODO: change this button, include the left icon */}
|
||||||
<Button>{uniqueId}</Button>
|
<Button>{uniqueId}</Button>
|
||||||
|
<Button onClick={onClose}>
|
||||||
|
<Icon name='close' />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex gap-2.5 flex-content-center'>
|
||||||
|
<Text variant='h4'>
|
||||||
|
with <span className='text-ut-burntorange underline'>{instructorString}</span>
|
||||||
|
</Text>
|
||||||
|
<div className='flex gap-1 flex-content-center'>
|
||||||
|
{flags.map(flag => (
|
||||||
|
<div className='p flex justify-center flex-content-center rounded-lg bg-ut-yellow px-1 py-px'>
|
||||||
|
{/* get the first letter of each word in flag */}
|
||||||
|
<Text variant='h4' className='text-ut-black'>
|
||||||
|
{flag
|
||||||
|
.split(' ')
|
||||||
|
.map(word => word.charAt(0))
|
||||||
|
.join('')}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
{schedule.meetings.map(meeting => (
|
||||||
|
<Text variant='h4'>
|
||||||
|
{meeting.getDaysString({ format: 'long', separator: 'long' })}{' '}
|
||||||
|
{meeting.getTimeString({ separator: ' to ', capitalize: false })}
|
||||||
|
{meeting.location && (
|
||||||
|
<>
|
||||||
|
{` in `}
|
||||||
|
<Text variant='h4' className='text-ut-burntorange underline'>
|
||||||
|
{meeting.location.building}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='my-3 flex justify-start gap-1'>
|
||||||
|
<Button className='m0'>
|
||||||
|
<Icon name='calendar_today' />
|
||||||
|
</Button>
|
||||||
|
<Button>RateMyProf</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
import Popup from '@views/components/common/Popup/Popup';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Course } from 'src/shared/types/Course';
|
import { Course } from 'src/shared/types/Course';
|
||||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||||
import Popup from '../../common/Popup/Popup';
|
|
||||||
import CourseHeadingAndActions from './CourseHeadingAndActions';
|
import CourseHeadingAndActions from './CourseHeadingAndActions';
|
||||||
|
|
||||||
interface CoursePopup2Props {
|
interface CoursePopup2Props {
|
||||||
course: Course;
|
course: Course;
|
||||||
activeSchedule?: UserSchedule;
|
activeSchedule?: UserSchedule;
|
||||||
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoursePopup2 = ({ course, activeSchedule }: CoursePopup2Props) => (
|
const CoursePopup2 = ({ course, activeSchedule, onClose }: CoursePopup2Props) => (
|
||||||
<Popup className='px-6'>
|
<Popup overlay className='px-6' onClose={onClose}>
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
<CourseHeadingAndActions course={course} />
|
<CourseHeadingAndActions course={course} onClose={onClose} />
|
||||||
</div>
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default CoursePopup2;
|
export default CoursePopup2;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
ut: {
|
ut: {
|
||||||
'burnt-orange': '#BF5700',
|
burntorange: '#BF5700',
|
||||||
black: '#333F48',
|
black: '#333F48',
|
||||||
orange: '#f8971f',
|
orange: '#f8971f',
|
||||||
yellow: '#ffd600',
|
yellow: '#ffd600',
|
||||||
|
|||||||
Reference in New Issue
Block a user