From 174339876dd368bd949bbc37e9b513a3b080f961 Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Fri, 23 Apr 2021 08:20:12 +0200
Subject: [PATCH 1/5] Remove proxy and fix routes

---
 client/package.json                           |  2 +-
 client/src/actions/cities.ts                  |  2 +-
 client/src/actions/competitions.ts            |  2 +-
 client/src/actions/editor.ts                  |  2 +-
 client/src/actions/presentation.ts            |  4 ++--
 client/src/actions/roles.ts                   |  2 +-
 client/src/actions/searchUser.ts              |  2 +-
 client/src/actions/typesAction.ts             |  2 +-
 client/src/actions/user.ts                    |  6 ++---
 .../admin/competitions/AddCompetition.tsx     |  2 +-
 .../admin/competitions/CompetitionManager.tsx |  4 ++--
 client/src/pages/admin/regions/AddRegion.tsx  |  2 +-
 client/src/pages/admin/regions/Regions.tsx    |  4 ++--
 client/src/pages/admin/users/AddUser.tsx      |  2 +-
 client/src/pages/admin/users/EditUser.tsx     |  4 ++--
 .../PresentationEditorPage.test.tsx           |  2 +-
 .../PresentationEditorPage.tsx                |  6 ++---
 .../components/CompetitionSettings.tsx        |  8 +++----
 .../components/RndComponent.tsx               |  4 ++--
 .../components/SlideSettings.tsx              | 23 +++++++++++--------
 .../components/TextComponentEdit.tsx          |  4 ++--
 client/src/pages/views/JudgeViewPage.test.tsx |  2 +-
 .../pages/views/PresenterViewPage.test.tsx    |  2 +-
 client/src/utils/checkAuthentication.ts       |  2 +-
 24 files changed, 49 insertions(+), 46 deletions(-)

diff --git a/client/package.json b/client/package.json
index 7c354ece..8733d1d4 100644
--- a/client/package.json
+++ b/client/package.json
@@ -96,5 +96,5 @@
       "html"
     ]
   },
-  "proxy": "http://localhost:5000/api/"
+  "proxy": "http://localhost:5000/"
 }
