feat: calendar matchings (#173)
* feat: calendar matchings * fix: build * refactor: resolve pr comments * fix: destrucure editorRef --------- Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
.scrollableSchedules {
|
||||
overflow-y: auto; /* Enables vertical scrolling */
|
||||
}
|
||||
|
||||
.scrollableLimit {
|
||||
overflow-y: auto; /* Enables vertical scrolling */
|
||||
max-height: 35vh; /* Adjusts based on your needs and testing */
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import { useFlattenedCourseSchedule } from '@views/hooks/useFlattenedCourseSched
|
||||
import { MessageListener } from 'chrome-extension-toolkit';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import styles from './Calendar.module.scss';
|
||||
/**
|
||||
* A reusable chip component that follows the design system of the extension.
|
||||
* @returns
|
||||
@@ -33,8 +32,6 @@ export default function Calendar(): JSX.Element {
|
||||
});
|
||||
|
||||
const [showPopup, setShowPopup] = useState<boolean>(course !== null);
|
||||
const [sidebarWidth, setSidebarWidth] = useState('20%');
|
||||
const [scale, setScale] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = new MessageListener<CalendarTabMessages>({
|
||||
@@ -52,59 +49,21 @@ export default function Calendar(): JSX.Element {
|
||||
return () => listener.unlisten();
|
||||
}, [activeSchedule.courses]);
|
||||
|
||||
useEffect(() => {
|
||||
const adjustLayout = () => {
|
||||
const windowHeight = window.innerHeight;
|
||||
const windowWidth = window.innerWidth;
|
||||
|
||||
const desiredCalendarHeight = 760;
|
||||
const minSidebarWidthPixels = 230;
|
||||
|
||||
const scale = Math.min(1, windowHeight / desiredCalendarHeight);
|
||||
|
||||
const sidebarWidthPixels = Math.max(
|
||||
windowWidth * scale - windowWidth + minSidebarWidthPixels,
|
||||
minSidebarWidthPixels
|
||||
);
|
||||
const newSidebarWidth = `${(sidebarWidthPixels / windowWidth) * 100}%`;
|
||||
|
||||
setScale(scale);
|
||||
setSidebarWidth(newSidebarWidth);
|
||||
};
|
||||
|
||||
adjustLayout();
|
||||
|
||||
window.addEventListener('resize', adjustLayout);
|
||||
return () => window.removeEventListener('resize', adjustLayout);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (course) setShowPopup(true);
|
||||
}, [course]);
|
||||
|
||||
const calendarContainerStyle = {
|
||||
transform: `scale(${scale})`,
|
||||
transformOrigin: 'top left',
|
||||
marginTop: '-20px',
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='h-screen flex flex-col' style={{ width: 'calc(100% - 1rem)' }}>
|
||||
<div className='pl-5'>
|
||||
<CalendarHeader />
|
||||
</div>
|
||||
<div className={`flex flex-grow flex-row overflow-hidden pl-4 ${styles.scrollableSchedules}`}>
|
||||
<div className='sidebar-style' style={{ width: sidebarWidth, padding: '10px 15px 5px 5px' }}>
|
||||
<div className={`mb-4 ${styles.scrollableLimit}`}>
|
||||
<CalendarSchedules />
|
||||
</div>
|
||||
<Divider orientation='horizontal' size='100%' />
|
||||
<div className='mt-4'>
|
||||
<ImportantLinks />
|
||||
</div>
|
||||
<div className='h-full w-full flex flex-col'>
|
||||
<CalendarHeader />
|
||||
<div className='h-full flex flex-grow overflow-hidden pl-7.5'>
|
||||
<div className='overflow-auto py-5'>
|
||||
<CalendarSchedules />
|
||||
<Divider orientation='horizontal' size='100%' className='my-5' />
|
||||
<ImportantLinks />
|
||||
</div>
|
||||
<div className='flex flex-grow flex-col' style={calendarContainerStyle} ref={calendarRef}>
|
||||
<div className='flex-grow overflow-auto'>
|
||||
<div className='flex flex-grow flex-col' ref={calendarRef}>
|
||||
<div className='flex-grow overflow-auto px-4 pt-6.5'>
|
||||
<CalendarGrid courseCells={courseCells} setCourse={setCourse} />
|
||||
</div>
|
||||
<CalendarBottomBar calendarRef={calendarRef} />
|
||||
|
||||
@@ -56,7 +56,11 @@ export default function CalendarCourseCell({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx('h-full w-full flex justify-center rounded p-2 cursor-pointer', fontColor, className)}
|
||||
className={clsx(
|
||||
'h-full min-w-full w-0 flex justify-center rounded p-2 cursor-pointer',
|
||||
fontColor,
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: colors.primaryColor,
|
||||
}}
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
.dayLabelContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 13px;
|
||||
min-width: 40px;
|
||||
min-height: 13px;
|
||||
padding-bottom: 15px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
.calendarGrid {
|
||||
display: grid;
|
||||
grid-template-columns: auto repeat(5, 6fr);
|
||||
grid-template-rows: repeat(26, 1fr);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.calendarRow {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.calendar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.day {
|
||||
gap: 5px;
|
||||
color: #bf5700;
|
||||
text-align: center;
|
||||
font-size: 14.22px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
margin-top: 20px;
|
||||
border-right: 1px solid #dadce0;
|
||||
border-bottom: 1px solid #dadce0;
|
||||
border-left: 1px solid #dadce0;
|
||||
}
|
||||
|
||||
.timeAndGrid {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.timeColumn {
|
||||
display: flex;
|
||||
min-height: 573px;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
flex: 1 0 0;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.timeBlock {
|
||||
display: flex;
|
||||
width: auto;
|
||||
height: auto;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
|
||||
.timeLabelContainer {
|
||||
display: flex;
|
||||
max-height: 20px;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 17px;
|
||||
flex: 1 0 0;
|
||||
border-radius: var(--border-radius-none, 0px);
|
||||
}
|
||||
|
||||
p {
|
||||
color: #1a2024;
|
||||
text-align: left;
|
||||
height: 6.6px;
|
||||
align-self: stretch;
|
||||
margin-top: -10px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 0;
|
||||
|
||||
/* Type scale/small */
|
||||
font-size: 14.22px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.calendarButton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 6px 6px;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.buttonIcon {
|
||||
height: 24px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 30px;
|
||||
width: 1px;
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
.dot {
|
||||
height: 75%; /* 75% of the container's height */
|
||||
width: 75%; /* 75% of the container's width */
|
||||
background-color: #000000; /* Color of the dot */
|
||||
border-radius: 50%; /* Rounds the corners into a circle */
|
||||
top: 12.5%; /* Centers the dot vertically */
|
||||
left: 12.5%; /* Centers the dot horizontally */
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
import type { Course } from '@shared/types/Course';
|
||||
import { DAY_MAP } from '@shared/types/CourseMeeting';
|
||||
import { getCourseColors } from '@shared/util/colors';
|
||||
import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell';
|
||||
import CalendarCell from '@views/components/calendar/CalendarGridCell/CalendarGridCell';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import styles from './CalendarGrid.module.scss';
|
||||
import CalendarCell from '../CalendarGridCell/CalendarGridCell';
|
||||
|
||||
const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key));
|
||||
const daysOfWeek = ['MON', 'TUE', 'WED', 'THU', 'FRI'];
|
||||
const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8);
|
||||
|
||||
interface Props {
|
||||
@@ -17,55 +16,60 @@ interface Props {
|
||||
setCourse: React.Dispatch<React.SetStateAction<Course | null>>;
|
||||
}
|
||||
|
||||
function CalendarHour(hour: number) {
|
||||
return (
|
||||
<div className='grid-row-span-2 pr-2'>
|
||||
<Text variant='small' className='inline-block w-full text-right -translate-y-2.25'>
|
||||
{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}
|
||||
</Text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function makeGridRow(row: number, cols: number): JSX.Element {
|
||||
const hour = hoursOfDay[row];
|
||||
|
||||
return (
|
||||
<>
|
||||
{CalendarHour(hour)}
|
||||
<div className='grid-row-span-2 w-4 border-b border-r border-gray-300' />
|
||||
{[...Array(cols).keys()].map(col => (
|
||||
<CalendarCell key={`${row}${col}`} row={row} col={col} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: add Saturday class support
|
||||
|
||||
/**
|
||||
* Grid of CalendarGridCell components forming the user's course schedule calendar view
|
||||
* @param props
|
||||
*/
|
||||
export default function CalendarGrid({
|
||||
courseCells,
|
||||
saturdayClass,
|
||||
saturdayClass, // TODO: implement/move away from props
|
||||
setCourse,
|
||||
}: React.PropsWithChildren<Props>): JSX.Element {
|
||||
const [grid, setGrid] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const newGrid = [];
|
||||
for (let i = 0; i < 13; i++) {
|
||||
const row = [];
|
||||
let hour = hoursOfDay[i];
|
||||
let styleProp = {
|
||||
gridColumn: '1',
|
||||
gridRow: `${2 * i + 2}`,
|
||||
};
|
||||
row.push(
|
||||
<div key={hour} className={styles.timeBlock} style={styleProp}>
|
||||
<div className={styles.timeLabelContainer}>
|
||||
<p>{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
for (let k = 0; k < 5; k++) {
|
||||
styleProp = {
|
||||
gridColumn: `${k + 2}`,
|
||||
gridRow: `${2 * i + 2} / ${2 * i + 4}`,
|
||||
};
|
||||
row.push(<CalendarCell key={k} styleProp={styleProp} />);
|
||||
}
|
||||
newGrid.push(row);
|
||||
}
|
||||
setGrid(newGrid);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.calendarGrid}>
|
||||
<div className='grid grid-cols-[auto_auto_repeat(5,1fr)] grid-rows-[auto_repeat(26,1fr)] h-full'>
|
||||
{/* Displaying day labels */}
|
||||
<div className={styles.timeBlock} />
|
||||
<div />
|
||||
<div className='w-4 border-b border-r border-gray-300' />
|
||||
{daysOfWeek.map(day => (
|
||||
<div key={day} className={styles.day}>
|
||||
{day}
|
||||
<div className='h-4 flex items-end justify-center border-b border-r border-gray-300 pb-1.5'>
|
||||
<Text key={day} variant='small' className='text text-center text-ut-burntorange' as='div'>
|
||||
{day}
|
||||
</Text>
|
||||
</div>
|
||||
))}
|
||||
{grid.map(row => row)}
|
||||
{[...Array(13).keys()].map(i => makeGridRow(i, 5))}
|
||||
{CalendarHour(21)}
|
||||
{Array(6)
|
||||
.fill(1)
|
||||
.map(() => (
|
||||
<div className='h-4 flex items-end justify-center border-r border-gray-300' />
|
||||
))}
|
||||
{courseCells ? <AccountForCourseConflicts courseCells={courseCells} setCourse={setCourse} /> : null}
|
||||
</div>
|
||||
);
|
||||
@@ -76,6 +80,7 @@ interface AccountForCourseConflictsProps {
|
||||
setCourse: React.Dispatch<React.SetStateAction<Course | null>>;
|
||||
}
|
||||
|
||||
// TODO: Possibly refactor to be more concise
|
||||
function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseConflictsProps): JSX.Element[] {
|
||||
// Groups by dayIndex to identify overlaps
|
||||
const days = courseCells.reduce((acc, cell: CalendarGridCourse) => {
|
||||
@@ -123,7 +128,7 @@ function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseC
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`${block}`}
|
||||
key={`${JSON.stringify(block)}`}
|
||||
style={{
|
||||
gridColumn: `${block.calendarGridPoint.dayIndex + 2}`,
|
||||
gridRow: `${block.calendarGridPoint.startIndex} / ${block.calendarGridPoint.endIndex}`,
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
.calendarCell {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 45px;
|
||||
min-height: 40px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
border: 1px solid #dadce0;
|
||||
}
|
||||
|
||||
.hourLine {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
border-radius: 0px;
|
||||
background: rgba(218, 220, 224, 0.25);
|
||||
}
|
||||
@@ -1,19 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
import styles from './CalendarGridCell.module.scss';
|
||||
|
||||
interface Props {
|
||||
styleProp: any;
|
||||
row: number;
|
||||
col: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component representing each 1 hour time block of a calendar
|
||||
* @param props
|
||||
*/
|
||||
function CalendarCell({ styleProp }: Props): JSX.Element {
|
||||
function CalendarCell(props: Props): JSX.Element {
|
||||
return (
|
||||
<div className={styles.calendarCell} style={styleProp}>
|
||||
<div className={styles.hourLine} />
|
||||
<div
|
||||
className='h-full w-full flex items-center border-b border-r border-gray-300'
|
||||
style={{
|
||||
gridColumn: props.col + 3,
|
||||
gridRow: `${2 * props.row + 2} / ${2 * props.row + 4}`,
|
||||
}}
|
||||
>
|
||||
<div className='h-0 w-full border-t border-gray-300/25' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Status } from '@shared/types/Course';
|
||||
import { Button } from '@views/components/common/Button/Button';
|
||||
import CourseStatus from '@views/components/common/CourseStatus/CourseStatus';
|
||||
import Divider from '@views/components/common/Divider/Divider';
|
||||
import { LogoIcon } from '@views/components/common/LogoIcon';
|
||||
import { LargeLogo } from '@views/components/common/LogoIcon';
|
||||
import ScheduleTotalHoursAndCourses from '@views/components/common/ScheduleTotalHoursAndCourses/ScheduleTotalHoursAndCourses';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import useSchedules from '@views/hooks/useSchedules';
|
||||
@@ -11,9 +11,7 @@ import { openTabFromContentScript } from '@views/lib/openNewTabFromContentScript
|
||||
import React from 'react';
|
||||
|
||||
import MenuIcon from '~icons/material-symbols/menu';
|
||||
import RedoIcon from '~icons/material-symbols/redo';
|
||||
import SettingsIcon from '~icons/material-symbols/settings';
|
||||
import UndoIcon from '~icons/material-symbols/undo';
|
||||
import RefreshIcon from '~icons/material-symbols/refresh';
|
||||
|
||||
/**
|
||||
* Opens the options page in a new tab.
|
||||
@@ -32,44 +30,34 @@ export default function CalendarHeader(): JSX.Element {
|
||||
const [activeSchedule] = useSchedules();
|
||||
|
||||
return (
|
||||
<div className='min-h-79px min-w-672px w-full flex px-0 py-5'>
|
||||
<div className='w-full flex flex-row gap-20'>
|
||||
<div className='flex gap-10'>
|
||||
<div className='flex gap-1'>
|
||||
<Button className='self-center' variant='single' icon={MenuIcon} color='ut-gray' />
|
||||
<div className='flex items-center gap-2'>
|
||||
<LogoIcon />
|
||||
<div className='flex flex-col whitespace-nowrap'>
|
||||
<Text className='text-ut-burntorange text-lg! font-medium!'>UT Registration</Text>
|
||||
<Text className='text-ut-orange text-lg! font-medium!'>Plus</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Divider className='self-center' size='2.5rem' orientation='vertical' />
|
||||
<div className='flex flex-col self-center'>
|
||||
<ScheduleTotalHoursAndCourses
|
||||
scheduleName={activeSchedule.name}
|
||||
totalHours={activeSchedule.hours}
|
||||
totalCourses={activeSchedule.courses.length}
|
||||
/>
|
||||
<Text variant='h4' className='text-gray text-xs! font-medium! leading-normal!'>
|
||||
LAST UPDATED: {getUpdatedAtDateTimeString(activeSchedule.updatedAt)}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
<div className='ml-auto flex flex-row items-center justify-end space-x-8'>
|
||||
<div className='flex flex-row space-x-4'>
|
||||
<CourseStatus size='small' status={Status.WAITLISTED} />
|
||||
<CourseStatus size='small' status={Status.CLOSED} />
|
||||
<CourseStatus size='small' status={Status.CANCELLED} />
|
||||
</div>
|
||||
<div className='flex flex-row'>
|
||||
<Button variant='single' icon={UndoIcon} color='ut-black' />
|
||||
<Button variant='single' icon={RedoIcon} color='ut-black' />
|
||||
<Button variant='single' icon={SettingsIcon} color='ut-black' onClick={handleOpenOptions} />
|
||||
</div>
|
||||
<div className='flex items-center gap-5 border-b px-7 py-4'>
|
||||
<Button variant='single' icon={MenuIcon} color='ut-gray' />
|
||||
<LargeLogo />
|
||||
<Divider className='mx-4 self-center' size='2.5rem' orientation='vertical' />
|
||||
<div className='flex-grow'>
|
||||
<ScheduleTotalHoursAndCourses
|
||||
scheduleName={activeSchedule.name}
|
||||
totalHours={activeSchedule.hours}
|
||||
totalCourses={activeSchedule.courses.length}
|
||||
/>
|
||||
<div className='flex items-center gap-1'>
|
||||
<Text variant='mini' className='text-ut-gray'>
|
||||
LAST UPDATED: {getUpdatedAtDateTimeString(activeSchedule.updatedAt)}
|
||||
</Text>
|
||||
<button className='inline-block h-4 w-4 bg-transparent p-0 btn'>
|
||||
<RefreshIcon className='h-4 w-4 animate-duration-800 text-ut-black' />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-row items-center justify-end gap-6'>
|
||||
<CourseStatus size='small' status={Status.WAITLISTED} />
|
||||
<CourseStatus size='small' status={Status.CLOSED} />
|
||||
<CourseStatus size='small' status={Status.CANCELLED} />
|
||||
|
||||
{/* <Button variant='single' icon={UndoIcon} color='ut-black' />
|
||||
<Button variant='single' icon={RedoIcon} color='ut-black' /> */}
|
||||
{/* <Button variant='single' icon={SettingsIcon} color='ut-black' onClick={handleOpenOptions} /> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,68 +1,35 @@
|
||||
import { background } from '@shared/messages';
|
||||
import createSchedule from '@pages/background/lib/createSchedule';
|
||||
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
|
||||
import type { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import { Button } from '@views/components/common/Button/Button';
|
||||
import List from '@views/components/common/List/List';
|
||||
import ScheduleListItem from '@views/components/common/ScheduleListItem/ScheduleListItem';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import AddSchedule from '~icons/material-symbols/add';
|
||||
|
||||
/**
|
||||
* Props for the CalendarSchedules component.
|
||||
*/
|
||||
export type Props = {
|
||||
style?: React.CSSProperties;
|
||||
dummySchedules?: UserSchedule[];
|
||||
dummyActiveIndex?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a component that displays a list of schedules.
|
||||
*
|
||||
* @param props - The component props.
|
||||
* @returns The rendered component.
|
||||
*/
|
||||
export function CalendarSchedules({ style, dummySchedules, dummyActiveIndex }: Props) {
|
||||
const [activeScheduleIndex, setActiveScheduleIndex] = useState(0);
|
||||
const [newSchedule, setNewSchedule] = useState('');
|
||||
const [activeSchedule, schedules] = useSchedules();
|
||||
|
||||
useEffect(() => {
|
||||
const index = schedules.findIndex(schedule => schedule.id === activeSchedule.id);
|
||||
if (index !== -1) {
|
||||
setActiveScheduleIndex(index);
|
||||
}
|
||||
}, [activeSchedule, schedules]);
|
||||
|
||||
const handleKeyDown = event => {
|
||||
if (event.code === 'Enter') {
|
||||
background.createSchedule({ scheduleName: newSchedule }).then(() => {
|
||||
setNewSchedule('');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleScheduleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setNewSchedule(e.target.value);
|
||||
};
|
||||
|
||||
const fixBuildError = {
|
||||
dummySchedules,
|
||||
dummyActiveIndex,
|
||||
};
|
||||
console.log(fixBuildError);
|
||||
export function CalendarSchedules() {
|
||||
const [, schedules] = useSchedules();
|
||||
|
||||
return (
|
||||
<div style={{ ...style }} className='items-center'>
|
||||
<div className='min-w-full w-0 items-center'>
|
||||
<div className='m0 m-b-2 w-full flex justify-between'>
|
||||
<Text variant='h3'>MY SCHEDULES</Text>
|
||||
<div className='cursor-pointer items-center justify-center btn-transition -ml-1.5 hover:text-zinc-400'>
|
||||
<Text variant='h3'>
|
||||
<AddSchedule />
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
variant='single'
|
||||
color='theme-black'
|
||||
className='h-fit p-0 btn'
|
||||
onClick={() => createSchedule('New Schedule')}
|
||||
>
|
||||
<AddSchedule className='h-6 w-6' />
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex flex-col space-y-2.5'>
|
||||
<List
|
||||
@@ -88,13 +55,6 @@ export function CalendarSchedules({ style, dummySchedules, dummyActiveIndex }: P
|
||||
/>
|
||||
)}
|
||||
</List>
|
||||
<input
|
||||
type='text'
|
||||
placeholder='Enter new schedule'
|
||||
value={newSchedule}
|
||||
onChange={handleScheduleInputChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ export default function ImportantLinks({ className }: Props): JSX.Element {
|
||||
<a
|
||||
key={link.text}
|
||||
href={link.url}
|
||||
className='flex items-center gap-0.5 text-ut-burntorange'
|
||||
className='flex items-center gap-0.5 text-ut-burntorange underline-offset-2 hover:underline'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user