diff --git a/src/@types/index.d.ts b/src/@types/index.d.ts index 7c66d2b2..c6f41d1b 100644 --- a/src/@types/index.d.ts +++ b/src/@types/index.d.ts @@ -108,7 +108,6 @@ export type MultipleOptions = { index: number selected: CourseOption[] options: CourseOption[][] - names: string[] } export type ImportedCourses = { diff --git a/src/api/storage.ts b/src/api/storage.ts index efd85b6a..040e2f81 100644 --- a/src/api/storage.ts +++ b/src/api/storage.ts @@ -3,7 +3,7 @@ import { getCourseTeachers } from '../utils/utils' import API from './backend' -const INITIAL_VALUE = { index: 0, selected: [], options: [], names: Array.from({ length: 10 }, (_, i) => `Horário ${i + 1}`) } +const INITIAL_VALUE = { index: 0, selected: [], options: [] } const isStorageValid = (key: string, daysElapsed: number) => { const stored = JSON.parse(localStorage.getItem(key)) @@ -32,8 +32,6 @@ const getOptionsStorage = (): MultipleOptions => { try { if (isStorageValid(key, 7)) { const courseOptions: MultipleOptions = JSON.parse(localStorage.getItem(key)) - // For older files (which don't have the attribute 'names') - if (courseOptions.names === undefined) courseOptions.names = INITIAL_VALUE.names for (let i = 0; i < courseOptions.options.length; i++) { for (let j = 0; j < courseOptions.options[i].length; j++) { diff --git a/src/components/planner/schedule/PrintSchedule.tsx b/src/components/planner/schedule/PrintSchedule.tsx index 14ef58ea..5a260bda 100644 --- a/src/components/planner/schedule/PrintSchedule.tsx +++ b/src/components/planner/schedule/PrintSchedule.tsx @@ -1,32 +1,38 @@ -import { useCallback } from 'react' +import { useCallback, useContext } from 'react' +import { ThemeContext } from '../../../contexts/ThemeContext' import { Button } from '../../ui/button' import { CameraIcon } from '@heroicons/react/24/outline' import { toPng } from 'html-to-image' import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '../../ui/tooltip' const PrintSchedule = ({ component }) => { - const takeScreenshot = useCallback(() => { - if (component.current === null) { - return - } + const { enabled, setEnabled } = useContext(ThemeContext) - toPng(component.current, { cacheBust: true, backgroundColor: 'white' }) - .then((dataUrl) => { - const link = document.createElement('a') - link.download = 'horario.png' - link.href = dataUrl - link.click() - }) - .catch((err) => { - console.log(err) - }) - }, [component]) + const takeScreenshot = useCallback( + (isThemeEnabled) => { + if (component.current === null) { + return + } + + toPng(component.current, { cacheBust: true, backgroundColor: isThemeEnabled ? '#252733' : '#fbfbfb' }) + .then((dataUrl) => { + const link = document.createElement('a') + link.download = 'horario.png' + link.href = dataUrl + link.click() + }) + .catch((err) => { + console.log(err) + }) + }, + [component] + ) return ( - diff --git a/src/components/planner/sidebar/ClassSelector.tsx b/src/components/planner/sidebar/ClassSelector.tsx index 74c3c030..93dcedd5 100644 --- a/src/components/planner/sidebar/ClassSelector.tsx +++ b/src/components/planner/sidebar/ClassSelector.tsx @@ -85,7 +85,6 @@ const ClassSelector = ({ courseOption, multipleOptionsHook, isImportedOptionHook index: prev.index, selected: [...newCourseOptions], options: prev.options, - names: prev.names, } }) } @@ -122,7 +121,6 @@ const ClassSelector = ({ courseOption, multipleOptionsHook, isImportedOptionHook index: prev.index, selected: [...newCourseOptions], options: prev.options, - names: prev.names, } }) } else if (type === 'TP') { @@ -141,7 +139,6 @@ const ClassSelector = ({ courseOption, multipleOptionsHook, isImportedOptionHook index: prev.index, selected: [...newCourseOptions], options: prev.options, - names: prev.names, } }) } @@ -183,7 +180,6 @@ const ClassSelector = ({ courseOption, multipleOptionsHook, isImportedOptionHook index: prevMultipleOptions.index, selected: resolvedCourseOptions, options: resolvedOptions, - names: prevMultipleOptions.names, } return value diff --git a/src/components/planner/sidebar/CoursesController.tsx b/src/components/planner/sidebar/CoursesController.tsx index bd93d8aa..8d2f15e1 100644 --- a/src/components/planner/sidebar/CoursesController.tsx +++ b/src/components/planner/sidebar/CoursesController.tsx @@ -1,5 +1,5 @@ import { removeDuplicatesFromCourseOption } from '../../../utils/utils' -import { default as ClassSelector } from './ClassSelector' +import ClassSelector from './ClassSelector' const CoursesController = ({ multilpleOptionsHook, isImportedOptionHook }) => { const [multipleOptions, setMultipleOptions] = multilpleOptionsHook @@ -8,16 +8,16 @@ const CoursesController = ({ multilpleOptionsHook, isImportedOptionHook }) => { return (
{multipleOptions.selected.length > 0 && - removeDuplicatesFromCourseOption(multipleOptions.options[multipleOptions.index]).map( - (courseOption, courseOptionIdx) => ( + removeDuplicatesFromCourseOption(multipleOptions.options[multipleOptions.index]) + .sort((a, b) => a.course.info.sigarra_id - b.course.info.sigarra_id) + .map((courseOption, courseOptionIdx) => ( - ) - )} + ))}
) } diff --git a/src/components/planner/sidebar/OptionsController.tsx b/src/components/planner/sidebar/OptionsController.tsx index 97e2fa84..1a4fc4ea 100644 --- a/src/components/planner/sidebar/OptionsController.tsx +++ b/src/components/planner/sidebar/OptionsController.tsx @@ -24,7 +24,6 @@ const Option = ({ item, selectedHook, multipleOptionsHook }) => { index: newIndex - 1, selected: prev.options[newIndex - 1], options: [...prev.options], - names: prev.names, })) } diff --git a/src/components/planner/sidebar/index.ts b/src/components/planner/sidebar/index.ts index 9a25bc70..437a5e95 100644 --- a/src/components/planner/sidebar/index.ts +++ b/src/components/planner/sidebar/index.ts @@ -2,10 +2,12 @@ import SessionController from './SessionController' import OptionsController from './OptionsController' import SelectedOptionController from './SelectedOptionController' import CoursesController from './CoursesController' +import ClassSelector from './ClassSelector' export { SessionController, OptionsController, SelectedOptionController, - CoursesController + CoursesController, + ClassSelector } diff --git a/src/components/planner/sidebar/selectedOptionController/CopyOption.tsx b/src/components/planner/sidebar/selectedOptionController/CopyOption.tsx index fa375675..71bd46ab 100644 --- a/src/components/planner/sidebar/selectedOptionController/CopyOption.tsx +++ b/src/components/planner/sidebar/selectedOptionController/CopyOption.tsx @@ -4,11 +4,12 @@ import { CheckIcon, DocumentDuplicateIcon } from '@heroicons/react/24/outline' import { Major, CourseOption } from '../../../../@types' import { useToast } from '../../../ui/use-toast' import { Buffer } from 'buffer' +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../ui/tooltip' type Props = { majorHook: [Major, React.Dispatch>] currentOption: CourseOption[] - className?: string, + className?: string } /** @@ -68,13 +69,20 @@ const CopyOption = ({ majorHook, currentOption, className }: Props) => { } return ( - + + + + + + Copiar horário + + ) } diff --git a/src/components/planner/sidebar/selectedOptionController/PasteOption.tsx b/src/components/planner/sidebar/selectedOptionController/PasteOption.tsx index 2e713bb0..83c3e376 100644 --- a/src/components/planner/sidebar/selectedOptionController/PasteOption.tsx +++ b/src/components/planner/sidebar/selectedOptionController/PasteOption.tsx @@ -16,6 +16,7 @@ import React, { useEffect, useState } from 'react' import ConfirmationModal from './ConfirmationModal' import { Buffer } from 'buffer' import fillOptions from './fillOptions' +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../../ui/tooltip' type Props = { majors: Major[] @@ -25,13 +26,7 @@ type Props = { isImportedOptionHook: [boolean, React.Dispatch>] } -const PasteOption = ({ - majors, - majorHook, - multipleOptionsHook, - checkCourses, - isImportedOptionHook, -}: Props) => { +const PasteOption = ({ majors, majorHook, multipleOptionsHook, checkCourses, isImportedOptionHook }: Props) => { const [multipleOptions, setMultipleOptions] = multipleOptionsHook const [major, setMajor] = majorHook const [modalOpen, setModalOpen] = useState(false) @@ -54,12 +49,14 @@ const PasteOption = ({ } }, []) - const importSchedule = async (value = null) => { - const url = value ?? await navigator.clipboard.readText() + const importSchedule = async (value) => { + const url = value const decoded_url = Buffer.from(url, 'base64').toString() if (!isValidURL(decoded_url)) { - const description = value ? 'O texto inserido não é uma opção válida' : 'O texto do clipboard não é uma opção válida'; + const description = value + ? 'O texto inserido não é uma opção válida' + : 'O texto do clipboard não é uma opção válida' toast({ title: 'Erro ao colar opção', description, @@ -168,8 +165,8 @@ const PasteOption = ({ const selected_option = class_name_option !== 'null' ? course_schedules.find( - (schedule) => schedule.class_name === class_name_option && schedule.lesson_type !== 'T' - ) + (schedule) => schedule.class_name === class_name_option && schedule.lesson_type !== 'T' + ) : null const course_option: CourseOption = { @@ -205,7 +202,6 @@ const PasteOption = ({ index: prevMultipleOptions.index, selected: importedOption.courses, options: newOptions, - names: prevMultipleOptions.names, } return value @@ -217,34 +213,59 @@ const PasteOption = ({ return ( <> - {isClipboardSupported - ? - : + {isClipboardSupported ? ( + + + + + + Colar horário + + + ) : ( - - - - - importSchedule(e.clipboardData.getData('text/plain'))} - onKeyDown={(e) => { - if (e.key === 'Enter') { - importSchedule(e.currentTarget.value) - } - }} - onBlur={() => setIsDropdownOpen(false)} - /> - + + + + + + + + Colar horário + + importSchedule(e.clipboardData.getData('text/plain'))} + onKeyDown={(e) => { + if (e.key === 'Enter') { + importSchedule(e.currentTarget.value) + } + }} + onBlur={() => setIsDropdownOpen(false)} + /> + + + - } + )} >] @@ -15,12 +16,10 @@ type Props = { const RandomFill = ({ multipleOptionsHook, className }: Props) => { const [multipleOptions, setMultipleOptions] = multipleOptionsHook const courseOptions = removeDuplicatesFromCourseOption(multipleOptions.selected) - const [permutations, setPermutations] = useState([]) const [lockedCourses, setLockedCourses] = useState( courseOptions.filter((course) => course.locked).map((course) => course.course.info.acronym) ) - const [randomClasses, setRandomClasses] = useState({}) /* @@ -56,8 +55,7 @@ const RandomFill = ({ multipleOptionsHook, className }: Props) => { if (course.locked) { return [course.option] } - let aux = course.schedules.filter((schedule) => schedule.lesson_type != 'T' && randomClasses[schedule.class_name]) - return aux + return course.schedules.filter((schedule) => schedule.lesson_type != 'T' && randomClasses[schedule.class_name]) }) return cartesianGenerator(...allSchedules) @@ -134,7 +132,6 @@ const RandomFill = ({ multipleOptionsHook, className }: Props) => { index: prevMultipleOptions.index, selected: [...newSelected], options: prevMultipleOptions.options, - names: prevMultipleOptions.names, } return value @@ -175,7 +172,13 @@ const RandomFill = ({ multipleOptionsHook, className }: Props) => { }) setRandomClasses(keyValue) + }, [multipleOptions]) + /** + * Reseting generator and permutations when: + * - + */ + useEffect(() => { // ------------------------------------------------------ // Updating locked courses const newLockedCourses = multipleOptions.selected @@ -184,18 +187,20 @@ const RandomFill = ({ multipleOptionsHook, className }: Props) => { // Only update if locked courses changed if (newLockedCourses.join() !== lockedCourses.join()) { setLockedCourses(newLockedCourses) + setPermutations([]) + setGenerator(getSchedulesGenerator()) } }, [multipleOptions]) /** * Reseting generator and permutations when: - * - Multiple options change + * - Selected option changes * - Selected classes for random generations change */ useEffect(() => { setPermutations([]) setGenerator(getSchedulesGenerator()) - }, [multipleOptions, randomClasses]) + }, [multipleOptions.index, randomClasses]) const [generator, setGenerator] = useState(getSchedulesGenerator()) @@ -213,6 +218,8 @@ const RandomFill = ({ multipleOptionsHook, className }: Props) => { +
Preenchimento aleatório
+ {Object.keys(randomClasses).map((key) => (
- {year.map((course: CheckedCourse, courseIdx: number) => ( -
- handleCheck(event, yearIdx, courseIdx)} - /> -
+ ))}
)) diff --git a/src/pages/TimeTableScheduler.tsx b/src/pages/TimeTableScheduler.tsx index aea67750..316cc8a6 100644 --- a/src/pages/TimeTableScheduler.tsx +++ b/src/pages/TimeTableScheduler.tsx @@ -136,7 +136,6 @@ const TimeTableSchedulerPage = () => { index: 0, selected: [], options: [], - names: Array.from({ length: 10 }, (_, i) => `Horário ${i + 1}`), }) // schedule options and selected schedule const totalSelected = useMemo( () => multipleOptions.options.map((co: CourseOption[]) => co.filter((item) => item.option !== null)).flat(), @@ -352,7 +351,6 @@ const TimeTableSchedulerPage = () => { index: prev.index, selected: newCourseOptions, options: newOptions, - names: prev.names, } })