diff --git a/client/src/actions/cities.ts b/client/src/actions/cities.ts
index 9226aee5..594a43c4 100644
--- a/client/src/actions/cities.ts
+++ b/client/src/actions/cities.ts
@@ -4,7 +4,7 @@ import Types from './types'
 
 export const getCities = () => async (dispatch: AppDispatch) => {
   await axios
-    .get('/misc/cities')
+    .get('/api/misc/cities')
     .then((res) => {
       dispatch({
         type: Types.SET_CITIES,
diff --git a/client/src/actions/competitions.ts b/client/src/actions/competitions.ts
index 7d248e46..1a9d789c 100644
--- a/client/src/actions/competitions.ts
+++ b/client/src/actions/competitions.ts
@@ -15,7 +15,7 @@ export const getCompetitions = () => async (dispatch: AppDispatch, getState: ()
     year: currentParams.year,
   }
   await axios
-    .get('/competitions/search', { params })
+    .get('/api/competitions/search', { params })
     .then((res) => {
       dispatch({
         type: Types.SET_COMPETITIONS,
diff --git a/client/src/actions/editor.ts b/client/src/actions/editor.ts
index 903dfa7b..45fbce98 100644
--- a/client/src/actions/editor.ts
+++ b/client/src/actions/editor.ts
@@ -4,7 +4,7 @@ import Types from './types'
 
 export const getEditorCompetition = (id: string) => async (dispatch: AppDispatch, getState: () => RootState) => {
   await axios
-    .get(`/competitions/${id}`)
+    .get(`/api/competitions/${id}`)
     .then((res) => {
       dispatch({
         type: Types.SET_EDITOR_COMPETITION,
diff --git a/client/src/actions/presentation.ts b/client/src/actions/presentation.ts
index c967131f..97c611df 100644
--- a/client/src/actions/presentation.ts
+++ b/client/src/actions/presentation.ts
@@ -6,7 +6,7 @@ import Types from './types'
 
 export const getPresentationCompetition = (id: string) => async (dispatch: AppDispatch) => {
   await axios
-    .get(`/competitions/${id}`)
+    .get(`/api/competitions/${id}`)
     .then((res) => {
       dispatch({
         type: Types.SET_PRESENTATION_COMPETITION,
@@ -20,7 +20,7 @@ export const getPresentationCompetition = (id: string) => async (dispatch: AppDi
 
 export const getPresentationTeams = (id: string) => async (dispatch: AppDispatch) => {
   await axios
-    .get(`/competitions/${id}/teams`)
+    .get(`/api/competitions/${id}/teams`)
     .then((res) => {
       dispatch({
         type: Types.SET_PRESENTATION_TEAMS,
diff --git a/client/src/actions/roles.ts b/client/src/actions/roles.ts
index 0160353b..19a148c7 100644
--- a/client/src/actions/roles.ts
+++ b/client/src/actions/roles.ts
@@ -4,7 +4,7 @@ import Types from './types'
 
 export const getRoles = () => async (dispatch: AppDispatch) => {
   await axios
-    .get('/misc/roles')
+    .get('/api/misc/roles')
     .then((res) => {
       dispatch({
         type: Types.SET_ROLES,
diff --git a/client/src/actions/searchUser.ts b/client/src/actions/searchUser.ts
index c6211056..a3ea55c7 100644
--- a/client/src/actions/searchUser.ts
+++ b/client/src/actions/searchUser.ts
@@ -15,7 +15,7 @@ export const getSearchUsers = () => async (dispatch: AppDispatch, getState: () =
     email: currentParams.email,
   }
   await axios
-    .get('/users/search', { params })
+    .get('/api/users/search', { params })
     .then((res) => {
       dispatch({
         type: Types.SET_SEARCH_USERS,
diff --git a/client/src/actions/typesAction.ts b/client/src/actions/typesAction.ts
index 4fcde4f5..32a212b0 100644
--- a/client/src/actions/typesAction.ts
+++ b/client/src/actions/typesAction.ts
@@ -4,7 +4,7 @@ import Types from './types'
 
 export const getTypes = () => async (dispatch: AppDispatch) => {
   await axios
-    .get('/misc/types')
+    .get('/api/misc/types')
     .then((res) => {
       dispatch({
         type: Types.SET_TYPES,
diff --git a/client/src/actions/user.ts b/client/src/actions/user.ts
index 371dcaeb..e2ad88ac 100644
--- a/client/src/actions/user.ts
+++ b/client/src/actions/user.ts
@@ -7,7 +7,7 @@ import Types from './types'
 export const loginUser = (userData: AccountLoginModel, history: History) => async (dispatch: AppDispatch) => {
   dispatch({ type: Types.LOADING_UI })
   await axios
-    .post('/auth/login', userData)
+    .post('/api/auth/login', userData)
     .then((res) => {
       const token = `Bearer ${res.data.access_token}`
       localStorage.setItem('token', token) //setting token to local storage
@@ -28,7 +28,7 @@ export const loginUser = (userData: AccountLoginModel, history: History) => asyn
 export const getUserData = () => async (dispatch: AppDispatch) => {
   dispatch({ type: Types.LOADING_USER })
   await axios
-    .get('/users')
+    .get('/api/users')
     .then((res) => {
       dispatch({
         type: Types.SET_USER,
@@ -42,7 +42,7 @@ export const getUserData = () => async (dispatch: AppDispatch) => {
 
 export const logoutUser = () => async (dispatch: AppDispatch) => {
   localStorage.removeItem('token')
-  await axios.post('/auth/logout').then(() => {
+  await axios.post('/api/auth/logout').then(() => {
     delete axios.defaults.headers.common['Authorization']
     dispatch({
       type: Types.SET_UNAUTHENTICATED,
diff --git a/client/src/pages/admin/competitions/AddCompetition.tsx b/client/src/pages/admin/competitions/AddCompetition.tsx
index 0ce9a6ff..6053f2f8 100644
--- a/client/src/pages/admin/competitions/AddCompetition.tsx
+++ b/client/src/pages/admin/competitions/AddCompetition.tsx
@@ -63,7 +63,7 @@ const AddCompetition: React.FC = (props: any) => {
     }
 
     await axios
-      .post('/competitions', params) // send to database
+      .post('/api/competitions', params) // send to database
       .then(() => {
         actions.resetForm() // reset the form
         setAnchorEl(null)
diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx
index 929d3145..83f399b9 100644
--- a/client/src/pages/admin/competitions/CompetitionManager.tsx
+++ b/client/src/pages/admin/competitions/CompetitionManager.tsx
@@ -82,7 +82,7 @@ const CompetitionManager: React.FC = (props: any) => {
   const handleDeleteCompetition = async () => {
     if (activeId) {
       await axios
-        .delete(`/competitions/${activeId}`)
+        .delete(`/api/competitions/${activeId}`)
         .then(() => {
           setAnchorEl(null)
           dispatch(getCompetitions()) // refresh the competition list
@@ -101,7 +101,7 @@ const CompetitionManager: React.FC = (props: any) => {
   const handleDuplicateCompetition = async () => {
     if (activeId) {
       await axios
-        .post(`/competitions/${activeId}/copy`)
+        .post(`/api/competitions/${activeId}/copy`)
         .then(() => {
           setAnchorEl(null)
           dispatch(getCompetitions())
diff --git a/client/src/pages/admin/regions/AddRegion.tsx b/client/src/pages/admin/regions/AddRegion.tsx
index c8ae412e..b0096138 100644
--- a/client/src/pages/admin/regions/AddRegion.tsx
+++ b/client/src/pages/admin/regions/AddRegion.tsx
@@ -51,7 +51,7 @@ const AddRegion: React.FC = (props: any) => {
       name: values.model.name,
     }
     await axios
-      .post('/misc/cities', params)
+      .post('/api/misc/cities', params)
       .then(() => {
         actions.resetForm()
         dispatch(getCities())
diff --git a/client/src/pages/admin/regions/Regions.tsx b/client/src/pages/admin/regions/Regions.tsx
index eb79575e..436da6f6 100644
--- a/client/src/pages/admin/regions/Regions.tsx
+++ b/client/src/pages/admin/regions/Regions.tsx
@@ -45,7 +45,7 @@ const RegionManager: React.FC = (props: any) => {
   const handleDeleteCity = async () => {
     if (activeId) {
       await axios
-        .delete(`/misc/cities/${activeId}`)
+        .delete(`/api/misc/cities/${activeId}`)
         .then(() => {
           setAnchorEl(null)
           dispatch(getCities())
@@ -63,7 +63,7 @@ const RegionManager: React.FC = (props: any) => {
 
   const handleAddCity = async () => {
     await axios
-      .post(`/misc/cities`, { name: newCity })
+      .post(`/api/misc/cities`, { name: newCity })
       .then(() => {
         setAnchorEl(null)
         dispatch(getCities())
diff --git a/client/src/pages/admin/users/AddUser.tsx b/client/src/pages/admin/users/AddUser.tsx
index d58a5d5d..9f1511ea 100644
--- a/client/src/pages/admin/users/AddUser.tsx
+++ b/client/src/pages/admin/users/AddUser.tsx
@@ -59,7 +59,7 @@ const AddUser: React.FC = (props: any) => {
       role_id: selectedRole?.id as number,
     }
     await axios
-      .post('/auth/signup', params)
+      .post('/api/auth/signup', params)
       .then(() => {
         actions.resetForm()
         setAnchorEl(null)
diff --git a/client/src/pages/admin/users/EditUser.tsx b/client/src/pages/admin/users/EditUser.tsx
index 7db5aeec..9b4a5d1b 100644
--- a/client/src/pages/admin/users/EditUser.tsx
+++ b/client/src/pages/admin/users/EditUser.tsx
@@ -110,7 +110,7 @@ const EditUser = ({ user }: UserIdProps) => {
   const handleDeleteUsers = async () => {
     setOpen(false)
     await axios
-      .delete(`/auth/delete/${user.id}`)
+      .delete(`/api/auth/delete/${user.id}`)
       .then(() => {
         setAnchorEl(null)
         dispatch(getSearchUsers())
@@ -141,7 +141,7 @@ const EditUser = ({ user }: UserIdProps) => {
       req['role_id'] = params.role_id
     }
     await axios
-      .put('/users/' + user.id, req)
+      .put('/api/users/' + user.id, req)
       .then((res) => {
         setAnchorEl(null)
         dispatch(getSearchUsers())
diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
index 956d0b72..c645724e 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
@@ -28,7 +28,7 @@ it('renders presentation editor', () => {
     },
   }
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
-    if (path.startsWith('/competitions')) return Promise.resolve(competitionRes)
+    if (path.startsWith('/api/competitions')) return Promise.resolve(competitionRes)
     return Promise.resolve(citiesRes)
   })
   render(
diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
index 4087d6c7..da18cd52 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
@@ -104,7 +104,7 @@ const PresentationEditorPage: React.FC = () => {
   }
 
   const createNewSlide = async () => {
-    await axios.post(`/competitions/${id}/slides`, { title: 'new slide' })
+    await axios.post(`/api/competitions/${id}/slides`, { title: 'new slide' })
     dispatch(getEditorCompetition(id))
   }
 
@@ -128,13 +128,13 @@ const PresentationEditorPage: React.FC = () => {
   }
 
   const handleRemoveSlide = async () => {
-    await axios.delete(`/competitions/${id}/slides/${contextState.slideId}`)
+    await axios.delete(`/api/competitions/${id}/slides/${contextState.slideId}`)
     dispatch(getEditorCompetition(id))
     setContextState(initialState)
   }
 
   const handleDuplicateSlide = async () => {
-    await axios.post(`/competitions/${id}/slides/${contextState.slideId}/copy`)
+    await axios.post(`/api/competitions/${id}/slides/${contextState.slideId}/copy`)
     dispatch(getEditorCompetition(id))
     setContextState(initialState)
   }
diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
index 75d41840..53c2ecdb 100644
--- a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
+++ b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
@@ -77,7 +77,7 @@ const CompetitionSettings: React.FC = () => {
   const competition = useAppSelector((state) => state.editor.competition)
   const updateCompetitionName = async (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
     await axios
-      .put(`/competitions/${id}`, { name: event.target.value })
+      .put(`/api/competitions/${id}`, { name: event.target.value })
       .then(() => {
         dispatch(getEditorCompetition(id))
       })
@@ -87,7 +87,7 @@ const CompetitionSettings: React.FC = () => {
   const cities = useAppSelector((state) => state.cities.cities)
   const updateCompetitionCity = async (city: City) => {
     await axios
-      .put(`/competitions/${id}`, { city_id: city.id })
+      .put(`/api/competitions/${id}`, { city_id: city.id })
       .then(() => {
         dispatch(getEditorCompetition(id))
       })
@@ -104,7 +104,7 @@ const CompetitionSettings: React.FC = () => {
 
   const removeTeam = async (tid: number) => {
     await axios
-      .delete(`/competitions/${id}/teams/${tid}`)
+      .delete(`/api/competitions/${id}/teams/${tid}`)
       .then(() => {
         dispatch(getEditorCompetition(id))
       })
@@ -113,7 +113,7 @@ const CompetitionSettings: React.FC = () => {
   const addTeam = async () => {
     setAddTeamOpen(false)
     await axios
-      .post(`/competitions/${id}/teams`, { name: selectedTeamName })
+      .post(`/api/competitions/${id}/teams`, { name: selectedTeamName })
       .then(() => {
         dispatch(getEditorCompetition(id))
       })
diff --git a/client/src/pages/presentationEditor/components/RndComponent.tsx b/client/src/pages/presentationEditor/components/RndComponent.tsx
index 890e5160..6302d3fc 100644
--- a/client/src/pages/presentationEditor/components/RndComponent.tsx
+++ b/client/src/pages/presentationEditor/components/RndComponent.tsx
@@ -20,13 +20,13 @@ const RndComponent = ({ component }: ImageComponentProps) => {
   const competitionId = useAppSelector((state) => state.editor.competition.id)
   const slideId = useAppSelector((state) => state.editor.activeSlideId)
   const handleUpdatePos = (pos: Position) => {
-    axios.put(`/competitions/${competitionId}/slides/${slideId}/components/${component.id}`, {
+    axios.put(`/api/competitions/${competitionId}/slides/${slideId}/components/${component.id}`, {
       x: pos.x,
       y: pos.y,
     })
   }
   const handleUpdateSize = (size: Size) => {
-    axios.put(`/competitions/${competitionId}/slides/${slideId}/components/${component.id}`, {
+    axios.put(`/api/competitions/${competitionId}/slides/${slideId}/components/${component.id}`, {
       w: size.w,
       h: size.h,
     })
diff --git a/client/src/pages/presentationEditor/components/SlideSettings.tsx b/client/src/pages/presentationEditor/components/SlideSettings.tsx
index 7cc78b34..85fe3cc0 100644
--- a/client/src/pages/presentationEditor/components/SlideSettings.tsx
+++ b/client/src/pages/presentationEditor/components/SlideSettings.tsx
@@ -133,7 +133,7 @@ const SlideSettings: React.FC = () => {
         if (selectedSlideType === 0) {
           // Change slide type from a question type to information
           await axios
-            .delete(`/competitions/${id}/slides/${activeSlide.id}/questions/${activeSlide.questions[0].id}`)
+            .delete(`/api/competitions/${id}/slides/${activeSlide.id}/questions/${activeSlide.questions[0].id}`)
             .then(() => {
               dispatch(getEditorCompetition(id))
             })
@@ -141,10 +141,10 @@ const SlideSettings: React.FC = () => {
         } else {
           // Change slide type from question type to another question type
           await axios
-            .delete(`/competitions/${id}/slides/${activeSlide.id}/questions/${activeSlide.questions[0].id}`)
+            .delete(`/api/competitions/${id}/slides/${activeSlide.id}/questions/${activeSlide.questions[0].id}`)
             .catch(console.log)
           await axios
-            .post(`/competitions/${id}/slides/${activeSlide.id}/questions`, {
+            .post(`/api/competitions/${id}/slides/${activeSlide.id}/questions`, {
               name: 'Ny fråga',
               total_score: 0,
               type_id: selectedSlideType,
@@ -158,7 +158,7 @@ const SlideSettings: React.FC = () => {
       } else if (selectedSlideType !== 0) {
         // Change slide type from information to a question type
         await axios
-          .post(`/competitions/${id}/slides/${activeSlide.id}/questions`, {
+          .post(`/api/competitions/${id}/slides/${activeSlide.id}/questions`, {
             name: 'Ny fråga',
             total_score: 0,
             type_id: selectedSlideType,
@@ -208,10 +208,13 @@ const SlideSettings: React.FC = () => {
   const addAlternative = async () => {
     if (activeSlide && activeSlide.questions[0]) {
       await axios
-        .post(`/competitions/${id}/slides/${activeSlide?.id}/questions/${activeSlide?.questions[0].id}/alternatives`, {
-          text: '',
-          value: 0,
-        })
+        .post(
+          `/api/competitions/${id}/slides/${activeSlide?.id}/questions/${activeSlide?.questions[0].id}/alternatives`,
+          {
+            text: '',
+            value: 0,
+          }
+        )
         .then(() => {
           dispatch(getEditorCompetition(id))
         })
@@ -237,7 +240,7 @@ const SlideSettings: React.FC = () => {
 
   const handleAddText = async () => {
     if (activeSlide) {
-      await axios.post(`/competitions/${id}/slides/${activeSlide?.id}/components`, {
+      await axios.post(`/api/competitions/${id}/slides/${activeSlide?.id}/components`, {
         type_id: 1,
         data: { text: 'Ny text' },
         w: 315,
@@ -261,7 +264,7 @@ const SlideSettings: React.FC = () => {
     setTimer(+event.target.value)
     if (activeSlide) {
       await axios
-        .put(`/competitions/${id}/slides/${activeSlide.id}`, { timer: event.target.value })
+        .put(`/api/competitions/${id}/slides/${activeSlide.id}`, { timer: event.target.value })
         .then(() => {
           dispatch(getEditorCompetition(id))
         })
diff --git a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
index e0f0d5b4..c347bd5b 100644
--- a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
+++ b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
@@ -37,7 +37,7 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => {
     setTimerHandle(
       window.setTimeout(async () => {
         console.log('Content was updated on server. id: ', component.id)
-        await axios.put(`/competitions/${competitionId}/slides/${activeSlideId}/components/${component.id}`, {
+        await axios.put(`/api/competitions/${competitionId}/slides/${activeSlideId}/components/${component.id}`, {
           data: { ...component.data, text: a },
         })
         dispatch(getEditorCompetition(id))
@@ -46,7 +46,7 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => {
   }
 
   const handleDeleteText = async (componentId: number) => {
-    await axios.delete(`/competitions/${id}/slides/${activeSlideId}/components/${componentId}`)
+    await axios.delete(`/api/competitions/${id}/slides/${activeSlideId}/components/${componentId}`)
     dispatch(getEditorCompetition(id))
   }
 
diff --git a/client/src/pages/views/JudgeViewPage.test.tsx b/client/src/pages/views/JudgeViewPage.test.tsx
index 537dae4c..fef8bee5 100644
--- a/client/src/pages/views/JudgeViewPage.test.tsx
+++ b/client/src/pages/views/JudgeViewPage.test.tsx
@@ -30,7 +30,7 @@ it('renders judge view page', () => {
   }
 
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
-    if (path.endsWith('/teams')) return Promise.resolve(teamsRes)
+    if (path.endsWith('/api/teams')) return Promise.resolve(teamsRes)
     else return Promise.resolve(compRes)
   })
   render(
diff --git a/client/src/pages/views/PresenterViewPage.test.tsx b/client/src/pages/views/PresenterViewPage.test.tsx
index fd7b0a96..e1d168c3 100644
--- a/client/src/pages/views/PresenterViewPage.test.tsx
+++ b/client/src/pages/views/PresenterViewPage.test.tsx
@@ -30,7 +30,7 @@ it('renders presenter view page', () => {
   }
 
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
-    if (path.endsWith('/teams')) return Promise.resolve(teamsRes)
+    if (path.endsWith('/api/teams')) return Promise.resolve(teamsRes)
     else return Promise.resolve(compRes)
   })
   render(
diff --git a/client/src/utils/checkAuthentication.ts b/client/src/utils/checkAuthentication.ts
index a782ea10..9225aa29 100644
--- a/client/src/utils/checkAuthentication.ts
+++ b/client/src/utils/checkAuthentication.ts
@@ -16,7 +16,7 @@ export const CheckAuthentication = async () => {
       axios.defaults.headers.common['Authorization'] = authToken
       store.dispatch({ type: Types.LOADING_USER })
       await axios
-        .get('/users')
+        .get('/api/users')
         .then((res) => {
           store.dispatch({ type: Types.SET_AUTHENTICATED })
           store.dispatch({
-- 
GitLab


From fe6a318d7e0d07f02cefdddf5bad755205b8e20a Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Fri, 23 Apr 2021 08:23:07 +0200
Subject: [PATCH 2/5] Fix test

---
 client/src/pages/views/JudgeViewPage.test.tsx     | 2 +-
 client/src/pages/views/PresenterViewPage.test.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/client/src/pages/views/JudgeViewPage.test.tsx b/client/src/pages/views/JudgeViewPage.test.tsx
index fef8bee5..537dae4c 100644
--- a/client/src/pages/views/JudgeViewPage.test.tsx
+++ b/client/src/pages/views/JudgeViewPage.test.tsx
@@ -30,7 +30,7 @@ it('renders judge view page', () => {
   }
 
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
-    if (path.endsWith('/api/teams')) return Promise.resolve(teamsRes)
+    if (path.endsWith('/teams')) return Promise.resolve(teamsRes)
     else return Promise.resolve(compRes)
   })
   render(
diff --git a/client/src/pages/views/PresenterViewPage.test.tsx b/client/src/pages/views/PresenterViewPage.test.tsx
index e1d168c3..fd7b0a96 100644
--- a/client/src/pages/views/PresenterViewPage.test.tsx
+++ b/client/src/pages/views/PresenterViewPage.test.tsx
@@ -30,7 +30,7 @@ it('renders presenter view page', () => {
   }
 
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
-    if (path.endsWith('/api/teams')) return Promise.resolve(teamsRes)
+    if (path.endsWith('/teams')) return Promise.resolve(teamsRes)
     else return Promise.resolve(compRes)
   })
   render(
-- 
GitLab


From 566ebca869fe13bdc6b3ed7774eb09cacee7abf5 Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Fri, 23 Apr 2021 12:13:25 +0200
Subject: [PATCH 3/5] Fix broken api

---
 client/src/Main.tsx                           |  2 +-
 client/src/actions/competitionLogin.ts        | 20 +++++++
 client/src/pages/admin/AdminPage.tsx          |  2 +
 .../login/components/CompetitionLogin.tsx     | 44 +++++++-------
 client/src/pages/views/ViewSelectPage.tsx     | 57 +++++++++++++++----
 server/app/apis/auth.py                       |  2 +-
 server/app/database/controller/get.py         |  4 +-
 7 files changed, 98 insertions(+), 33 deletions(-)
 create mode 100644 client/src/actions/competitionLogin.ts

diff --git a/client/src/Main.tsx b/client/src/Main.tsx
index bc0a2e85..b7c74b55 100644
--- a/client/src/Main.tsx
+++ b/client/src/Main.tsx
@@ -23,7 +23,7 @@ const Main: React.FC = () => {
         <SecureRoute login exact path="/" component={LoginPage} />
         <SecureRoute path="/admin" component={AdminPage} />
         <SecureRoute path="/editor/competition-id=:id" component={PresentationEditorPage} />
-        <Route exact path="/view" component={ViewSelectPage} />
+        <Route exact path="/:code" component={ViewSelectPage} />
         <Route exact path="/participant/id=:id&code=:code" component={ParticipantViewPage} />
         <SecureRoute exact path="/presenter/id=:id&code=:code" component={PresenterViewPage} />
         <Route exact path="/judge/id=:id&code=:code" component={JudgeViewPage} />
diff --git a/client/src/actions/competitionLogin.ts b/client/src/actions/competitionLogin.ts
new file mode 100644
index 00000000..4b1eeb83
--- /dev/null
+++ b/client/src/actions/competitionLogin.ts
@@ -0,0 +1,20 @@
+import axios from 'axios'
+import { History } from 'history'
+import { AppDispatch } from '../store'
+import { AccountLoginModel } from './../interfaces/FormModels'
+import Types from './types'
+
+export const loginCompetition = (code: string, history: History) => async (dispatch: AppDispatch) => {
+  await axios
+    .post('/api/auth/login/code', { code })
+    .then((res) => {
+      console.log(code, res.data[0])
+      // history.push('/admin') //redirecting to admin page after login success
+      if (res.data && res.data[0] && res.data[0].view_type_id) {
+        history.push(`/${code}`)
+      }
+    })
+    .catch((err) => {
+      console.log(err)
+    })
+}
diff --git a/client/src/pages/admin/AdminPage.tsx b/client/src/pages/admin/AdminPage.tsx
index 30cfe656..89d4707c 100644
--- a/client/src/pages/admin/AdminPage.tsx
+++ b/client/src/pages/admin/AdminPage.tsx
@@ -16,6 +16,7 @@ import ExitToAppIcon from '@material-ui/icons/ExitToApp'
 import LocationCityIcon from '@material-ui/icons/LocationCity'
 import PeopleIcon from '@material-ui/icons/People'
 import SettingsOverscanIcon from '@material-ui/icons/SettingsOverscan'
+import axios from 'axios'
 import React, { useEffect } from 'react'
 import { Link, Route, Switch, useRouteMatch } from 'react-router-dom'
 import { getCities } from '../../actions/cities'
@@ -71,6 +72,7 @@ const AdminView: React.FC = () => {
     dispatch(getCities())
     dispatch(getRoles())
     dispatch(getTypes())
+    axios.get('/api/competitions/2/codes').then(console.log).catch(console.log)
   }, [])
 
   const menuAdminItems = [
diff --git a/client/src/pages/login/components/CompetitionLogin.tsx b/client/src/pages/login/components/CompetitionLogin.tsx
index 75f73c5b..738fcb34 100644
--- a/client/src/pages/login/components/CompetitionLogin.tsx
+++ b/client/src/pages/login/components/CompetitionLogin.tsx
@@ -2,8 +2,11 @@ import { Button, TextField } from '@material-ui/core'
 import { Alert, AlertTitle } from '@material-ui/lab'
 import axios from 'axios'
 import { Formik, FormikHelpers } from 'formik'
-import React from 'react'
+import { useHistory } from 'react-router-dom'
+import React, { useEffect } from 'react'
 import * as Yup from 'yup'
+import { loginCompetition } from '../../../actions/competitionLogin'
+import { useAppDispatch } from '../../../hooks'
 import { CompetitionLoginModel } from '../../../interfaces/FormModels'
 import { LoginForm } from './styled'
 
@@ -26,28 +29,31 @@ const competitionSchema: Yup.SchemaOf<CompetitionLoginFormModel> = Yup.object({
   error: Yup.string().optional(),
 })
 
-const handleCompetitionSubmit = async (
-  values: CompetitionLoginFormModel,
-  actions: FormikHelpers<CompetitionLoginFormModel>
-) => {
-  await axios
-    .post<ServerResponse>(`users/login`, { code: values.model.code })
-    .then(() => {
-      actions.resetForm()
-    })
-    .catch(({ response }) => {
-      console.log(response.data.message)
-      actions.setFieldError('error', response.data.message)
-    })
-    .finally(() => {
-      actions.setSubmitting(false)
-    })
-}
-
 const CompetitionLogin: React.FC = () => {
+  const dispatch = useAppDispatch()
+  const history = useHistory()
+
   const competitionInitialValues: CompetitionLoginFormModel = {
     model: { code: '' },
   }
+  const handleCompetitionSubmit = async (
+    values: CompetitionLoginFormModel,
+    actions: FormikHelpers<CompetitionLoginFormModel>
+  ) => {
+    dispatch(loginCompetition(values.model.code, history))
+    /*   await axios
+      .post<ServerResponse>(`users/login`, { code: values.model.code })
+      .then(() => {
+        actions.resetForm()
+      })
+      .catch(({ response }) => {
+        console.log(response.data.message)
+        actions.setFieldError('error', response.data.message)
+      })
+      .finally(() => {
+        actions.setSubmitting(false)
+      }) */
+  }
   return (
     <Formik
       initialValues={competitionInitialValues}
diff --git a/client/src/pages/views/ViewSelectPage.tsx b/client/src/pages/views/ViewSelectPage.tsx
index 2781f60c..96837ebe 100644
--- a/client/src/pages/views/ViewSelectPage.tsx
+++ b/client/src/pages/views/ViewSelectPage.tsx
@@ -1,22 +1,59 @@
 import Button from '@material-ui/core/Button'
-import React from 'react'
+import React, { useEffect, useState } from 'react'
 import { Link, useRouteMatch } from 'react-router-dom'
 import { ViewSelectButtonGroup, ViewSelectContainer } from './styled'
+import { useParams } from 'react-router-dom'
+import { CircularProgress, Typography } from '@material-ui/core'
+import ParticipantViewPage from './ParticipantViewPage'
+import axios from 'axios'
+import PresenterViewPage from './PresenterViewPage'
+import JudgeViewPage from './JudgeViewPage'
+import AudienceViewPage from './AudienceViewPage'
 
+interface ViewSelectParams {
+  code: string
+}
 const ViewSelectPage: React.FC = () => {
   const url = useRouteMatch().url
+  const [loading, setLoading] = useState(true)
+  const [error, setError] = useState(false)
+  const [viewType, setViewType] = useState(undefined)
+  const { code }: ViewSelectParams = useParams()
+
+  const renderView = (viewTypeId: number | undefined) => {
+    //Renders the correct view depending on view type
+    switch (viewTypeId) {
+      case 1:
+        return <ParticipantViewPage />
+      case 2:
+        return <JudgeViewPage />
+      case 3:
+        return <AudienceViewPage />
+      case 4:
+        return <PresenterViewPage />
+      default:
+        return <Typography>Inkorrekt vy</Typography>
+    }
+  }
+
+  useEffect(() => {
+    axios
+      .post('/api/auth/login/code', { code })
+      .then((response) => {
+        setLoading(false)
+        setViewType(response.data[0].view_type_id)
+      })
+      .catch(() => {
+        setLoading(false)
+        setError(true)
+      })
+  }, [])
   return (
     <ViewSelectContainer>
       <ViewSelectButtonGroup>
-        <Button color="primary" variant="contained" component={Link} to={`${url}/participant`}>
-          Deltagarvy
-        </Button>
-        <Button color="primary" variant="contained" component={Link} to={`${url}/audience`}>
-          Åskådarvy
-        </Button>
-        <Button color="primary" variant="contained" component={Link} to={`${url}/judge`}>
-          Domarvy
-        </Button>
+        {loading && <CircularProgress />}
+        {!loading && renderView(viewType)}
+        {error && <Typography>Något gick fel, dubbelkolla koden och försök igen</Typography>}
       </ViewSelectButtonGroup>
     </ViewSelectContainer>
   )
diff --git a/server/app/apis/auth.py b/server/app/apis/auth.py
index d249fec5..87d7f1d1 100644
--- a/server/app/apis/auth.py
+++ b/server/app/apis/auth.py
@@ -79,7 +79,7 @@ class AuthLoginCode(Resource):
         if not verify_code(code):
             api.abort(codes.BAD_REQUEST, "Invalid code")
 
-        item_code = dbc.get.code_by_code(code, True, "A presentation with that code does not exist")
+        item_code = dbc.get.code_by_code(code)
         return item_response(CodeDTO.schema.dump(item_code)), codes.OK
 
 
diff --git a/server/app/database/controller/get.py b/server/app/database/controller/get.py
index 15e908ef..bf5d8c3b 100644
--- a/server/app/database/controller/get.py
+++ b/server/app/database/controller/get.py
@@ -34,7 +34,7 @@ def one(db_type, id):
 def code_by_code(code):
     """ Gets the code object associated with the provided code. """
 
-    return Code.query.filter(Code.code == code.upper()).first_extended()
+    return Code.query.filter(Code.code == code.upper()).first_extended( True, "A presentation with that code does not exist")
 
 
 def code_list(competition_id):
@@ -42,7 +42,7 @@ def code_list(competition_id):
 
     team_view_id = 1
     join_filters = (Code.view_type_id == team_view_id) & (Team.id == Code.pointer)
-    filters = ((Code.view_type_id != team_view_id) & (Code.pointer == competition_id))(
+    filters = ((Code.view_type_id != team_view_id) & (Code.pointer == competition_id)) | (
         (Code.view_type_id == team_view_id) & (competition_id == Team.competition_id)
     )
     return Code.query.join(Team, join_filters, isouter=True).filter(filters).all()
-- 
GitLab


From ec7cae3025c816e0ca9bf10dfa0a6a85d221c1a0 Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Fri, 23 Apr 2021 18:07:11 +0200
Subject: [PATCH 4/5] Add competition login

---
 client/src/actions/competitionLogin.ts        |  3 ++
 client/src/actions/types.ts                   |  3 ++
 .../src/pages/login/components/AdminLogin.tsx |  5 ++-
 .../login/components/CompetitionLogin.tsx     | 41 ++++++-------------
 client/src/pages/views/JudgeViewPage.tsx      |  5 ++-
 .../src/pages/views/ParticipantViewPage.tsx   |  1 +
 client/src/pages/views/PresenterViewPage.tsx  | 16 +++-----
 client/src/pages/views/ViewSelectPage.tsx     | 22 ++++------
 client/src/reducers/allReducers.ts            |  2 +
 .../src/reducers/competitionLoginReducer.ts   | 38 +++++++++++++++++
 10 files changed, 82 insertions(+), 54 deletions(-)
 create mode 100644 client/src/reducers/competitionLoginReducer.ts

diff --git a/client/src/actions/competitionLogin.ts b/client/src/actions/competitionLogin.ts
index 4b1eeb83..ff177a2b 100644
--- a/client/src/actions/competitionLogin.ts
+++ b/client/src/actions/competitionLogin.ts
@@ -5,16 +5,19 @@ import { AccountLoginModel } from './../interfaces/FormModels'
 import Types from './types'
 
 export const loginCompetition = (code: string, history: History) => async (dispatch: AppDispatch) => {
+  dispatch({ type: Types.LOADING_COMPETITION_LOGIN })
   await axios
     .post('/api/auth/login/code', { code })
     .then((res) => {
       console.log(code, res.data[0])
+      dispatch({ type: Types.CLEAR_COMPETITION_LOGIN_ERRORS }) // no error
       // history.push('/admin') //redirecting to admin page after login success
       if (res.data && res.data[0] && res.data[0].view_type_id) {
         history.push(`/${code}`)
       }
     })
     .catch((err) => {
+      dispatch({ type: Types.SET_COMPETITION_LOGIN_ERRORS, payload: err && err.response && err.response.data })
       console.log(err)
     })
 }
diff --git a/client/src/actions/types.ts b/client/src/actions/types.ts
index 189bf16c..6e9c098e 100644
--- a/client/src/actions/types.ts
+++ b/client/src/actions/types.ts
@@ -1,6 +1,7 @@
 export default {
   LOADING_UI: 'LOADING_UI',
   LOADING_USER: 'LOADING_USER',
+  LOADING_COMPETITION_LOGIN: 'LOADING_COMPETITION_LOGIN',
   SET_ROLES: 'SET_ROLES',
   SET_USER: 'SET_USER',
   SET_SEARCH_USERS: 'SET_SEARCH_USERS',
@@ -9,6 +10,8 @@ export default {
   SET_SEARCH_USERS_TOTAL_COUNT: 'SET_SEARCH_USERS_TOTAL_COUNT',
   SET_ERRORS: 'SET_ERRORS',
   CLEAR_ERRORS: 'CLEAR_ERRORS',
+  SET_COMPETITION_LOGIN_ERRORS: 'SET_COMPETITION_LOGIN_ERRORS',
+  CLEAR_COMPETITION_LOGIN_ERRORS: 'CLEAR_COMPETITION_LOGIN_ERRORS',
   SET_UNAUTHENTICATED: 'SET_UNAUTHENTICATED',
   SET_AUTHENTICATED: 'SET_AUTHENTICATED',
   SET_COMPETITIONS: 'SET_COMPETITIONS',
diff --git a/client/src/pages/login/components/AdminLogin.tsx b/client/src/pages/login/components/AdminLogin.tsx
index 7f478caf..964fb8ab 100644
--- a/client/src/pages/login/components/AdminLogin.tsx
+++ b/client/src/pages/login/components/AdminLogin.tsx
@@ -1,4 +1,4 @@
-import { Button, TextField } from '@material-ui/core'
+import { Button, TextField, Typography } from '@material-ui/core'
 import { Alert, AlertTitle } from '@material-ui/lab'
 import { Formik, FormikHelpers } from 'formik'
 import React, { useEffect, useState } from 'react'
@@ -83,7 +83,8 @@ const AdminLogin: React.FC = () => {
           {errors.message && (
             <Alert severity="error">
               <AlertTitle>Error</AlertTitle>
-              {errors.message}
+              <Typography>NÃ¥gonting gick fel. Kontrollera</Typography>
+              <Typography>dina användaruppgifter och försök igen</Typography>
             </Alert>
           )}
           {loading && <CenteredCircularProgress color="secondary" />}
diff --git a/client/src/pages/login/components/CompetitionLogin.tsx b/client/src/pages/login/components/CompetitionLogin.tsx
index 738fcb34..d89cafcf 100644
--- a/client/src/pages/login/components/CompetitionLogin.tsx
+++ b/client/src/pages/login/components/CompetitionLogin.tsx
@@ -1,29 +1,28 @@
-import { Button, TextField } from '@material-ui/core'
+import { Button, TextField, Typography } from '@material-ui/core'
 import { Alert, AlertTitle } from '@material-ui/lab'
 import axios from 'axios'
 import { Formik, FormikHelpers } from 'formik'
 import { useHistory } from 'react-router-dom'
-import React, { useEffect } from 'react'
+import React, { useEffect, useState } from 'react'
 import * as Yup from 'yup'
 import { loginCompetition } from '../../../actions/competitionLogin'
-import { useAppDispatch } from '../../../hooks'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
 import { CompetitionLoginModel } from '../../../interfaces/FormModels'
-import { LoginForm } from './styled'
+import { CenteredCircularProgress, LoginForm } from './styled'
 
 interface CompetitionLoginFormModel {
   model: CompetitionLoginModel
   error?: string
 }
 
-interface ServerResponse {
-  code: number
+interface formError {
   message: string
 }
 
 const competitionSchema: Yup.SchemaOf<CompetitionLoginFormModel> = Yup.object({
   model: Yup.object()
     .shape({
-      code: Yup.string().required('Mata in kod').min(6, 'Koden måste vara minst 6 tecken'),
+      code: Yup.string().required('Mata in kod').length(6, 'Koden måste vara 6 tecken'),
     })
     .required(),
   error: Yup.string().optional(),
@@ -32,27 +31,13 @@ const competitionSchema: Yup.SchemaOf<CompetitionLoginFormModel> = Yup.object({
 const CompetitionLogin: React.FC = () => {
   const dispatch = useAppDispatch()
   const history = useHistory()
-
+  const errors = useAppSelector((state) => state.competitionLogin.errors)
+  const loading = useAppSelector((state) => state.competitionLogin.loading)
   const competitionInitialValues: CompetitionLoginFormModel = {
     model: { code: '' },
   }
-  const handleCompetitionSubmit = async (
-    values: CompetitionLoginFormModel,
-    actions: FormikHelpers<CompetitionLoginFormModel>
-  ) => {
+  const handleCompetitionSubmit = async (values: CompetitionLoginFormModel) => {
     dispatch(loginCompetition(values.model.code, history))
-    /*   await axios
-      .post<ServerResponse>(`users/login`, { code: values.model.code })
-      .then(() => {
-        actions.resetForm()
-      })
-      .catch(({ response }) => {
-        console.log(response.data.message)
-        actions.setFieldError('error', response.data.message)
-      })
-      .finally(() => {
-        actions.setSubmitting(false)
-      }) */
   }
   return (
     <Formik
@@ -74,14 +59,14 @@ const CompetitionLogin: React.FC = () => {
           <Button type="submit" fullWidth variant="contained" color="secondary" disabled={!formik.isValid}>
             Anslut till tävling
           </Button>
-          {formik.errors.error ? (
+          {errors && errors.message && (
             <Alert severity="error">
               <AlertTitle>Error</AlertTitle>
-              {formik.errors.error}
+              <Typography>En tävling med den koden hittades ej.</Typography>
+              <Typography>kontrollera koden och försök igen</Typography>
             </Alert>
-          ) : (
-            <div />
           )}
+          {loading && <CenteredCircularProgress color="secondary" />}
         </LoginForm>
       )}
     </Formik>
diff --git a/client/src/pages/views/JudgeViewPage.tsx b/client/src/pages/views/JudgeViewPage.tsx
index 60018624..66450f3a 100644
--- a/client/src/pages/views/JudgeViewPage.tsx
+++ b/client/src/pages/views/JudgeViewPage.tsx
@@ -14,6 +14,7 @@ import { socket_connect } from '../../sockets'
 import { SlideListItem } from '../presentationEditor/styled'
 import JudgeScoreDisplay from './components/JudgeScoreDisplay'
 import SlideDisplay from './components/SlideDisplay'
+import { useHistory } from 'react-router-dom'
 import {
   Content,
   JudgeAnswersLabel,
@@ -41,6 +42,7 @@ const useStyles = makeStyles((theme: Theme) =>
 
 const JudgeViewPage: React.FC = () => {
   const classes = useStyles()
+  const history = useHistory()
   const { id, code }: ViewParams = useParams()
   const dispatch = useAppDispatch()
   const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0)
@@ -50,12 +52,13 @@ const JudgeViewPage: React.FC = () => {
     setActiveSlideIndex(index)
     dispatch(setCurrentSlide(slides[index]))
   }
-
   useEffect(() => {
     socket_connect()
     dispatch(getPresentationCompetition(id))
     dispatch(getPresentationTeams(id))
     dispatch(setPresentationCode(code))
+    //hides the url so people can't sneak peak
+    history.push('judge')
   }, [])
 
   return (
diff --git a/client/src/pages/views/ParticipantViewPage.tsx b/client/src/pages/views/ParticipantViewPage.tsx
index 7447f2a6..f531ad76 100644
--- a/client/src/pages/views/ParticipantViewPage.tsx
+++ b/client/src/pages/views/ParticipantViewPage.tsx
@@ -5,6 +5,7 @@ import { useHistory } from 'react-router-dom'
 const ParticipantViewPage: React.FC = () => {
   const history = useHistory()
   useEffect(() => {
+    //hides the url so people can't sneak peak
     history.push('participant')
   }, [])
   return <SlideDisplay />
diff --git a/client/src/pages/views/PresenterViewPage.tsx b/client/src/pages/views/PresenterViewPage.tsx
index 23e5928a..1abeee92 100644
--- a/client/src/pages/views/PresenterViewPage.tsx
+++ b/client/src/pages/views/PresenterViewPage.tsx
@@ -46,31 +46,27 @@ import {
 /**
  *  Presentation is an active competition
  */
-type PresenterViewPageProps = {
-  competitionId: number
-}
 
-const PresenterViewPage = ({ competitionId }: PresenterViewPageProps) => {
+const PresenterViewPage: React.FC = () => {
   // for dialog alert
   const [openAlert, setOpen] = React.useState(false)
   const theme = useTheme()
   const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
-
   const teams = useAppSelector((state) => state.presentation.teams)
   const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
-  const { code }: ViewParams = useParams()
+  const { id, code }: ViewParams = useParams()
   const presentation = useAppSelector((state) => state.presentation)
   const history = useHistory()
   const dispatch = useAppDispatch()
 
   useEffect(() => {
-    dispatch(getPresentationCompetition(competitionId.toString()))
-    dispatch(getPresentationTeams(competitionId.toString()))
+    dispatch(getPresentationCompetition(id))
+    dispatch(getPresentationTeams(id))
     dispatch(setPresentationCode(code))
     socket_connect()
     socketSetSlide // Behövs denna?
     setTimeout(startCompetition, 500) // Ghetto, wait for everything to load
-    // console.log(competitionId)
+    // console.log(id)
   }, [])
 
   const handleOpenPopover = (event: React.MouseEvent<HTMLButtonElement>) => {
@@ -85,7 +81,7 @@ const PresenterViewPage = ({ competitionId }: PresenterViewPageProps) => {
   const startCompetition = () => {
     socketStartPresentation()
     console.log('started competition for')
-    console.log(competitionId)
+    console.log(id)
   }
 
   const handleVerifyExit = () => {
diff --git a/client/src/pages/views/ViewSelectPage.tsx b/client/src/pages/views/ViewSelectPage.tsx
index fa3a58b8..3c3599ed 100644
--- a/client/src/pages/views/ViewSelectPage.tsx
+++ b/client/src/pages/views/ViewSelectPage.tsx
@@ -15,27 +15,23 @@ interface ViewSelectParams {
   code: string
 }
 const ViewSelectPage: React.FC = () => {
-  const url = useRouteMatch().url
   const [loading, setLoading] = useState(true)
   const [error, setError] = useState(false)
-  const [viewType, setViewType] = useState(undefined)
+  const [viewTypeId, setViewTypeId] = useState(undefined)
   const [competitionId, setCompetitionId] = useState<number | undefined>(undefined)
   const { code }: ViewSelectParams = useParams()
+  const viewType = useAppSelector((state) => state.types.viewTypes.find((viewType) => viewType.id === viewTypeId)?.name)
 
   const renderView = (viewTypeId: number | undefined) => {
     //Renders the correct view depending on view type
-    // TODO: use state instead of hard-coded values
-    //const viewTypes = useAppSelector(state => state.types.viewTypes)
     if (competitionId) {
-      switch (viewTypeId) {
-        case 1:
+      switch (viewType) {
+        case 'Team':
           return <ParticipantViewPage />
-        case 2:
+        case 'Judge':
           return <JudgeViewPage />
-        case 3:
+        case 'Audience':
           return <AudienceViewPage />
-        case 4:
-          return <PresenterViewPage competitionId={competitionId} />
         default:
           return <Typography>Inkorrekt vy</Typography>
       }
@@ -47,8 +43,8 @@ const ViewSelectPage: React.FC = () => {
       .post('/api/auth/login/code', { code })
       .then((response) => {
         setLoading(false)
-        setViewType(response.data[0].view_type_id)
-        setCompetitionId(response.data[0].pointer)
+        setViewTypeId(response.data[0].view_type_id)
+        setCompetitionId(response.data[0].competition_id)
       })
       .catch(() => {
         setLoading(false)
@@ -60,7 +56,7 @@ const ViewSelectPage: React.FC = () => {
     <ViewSelectContainer>
       <ViewSelectButtonGroup>
         {loading && <CircularProgress />}
-        {!loading && renderView(viewType)}
+        {!loading && renderView(viewTypeId)}
         {error && <Typography>Något gick fel, dubbelkolla koden och försök igen</Typography>}
       </ViewSelectButtonGroup>
     </ViewSelectContainer>
diff --git a/client/src/reducers/allReducers.ts b/client/src/reducers/allReducers.ts
index c23384c2..038b172e 100644
--- a/client/src/reducers/allReducers.ts
+++ b/client/src/reducers/allReducers.ts
@@ -2,6 +2,7 @@
 
 import { combineReducers } from 'redux'
 import citiesReducer from './citiesReducer'
+import competitionLoginReducer from './competitionLoginReducer'
 import competitionsReducer from './competitionsReducer'
 import editorReducer from './editorReducer'
 import presentationReducer from './presentationReducer'
@@ -24,5 +25,6 @@ const allReducers = combineReducers({
   searchUsers: searchUserReducer,
   types: typesReducer,
   statistics: statisticsReducer,
+  competitionLogin: competitionLoginReducer,
 })
 export default allReducers
diff --git a/client/src/reducers/competitionLoginReducer.ts b/client/src/reducers/competitionLoginReducer.ts
new file mode 100644
index 00000000..81c426a4
--- /dev/null
+++ b/client/src/reducers/competitionLoginReducer.ts
@@ -0,0 +1,38 @@
+import { AnyAction } from 'redux'
+import Types from '../actions/types'
+
+interface UIError {
+  message: string
+}
+
+interface UserState {
+  loading: boolean
+  errors: null | UIError
+}
+
+const initialState: UserState = {
+  loading: false,
+  errors: null,
+}
+
+export default function (state = initialState, action: AnyAction) {
+  switch (action.type) {
+    case Types.SET_COMPETITION_LOGIN_ERRORS:
+      return {
+        errors: action.payload as UIError,
+        loading: false,
+      }
+    case Types.CLEAR_COMPETITION_LOGIN_ERRORS:
+      return {
+        loading: false,
+        errors: null,
+      }
+    case Types.LOADING_COMPETITION_LOGIN:
+      return {
+        ...state,
+        loading: true,
+      }
+    default:
+      return state
+  }
+}
-- 
GitLab


From 6406546fe04a7897b4077724c2491cf0be8e8c3a Mon Sep 17 00:00:00 2001
From: Albin Henriksson <albhe428@student.liu.se>
Date: Sat, 24 Apr 2021 14:39:04 +0200
Subject: [PATCH 5/5] Fix tests

---
 client/src/pages/admin/AdminPage.tsx          |  1 -
 .../components/CompetitionLogin.test.tsx      |  8 +++++-
 .../pages/views/ParticipantViewPage.test.tsx  |  9 ++++---
 .../src/pages/views/ViewSelectPage.test.tsx   | 26 ++++++++++++++-----
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/client/src/pages/admin/AdminPage.tsx b/client/src/pages/admin/AdminPage.tsx
index 4823f442..a8b1746a 100644
--- a/client/src/pages/admin/AdminPage.tsx
+++ b/client/src/pages/admin/AdminPage.tsx
@@ -73,7 +73,6 @@ const AdminView: React.FC = () => {
     dispatch(getCities())
     dispatch(getRoles())
     dispatch(getTypes())
-    axios.get('/api/competitions/1/codes').then(console.log).catch(console.log)
     dispatch(getStatistics())
   }, [])
 
diff --git a/client/src/pages/login/components/CompetitionLogin.test.tsx b/client/src/pages/login/components/CompetitionLogin.test.tsx
index 29213c94..862880bc 100644
--- a/client/src/pages/login/components/CompetitionLogin.test.tsx
+++ b/client/src/pages/login/components/CompetitionLogin.test.tsx
@@ -1,7 +1,13 @@
 import { render } from '@testing-library/react'
 import React from 'react'
+import { Provider } from 'react-redux'
+import store from '../../../store'
 import CompetitionLogin from './CompetitionLogin'
 
 it('renders competition login', () => {
-  render(<CompetitionLogin />)
+  render(
+    <Provider store={store}>
+      <CompetitionLogin />
+    </Provider>
+  )
 })
diff --git a/client/src/pages/views/ParticipantViewPage.test.tsx b/client/src/pages/views/ParticipantViewPage.test.tsx
index 85360e4f..c0950b3c 100644
--- a/client/src/pages/views/ParticipantViewPage.test.tsx
+++ b/client/src/pages/views/ParticipantViewPage.test.tsx
@@ -1,13 +1,16 @@
 import { render } from '@testing-library/react'
 import React from 'react'
 import { Provider } from 'react-redux'
+import { BrowserRouter } from 'react-router-dom'
 import store from '../../store'
 import ParticipantViewPage from './ParticipantViewPage'
 
 it('renders participant view page', () => {
   render(
-    <Provider store={store}>
-      <ParticipantViewPage />
-    </Provider>
+    <BrowserRouter>
+      <Provider store={store}>
+        <ParticipantViewPage />
+      </Provider>
+    </BrowserRouter>
   )
 })
diff --git a/client/src/pages/views/ViewSelectPage.test.tsx b/client/src/pages/views/ViewSelectPage.test.tsx
index 2e649977..83b71db0 100644
--- a/client/src/pages/views/ViewSelectPage.test.tsx
+++ b/client/src/pages/views/ViewSelectPage.test.tsx
@@ -1,12 +1,26 @@
 import { render } from '@testing-library/react'
 import React from 'react'
+import { Provider } from 'react-redux'
 import { BrowserRouter } from 'react-router-dom'
+import store from '../../store'
 import ViewSelectPage from './ViewSelectPage'
+import mockedAxios from 'axios'
+import { act } from 'react-dom/test-utils'
 
-it('renders view select page', () => {
-  render(
-    <BrowserRouter>
-      <ViewSelectPage />
-    </BrowserRouter>
-  )
+it('renders view select page', async () => {
+  await act(async () => {
+    const res = {
+      data: {},
+    }
+    ;(mockedAxios.post as jest.Mock).mockImplementation(() => {
+      return Promise.resolve(res)
+    })
+    render(
+      <BrowserRouter>
+        <Provider store={store}>
+          <ViewSelectPage />
+        </Provider>
+      </BrowserRouter>
+    )
+  })
 })
-- 
GitLab