From 914da13bba778c3c0847d6cbc69a6eaaa2152834 Mon Sep 17 00:00:00 2001 From: GabrielCastelo-31 Date: Wed, 17 Jan 2024 18:58:16 -0300 Subject: [PATCH 1/9] add error and success toast for schedule saving --- .../SchedulePreview/SchedulePreview.tsx | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/web/app/components/SchedulePreview/SchedulePreview.tsx b/web/app/components/SchedulePreview/SchedulePreview.tsx index a7bd7ae..0a7de80 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -21,6 +21,7 @@ import deleteSchedule from '@/app/utils/api/deleteSchedule'; import { errorToast } from '@/app/utils/errorToast'; import jsPDF from 'jspdf'; +import toast from 'react-hot-toast'; const commonError = () => errorToast('Houve um erro na atualização das grades!'); @@ -97,14 +98,19 @@ function BottomPart(props: { 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!'); + try { + 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()); + toast.success('Grade salva na nuvem!'); + } + } catch (error) { + errorToast('Você atingiu o limite de grades na nuvem!') + } } useEffect(() => { @@ -220,4 +226,4 @@ export default function SchedulePreview({ localSchedule, cloudSchedule, index, p /> ); -} \ No newline at end of file +} From 682230e27a70ce3a4a44905b2709a3931ae19ce1 Mon Sep 17 00:00:00 2001 From: GabrielCastelo-31 Date: Wed, 17 Jan 2024 22:27:31 -0300 Subject: [PATCH 2/9] fix semicolon error --- web/app/components/SchedulePreview/SchedulePreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/SchedulePreview/SchedulePreview.tsx b/web/app/components/SchedulePreview/SchedulePreview.tsx index 0a7de80..837e1da 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -109,7 +109,7 @@ function BottomPart(props: { toast.success('Grade salva na nuvem!'); } } catch (error) { - errorToast('Você atingiu o limite de grades na nuvem!') + errorToast('Você atingiu o limite de grades na nuvem!'); } } From e1e1c5e266d21f7d76c3c5936892f1cf46163518 Mon Sep 17 00:00:00 2001 From: GabrielCastelo-31 Date: Fri, 26 Jan 2024 19:45:12 -0300 Subject: [PATCH 3/9] modifica toast para imprimir mensagem retornada pela API. --- api/api/views/save_schedule.py | 6 +++--- .../components/SchedulePreview/SchedulePreview.tsx | 14 ++++++++++++-- web/app/utils/successToast.ts | 11 +++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 web/app/utils/successToast.ts diff --git a/api/api/views/save_schedule.py b/api/api/views/save_schedule.py index 8c25df7..d030f6a 100644 --- a/api/api/views/save_schedule.py +++ b/api/api/views/save_schedule.py @@ -13,7 +13,7 @@ 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." class SaveSchedule(): @@ -51,13 +51,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 = "Erro ao salvar a grade horária. Você pode ter escolhido disciplinas com horários incompatíveis." 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("Ocorreu um erro no servidor ao salvar a grade horária. Tente novamente.") def check_discipline_key_existence(key: str, discipline_key: str, **kwargs): diff --git a/web/app/components/SchedulePreview/SchedulePreview.tsx b/web/app/components/SchedulePreview/SchedulePreview.tsx index 837e1da..47383ec 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -19,9 +19,11 @@ 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 { successToast } from '@/app/utils/successToast'; import jsPDF from 'jspdf'; import toast from 'react-hot-toast'; +import { Axios, AxiosError } from 'axios'; const commonError = () => errorToast('Houve um erro na atualização das grades!'); @@ -97,6 +99,10 @@ function BottomPart(props: { const [changeDate, setChangeDate] = useState(''); + /** + * Tenta salvar a grade na nuvem, se der certo, atualiza as grades locais. + * Caso contrário, exibe errotToast com mensagem retornada pela API. + */ async function handleUploadToCloud() { try { const saveResponse = await saveSchedule(props.schedules.localSchedule, user.access); @@ -106,10 +112,14 @@ function BottomPart(props: { props.handleDelete(); setCloudSchedules(response.data); }).catch(() => commonError()); - toast.success('Grade salva na nuvem!'); + successToast('Grade salva com sucesso!'); } } catch (error) { - errorToast('Você atingiu o limite de grades na nuvem!'); + const axiosError = error as AxiosError; + if (axiosError.response) { + const data = axiosError.response.data as { errors: string }; + errorToast(data.errors); + } } } diff --git a/web/app/utils/successToast.ts b/web/app/utils/successToast.ts new file mode 100644 index 0000000..344b7ed --- /dev/null +++ b/web/app/utils/successToast.ts @@ -0,0 +1,11 @@ +import toast from 'react-hot-toast'; +import React from 'react'; + +export const successToast = (message: string, centered: boolean = true) => { + toast.success(message, { + duration: 5000, + style: { + textAlign: centered ? 'center' : 'justify' + }, + }); +}; From 978a4f1747355f3f1ee4c3183633c102c887f412 Mon Sep 17 00:00:00 2001 From: GabrielCastelo-31 Date: Fri, 26 Jan 2024 19:57:35 -0300 Subject: [PATCH 4/9] Fix test case errors --- api/api/tests/test_schedule_save.py | 4 ++-- api/api/views/save_schedule.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/api/api/tests/test_schedule_save.py b/api/api/tests/test_schedule_save.py index 51792a6..f88d69e 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 d030f6a..1bac7d6 100644 --- a/api/api/views/save_schedule.py +++ b/api/api/views/save_schedule.py @@ -14,6 +14,8 @@ SCHEDULES_LIMIT = 10 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 disciplinas 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 = "Erro ao salvar a grade horária. Você pode ter escolhido disciplinas com horários incompatíveis." + 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("Ocorreu um erro no servidor ao salvar a grade horária. Tente novamente.") + 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): From ef3ccc5925487efdb9449706bd3d0e86063a0063 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 5 Feb 2024 13:14:40 -0300 Subject: [PATCH 5/9] front(toast): remove error and success toasts files --- web/app/utils/errorToast.ts | 11 ----------- web/app/utils/successToast.ts | 11 ----------- 2 files changed, 22 deletions(-) delete mode 100644 web/app/utils/errorToast.ts delete mode 100644 web/app/utils/successToast.ts diff --git a/web/app/utils/errorToast.ts b/web/app/utils/errorToast.ts deleted file mode 100644 index 449b0d8..0000000 --- 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/successToast.ts b/web/app/utils/successToast.ts deleted file mode 100644 index 344b7ed..0000000 --- a/web/app/utils/successToast.ts +++ /dev/null @@ -1,11 +0,0 @@ -import toast from 'react-hot-toast'; -import React from 'react'; - -export const successToast = (message: string, centered: boolean = true) => { - toast.success(message, { - duration: 5000, - style: { - textAlign: centered ? 'center' : 'justify' - }, - }); -}; From 4a6a636aba0bbcde0b452f9853453236d359a486 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 5 Feb 2024 13:15:21 -0300 Subject: [PATCH 6/9] front(toast): update new path for toast util --- .../AsideSchedulePopUp/Form/DisciplineOptionForm.tsx | 2 +- web/app/components/SchedulePreview/SchedulePreview.tsx | 3 +-- .../SelectedClassesContext/SelectedClassesContext.tsx | 2 +- web/app/contexts/UserContext.tsx | 2 +- web/app/schedules/home/components/GenerateScheduleButton.tsx | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx b/web/app/components/AsideSchedulePopUp/Form/DisciplineOptionForm.tsx index 9bcffc1..016c614 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 47383ec..a969cb0 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -18,8 +18,7 @@ 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 { successToast } from '@/app/utils/successToast'; +import { errorToast, successToast } from '@/app/utils/toast'; import jsPDF from 'jspdf'; import toast from 'react-hot-toast'; diff --git a/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx b/web/app/contexts/SelectedClassesContext/SelectedClassesContext.tsx index 9a3c474..06ce091 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 8cdf3aa..2ff4221 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 086e9e3..b43887e 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); From 6fe515a7019f48e041ad51bb16a47c3deaf7158e Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 5 Feb 2024 13:15:47 -0300 Subject: [PATCH 7/9] front(toast): add toast util success and error msg --- web/app/utils/toast.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 web/app/utils/toast.ts diff --git a/web/app/utils/toast.ts b/web/app/utils/toast.ts new file mode 100644 index 0000000..7520924 --- /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); From 3f5b08533cc4a5d4eb6ec3dba6abb1a96be84b66 Mon Sep 17 00:00:00 2001 From: GabrielCastelo-31 Date: Fri, 9 Feb 2024 15:49:45 -0300 Subject: [PATCH 8/9] =?UTF-8?q?Commit=20para=20for=C3=A7ar=20codeclimate?= =?UTF-8?q?=20a=20renalisar=20o=20c=C3=B3digo.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api/views/save_schedule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api/views/save_schedule.py b/api/api/views/save_schedule.py index 1bac7d6..5d9081f 100644 --- a/api/api/views/save_schedule.py +++ b/api/api/views/save_schedule.py @@ -14,7 +14,7 @@ SCHEDULES_LIMIT = 10 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 disciplinas com horários incompatíveis." +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." From 5065f1560a3e275ef04c44ae67c8e75aee5e09f7 Mon Sep 17 00:00:00 2001 From: mateusvrs Date: Mon, 12 Feb 2024 23:03:57 -0300 Subject: [PATCH 9/9] front(comps): decrease cog complexity of functions --- .../SchedulePreview/SchedulePreview.tsx | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/web/app/components/SchedulePreview/SchedulePreview.tsx b/web/app/components/SchedulePreview/SchedulePreview.tsx index a969cb0..b805258 100644 --- a/web/app/components/SchedulePreview/SchedulePreview.tsx +++ b/web/app/components/SchedulePreview/SchedulePreview.tsx @@ -21,8 +21,7 @@ import deleteSchedule from '@/app/utils/api/deleteSchedule'; import { errorToast, successToast } from '@/app/utils/toast'; import jsPDF from 'jspdf'; -import toast from 'react-hot-toast'; -import { Axios, AxiosError } from 'axios'; +import { AxiosError } from 'axios'; const commonError = () => errorToast('Houve um erro na atualização das grades!'); @@ -94,34 +93,9 @@ function BottomPart(props: { } }) { const { user } = useUser(); - const { setCloudSchedules } = useSchedules(); const [changeDate, setChangeDate] = useState(''); - /** - * Tenta salvar a grade na nuvem, se der certo, atualiza as grades locais. - * Caso contrário, exibe errotToast com mensagem retornada pela API. - */ - async function handleUploadToCloud() { - try { - 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()); - successToast('Grade salva com sucesso!'); - } - } catch (error) { - const axiosError = error as AxiosError; - if (axiosError.response) { - const data = axiosError.response.data as { errors: string }; - errorToast(data.errors); - } - } - } - useEffect(() => { if (props.isCloud && props.schedules.cloudSchedule?.created_at) { setChangeDate(handleDate(props.schedules.cloudSchedule.created_at)); @@ -130,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')!;