diff --git a/api/api/tests/test_schedule_save.py b/api/api/tests/test_schedule_save.py index 51792a6b..f88d69ec 100644 --- a/api/api/tests/test_schedule_save.py +++ b/api/api/tests/test_schedule_save.py @@ -3,7 +3,7 @@ from rest_framework_simplejwt.serializers import TokenObtainPairSerializer -from ..views.save_schedule import SCHEDULES_LIMIT, SCHEDULES_LIMIT_ERROR_MSG +from ..views.save_schedule import SCHEDULES_LIMIT, SCHEDULES_LIMIT_ERROR_MSG, SCHEDULES_INVALID_SCHEDULES_MSG from utils import db_handler as dbh @@ -251,7 +251,7 @@ def test_save_incorrect_schedule_with_compatible_classes(self): response = self.make_post_request(schedule=schedule) - error_msg = 'error while saving schedule, you may have chosen classes that are not compatible' + error_msg = SCHEDULES_INVALID_SCHEDULES_MSG self.assertEqual(response.data.get('errors'), error_msg) self.assertEqual(response.status_code, 400) diff --git a/api/api/views/save_schedule.py b/api/api/views/save_schedule.py index 8c25df72..5d9081f2 100644 --- a/api/api/views/save_schedule.py +++ b/api/api/views/save_schedule.py @@ -13,7 +13,9 @@ from api import serializers SCHEDULES_LIMIT = 10 -SCHEDULES_LIMIT_ERROR_MSG = f"you have reached the limit of {SCHEDULES_LIMIT} schedules" +SCHEDULES_LIMIT_ERROR_MSG = f"Você atingiu o limite de {SCHEDULES_LIMIT} grades na nuvem." +SCHEDULES_INVALID_SCHEDULES_MSG = "Erro ao salvar a grade horária. Você pode ter escolhido matérias com horários incompatíveis." +SCHEDULES_SAVE_ERROR_MSG = "Ocorreu um erro no servidor ao salvar a grade horária. Tente novamente." class SaveSchedule(): @@ -51,13 +53,13 @@ def post(self, request: request.Request, *args, **kwargs) -> response.Response: try: valid_schedule = validate_received_schedule(current_db_classes_ids) except: - error_msg = "error while saving schedule, you may have chosen classes that are not compatible" + error_msg = SCHEDULES_INVALID_SCHEDULES_MSG return handle_400_error(error_msg) user = request.user answer = save_schedule(user, valid_schedule) - return response.Response(status=status.HTTP_201_CREATED) if answer else handle_400_error("error while saving schedule") + return response.Response(status=status.HTTP_201_CREATED) if answer else handle_400_error(SCHEDULES_SAVE_ERROR_MSG) def check_discipline_key_existence(key: str, discipline_key: str, **kwargs): diff --git a/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx b/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx index 9bcffc10..016c614b 100644 --- a/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx +++ b/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx @@ -2,7 +2,7 @@ import { ChangeEvent, Dispatch, SetStateAction, useEffect, useState } from 'reac import useYearPeriod from '@/app/hooks/useYearPeriod'; import useSelectedClasses from '@/app/hooks/useSelectedClasses'; -import { errorToast } from '@/app/utils/errorToast'; +import { errorToast } from '@/app/utils/toast'; import { DisciplineOptionFormPropsType, FormType, defaultFormData } from '../types/types'; import { DisciplineType } from '@/app/utils/api/searchDiscipline'; diff --git a/web/app/components/SchedulePreview/SchedulePreview.tsx b/web/app/components/SchedulePreview/SchedulePreview.tsx index a7bd7aeb..b805258d 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -18,9 +18,10 @@ import saveSchedule from '@/app/utils/api/saveSchedule'; import getSchedules from '@/app/utils/api/getSchedules'; import { days, months } from '@/app/utils/dates'; import deleteSchedule from '@/app/utils/api/deleteSchedule'; -import { errorToast } from '@/app/utils/errorToast'; +import { errorToast, successToast } from '@/app/utils/toast'; import jsPDF from 'jspdf'; +import { AxiosError } from 'axios'; const commonError = () => errorToast('Houve um erro na atualização das grades!'); @@ -92,21 +93,9 @@ function BottomPart(props: { } }) { const { user } = useUser(); - const { setCloudSchedules } = useSchedules(); const [changeDate, setChangeDate] = useState(''); - async function handleUploadToCloud() { - const saveResponse = await saveSchedule(props.schedules.localSchedule, user.access); - - if (saveResponse.status == 201) { - getSchedules(user.access).then(response => { - props.handleDelete(); - setCloudSchedules(response.data); - }).catch(() => commonError()); - } else errorToast('Não foi possível salvar a grade na nuvem!'); - } - useEffect(() => { if (props.isCloud && props.schedules.cloudSchedule?.created_at) { setChangeDate(handleDate(props.schedules.cloudSchedule.created_at)); @@ -115,18 +104,12 @@ function BottomPart(props: { return (
-
+
Grade {props.position}
{props.isCloud && changeDate && {changeDate}}
- {!props.isCloud && !user.is_anonymous && - - } + {!props.isCloud && !user.is_anonymous && } + ); +} + function handleDownloadPDF(isCloud: boolean, index: number) { const doc = document.getElementById('download-content')!; @@ -220,4 +244,4 @@ export default function SchedulePreview({ localSchedule, cloudSchedule, index, p /> ); -} \ No newline at end of file +} diff --git a/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx b/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx index 9a3c474b..06ce0915 100644 --- a/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx +++ b/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx @@ -2,7 +2,7 @@ import { createContext, useState } from 'react'; -import { errorToast } from '../../utils/errorToast'; +import { errorToast } from '../../utils/toast'; import { ProviderJSXPropsType, SelectedClassesContextProviderPropsType, SelectedClassesContextType, SelectedClassesType } from './types'; diff --git a/web/app/contexts/UserContext.tsx b/web/app/contexts/UserContext.tsx index 8cdf3aa6..2ff42210 100644 --- a/web/app/contexts/UserContext.tsx +++ b/web/app/contexts/UserContext.tsx @@ -7,7 +7,7 @@ import { UserData } from '../components/SignInSection'; import { settings } from '../utils/settings'; import request from '../utils/request'; import getSchedules from '../utils/api/getSchedules'; -import { errorToast } from '../utils/errorToast'; +import { errorToast } from '../utils/toast'; import useSchedules from '../hooks/useSchedules'; export interface User { diff --git a/web/app/schedules/home/components/GenerateScheduleButton.tsx b/web/app/schedules/home/components/GenerateScheduleButton.tsx index 086e9e36..b43887e1 100644 --- a/web/app/schedules/home/components/GenerateScheduleButton.tsx +++ b/web/app/schedules/home/components/GenerateScheduleButton.tsx @@ -13,7 +13,7 @@ import Modal from '@/app/components/Modal/Modal'; import { ScheduleAPIType, ScheduleClassType } from '@/app/contexts/SchedulesContext'; import generateSchedule, { EachFieldNumber } from '@/app/utils/api/generateSchedule'; -import { errorToast } from '@/app/utils/errorToast'; +import { errorToast } from '@/app/utils/toast'; function PreferenceOrder({ setPreference }: { setPreference: (preference: EachFieldNumber) => void @@ -58,7 +58,7 @@ export default function GenerateScheduleButton() { const schedules = data.schedules as Array; if (!schedules.length) { - errorToast(data.message, data.message.split('\n').length == 1); + errorToast(data.message, {centered: data.message.split('\n').length == 1}); setLoading(false); } else { setLocalSchedules(schedules); diff --git a/web/app/utils/errorToast.ts b/web/app/utils/errorToast.ts deleted file mode 100644 index 449b0d8f..00000000 --- a/web/app/utils/errorToast.ts +++ /dev/null @@ -1,11 +0,0 @@ -import toast from 'react-hot-toast'; -import React from 'react'; - -export const errorToast = (message: string, centered: boolean = true) => { - toast.error(message, { - duration: 5000, - style: { - textAlign: centered ? 'center' : 'justify' - }, - }); -}; \ No newline at end of file diff --git a/web/app/utils/toast.ts b/web/app/utils/toast.ts new file mode 100644 index 00000000..75209248 --- /dev/null +++ b/web/app/utils/toast.ts @@ -0,0 +1,23 @@ +import toast from 'react-hot-toast'; + +interface ToastOptions { + duration?: number; + centered?: boolean; + style?: React.CSSProperties; +} + +const createToast = (message: string, type: 'success' | 'error', options?: ToastOptions) => { + const { duration = 5000, centered = true, style } = options || {}; + + toast[type](message, { + duration, + style: { + textAlign: centered ? 'center' : 'justify', + ...style, + }, + }); +}; + +export const successToast = (message: string, options?: ToastOptions) => createToast(message, 'success', options); + +export const errorToast = (message: string, options?: ToastOptions) => createToast(message, 'error', options);