Skip to content

Commit

Permalink
task(front): cria página de criação de grades com funcionalidades pro…
Browse files Browse the repository at this point in the history
…postas (#157)

* web(components): cria modal flutuante padrão

Co-authored-by: Arthur Ribeiro <[email protected]>

* web(context): disponibilização das grades p/app

* web(comp): versão básica do botão de gerar grades

* web(api): integração com a geração de grades

* web(schedules): versão simples da grade horária

Co-authored-by: Arthur Ribeiro <[email protected]>

* web(fix): fix the bug of info page

* web(comp): arruma nome do setModal

* web(comp): define v1 da mostragem de grade

* web(contexts): personaliza set de grades do user

* web(mygrades): adiciona test index 0 p

* web(api): remove import desnecessário

* web(tailwind): adiciona nova cor snow

* web(fix): changing the modal and schedule base colors

* web(icons): add icons for upload, download, delete

* web(modal): rm context desnecessário

* web(comps): adiciona estado de preview ao schedule

* web(schedules): muda layout pra p[a]

* fix(app): lógica correta p/atualização de grades

* web(schedules): add fnc remover grades locais

* web(styles): deixa scroll bar mais fina no chrome

* web(comp): cria um set de profs únicos pmostrar

* task(frontend): trás as modificações da api para salvamento de grade para continuidade da criação do flow layout (#152)

* task(schedule/save): criar a rota de salvamento de grade p/usuários autênticados (#144)

* api(save-schedule): Created models and url path.

- Still working on views

* api(models): add migrations para o modelo d/grades

* api(urls): arruma rota da view de salvamento

* api(views): organiza imports por grupos de lib

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(settings): desliga adição de slash

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(utils): funcs p/salvar grade horária no db

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(views): modulariza views em uma pasta separada

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(views): fnc p/verificar e salvar grade do user

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(urls): adição da view nas rotas e no admin

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(settings): definição da auth padrão do swagger

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* api(views): correção do parm status de retorno da

* api(utils): add linha de no cover p/tests

* refactor(api): add espaço entre classe e função

* tests(api): verifica as fnc do salvamento de grade

- Tests para os casos de sucesso e erro do salvamento de grade
- Verificação da models e do método __str__ da grade

* refactor(views): tenta diminuir cog complexidade

* refactor(views): diminui cog complexidade

- A função de gerar estava com uma complexidade alta
assim foi necessário refatorar para diminuir a complexidade

* api(admin): deixa json bonito na pág admin

* api(views): adiciona validador de request body

* tests(api): verifica os casos de body incorreto

* refactor(api/views): diminui cog complexidade

* refactor(api): reduz cong complexidade do checker

* refactor(api): modulariza validade class func

---------

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* task(frontend): alteração do ícone da volta para tela de login (#147)

* frontend(feature): criação da nova página de informações para usuários

* frontend(fixxing): ajustando tamanho do ícone de informação

* frontend(feature): add information page for new users

* web(info): organiza layout dos colaboradores

* web(info): adição da descrição de utilização do site.

* web(info): modulariza página de informações

* fix(web): fix information page for new users

* web(icons): add icons for google and search

* web(icon): mudando o icone da volta para o home

* web(icon): add search icon to the search bar

* web(fixing): fixing search icon alt text

---------

Co-authored-by: mateuvrs <[email protected]>
Co-authored-by: Mateus Vieira <[email protected]>

* models(schedules): add created_at field

* serializers(schedules): add serializer for schedule

* api(urls): add get_schedules endpoint

* models(migrations): make migrations

* api(schedules): add get schedules api

* utils(db_handler): add get_schedule function

* api(test): make tests for get schedule api

---------

Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>

* Squashed commit of the following:

commit 25375c9
Author: Caio Felipe <[email protected]>
Date:   Fri Dec 8 17:29:50 2023 -0300

    task(delete-schedule): deleta grades do usuário e altera rotas (#151)

    * utils(db-handler): add delete_schedule function

    * api(delete-schedules): delete schedule endpoint

    * test(deleteschedule): add test for delete schedule

    * test(delete-schedule): add test for invalid token

    * Delete api/api/tests/test_schedules_api.py

    * django(api): rename and delete useless files

    * api(urls): update urls

    * utils(test): update test urls

    * api(save_schedule): remove auth save_schedule

    * api(views): add schedule view

    * api(views): rename view generate schedule

    * fix(typo): nome da classe p/ testar delete

    ---------

    Co-authored-by: Mateus Vieira <[email protected]>

commit 16813ab
Merge: d39a16d 610c520
Author: Caio Felipe <[email protected]>
Date:   Thu Dec 7 23:38:43 2023 -0300

    Merge pull request #149 from unb-mds/task/get-schedule

    task(get-schedule): Cria API para obtenção de grades do usuário

commit 610c520
Author: Caio <[email protected]>
Date:   Thu Dec 7 23:14:08 2023 -0300

    api(test): make tests for get schedule api

commit fe4dee5
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:34:30 2023 -0300

    utils(db_handler): add get_schedule function

commit d4b1505
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:33:57 2023 -0300

    api(schedules): add get schedules api

commit 492c0de
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:33:38 2023 -0300

    models(migrations): make migrations

commit 67ed0ee
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:28:20 2023 -0300

    api(urls): add get_schedules endpoint

commit 9b754ce
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:27:59 2023 -0300

    serializers(schedules): add serializer for schedule

commit e028f6d
Author: Caio <[email protected]>
Date:   Thu Dec 7 22:27:43 2023 -0300

    models(schedules): add created_at field

commit d39a16d
Author: Arthur Ribeiro <[email protected]>
Date:   Thu Dec 7 22:18:30 2023 -0300

    task(frontend): alteração do ícone da volta para tela de login (#147)

    * frontend(feature): criação da nova página de informações para usuários

    * frontend(fixxing): ajustando tamanho do ícone de informação

    * frontend(feature): add information page for new users

    * web(info): organiza layout dos colaboradores

    * web(info): adição da descrição de utilização do site.

    * web(info): modulariza página de informações

    * fix(web): fix information page for new users

    * web(icons): add icons for google and search

    * web(icon): mudando o icone da volta para o home

    * web(icon): add search icon to the search bar

    * web(fixing): fixing search icon alt text

    ---------

    Co-authored-by: mateuvrs <[email protected]>
    Co-authored-by: Mateus Vieira <[email protected]>

commit 39c7d1a
Author: Mateus Vieira <[email protected]>
Date:   Thu Dec 7 21:05:46 2023 -0300

    task(schedule/save): criar a rota de salvamento de grade p/usuários autênticados (#144)

    * api(save-schedule): Created models and url path.

    - Still working on views

    * api(models): add migrations para o modelo d/grades

    * api(urls): arruma rota da view de salvamento

    * api(views): organiza imports por grupos de lib

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(settings): desliga adição de slash

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(utils): funcs p/salvar grade horária no db

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(views): modulariza views em uma pasta separada

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(views): fnc p/verificar e salvar grade do user

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(urls): adição da view nas rotas e no admin

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(settings): definição da auth padrão do swagger

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

    * api(views): correção do parm status de retorno da

    * api(utils): add linha de no cover p/tests

    * refactor(api): add espaço entre classe e função

    * tests(api): verifica as fnc do salvamento de grade

    - Tests para os casos de sucesso e erro do salvamento de grade
    - Verificação da models e do método __str__ da grade

    * refactor(views): tenta diminuir cog complexidade

    * refactor(views): diminui cog complexidade

    - A função de gerar estava com uma complexidade alta
    assim foi necessário refatorar para diminuir a complexidade

    * api(admin): deixa json bonito na pág admin

    * api(views): adiciona validador de request body

    * tests(api): verifica os casos de body incorreto

    * refactor(api/views): diminui cog complexidade

    * refactor(api): reduz cong complexidade do checker

    * refactor(api): modulariza validade class func

    ---------

    Co-authored-by: GabrielCastelo-31 <[email protected]>
    Co-authored-by: Caio <[email protected]>
    Co-authored-by: Arthur Ribeiro <[email protected]>

* web(comp): rm unicidade de professores

* web(comps): add fnc de upload p/cloud

* web(utils): reorganiza datas e meses separados

* web(api): generate schedule request fnc

* web(api): get schedule request fnc com api

* web(api): fnc p/salvar grade no cloud

* web(utils): fnc p/request com auth

* web(contexts): add fnc de deletar grade da nuvem

* web(comps): func de fazer download grade com pdf

* refactor(app): arrumar erros de layout e ui/ux

* web(tailwind): adiciona font mono p/datas

* web(icons): adiciona expand_less/expand_more

* fix(front): arruma funçao do LayoutJSX

* web(fix): fixing LayoutJSX function cognitive complexity

* web(fix): improving MyGrades function

* web(fix): fix generate schedule function

* web(fix): fixing codeclimate issues

* fix(mygrades): export incorreto não utilizado

* refactor(comps): reduz cog complexidade do preview

* refactor(comps): reduz linhas de código

Co-authored-by: Arthur Ribeiro <[email protected]>

* fix(pdf): deixa download mais responsivo e ideal

Co-authored-by: Arthur Ribeiro <[email protected]>

* web(app): coloca index correto nas grades

---------

Co-authored-by: Arthur Ribeiro <[email protected]>
Co-authored-by: GabrielCastelo-31 <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Arthur Ribeiro <[email protected]>
  • Loading branch information
5 people authored Dec 10, 2023
1 parent e1b87d7 commit b8aefa4
Show file tree
Hide file tree
Showing 34 changed files with 979 additions and 76 deletions.
32 changes: 32 additions & 0 deletions api/api/views/get_schedules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status, request, response

from api.swagger import Errors
from api.serializers import ScheduleSerializer

from utils.db_handler import get_schedules

class GetSchedules(APIView):

permission_classes = [IsAuthenticated]

@swagger_auto_schema(
operation_description="Retorna as grades horárias do usuário logado.",
security=[{'Bearer': []}],
responses={
200: openapi.Response('OK', ScheduleSerializer(many=True)),
**Errors([401, 403]).retrieve_erros()
}
)
def get(self, request: request.Request) -> response.Response:
"""Retorna as grades horárias do usuário logado."""

user = request.user
schedules = get_schedules(user)
data = ScheduleSerializer(schedules, many=True).data

return response.Response(status=status.HTTP_200_OK, data=data)
4 changes: 2 additions & 2 deletions api/utils/db_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,5 @@ def delete_schedule(user: User, id: int) -> bool:
Schedule.objects.get(user=user, id=id).delete()
except Schedule.DoesNotExist:
return False

return True
return True
9 changes: 5 additions & 4 deletions web/app/components/AsideSchedulePopUp/DisciplineFragment.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Fragment } from 'react';
import Image from 'next/image';
import ClassInfoBox from './ClassInfoBox';

import { ClassType, DisciplineType } from '@/app/utils/api/searchDiscipline';

import ClassInfoBox from './ClassInfoBox';
import expand_more from '@/public/icons/expand_more.png';
import expand_less from '@/public/icons/expand_less.png';

interface DisciplineFragmentPropsType {
index: number,
Expand All @@ -26,9 +29,7 @@ function DisciplineFragmentJSX({ handleDisciplineToggle, ...props }: {
onClick={() => handleDisciplineToggle(index)}
className='flex items-center gap-3'
>
<span className="material-symbols-rounded">
{discipline.expanded ? 'expand_less' : 'expand_more'}
</span>
<Image src={discipline.expanded ? expand_more : expand_less} alt="expand icon" />
<span className='font-semibold'>{discipline.name} - {discipline.code}</span>
</button>
{discipline.expanded &&
Expand Down
10 changes: 5 additions & 5 deletions web/app/components/AsideSchedulePopUp/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ interface TooltipPropsType {
children: React.ReactNode,
};

export const isMobile = (width?: number) => {
return width && width <= 768;
};

export default function Tooltip({ children }: TooltipPropsType) {
const [active, setActive] = useState(false);
const { width } = useWindowDimensions();
Expand All @@ -25,10 +29,6 @@ export default function Tooltip({ children }: TooltipPropsType) {
};
}, [active]);

const isMobile = () => {
return width && width <= 768;
};

return (
<div className={styles.tooltip}>
<span
Expand All @@ -41,7 +41,7 @@ export default function Tooltip({ children }: TooltipPropsType) {
{children}
<button
onClick={() => setActive(false)}
className={`absolute right-2 ${isMobile() ? 'bottom-2' : 'top-2'} material-symbols-rounded`}
className={`absolute right-2 ${isMobile(width) ? 'bottom-2' : 'top-2'} material-symbols-rounded`}
>
close
</button>
Expand Down
51 changes: 29 additions & 22 deletions web/app/components/ClassInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ interface ClassInfoPropsType {
currentClass: ClassValueType
}

export function generateSpecialDates(special_dates: Array<Array<string>>, days: Array<string>) {
return special_dates.map((specialDate, index) => {
const day = specialDate[0];
const start = parseInt(specialDate[1]) - 1;
const end = parseInt(specialDate[2]) - 1;

function make_days(start: number, end: number) {
return days.slice(start, end + 1).map((day, index) =>
<div className='pl-3' key={index}>
{day}
</div>
);
}

return (
<Fragment key={index}>
<span className='font-semibold'>
{day}
</span>
{make_days(start, end)}
</Fragment>
);
});
}

export default function ClassInfo({ currentClass }: ClassInfoPropsType) {
return (
<div>
Expand All @@ -24,28 +49,10 @@ export default function ClassInfo({ currentClass }: ClassInfoPropsType) {
<div key={index}>
{day}
</div>
) : currentClass.class.special_dates.map((specialDate, index) => {
const day = specialDate[0];
const start = parseInt(specialDate[1]) - 1;
const end = parseInt(specialDate[2]) - 1;

function make_days(start: number, end: number) {
return currentClass.class.days.slice(start, end + 1).map((day, index) =>
<div className='pl-3' key={index}>
{day}
</div>
);
}

return (
<Fragment key={index}>
<span className='font-semibold'>
{day}
</span>
{make_days(start, end)}
</Fragment>
);
})}
) : generateSpecialDates(
currentClass.class.special_dates,
currentClass.class.days
)}
</div>
</Tooltip>
</div>
Expand Down
3 changes: 1 addition & 2 deletions web/app/components/InfoHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { useState } from 'react';
import useWindowDimensions from '../hooks/useWindowDimensions';
import useUser from '../hooks/useUser';

const days = ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'];
const months = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
import { days, months } from '../utils/dates';

const currentDateObject = new Date(
new Date().toLocaleString('en', {
Expand Down
23 changes: 23 additions & 0 deletions web/app/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
interface ModalPropsType {
children: React.ReactNode;
setActiveModal: (active: boolean) => void;
noExit?: boolean;
}

export default function Modal({ children, setActiveModal, noExit }: ModalPropsType) {
return (
<div className="flex justify-center items-center fixed bg-snow-primary bg-opacity-[55%] h-full w-full top-0 left-0 z-50">
<div className="relative overflow-auto h-[87%] w-11/12 rounded-lg bg-[#ECECEC] mx-2">
{children}
{!noExit &&
<button
onClick={() => setActiveModal(false)}
className='absolute left-2 top-2 material-symbols-rounded'
>
close
</button>
}
</div>
</div>
);
}
141 changes: 141 additions & 0 deletions web/app/components/Schedule/Schedule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
'use client';

import { ScheduleClassType } from '@/app/contexts/SchedulesContext';
import { HTMLProps, useEffect, useState } from 'react';
import { generateSpecialDates } from '../ClassInfo';
import Tooltip from '../AsideSchedulePopUp/Tooltip';

interface SchedulePropsType extends HTMLProps<HTMLDivElement> {
schedules?: Array<ScheduleClassType>;
preview?: boolean;
toDownload?: boolean;
}

export default function Schedule({ schedules, preview, toDownload, ...props }: SchedulePropsType) {
const [currentSchedule, setCurrentSchedule] = useState<Array<Array<ScheduleClassType>>>(new Array(6).fill(new Array(15).fill(null)));
const uniqueTeachers = new Set<string>();

const days = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];
const times = [
'08:00 - 08:55', '08:55 - 09:50', '10:00 - 10:55',
'10:55 - 11:50', '12:00 - 12:55', '12:55 - 13:50',
'14:00 - 14:55', '14:55 - 15:50', '16:00 - 16:55',
'16:55 - 17:50', '18:00 - 18:55', '19:00 - 19:50',
'19:50 - 20:40', '20:50 - 21:40', '21:40 - 22:30'
];

useEffect(() => {
const baseSchedule = new Array(6);
for (let i = 0; i < baseSchedule.length; i++) {
baseSchedule[i] = new Array(15).fill(null);
}

function addClassToSchedule(scheduleStructure: ScheduleClassType) {
const { schedule } = scheduleStructure;
const splitSchedule = schedule.split(' ');

splitSchedule.forEach((piece) => {
const regex = /^(\d+)([MNT])(\d+)$/;
const match = piece.match(regex);
if (match) {
const [, day, period, time] = match;

for (let i = 0; i < day.length; i++) {
const x = parseInt(day[i]) - 2;
for (let j = 0; j < time.length; j++) {
let y = parseInt(time[j]) - 1;

if (period === 'T') y += 5;
else if (period === 'N') y += 11;

baseSchedule[x][y] = scheduleStructure;
}
}
}
});
}

if (schedules) {
schedules.forEach((schedule) => addClassToSchedule(schedule));
setCurrentSchedule(baseSchedule);
}
}, [schedules]);

return (
<div
{...props}
className={`${toDownload ? 'flex justify-end flex-row-reverse pt-10 tracking-[0.01px]' : ''} ${preview ? 'scale-[.3]' : ''}`}
onClick={props.onClick}
>
<div className={`p-5 ${!toDownload ? 'm-auto' : ''} w-max`}>
<div className="flex justify-end">
<div className="w-40"></div>
<div className="flex">
{days.map((day, index) =>
<div key={index} className="text-center w-28 m-[2px]">
<p>{day}</p>
</div>
)}
</div>
</div>
<div className='flex flex-col'>
{times.map((time, timeIndex) =>
<div className="flex" key={timeIndex}>
<div className="flex justify-center items-center font-mono w-40">
<p>{time}</p>
</div>
<div className="flex">
{days.map((day, dayIndex) =>
<div key={dayIndex} className={`flex ${toDownload ? 'pb-5 font-mono' : ''} rounded-xl border border-[#9B9898] justify-center items-center w-28 h-8 m-[2px]`}>
{currentSchedule[dayIndex] &&
currentSchedule[dayIndex][timeIndex] &&
currentSchedule[dayIndex][timeIndex].discipline.code}
</div>
)}
</div>
</div>
)}
</div>
</div>
{!preview &&
<div className={`flex flex-col w-max pl-10 pb-5 ${toDownload ? 'max-w-lg' : ''}`}>
<ul className='list-disc'>
{schedules && schedules.map((schedule, index) => {
return (
<div className='p-1' key={index}>
<li>
<span className={`font-semibold ${toDownload ? 'font-mono' : ''}`}>
{schedule.discipline.code}
</span> - {schedule.discipline.name} - <span className={toDownload ? 'font-mono' : ''}>({schedule.classroom})</span>
</li>
<span className='font-semibold'>PROFESSORES:</span>
<ul className='list-inside'>
{schedule.teachers.map((teacher, index) => {
if (uniqueTeachers.has(teacher)) return null;

uniqueTeachers.add(teacher);
return (
<li key={index}>
<p>{teacher}</p>
</li>
);
})}
</ul>
{schedule.special_dates.length ?
<>
<span className='font-semibold pr-2'>DATAS:</span>
{!toDownload ? <Tooltip>
{generateSpecialDates(schedule.special_dates, schedule.days)}
</Tooltip> : generateSpecialDates(schedule.special_dates, schedule.days)}
</> : null
}

</div>
);
})}
</ul>
</div>
}
</div>
);
}
Loading

0 comments on commit b8aefa4

Please sign in to comment.