diff --git a/src/components/CourseCard.tsx b/src/components/CourseCard.tsx index 1bb855d..d411814 100644 --- a/src/components/CourseCard.tsx +++ b/src/components/CourseCard.tsx @@ -7,7 +7,6 @@ import styled, { css } from 'styled-components'; import { makeStyles } from '@material-ui/core/styles'; import DeleteIcon from '@material-ui/icons/Delete'; import { useMemo } from 'react'; -import { createClassTime } from '../utils'; import { dayMapping } from '../constants'; const CourseCardWrapper = styled.div` @@ -219,12 +218,9 @@ export const CourseCard = ({ course }: CourseCardProps) => { )} - {/* - {dayMapping[group.day]} {createClassTime(group.time)[0]} - {createClassTime(group.time)[1]} - */} {dayMapping[group.day]} - {createClassTime(group.time)[0]} - {createClassTime(group.time)[1]} + {group.time} - {group.endTime} diff --git a/src/components/SchedulerRow.tsx b/src/components/SchedulerRow.tsx index c528c41..a007620 100644 --- a/src/components/SchedulerRow.tsx +++ b/src/components/SchedulerRow.tsx @@ -77,7 +77,7 @@ const StyledSchedulerEvent = styled.div` `} transition: background-color ease-out 0.4s; box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75); - cursor:pointer; + cursor: pointer; `; const threeStyles = () => { @@ -189,12 +189,16 @@ export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight } = 3}>{groups[index].name} {groupsPerDay[group.day] < 3 ? ( - {`${groups[index].time[0]}-${groups[index].time[1]}`} - 3/{groups[index].capacity} + {`${groups[index].time}-${groups[index].endTime}`} + + {groups[index].takenPlaces}/{groups[index].capacity} + ) : ( - 3/{groups[index].capacity} + + {groups[index].takenPlaces}/{groups[index].capacity} + )} diff --git a/src/contexts/CASProvider.tsx b/src/contexts/CASProvider.tsx index 3ac9004..3633f5b 100644 --- a/src/contexts/CASProvider.tsx +++ b/src/contexts/CASProvider.tsx @@ -6,6 +6,7 @@ export interface CASContext { user: LoggedUser | undefined; logout: () => void; token: string | undefined; + refreshToken: string | undefined; } export const CASContext = createContext(undefined); @@ -17,6 +18,7 @@ export interface CASProviderProps { export const CASProvider = ({ children }: CASProviderProps) => { const [user, setUser] = useState(); const [token, setToken] = useState(); + const [refreshToken, setRefreshToken] = useState(); useEffect(() => { const login = async () => { const urlParams = new URLSearchParams(window.location.search); @@ -26,15 +28,19 @@ export const CASProvider = ({ children }: CASProviderProps) => { } try { if (!localStorage.getItem('userToken')) { - const { data: user } = await axiosInstance.get( + const { data: user } = await axiosInstance.get( `${process.env.REACT_APP_API_URL}/token?ticket=${ticket}`, ); + console.log('token response: ', user); setUser({ authorityRole: user.authorityRole, email: user.email, id: user.id }); localStorage.setItem('userToken', user.token); localStorage.setItem('userPrivilige', user.authorityRole); + localStorage.setItem('refreshToken', user.refreshToken); } const token = localStorage.getItem('userToken'); + const refreshToken = localStorage.getItem('refreshToken'); token && setToken(token); + refreshToken && setRefreshToken(refreshToken); } catch (e) { console.log(e); } @@ -44,6 +50,7 @@ export const CASProvider = ({ children }: CASProviderProps) => { function logout() { localStorage.removeItem('userToken'); + localStorage.removeItem('refreshToken'); localStorage.removeItem('userPrivilige'); redirectToCASLogoutService(); } @@ -56,5 +63,5 @@ export const CASProvider = ({ children }: CASProviderProps) => { window.location.replace(`https://cas.amu.edu.pl/cas/login?service=${window.origin}&locale=pl`); } - return {children}; + return {children}; }; diff --git a/src/contexts/CoursesProvider.tsx b/src/contexts/CoursesProvider.tsx index 16a8fd5..6962fb7 100644 --- a/src/contexts/CoursesProvider.tsx +++ b/src/contexts/CoursesProvider.tsx @@ -1,7 +1,6 @@ import React, { useState, createContext, useEffect, ReactNode } from 'react'; import { Course, Group, Basket, GroupType, SchedulerEvent } from '../types'; import { useSnackbar } from 'notistack'; -import { createClassTime } from '../utils'; import { axiosInstance } from '../utils/axiosInstance'; import CloseIcon from '@material-ui/icons/Close'; import styled from 'styled-components'; @@ -71,12 +70,13 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { return basket.reduce((res, el) => { const { name } = el; if (el.classes) { - const { time } = el.classes; - res.push({ ...el.classes, name, time: createClassTime(time) }); + console.log('element kurwa is: ', el); + res.push({ ...el.classes, name }); } if (el.lecture) { - const { time } = el.lecture; - res.push({ ...el.lecture, name, time: createClassTime(time) }); + console.log('element kurwa is: ', el); + + res.push({ ...el.lecture, name }); } return res; }, [] as Array); @@ -175,8 +175,12 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { const getNewestTimetable = async () => { try { - const { data } = await axiosInstance.get(`${process.env.REACT_APP_API_URL}/api/v1/commisions/user/schedule`); + const { data } = await axiosInstance.get | ''>( + `${process.env.REACT_APP_API_URL}/api/v1/commisions/user/schedule`, + ); const basket = data === '' ? [] : data; + console.log('basket is: ', basket); + console.log('mordo weź'); setBasket(basket); } catch (e) { console.log(e); @@ -189,6 +193,7 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { `${process.env.REACT_APP_API_URL}/api/v1/commisions/user/${studentId}/schedule`, ); const basket = data === '' ? [] : data; + setBasket(basket); } catch (e) { console.log(e); @@ -198,13 +203,14 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => { const fetchCourses = async () => { try { const { data: courses } = await axiosInstance.get>( - `${process.env.REACT_APP_API_URL}/api/v1/courses/all?groups=true`, + `${process.env.REACT_APP_API_URL}/api/v1/courses/all?groups=true&takenPlaces=true`, ); const sortedCourses = courses.sort((a, b) => (a.name > b.name ? 1 : -1)); + console.log('sortedCourses: ', sortedCourses); setCourses(sortedCourses); } catch (e) { console.log(e); - } + } }; useEffect(() => { diff --git a/src/contexts/StudentsProvider.tsx b/src/contexts/StudentsProvider.tsx index 1c0eb09..11faf16 100644 --- a/src/contexts/StudentsProvider.tsx +++ b/src/contexts/StudentsProvider.tsx @@ -20,8 +20,6 @@ export const StudentsProvider = ({ children }: StudentsProviderProps) => { const [selectedStudent, setSelectedStudent] = useState(null); //not working currently - const userPrivilige = localStorage.getItem('userPrivilige'); - const { user } = useContext(CASContext)!; const getStudents = async () => { try { @@ -41,8 +39,9 @@ export const StudentsProvider = ({ children }: StudentsProviderProps) => { useEffect(() => { setTimeout(() => { - // user?.authorityRole === 'DEANERY' && - getStudents(); + const userPrivilige = localStorage.getItem('userPrivilige'); + console.log('mordo privilidż: ', userPrivilige); + userPrivilige === 'DEANERY' && getStudents(); }, 500); }, []); diff --git a/src/types/index.ts b/src/types/index.ts index e4dbc07..fcf3b7c 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -14,10 +14,12 @@ export interface Group { id: number; day: number; time: string; + endTime: string; lecturer: string; room: string; type: GroupType; capacity?: number; + takenPlaces: number; } export interface Course { @@ -43,10 +45,12 @@ export interface Student { export interface SchedulerEvent { id: number; day: number; - time: [string, string]; + time: string; + endTime: string; lecturer: string; room: string; type: GroupType; capacity?: number; + takenPlaces: number; name: string; } diff --git a/src/utils/axiosInstance.ts b/src/utils/axiosInstance.ts index 7761a37..066c670 100644 --- a/src/utils/axiosInstance.ts +++ b/src/utils/axiosInstance.ts @@ -2,15 +2,47 @@ import axios from 'axios'; export const axiosInstance = axios.create(); +//getting new tokens +const getNewTokens = async () => { + try { + const refreshToken = localStorage.getItem('refreshToken'); + const { data } = await axiosInstance.get( + `${process.env.REACT_APP_API_URL}/token/refresh?refreshToken=${refreshToken}`, + ); + localStorage.setItem('userToken', data.token); + localStorage.setItem('refreshToken', data.refreshToken); + return data.token; + } catch (e) { + console.log(e); + } +}; + axiosInstance.interceptors.request.use( - (config) => { + (request) => { const token = localStorage.getItem('userToken'); - config.headers['Content-Type'] = 'application/json'; - config.headers['Authorization'] = token ? `Bearer ${token}` : ''; - return config; + request.headers['Content-Type'] = 'application/json'; + request.headers['Authorization'] = token ? `Bearer ${token}` : ''; + return request; }, (error) => { Promise.reject(error); }, ); + +// Response interceptor for API calls +axiosInstance.interceptors.response.use( + (response) => { + return response; + }, + async (error) => { + const originalRequest = error.config; + if (error.response.status === 403 && !originalRequest._retry) { + originalRequest._retry = true; + const access_token = await getNewTokens(); + axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`; + return axiosInstance(originalRequest); + } + return Promise.reject(error); + }, +); diff --git a/src/utils/index.ts b/src/utils/index.ts index 7ffeb9d..3ea4c29 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,21 +1,12 @@ import { courseStartTimeToEventRow } from '../constants/index'; import { SchedulerEvent } from '../types'; -export const createClassTime = (startTime: string): [string, string] => { - const startTimeMapped = courseStartTimeToEventRow[startTime]; - const endTime = Object.keys(courseStartTimeToEventRow).find( - (key) => courseStartTimeToEventRow[key] === startTimeMapped + 1, - )!; - return [startTime, endTime]; -}; + export const selectGroupsToShow = (schedulerEvents: Array, index: number) => { - return schedulerEvents.filter(({ time }: { time: [string, string] }) => courseStartTimeToEventRow[time[0]] === index); + return schedulerEvents.filter((schedulerEvent) => courseStartTimeToEventRow[schedulerEvent.time] === index); }; - - - //debounce declaration and implementation type Procedure = (...args: any[]) => any;