diff --git a/client/src/Main.tsx b/client/src/Main.tsx
index 9e079471e43b94367438ab58c08d29a28a4ebd9b..5cd27cc3d83e96bda772e2e9b07282903ed069f5 100644
--- a/client/src/Main.tsx
+++ b/client/src/Main.tsx
@@ -1,5 +1,5 @@
 import React, { useEffect } from 'react'
-import { BrowserRouter, Switch } from 'react-router-dom'
+import { BrowserRouter, Route, Switch } from 'react-router-dom'
 import { getTypes } from './actions/typesAction'
 import { useAppDispatch } from './hooks'
 import AdminPage from './pages/admin/AdminPage'
@@ -7,8 +7,8 @@ import LoginPage from './pages/login/LoginPage'
 import PresentationEditorPage from './pages/presentationEditor/PresentationEditorPage'
 import AudienceViewPage from './pages/views/AudienceViewPage'
 import JudgeViewPage from './pages/views/JudgeViewPage'
-import ParticipantViewPage from './pages/views/ParticipantViewPage'
-import PresenterViewPage from './pages/views/PresenterViewPage'
+import OperatorViewPage from './pages/views/OperatorViewPage'
+import TeamViewPage from './pages/views/TeamViewPage'
 import ViewSelectPage from './pages/views/ViewSelectPage'
 import SecureRoute from './utils/SecureRoute'
 
@@ -20,34 +20,34 @@ const Main: React.FC = () => {
   return (
     <BrowserRouter>
       <Switch>
-        <SecureRoute authLevel={'login'} exact path="/" component={LoginPage} />
-        <SecureRoute authLevel={'admin'} path="/admin" component={AdminPage} />
+        <SecureRoute authLevel="login" exact path="/" component={LoginPage} />
+        <SecureRoute authLevel="admin" path="/admin" component={AdminPage} />
         <SecureRoute
-          authLevel={'admin'}
+          authLevel="admin"
           path="/editor/competition-id=:competitionId"
           component={PresentationEditorPage}
         />
-        <SecureRoute authLevel={'competition'} exact path="/:code" component={ViewSelectPage} />
+        <Route exact path="/:code" component={ViewSelectPage} />
         <SecureRoute
-          authLevel={'competition'}
+          authLevel="competition"
           exact
           path="/team/competition-id=:competitionId"
-          component={ParticipantViewPage}
+          component={TeamViewPage}
         />
         <SecureRoute
-          authLevel={'competition'}
+          authLevel="competition"
           exact
           path="/operator/competition-id=:competitionId"
-          component={PresenterViewPage}
+          component={OperatorViewPage}
         />
         <SecureRoute
-          authLevel={'competition'}
+          authLevel="competition"
           exact
           path="/judge/competition-id=:competitionId"
           component={JudgeViewPage}
         />
         <SecureRoute
-          authLevel={'competition'}
+          authLevel="competition"
           exact
           path="/audience/competition-id=:competitionId"
           component={AudienceViewPage}
diff --git a/client/src/actions/competitionLogin.ts b/client/src/actions/competitionLogin.ts
index ed75e71133ba9c28e83432c50b4fca04bd4637b2..448eec249f360acbadeb6161abac6412daccb32b 100644
--- a/client/src/actions/competitionLogin.ts
+++ b/client/src/actions/competitionLogin.ts
@@ -8,7 +8,9 @@ import { AppDispatch } from '../store'
 import Types from './types'
 
 // Action creator to attempt to login with competition code
-export const loginCompetition = (code: string, history: History) => async (dispatch: AppDispatch) => {
+export const loginCompetition = (code: string, history: History, redirect: boolean) => async (
+  dispatch: AppDispatch
+) => {
   dispatch({ type: Types.LOADING_COMPETITION_LOGIN })
   await axios
     .post('/api/auth/login/code', { code })
@@ -16,10 +18,16 @@ export const loginCompetition = (code: string, history: History) => async (dispa
       const token = `Bearer ${res.data.access_token}`
       localStorage.setItem('competitionToken', token) //setting token to local storage
       axios.defaults.headers.common['Authorization'] = token //setting authorize token to header in axios
-      console.log(code, res.data)
       dispatch({ type: Types.CLEAR_COMPETITION_LOGIN_ERRORS }) // no error
-      // history.push('/admin') //redirecting to admin page after login success
-      if (res.data && res.data.view_type_id) {
+      dispatch({
+        type: Types.SET_COMPETITION_LOGIN_DATA,
+        payload: {
+          competition_id: res.data.competition_id,
+          team_id: res.data.team_id,
+          view: res.data.view,
+        },
+      })
+      if (redirect && res.data && res.data.view_type_id) {
         history.push(`/${code}`)
       }
     })
@@ -31,7 +39,7 @@ export const loginCompetition = (code: string, history: History) => async (dispa
 
 // Log out from competition and remove jwt token from local storage and axios
 export const logoutCompetition = () => async (dispatch: AppDispatch) => {
-  localStorage.removeItem('token')
+  localStorage.removeItem('competitionToken')
   await axios.post('/api/auth/logout').then(() => {
     delete axios.defaults.headers.common['Authorization']
     dispatch({
diff --git a/client/src/actions/editor.ts b/client/src/actions/editor.ts
index db688dcb59f3732c6bda801b0aada1b3063a1238..526ad9ff6ae1698644e32ea02806c7a6e8e2cd78 100644
--- a/client/src/actions/editor.ts
+++ b/client/src/actions/editor.ts
@@ -18,16 +18,28 @@ export const getEditorCompetition = (id: string) => async (dispatch: AppDispatch
       if (getState().editor.activeSlideId === -1 && res.data.slides[0]) {
         setEditorSlideId(res.data.slides[0].id)(dispatch)
       }
+      const defaultViewType = getState().types.viewTypes.find((viewType) => viewType.name === 'Audience')
+      if (getState().editor.activeViewTypeId === -1 && defaultViewType) {
+        setEditorViewId(defaultViewType.id)(dispatch)
+      }
     })
     .catch((err) => {
       console.log(err)
     })
 }
 
-// Set currentSlideId in editor state
+// Set activeSlideId in editor state
 export const setEditorSlideId = (id: number) => (dispatch: AppDispatch) => {
   dispatch({
     type: Types.SET_EDITOR_SLIDE_ID,
     payload: id,
   })
 }
+
+// Set activeViewTypeId in editor state
+export const setEditorViewId = (id: number) => (dispatch: AppDispatch) => {
+  dispatch({
+    type: Types.SET_EDITOR_VIEW_ID,
+    payload: id,
+  })
+}
diff --git a/client/src/actions/types.ts b/client/src/actions/types.ts
index 815e9d48c71a4e87409b79d635f198f3b4c8333d..b422f95423539cc2f2ea0bf4e7ecdc58f78bdbc8 100644
--- a/client/src/actions/types.ts
+++ b/client/src/actions/types.ts
@@ -14,6 +14,7 @@ export default {
   SET_SEARCH_USERS_TOTAL_COUNT: 'SET_SEARCH_USERS_TOTAL_COUNT',
   SET_ERRORS: 'SET_ERRORS',
   CLEAR_ERRORS: 'CLEAR_ERRORS',
+  SET_COMPETITION_LOGIN_DATA: 'SET_COMPETITION_LOGIN_DATA',
   SET_COMPETITION_LOGIN_AUTHENTICATED: 'SET_COMPETITION_LOGIN_AUTHENTICATED',
   SET_COMPETITION_LOGIN_UNAUTHENTICATED: 'SET_COMPETITION_LOGIN_UNAUTHENTICATED',
   SET_COMPETITION_LOGIN_ERRORS: 'SET_COMPETITION_LOGIN_ERRORS',
@@ -26,6 +27,7 @@ export default {
   SET_COMPETITIONS_COUNT: 'SET_COMPETITIONS_COUNT',
   SET_EDITOR_COMPETITION: 'SET_EDITOR_COMPETITION',
   SET_EDITOR_SLIDE_ID: 'SET_EDITOR_SLIDE_ID',
+  SET_EDITOR_VIEW_ID: 'SET_EDITOR_VIEW_ID',
   SET_PRESENTATION_COMPETITION: 'SET_PRESENTATION_COMPETITION',
   SET_PRESENTATION_SLIDE: 'SET_PRESENTATION_SLIDE',
   SET_PRESENTATION_SLIDE_PREVIOUS: 'SET_PRESENTATION_SLIDE_PREVIOUS',
diff --git a/client/src/interfaces/ApiModels.ts b/client/src/interfaces/ApiModels.ts
index 06fdee0afa3b467c5d0fe21f525b9ca7ec5e6a6a..a6fa68a0e9b58dcc63ad67d29884bbf3e781a64a 100644
--- a/client/src/interfaces/ApiModels.ts
+++ b/client/src/interfaces/ApiModels.ts
@@ -80,6 +80,8 @@ export interface Component {
   w: number
   h: number
   type_id: number
+  view_type_id: number
+  slide_id: number
 }
 
 export interface ImageComponent extends Component {
diff --git a/client/src/interfaces/ViewParams.ts b/client/src/interfaces/ViewParams.ts
index e9aa6a5c5f81a6bf852f8caa30443a793b0dddd7..b8114216500b3295050a0b62f6188fa065fcbfdb 100644
--- a/client/src/interfaces/ViewParams.ts
+++ b/client/src/interfaces/ViewParams.ts
@@ -1,4 +1,3 @@
 export interface ViewParams {
-  id: string
-  code: string
+  competitionId: string
 }
diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx
index 83f399b95a0c083727333c2f842a1c61a8eca2d0..8ec3ee2981277a3f150642410581d472602e65ed 100644
--- a/client/src/pages/admin/competitions/CompetitionManager.tsx
+++ b/client/src/pages/admin/competitions/CompetitionManager.tsx
@@ -94,7 +94,7 @@ const CompetitionManager: React.FC = (props: any) => {
   }
 
   const handleStartCompetition = () => {
-    history.push(`/presenter/id=${activeId}&code=123123`)
+    history.push(`/operator/id=${activeId}&code=123123`)
     console.log('GLHF!')
   }
 
diff --git a/client/src/pages/login/components/CompetitionLogin.tsx b/client/src/pages/login/components/CompetitionLogin.tsx
index d89cafcf8216197de081d65550116e2e06b56f22..8dbbee33b6962c5bcd21f346ee594b224719a9a7 100644
--- a/client/src/pages/login/components/CompetitionLogin.tsx
+++ b/client/src/pages/login/components/CompetitionLogin.tsx
@@ -1,9 +1,8 @@
 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 { Formik } from 'formik'
+import React from 'react'
 import { useHistory } from 'react-router-dom'
-import React, { useEffect, useState } from 'react'
 import * as Yup from 'yup'
 import { loginCompetition } from '../../../actions/competitionLogin'
 import { useAppDispatch, useAppSelector } from '../../../hooks'
@@ -37,8 +36,9 @@ const CompetitionLogin: React.FC = () => {
     model: { code: '' },
   }
   const handleCompetitionSubmit = async (values: CompetitionLoginFormModel) => {
-    dispatch(loginCompetition(values.model.code, history))
+    dispatch(loginCompetition(values.model.code, history, true))
   }
+  
   return (
     <Formik
       initialValues={competitionInitialValues}
diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
index c645724e3c7fabda69a2ad2434f4bd7b587c8c2e..5426152ff33783745f8dc1181237cd2926b0a16a 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx
@@ -27,8 +27,19 @@ it('renders presentation editor', () => {
       ],
     },
   }
+  const typesRes: any = {
+    data: {
+      view_types: [
+        {
+          name: '',
+          id: 0,
+        },
+      ],
+    },
+  }
   ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
     if (path.startsWith('/api/competitions')) return Promise.resolve(competitionRes)
+    if (path.startsWith('/api/misc/types')) return Promise.resolve(typesRes)
     return Promise.resolve(citiesRes)
   })
   render(
diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
index cd9d22c2055af4b4ddded3260db8b124b9124e6d..80d35c5f38c8b879976b91204f9572ac9cf5735a 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
@@ -10,7 +10,7 @@ import axios from 'axios'
 import React, { useEffect, useState } from 'react'
 import { Link, useParams } from 'react-router-dom'
 import { getCities } from '../../actions/cities'
-import { getEditorCompetition, setEditorSlideId } from '../../actions/editor'
+import { getEditorCompetition, setEditorSlideId, setEditorViewId } from '../../actions/editor'
 import { getTypes } from '../../actions/typesAction'
 import { useAppDispatch, useAppSelector } from '../../hooks'
 import { RichSlide } from '../../interfaces/ApiRichModels'
@@ -27,6 +27,7 @@ import {
   SlideListItem,
   ToolBarContainer,
   ViewButton,
+  ViewButtonClicked,
   ViewButtonGroup,
 } from './styled'
 
@@ -88,12 +89,13 @@ const PresentationEditorPage: React.FC = () => {
   const { competitionId }: CompetitionParams = useParams()
   const dispatch = useAppDispatch()
   const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
+  const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId)
   const competition = useAppSelector((state) => state.editor.competition)
   const competitionLoading = useAppSelector((state) => state.editor.loading)
   useEffect(() => {
+    dispatch(getTypes())
     dispatch(getEditorCompetition(competitionId))
     dispatch(getCities())
-    dispatch(getTypes())
   }, [])
 
   const setActiveSlideId = (id: number) => {
@@ -147,6 +149,16 @@ const PresentationEditorPage: React.FC = () => {
   })((props: CheckboxProps) => <Checkbox color="default" {...props} />)
   const [checkbox, setCheckbox] = useState(false)
 
+  const viewTypes = useAppSelector((state) => state.types.viewTypes)
+  const [activeViewTypeName, setActiveViewTypeName] = useState('')
+  const changeView = (clickedViewTypeName: string) => {
+    setActiveViewTypeName(clickedViewTypeName)
+    const clickedViewTypeId = viewTypes.find((viewType) => viewType.name === clickedViewTypeName)?.id
+    if (clickedViewTypeId) {
+      dispatch(setEditorViewId(clickedViewTypeId))
+    }
+  }
+
   return (
     <PresentationEditorContainer>
       <CssBaseline />
@@ -164,10 +176,20 @@ const PresentationEditorPage: React.FC = () => {
             <Typography className={classes.alignCheckboxText} variant="button">
               Applicera ändringar på samtliga vyer
             </Typography>
-            <ViewButton variant="contained" color="secondary">
+            <ViewButton
+              $activeView={activeViewTypeName === 'Audience'}
+              variant="contained"
+              color="secondary"
+              onClick={() => changeView('Audience')}
+            >
               Åskådarvy
             </ViewButton>
-            <ViewButton variant="contained" color="secondary">
+            <ViewButton
+              $activeView={activeViewTypeName === 'Team'}
+              variant="contained"
+              color="secondary"
+              onClick={() => changeView('Team')}
+            >
               Deltagarvy
             </ViewButton>
           </ViewButtonGroup>
@@ -229,7 +251,7 @@ const PresentationEditorPage: React.FC = () => {
 
       <Content leftDrawerWidth={leftDrawerWidth} rightDrawerWidth={rightDrawerWidth}>
         <InnerContent>
-          <SlideDisplay editor />
+          <SlideDisplay variant="editor" activeViewTypeId={activeViewTypeId} />
         </InnerContent>
       </Content>
       <Menu
diff --git a/client/src/pages/presentationEditor/components/BackgroundImageSelect.tsx b/client/src/pages/presentationEditor/components/BackgroundImageSelect.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..14dbaa63ed2cc267a080264ebe3d7abd243220ba
--- /dev/null
+++ b/client/src/pages/presentationEditor/components/BackgroundImageSelect.tsx
@@ -0,0 +1,126 @@
+import { ListItem, ListItemText, Typography } from '@material-ui/core'
+import React, { useState } from 'react'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
+import {
+  AddButton,
+  AddBackgroundButton,
+  Center,
+  HiddenInput,
+  ImportedImage,
+  SettingsList,
+  ImageNameText,
+  ImageTextContainer,
+} from './styled'
+import CloseIcon from '@material-ui/icons/Close'
+import axios from 'axios'
+import { Media } from '../../../interfaces/ApiModels'
+import { getEditorCompetition } from '../../../actions/editor'
+import { uploadFile } from '../../../utils/uploadImage'
+
+type BackgroundImageSelectProps = {
+  variant: 'competition' | 'slide'
+}
+
+const BackgroundImageSelect = ({ variant }: BackgroundImageSelectProps) => {
+  const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
+  const backgroundImage = useAppSelector((state) => {
+    if (variant === 'competition') return state.editor.competition.background_image
+    else return state.editor.competition.slides.find((slide) => slide.id === activeSlideId)?.background_image
+  })
+  const competitionId = useAppSelector((state) => state.editor.competition.id)
+  const dispatch = useAppDispatch()
+
+  const updateBackgroundImage = async (mediaId: number) => {
+    // Creates a new image component on the database using API call.
+    if (variant === 'competition') {
+      await axios
+        .put(`/api/competitions/${competitionId}`, { background_image_id: mediaId })
+        .then(() => {
+          dispatch(getEditorCompetition(competitionId.toString()))
+        })
+        .catch(console.log)
+    } else {
+      await axios
+        .put(`/api/competitions/${competitionId}/slides/${activeSlideId}`, { background_image_id: mediaId })
+        .then(() => {
+          dispatch(getEditorCompetition(competitionId.toString()))
+        })
+        .catch(console.log)
+    }
+  }
+
+  const removeBackgroundImage = async () => {
+    // Removes background image media and from competition using API calls.
+    await axios.delete(`/api/media/images/${backgroundImage?.id}`).catch(console.log)
+    if (variant === 'competition') {
+      await axios
+        .put(`/api/competitions/${competitionId}`, { background_image_id: null })
+        .then(() => {
+          dispatch(getEditorCompetition(competitionId.toString()))
+        })
+        .catch(console.log)
+    } else {
+      await axios
+        .put(`/api/competitions/${competitionId}/slides/${activeSlideId}`, { background_image_id: null })
+        .then(() => {
+          dispatch(getEditorCompetition(competitionId.toString()))
+        })
+        .catch(console.log)
+    }
+  }
+
+  const handleFileSelected = async (e: React.ChangeEvent<HTMLInputElement>) => {
+    // Reads the selected image file and uploads it to the server.
+    // Creates a new image component containing the file.
+    if (e.target.files !== null && e.target.files[0]) {
+      const files = Array.from(e.target.files)
+      const file = files[0]
+      const formData = new FormData()
+      formData.append('image', file)
+      const media = await uploadFile(formData, competitionId.toString())
+      if (media) {
+        updateBackgroundImage(media.id)
+      }
+    }
+  }
+
+  return (
+    <SettingsList>
+      {!backgroundImage && (
+        <ListItem button style={{ padding: 0 }}>
+          <HiddenInput
+            accept="image/*"
+            id="background-button-file"
+            multiple
+            type="file"
+            onChange={handleFileSelected}
+          />
+          <AddBackgroundButton htmlFor="background-button-file">
+            <Center>
+              <AddButton variant="button">Välj bakgrundsbild...</AddButton>
+            </Center>
+          </AddBackgroundButton>
+        </ListItem>
+      )}
+      {backgroundImage && (
+        <>
+          <ListItem divider>
+            <ImageTextContainer>
+              <ListItemText>Bakgrundsbild</ListItemText>
+              <Typography variant="body2">(Bilden bör ha sidförhållande 16:9)</Typography>
+            </ImageTextContainer>
+          </ListItem>
+          <ListItem divider button>
+            <ImportedImage src={`/static/images/thumbnail_${backgroundImage.filename}`} />
+            <Center>
+              <ImageNameText primary={backgroundImage.filename} />
+            </Center>
+            <CloseIcon onClick={removeBackgroundImage} />
+          </ListItem>
+        </>
+      )}
+    </SettingsList>
+  )
+}
+
+export default BackgroundImageSelect
diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
index 7ea2a84f99171fd75555e606abe2681a7f3c0c0d..9482b660550e729f2a5a4c443d0f935193679b1f 100644
--- a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
+++ b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
@@ -17,6 +17,7 @@ import { getEditorCompetition } from '../../../actions/editor'
 import { useAppDispatch, useAppSelector } from '../../../hooks'
 import { City } from '../../../interfaces/ApiModels'
 import Teams from './Teams'
+import BackgroundImageSelect from './BackgroundImageSelect'
 
 interface CompetitionParams {
   competitionId: string
@@ -92,17 +93,7 @@ const CompetitionSettings: React.FC = () => {
 
       <Teams competitionId={competitionId} />
 
-      <SettingsList>
-        <ListItem button>
-          <ImportedImage
-            id="temp source, todo: add image source to elements of pictureList"
-            src="https://i1.wp.com/stickoutmedia.se/wp-content/uploads/2021/01/placeholder-3.png?ssl=1"
-          />
-          <Center>
-            <ListItemText>Välj bakgrundsbild ...</ListItemText>
-          </Center>
-        </ListItem>
-      </SettingsList>
+      <BackgroundImageSelect variant="competition" />
     </PanelContainer>
   )
 }
diff --git a/client/src/pages/presentationEditor/components/RndComponent.tsx b/client/src/pages/presentationEditor/components/RndComponent.tsx
index e1cbc0f21652fe4eb65ed45fc65896c0c9f1bbab..8f2324c93a36d8e246043a4b5adeaec990f88dae 100644
--- a/client/src/pages/presentationEditor/components/RndComponent.tsx
+++ b/client/src/pages/presentationEditor/components/RndComponent.tsx
@@ -1,15 +1,13 @@
-import { Button, Card, IconButton, Tooltip, Typography } from '@material-ui/core'
+import { Card, IconButton, Tooltip } from '@material-ui/core'
 import axios from 'axios'
 import React, { useEffect, useState } from 'react'
 import { Rnd } from 'react-rnd'
 import { ComponentTypes } from '../../../enum/ComponentTypes'
 import { useAppSelector } from '../../../hooks'
-import { Component, ImageComponent, QuestionAlternativeComponent, TextComponent } from '../../../interfaces/ApiModels'
+import { Component, ImageComponent, TextComponent } from '../../../interfaces/ApiModels'
 import { Position, Size } from '../../../interfaces/Components'
-import CheckboxComponent from './CheckboxComponent'
 import ImageComponentDisplay from './ImageComponentDisplay'
 import { HoverContainer } from './styled'
-import FormatAlignCenterIcon from '@material-ui/icons/FormatAlignCenter'
 import TextComponentDisplay from './TextComponentDisplay'
 
 type RndComponentProps = {
@@ -26,6 +24,9 @@ const RndComponent = ({ component, width, height, scale }: RndComponentProps) =>
   const competitionId = useAppSelector((state) => state.editor.competition.id)
   const slideId = useAppSelector((state) => state.editor.activeSlideId)
   const [shiftPressed, setShiftPressed] = useState(false)
+  const typeName = useAppSelector(
+    (state) => state.types.componentTypes.find((componentType) => componentType.id === component.type_id)?.name
+  )
   const handleUpdatePos = (pos: Position) => {
     axios.put(`/api/competitions/${competitionId}/slides/${slideId}/components/${component.id}`, {
       x: pos.x,
@@ -39,13 +40,11 @@ const RndComponent = ({ component, width, height, scale }: RndComponentProps) =>
     })
   }
   const handleCenterHorizontal = () => {
-    console.log(width, currentSize.w)
     const centerX = width / (2 * scale) - currentSize.w / 2
     setCurrentPos({ x: centerX, y: currentPos.y })
     handleUpdatePos({ x: centerX, y: currentPos.y })
   }
   const handleCenterVertical = () => {
-    console.log(height, currentSize.h)
     const centerY = height / (2 * scale) - currentSize.h / 2
     setCurrentPos({ x: currentPos.x, y: centerY })
     handleUpdatePos({ x: currentPos.x, y: centerY })
@@ -98,6 +97,8 @@ const RndComponent = ({ component, width, height, scale }: RndComponentProps) =>
         setCurrentPos({ x: d.x / scale, y: d.y / scale })
         handleUpdatePos({ x: d.x / scale, y: d.y / scale })
       }}
+      //Makes text appear on images
+      style={{ zIndex: typeName === 'Text' ? 2 : 1 }}
       lockAspectRatio={shiftPressed}
       onMouseEnter={() => setHover(true)}
       onMouseLeave={() => setHover(false)}
@@ -114,6 +115,7 @@ const RndComponent = ({ component, width, height, scale }: RndComponentProps) =>
           w: ref.offsetWidth / scale,
           h: ref.offsetHeight / scale,
         })
+        setCurrentPos({ x: position.x / scale, y: position.y / scale })
       }}
     >
       {hover && (
diff --git a/client/src/pages/presentationEditor/components/SlideDisplay.tsx b/client/src/pages/presentationEditor/components/SlideDisplay.tsx
index f134d0a8ff4e8fef092ae4b92ef8e6b07fa38a71..aef4ca7c48d29bbfc47cac8f29b214ec6866f360 100644
--- a/client/src/pages/presentationEditor/components/SlideDisplay.tsx
+++ b/client/src/pages/presentationEditor/components/SlideDisplay.tsx
@@ -1,4 +1,3 @@
-import { Button, Typography } from '@material-ui/core'
 import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'
 import { getTypes } from '../../../actions/typesAction'
 import { useAppDispatch, useAppSelector } from '../../../hooks'
@@ -8,15 +7,27 @@ import { SlideEditorContainer, SlideEditorContainerRatio, SlideEditorPaper } fro
 
 type SlideDisplayProps = {
   //Prop to distinguish between editor and active competition
-  editor?: boolean | undefined
+  variant: 'editor' | 'presentation'
+  activeViewTypeId: number
 }
 
-const SlideDisplay = ({ editor }: SlideDisplayProps) => {
+const SlideDisplay = ({ variant, activeViewTypeId }: SlideDisplayProps) => {
   const components = useAppSelector((state) => {
-    if (editor)
+    if (variant === 'editor')
       return state.editor.competition.slides.find((slide) => slide.id === state.editor.activeSlideId)?.components
     return state.presentation.competition.slides.find((slide) => slide.id === state.presentation.slide?.id)?.components
   })
+  const competitionBackgroundImage = useAppSelector((state) => {
+    if (variant === 'editor') return state.editor.competition.background_image
+    return state.presentation.competition.background_image
+  })
+
+  const slideBackgroundImage = useAppSelector((state) => {
+    if (variant === 'editor')
+      return state.editor.competition.slides.find((slide) => slide.id === state.editor.activeSlideId)?.background_image
+    return state.presentation.competition.slides.find((slide) => slide.id === state.presentation.slide.id)
+      ?.background_image
+  })
   const dispatch = useAppDispatch()
   const editorPaperRef = useRef<HTMLDivElement>(null)
   const [width, setWidth] = useState(0)
@@ -42,22 +53,40 @@ const SlideDisplay = ({ editor }: SlideDisplayProps) => {
     <SlideEditorContainer>
       <SlideEditorContainerRatio>
         <SlideEditorPaper ref={editorPaperRef}>
+          {(competitionBackgroundImage || slideBackgroundImage) && (
+            <img
+              src={`/static/images/${
+                slideBackgroundImage ? slideBackgroundImage.filename : competitionBackgroundImage?.filename
+              }`}
+              height={height}
+              width={width}
+              draggable={false}
+            />
+          )}
           {components &&
-            components.map((component) => {
-              if (editor)
+            components
+              .filter((component) => component.view_type_id === activeViewTypeId)
+              .map((component) => {
+                if (variant === 'editor')
+                  return (
+                    <RndComponent
+                      height={height}
+                      width={width}
+                      key={component.id}
+                      component={component}
+                      scale={scale}
+                    />
+                  )
                 return (
-                  <RndComponent height={height} width={width} key={component.id} component={component} scale={scale} />
+                  <PresentationComponent
+                    height={height}
+                    width={width}
+                    key={component.id}
+                    component={component}
+                    scale={scale}
+                  />
                 )
-              return (
-                <PresentationComponent
-                  height={height}
-                  width={width}
-                  key={component.id}
-                  component={component}
-                  scale={scale}
-                />
-              )
-            })}
+              })}
         </SlideEditorPaper>
       </SlideEditorContainerRatio>
     </SlideEditorContainer>
diff --git a/client/src/pages/presentationEditor/components/SlideSettings.tsx b/client/src/pages/presentationEditor/components/SlideSettings.tsx
index 278887c1cb8b841224704ceb1f2e1bb9fa5c7b6a..d48b4565712d043d52d3b1e93e3633ec6b927d38 100644
--- a/client/src/pages/presentationEditor/components/SlideSettings.tsx
+++ b/client/src/pages/presentationEditor/components/SlideSettings.tsx
@@ -12,6 +12,7 @@ import Timer from './slideSettingsComponents/Timer'
 import Images from './slideSettingsComponents/Images'
 import Texts from './slideSettingsComponents/Texts'
 import QuestionSettings from './slideSettingsComponents/QuestionSettings'
+import BackgroundImageSelect from './BackgroundImageSelect'
 
 interface CompetitionParams {
   competitionId: string
@@ -24,6 +25,7 @@ const SlideSettings: React.FC = () => {
     // Gets the slide with id=activeSlideId from the database.
     state.editor.competition.slides.find((slide) => slide && slide.id === state.editor.activeSlideId)
   )
+  const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId)
 
   return (
     <PanelContainer>
@@ -47,21 +49,15 @@ const SlideSettings: React.FC = () => {
         <MultipleChoiceAlternatives activeSlide={activeSlide} competitionId={competitionId} />
       )}
 
-      {activeSlide && <Texts activeSlide={activeSlide} competitionId={competitionId} />}
+      {activeSlide && (
+        <Texts activeViewTypeId={activeViewTypeId} activeSlide={activeSlide} competitionId={competitionId} />
+      )}
 
-      {activeSlide && <Images activeSlide={activeSlide} competitionId={competitionId} />}
+      {activeSlide && (
+        <Images activeViewTypeId={activeViewTypeId} activeSlide={activeSlide} competitionId={competitionId} />
+      )}
 
-      <SettingsList>
-        <ListItem button>
-          <ImportedImage
-            id="temp source, todo: add image source to elements of pictureList"
-            src="https://i1.wp.com/stickoutmedia.se/wp-content/uploads/2021/01/placeholder-3.png?ssl=1"
-          />
-          <Center>
-            <ListItemText>Välj bakgrundsbild ...</ListItemText>
-          </Center>
-        </ListItem>
-      </SettingsList>
+      <BackgroundImageSelect variant="slide" />
     </PanelContainer>
   )
 }
diff --git a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
index b03696f37987a83347f57fb81c6b25febcb84824..04ddd6daa7bb015b3e48b905b3f17f3594c8ba98 100644
--- a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
+++ b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
@@ -20,6 +20,7 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => {
   const [content, setContent] = useState('')
   const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined)
   const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
+  const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId)
   const dispatch = useAppDispatch()
 
   useEffect(() => {
@@ -35,7 +36,6 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => {
     //Only updates 250ms after last input was made to not spam
     setTimerHandle(
       window.setTimeout(async () => {
-        console.log('Content was updated on server. id: ', component.id)
         await axios.put(`/api/competitions/${competitionId}/slides/${activeSlideId}/components/${component.id}`, {
           text: newText,
         })
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
index fa087dccbb39c77a0a2e433d5a6a6c8b4d201fd1..49f41e7f87fa6c53dac59704540ca3c186ef708b 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
@@ -11,11 +11,12 @@ import { ImageComponent, Media } from '../../../../interfaces/ApiModels'
 import { useAppDispatch, useAppSelector } from '../../../../hooks'
 
 type ImagesProps = {
+  activeViewTypeId: number
   activeSlide: RichSlide
   competitionId: string
 }
 
-const Images = ({ activeSlide, competitionId }: ImagesProps) => {
+const Images = ({ activeViewTypeId, activeSlide, competitionId }: ImagesProps) => {
   const dispatch = useAppDispatch()
 
   const uploadFile = async (formData: FormData) => {
@@ -37,6 +38,7 @@ const Images = ({ activeSlide, competitionId }: ImagesProps) => {
       y: 0,
       media_id: media.id,
       type_id: 2,
+      view_type_id: activeViewTypeId,
     }
     await axios
       .post(`/api/competitions/${competitionId}/slides/${activeSlide?.id}/components`, imageData)
@@ -56,7 +58,7 @@ const Images = ({ activeSlide, competitionId }: ImagesProps) => {
       formData.append('image', file)
       const response = await uploadFile(formData)
       if (response) {
-        const newComponent = createImageComponent(response)
+        createImageComponent(response)
       }
     }
   }
@@ -94,17 +96,19 @@ const Images = ({ activeSlide, competitionId }: ImagesProps) => {
         </Center>
       </ListItem>
       {images &&
-        images.map((image) => (
-          <div key={image.id}>
-            <ListItem divider button>
-              <ImportedImage src={`http://localhost:5000/static/images/thumbnail_${image.media?.filename}`} />
-              <Center>
-                <ListItemText primary={image.media?.filename} />
-              </Center>
-              <CloseIcon onClick={() => handleCloseimageClick(image)} />
-            </ListItem>
-          </div>
-        ))}
+        images
+          .filter((image) => image.view_type_id === activeViewTypeId)
+          .map((image) => (
+            <div key={image.id}>
+              <ListItem divider button>
+                <ImportedImage src={`http://localhost:5000/static/images/thumbnail_${image.media?.filename}`} />
+                <Center>
+                  <ListItemText primary={image.media?.filename} />
+                </Center>
+                <CloseIcon onClick={() => handleCloseimageClick(image)} />
+              </ListItem>
+            </div>
+          ))}
 
       <ListItem button style={{ padding: 0 }}>
         <HiddenInput accept="image/*" id="contained-button-file" multiple type="file" onChange={handleFileSelected} />
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
index 858dd75e65dc554cc6e1c2083f46873a925335a1..7d609300966a6f6e5141685f1fbaed7e0298d7ba 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
@@ -1,4 +1,4 @@
-import { ListItem, ListItemText, TextField, withStyles } from '@material-ui/core'
+import { ListItem, ListItemText, TextField } from '@material-ui/core'
 import axios from 'axios'
 import React from 'react'
 import { getEditorCompetition } from '../../../../actions/editor'
@@ -23,7 +23,6 @@ const Instructions = ({ activeSlide, competitionId }: InstructionsProps) => {
     //Only updates 250ms after last input was made to not spam
     setTimerHandle(
       window.setTimeout(async () => {
-        console.log('Content was updated on server. id: ', activeSlide.questions[0].id)
         if (activeSlide && activeSlide.questions[0]) {
           await axios
             // TODO: Implement instructions field in question and add put API
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
index 2bc10b3588133245d54767dbbc7d8381e4134b59..e917afbd19f1aac2d7256c1f5913d8a63f323ee1 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
@@ -18,7 +18,6 @@ const QuestionSettings = ({ activeSlide, competitionId }: QuestionSettingsProps)
     updateTitle: boolean,
     event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
   ) => {
-    console.log('Content was updated on server. id: ', activeSlide.questions[0].id)
     if (activeSlide && activeSlide.questions[0]) {
       if (updateTitle) {
         await axios
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
index 39cf09af3ca31b73f30c258570e28365117a4282..03656614e3076e6048984e70b7ddd0ae711a492d 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
@@ -9,11 +9,12 @@ import axios from 'axios'
 import { getEditorCompetition } from '../../../../actions/editor'
 
 type TextsProps = {
+  activeViewTypeId: number
   activeSlide: RichSlide
   competitionId: string
 }
 
-const Texts = ({ activeSlide, competitionId }: TextsProps) => {
+const Texts = ({ activeViewTypeId, activeSlide, competitionId }: TextsProps) => {
   const texts = useAppSelector(
     (state) =>
       state.editor.competition.slides
@@ -29,6 +30,7 @@ const Texts = ({ activeSlide, competitionId }: TextsProps) => {
         text: 'Ny text',
         w: 315,
         h: 50,
+        view_type_id: activeViewTypeId,
       })
       dispatch(getEditorCompetition(competitionId))
     }
@@ -42,12 +44,14 @@ const Texts = ({ activeSlide, competitionId }: TextsProps) => {
         </Center>
       </ListItem>
       {texts &&
-        texts.map((text) => (
-          <TextCard elevation={4} key={text.id}>
-            <TextComponentEdit component={text} />
-            <Divider />
-          </TextCard>
-        ))}
+        texts
+          .filter((text) => text.view_type_id === activeViewTypeId)
+          .map((text) => (
+            <TextCard elevation={4} key={text.id}>
+              <TextComponentEdit component={text} />
+              <Divider />
+            </TextCard>
+          ))}
       <ListItem button onClick={handleAddText}>
         <Center>
           <AddButton variant="button">Lägg till text</AddButton>
diff --git a/client/src/pages/presentationEditor/components/styled.tsx b/client/src/pages/presentationEditor/components/styled.tsx
index 7255c2bbc8a57475662191cd57428986a105348b..605972d2c4ee798388f9437f373cbabeab777d3c 100644
--- a/client/src/pages/presentationEditor/components/styled.tsx
+++ b/client/src/pages/presentationEditor/components/styled.tsx
@@ -9,6 +9,7 @@ import {
   ListItem,
   Select,
   InputLabel,
+  ListItemText,
 } from '@material-ui/core'
 import styled from 'styled-components'
 
@@ -71,6 +72,14 @@ export const Center = styled.div`
   width: 100%;
 `
 
+export const ImageTextContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+`
+
 export const PanelContainer = styled.div`
   padding: 10px;
   width: 100%;
@@ -91,7 +100,16 @@ export const Clickable = styled.div`
 
 export const AddImageButton = styled.label`
   padding: 8px 13px 8px 13px;
-  cursor: 'pointer';
+  display: flex;
+  justify-content: center;
+  text-align: center;
+  height: 100%;
+  width: 100%;
+  cursor: pointer;
+`
+
+export const AddBackgroundButton = styled.label`
+  padding: 16px 29px 16px 29px;
   display: flex;
   justify-content: center;
   text-align: center;
@@ -126,3 +144,7 @@ export const HoverContainer = styled.div<HoverContainerProps>`
   padding: ${(props) => (props.hover ? 0 : 1)}px;
   border: solid ${(props) => (props.hover ? 1 : 0)}px;
 `
+
+export const ImageNameText = styled(ListItemText)`
+  word-break: break-all;
+`
diff --git a/client/src/pages/presentationEditor/styled.tsx b/client/src/pages/presentationEditor/styled.tsx
index d1f05d6bf18de2eccc6b486fb6e94701acce3b5c..f68eb166043c970cb5f6e69bc57b090790b1d607 100644
--- a/client/src/pages/presentationEditor/styled.tsx
+++ b/client/src/pages/presentationEditor/styled.tsx
@@ -7,8 +7,18 @@ export const ToolBarContainer = styled(Toolbar)`
   padding-left: 0;
 `
 
-export const ViewButton = styled(Button)`
+interface ViewButtonProps {
+  $activeView: boolean
+}
+
+export const ViewButton = styled(Button)<ViewButtonProps>`
+  margin-right: 8px;
+  background: ${(props) => (props.$activeView ? '#5a0017' : undefined)};
+`
+
+export const ViewButtonClicked = styled(Button)`
   margin-right: 8px;
+  background: #5a0017;
 `
 
 export const ViewButtonGroup = styled.div`
diff --git a/client/src/pages/views/AudienceViewPage.tsx b/client/src/pages/views/AudienceViewPage.tsx
index 8d58a364e6d4688da1b0dcff5290a60486250de1..48b92c4686c762536c629e1c33f5bb33ade9cc59 100644
--- a/client/src/pages/views/AudienceViewPage.tsx
+++ b/client/src/pages/views/AudienceViewPage.tsx
@@ -1,16 +1,36 @@
-import React from 'react'
+import { Typography } from '@material-ui/core'
+import React, { useEffect } from 'react'
+import { useParams } from 'react-router-dom'
+import { getPresentationCompetition } from '../../actions/presentation'
+import { useAppDispatch, useAppSelector } from '../../hooks'
+import { ViewParams } from '../../interfaces/ViewParams'
+import { socketConnect, socketJoinPresentation } from '../../sockets'
 import SlideDisplay from '../presentationEditor/components/SlideDisplay'
-import PresentationComponent from './components/PresentationComponent'
-import mockedAxios from 'axios'
+import { PresentationBackground, PresentationContainer } from './styled'
 
 const AudienceViewPage: React.FC = () => {
-  const res = {
-    data: {},
+  const { competitionId }: ViewParams = useParams()
+  const code = useAppSelector((state) => state.presentation.code)
+  const dispatch = useAppDispatch()
+  const viewTypes = useAppSelector((state) => state.types.viewTypes)
+  const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Audience')?.id
+  useEffect(() => {
+    dispatch(getPresentationCompetition(competitionId))
+    if (code && code !== '') {
+      socketConnect()
+      socketJoinPresentation()
+    }
+  }, [])
+  if (activeViewTypeId) {
+    return (
+      <PresentationBackground>
+        <PresentationContainer>
+          <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />
+        </PresentationContainer>
+      </PresentationBackground>
+    )
   }
-  ;(mockedAxios.get as jest.Mock).mockImplementation(() => {
-    return Promise.resolve(res)
-  })
-  return <SlideDisplay />
+  return <Typography>Error: Åskådarvyn kunde inte laddas</Typography>
 }
 
 export default AudienceViewPage
diff --git a/client/src/pages/views/JudgeViewPage.tsx b/client/src/pages/views/JudgeViewPage.tsx
index 5a806d237f190d6483bc8265ec0eac61c58e9151..c6e1a79dca481c397d5d5801e6b3c5be9c6ef93d 100644
--- a/client/src/pages/views/JudgeViewPage.tsx
+++ b/client/src/pages/views/JudgeViewPage.tsx
@@ -1,14 +1,16 @@
-import { Card, Divider, List, ListItem, ListItemText, Paper, Typography } from '@material-ui/core'
+import { Divider, List, ListItemText, Typography } from '@material-ui/core'
 import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
 import React, { useEffect, useState } from 'react'
-import { getPresentationCompetition, setCurrentSlide, setPresentationCode } from '../../actions/presentation'
+import { useHistory, useParams } from 'react-router-dom'
+import { getPresentationCompetition, setCurrentSlide } from '../../actions/presentation'
 import { useAppDispatch, useAppSelector } from '../../hooks'
 import { ViewParams } from '../../interfaces/ViewParams'
-import { socket_connect } from '../../sockets'
+import { socketConnect } from '../../sockets'
+import { renderSlideIcon } from '../../utils/renderSlideIcon'
+import SlideDisplay from '../presentationEditor/components/SlideDisplay'
 import { SlideListItem } from '../presentationEditor/styled'
 import JudgeScoreDisplay from './components/JudgeScoreDisplay'
-import PresentationComponent from './components/PresentationComponent'
-import { useHistory } from 'react-router-dom'
+import JudgeScoringInstructions from './components/JudgeScoringInstructions'
 import {
   Content,
   InnerContent,
@@ -18,13 +20,10 @@ import {
   JudgeToolbar,
   LeftDrawer,
   RightDrawer,
+  ScoreFooterPadding,
   ScoreHeaderPadding,
   ScoreHeaderPaper,
-  ScoreFooterPadding,
 } from './styled'
-import SlideDisplay from '../presentationEditor/components/SlideDisplay'
-import JudgeScoringInstructions from './components/JudgeScoringInstructions'
-import { renderSlideIcon } from '../../utils/renderSlideIcon'
 
 const leftDrawerWidth = 150
 const rightDrawerWidth = 700
@@ -40,30 +39,25 @@ const useStyles = makeStyles((theme: Theme) =>
     toolbar: theme.mixins.toolbar,
   })
 )
-type JudgeViewPageProps = {
-  //Prop to distinguish between editor and active competition
-  competitionId: number
-  code: string
-}
 
-const JudgeViewPage = ({ competitionId, code }: JudgeViewPageProps) => {
+const JudgeViewPage: React.FC = () => {
   const classes = useStyles()
   const history = useHistory()
   const dispatch = useAppDispatch()
   const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0)
+  const viewTypes = useAppSelector((state) => state.types.viewTypes)
+  const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Team')?.id
   const teams = useAppSelector((state) => state.presentation.competition.teams)
   const slides = useAppSelector((state) => state.presentation.competition.slides)
   const currentQuestion = slides[activeSlideIndex]?.questions[0]
+  const { competitionId }: ViewParams = useParams()
   const handleSelectSlide = (index: number) => {
     setActiveSlideIndex(index)
     dispatch(setCurrentSlide(slides[index]))
   }
   useEffect(() => {
-    socket_connect()
+    socketConnect()
     dispatch(getPresentationCompetition(competitionId.toString()))
-    dispatch(setPresentationCode(code))
-    //hides the url so people can't sneak peak
-    history.push('judge')
   }, [])
 
   return (
@@ -128,7 +122,7 @@ const JudgeViewPage = ({ competitionId, code }: JudgeViewPageProps) => {
       <div className={classes.toolbar} />
       <Content leftDrawerWidth={leftDrawerWidth} rightDrawerWidth={rightDrawerWidth}>
         <InnerContent>
-          <SlideDisplay />
+          {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />}
         </InnerContent>
       </Content>
     </div>
diff --git a/client/src/pages/views/PresenterViewPage.test.tsx b/client/src/pages/views/OperatorViewPage.test.tsx
similarity index 91%
rename from client/src/pages/views/PresenterViewPage.test.tsx
rename to client/src/pages/views/OperatorViewPage.test.tsx
index fd7b0a9692e08354330b3e4db98c046649c0d10a..e658fe3b386899b9ab2972243c5d4ceeefc6dec4 100644
--- a/client/src/pages/views/PresenterViewPage.test.tsx
+++ b/client/src/pages/views/OperatorViewPage.test.tsx
@@ -4,7 +4,7 @@ import React from 'react'
 import { Provider } from 'react-redux'
 import { BrowserRouter } from 'react-router-dom'
 import store from '../../store'
-import PresenterViewPage from './PresenterViewPage'
+import OperatorViewPage from './OperatorViewPage'
 
 it('renders presenter view page', () => {
   const compRes: any = {
@@ -36,7 +36,7 @@ it('renders presenter view page', () => {
   render(
     <BrowserRouter>
       <Provider store={store}>
-        <PresenterViewPage />
+        <OperatorViewPage />
       </Provider>
     </BrowserRouter>
   )
diff --git a/client/src/pages/views/OperatorViewPage.tsx b/client/src/pages/views/OperatorViewPage.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0dbf2765f85ee68843dc80aa2d0aa22015c8d5cb
--- /dev/null
+++ b/client/src/pages/views/OperatorViewPage.tsx
@@ -0,0 +1,315 @@
+import {
+  Button,
+  Dialog,
+  DialogActions,
+  DialogContent,
+  DialogContentText,
+  DialogTitle,
+  List,
+  ListItem,
+  ListItemText,
+  Popover,
+  Tooltip,
+  Typography,
+  useMediaQuery,
+  useTheme,
+} from '@material-ui/core'
+import AssignmentIcon from '@material-ui/icons/Assignment'
+import BackspaceIcon from '@material-ui/icons/Backspace'
+import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'
+import ChevronRightIcon from '@material-ui/icons/ChevronRight'
+import FileCopyIcon from '@material-ui/icons/FileCopy'
+import SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount'
+import TimerIcon from '@material-ui/icons/Timer'
+import React, { useEffect } from 'react'
+import { useHistory, useParams } from 'react-router-dom'
+import { getPresentationCompetition } from '../../actions/presentation'
+import { useAppDispatch, useAppSelector } from '../../hooks'
+import { ViewParams } from '../../interfaces/ViewParams'
+import {
+  socketConnect,
+  socketEndPresentation,
+  socketSetSlide,
+  socketSetSlideNext,
+  socketSetSlidePrev,
+  socketStartPresentation,
+  socketStartTimer,
+} from '../../sockets'
+import SlideDisplay from '../presentationEditor/components/SlideDisplay'
+import Timer from './components/Timer'
+import {
+  OperatorButton,
+  OperatorContainer,
+  OperatorContent,
+  OperatorFooter,
+  OperatorHeader,
+  OperatorInnerContent,
+  SlideCounter,
+  ToolBarContainer,
+} from './styled'
+
+/**
+ *  Description:
+ *
+ *  Presentation is an active competition
+ *
+ *
+ *  ===========================================
+ *  TODO:
+ *  - Instead of copying code for others to join the competition, copy URL.
+ *
+ *  - Make code popup less code by using .map instead
+ *
+ *  - Fix scoreboard
+ *
+ *  - When two userers are connected to the same Localhost:5000 and updates/starts/end competition it
+ *    creates a bug where the competition can't be started.
+ * ===========================================
+ */
+
+const OperatorViewPage: React.FC = () => {
+  // for dialog alert
+  const [openAlert, setOpen] = React.useState(false)
+  const [openAlertCode, setOpenCode] = React.useState(true)
+  const theme = useTheme()
+  const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
+  const teams = useAppSelector((state) => state.presentation.competition.teams)
+  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
+  const { competitionId }: ViewParams = useParams()
+  const presentation = useAppSelector((state) => state.presentation)
+  const history = useHistory()
+  const dispatch = useAppDispatch()
+  const viewTypes = useAppSelector((state) => state.types.viewTypes)
+  const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Audience')?.id
+
+  useEffect(() => {
+    dispatch(getPresentationCompetition(competitionId))
+    socketConnect()
+    socketSetSlide // Behövs denna?
+    setTimeout(startCompetition, 1000) // Ghetto, wait for everything to load
+    // console.log(id)
+  }, [])
+
+  window.onpopstate = () => {
+    //Handle browser back arrow
+    alert('Tävlingen avslutas för alla')
+    endCompetition()
+  }
+
+  const handleOpenPopover = (event: React.MouseEvent<HTMLButtonElement>) => {
+    setAnchorEl(event.currentTarget)
+  }
+
+  const handleClose = () => {
+    setOpen(false)
+    setOpenCode(false)
+    setAnchorEl(null)
+  }
+
+  const startCompetition = () => {
+    socketStartPresentation()
+    console.log('started competition for')
+    console.log(competitionId)
+  }
+
+  const handleVerifyExit = () => {
+    setOpen(true)
+  }
+
+  const handleOpenCodes = () => {
+    setOpenCode(true)
+  }
+
+  const handleCopy = () => {
+    console.log('copied code to clipboard')
+  }
+
+  const endCompetition = () => {
+    setOpen(false)
+    socketEndPresentation()
+    history.push('/admin/tävlingshanterare')
+    window.location.reload(false) // TODO: fix this ugly hack, we "need" to refresh site to be able to run the competition correctly again
+  }
+
+  return (
+    <OperatorContainer>
+      <Dialog
+        fullScreen={fullScreen}
+        open={openAlertCode}
+        onClose={handleClose}
+        aria-labelledby="responsive-dialog-title"
+      >
+        <DialogTitle id="responsive-dialog-title">{'Koder för tävlingen'}</DialogTitle>
+        <DialogContent>
+          <ListItem>
+            <ListItemText primary={`Domare: ${presentation.code}`} />
+            <Tooltip title="Kopiera kod" arrow>
+              <Button
+                onClick={() => {
+                  navigator.clipboard.writeText(presentation.code)
+                }}
+              >
+                <FileCopyIcon fontSize="small" />
+              </Button>
+            </Tooltip>
+          </ListItem>
+          <ListItem>
+            <ListItemText primary={`Tävlande: ${presentation.code}`} />
+            <Tooltip title="Kopiera kod" arrow>
+              <Button
+                onClick={() => {
+                  navigator.clipboard.writeText(presentation.code)
+                }}
+              >
+                <FileCopyIcon fontSize="small" />
+              </Button>
+            </Tooltip>
+          </ListItem>
+          <ListItem>
+            <ListItemText primary={`Publik: ${presentation.code}`} />
+            <Tooltip title="Kopiera kod" arrow>
+              <Button
+                onClick={() => {
+                  navigator.clipboard.writeText(presentation.code)
+                }}
+              >
+                <FileCopyIcon fontSize="small" />
+              </Button>
+            </Tooltip>
+          </ListItem>
+        </DialogContent>
+        <DialogActions>
+          <Button autoFocus onClick={handleClose} color="primary">
+            Ok
+          </Button>
+        </DialogActions>
+      </Dialog>
+
+      <OperatorHeader>
+        <Tooltip title="Avsluta tävling" arrow>
+          <OperatorButton onClick={handleVerifyExit} variant="contained" color="secondary">
+            <BackspaceIcon fontSize="large" />
+          </OperatorButton>
+        </Tooltip>
+
+        <Dialog
+          fullScreen={fullScreen}
+          open={openAlert}
+          onClose={handleClose}
+          aria-labelledby="responsive-dialog-title"
+        >
+          <DialogTitle id="responsive-dialog-title">{'Vill du avsluta tävlingen?'}</DialogTitle>
+          <DialogContent>
+            <DialogContentText>
+              Genom att avsluta tävlingen kommer den avslutas för alla. Du kommer gå tillbaka till startsidan.
+            </DialogContentText>
+          </DialogContent>
+          <DialogActions>
+            <Button autoFocus onClick={handleClose} color="primary">
+              Avbryt
+            </Button>
+            <Button onClick={endCompetition} color="primary" autoFocus>
+              Avsluta tävling
+            </Button>
+          </DialogActions>
+        </Dialog>
+        <Typography variant="h3">{presentation.competition.name}</Typography>
+        <SlideCounter>
+          <Typography variant="h3">
+            {presentation.slide.order + 1} / {presentation.competition.slides.length}
+          </Typography>
+        </SlideCounter>
+      </OperatorHeader>
+      <div style={{ height: 0, paddingTop: 120 }} />
+      <OperatorContent>
+        <OperatorInnerContent>
+          {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />}
+        </OperatorInnerContent>
+      </OperatorContent>
+      <div style={{ height: 0, paddingTop: 140 }} />
+      <OperatorFooter>
+        <ToolBarContainer>
+          <Tooltip title="Föregående" arrow>
+            <OperatorButton onClick={socketSetSlidePrev} variant="contained">
+              <ChevronLeftIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+
+          {/* 
+          // Manual start button
+          <Tooltip title="Start Presentation" arrow>
+            <OperatorButton onClick={startCompetition} variant="contained">
+              start
+            </OperatorButton>
+          </Tooltip>
+
+          
+          // This creates a join button, but Operator should not join others, others should join Operator
+          <Tooltip title="Join Presentation" arrow>
+            <OperatorButton onClick={socketJoinPresentation} variant="contained">
+              <GroupAddIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+          
+
+          // This creates another end button, it might not be needed since we already have one
+          <Tooltip title="End Presentation" arrow>
+            <OperatorButton onClick={socketEndPresentation} variant="contained">
+              <CancelIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+          */}
+
+          <Tooltip title="Starta Timer" arrow>
+            <OperatorButton onClick={socketStartTimer} variant="contained">
+              <TimerIcon fontSize="large" />
+              <Timer></Timer>
+            </OperatorButton>
+          </Tooltip>
+
+          <Tooltip title="Ställning" arrow>
+            <OperatorButton onClick={handleOpenPopover} variant="contained">
+              <AssignmentIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+
+          <Tooltip title="Koder" arrow>
+            <OperatorButton onClick={handleOpenCodes} variant="contained">
+              <SupervisorAccountIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+
+          <Tooltip title="Nästa" arrow>
+            <OperatorButton onClick={socketSetSlideNext} variant="contained">
+              <ChevronRightIcon fontSize="large" />
+            </OperatorButton>
+          </Tooltip>
+        </ToolBarContainer>
+      </OperatorFooter>
+      <Popover
+        open={Boolean(anchorEl)}
+        anchorEl={anchorEl}
+        onClose={handleClose}
+        anchorOrigin={{
+          vertical: 'bottom',
+          horizontal: 'center',
+        }}
+        transformOrigin={{
+          vertical: 'top',
+          horizontal: 'center',
+        }}
+      >
+        <List>
+          {teams &&
+            teams.map((team) => (
+              <ListItem key={team.id}>
+                {team.name} score: {team.question_answers}{' '}
+              </ListItem>
+            ))}
+        </List>
+      </Popover>
+    </OperatorContainer>
+  )
+}
+
+export default OperatorViewPage
diff --git a/client/src/pages/views/ParticipantViewPage.tsx b/client/src/pages/views/ParticipantViewPage.tsx
deleted file mode 100644
index ffee1ee11857e875314f847fbd3aca58d6bdd9db..0000000000000000000000000000000000000000
--- a/client/src/pages/views/ParticipantViewPage.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React, { useEffect } from 'react'
-import PresentationComponent from './components/PresentationComponent'
-import { useHistory } from 'react-router-dom'
-import SlideDisplay from '../presentationEditor/components/SlideDisplay'
-import { ParticipantContainer } from './styled'
-import { socketJoinPresentation, socket_connect } from '../../sockets'
-import { useAppSelector } from '../../hooks'
-
-const ParticipantViewPage: React.FC = () => {
-  const history = useHistory()
-  const code = useAppSelector((state) => state.presentation.code)
-  useEffect(() => {
-    //hides the url so people can't sneak peak
-    history.push('participant')
-    if (code && code !== '') {
-      socket_connect()
-      socketJoinPresentation()
-    }
-  }, [])
-  return (
-    <ParticipantContainer>
-      <SlideDisplay />
-    </ParticipantContainer>
-  )
-}
-
-export default ParticipantViewPage
diff --git a/client/src/pages/views/PresenterViewPage.tsx b/client/src/pages/views/PresenterViewPage.tsx
deleted file mode 100644
index f221f5a9b6e612243f626e0fafd490ee02d619e8..0000000000000000000000000000000000000000
--- a/client/src/pages/views/PresenterViewPage.tsx
+++ /dev/null
@@ -1,224 +0,0 @@
-import {
-  Button,
-  Dialog,
-  DialogActions,
-  DialogContent,
-  DialogContentText,
-  DialogTitle,
-  List,
-  ListItem,
-  Popover,
-  Tooltip,
-  Typography,
-  useMediaQuery,
-  useTheme,
-} from '@material-ui/core'
-import AssignmentIcon from '@material-ui/icons/Assignment'
-import BackspaceIcon from '@material-ui/icons/Backspace'
-import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'
-import ChevronRightIcon from '@material-ui/icons/ChevronRight'
-import TimerIcon from '@material-ui/icons/Timer'
-import React, { useEffect } from 'react'
-import { useHistory, useParams } from 'react-router-dom'
-import { getPresentationCompetition, setPresentationCode } from '../../actions/presentation'
-import { useAppDispatch, useAppSelector } from '../../hooks'
-import { ViewParams } from '../../interfaces/ViewParams'
-import {
-  socketEndPresentation,
-  socketSetSlide,
-  socketSetSlideNext,
-  socketSetSlidePrev,
-  socketStartPresentation,
-  socketStartTimer,
-  socket_connect,
-} from '../../sockets'
-import SlideDisplay from '../presentationEditor/components/SlideDisplay'
-import PresentationComponent from './components/PresentationComponent'
-import Timer from './components/Timer'
-import {
-  PresenterButton,
-  PresenterContainer,
-  PresenterContent,
-  PresenterFooter,
-  PresenterHeader,
-  PresenterInnerContent,
-  SlideCounter,
-  ToolBarContainer,
-} from './styled'
-
-/**
- *  Presentation is an active competition
- */
-
-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.competition.teams)
-  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
-  const { id, code }: ViewParams = useParams()
-  const presentation = useAppSelector((state) => state.presentation)
-  const history = useHistory()
-  const dispatch = useAppDispatch()
-
-  useEffect(() => {
-    dispatch(getPresentationCompetition(id))
-    dispatch(setPresentationCode(code))
-    socket_connect()
-    socketSetSlide // Behövs denna?
-    setTimeout(startCompetition, 500) // Ghetto, wait for everything to load
-    // console.log(id)
-  }, [])
-
-  const handleOpenPopover = (event: React.MouseEvent<HTMLButtonElement>) => {
-    setAnchorEl(event.currentTarget)
-  }
-
-  const handleClose = () => {
-    setOpen(false)
-    setAnchorEl(null)
-  }
-
-  const startCompetition = () => {
-    socketStartPresentation()
-    console.log('started competition for')
-    console.log(id)
-  }
-
-  const handleVerifyExit = () => {
-    setOpen(true)
-  }
-
-  const endCompetition = () => {
-    setOpen(false)
-    socketEndPresentation()
-    history.push('/admin/tävlingshanterare')
-    window.location.reload(false) // TODO: fix this ugly hack, we "need" to refresh site to be able to run the competition correctly again
-  }
-
-  return (
-    <PresenterContainer>
-      <PresenterHeader>
-        <Tooltip title="Avsluta tävling" arrow>
-          <PresenterButton onClick={handleVerifyExit} variant="contained" color="secondary">
-            <BackspaceIcon fontSize="large" />
-          </PresenterButton>
-        </Tooltip>
-
-        <Dialog
-          fullScreen={fullScreen}
-          open={openAlert}
-          onClose={handleClose}
-          aria-labelledby="responsive-dialog-title"
-        >
-          <DialogTitle id="responsive-dialog-title">{'Vill du avsluta tävlingen?'}</DialogTitle>
-          <DialogContent>
-            <DialogContentText>
-              Genom att avsluta tävlingen kommer den avslutas för alla. Du kommer gå tillbaka till startsidan.
-            </DialogContentText>
-          </DialogContent>
-          <DialogActions>
-            <Button autoFocus onClick={handleClose} color="primary">
-              Avbryt
-            </Button>
-            <Button onClick={endCompetition} color="primary" autoFocus>
-              Avsluta tävling
-            </Button>
-          </DialogActions>
-        </Dialog>
-        <Typography variant="h3">{presentation.competition.name}</Typography>
-        <SlideCounter>
-          <Typography variant="h3">
-            {presentation.slide.order + 1} / {presentation.competition.slides.length}
-          </Typography>
-        </SlideCounter>
-      </PresenterHeader>
-      <div style={{ height: 0, paddingTop: 120 }} />
-      <PresenterContent>
-        <PresenterInnerContent>
-          <SlideDisplay />
-        </PresenterInnerContent>
-      </PresenterContent>
-      <div style={{ height: 0, paddingTop: 140 }} />
-      <PresenterFooter>
-        <ToolBarContainer>
-          <Tooltip title="Previous Slide" arrow>
-            <PresenterButton onClick={socketSetSlidePrev} variant="contained">
-              <ChevronLeftIcon fontSize="large" />
-            </PresenterButton>
-          </Tooltip>
-
-          {/* 
-          // Manual start button
-          <Tooltip title="Start Presentation" arrow>
-            <PresenterButton onClick={startCompetition} variant="contained">
-              start
-            </PresenterButton>
-          </Tooltip>
-
-          
-          // This creates a join button, but presenter should not join others, others should join presenter
-          <Tooltip title="Join Presentation" arrow>
-            <PresenterButton onClick={socketJoinPresentation} variant="contained">
-              <GroupAddIcon fontSize="large" />
-            </PresenterButton>
-          </Tooltip>
-          
-
-          // This creates another end button, it might not be needed since we already have one
-          <Tooltip title="End Presentation" arrow>
-            <PresenterButton onClick={socketEndPresentation} variant="contained">
-              <CancelIcon fontSize="large" />
-            </PresenterButton>
-          </Tooltip>
-          */}
-
-          <Tooltip title="Start Timer" arrow>
-            <PresenterButton onClick={socketStartTimer} variant="contained">
-              <TimerIcon fontSize="large" />
-              <Timer></Timer>
-            </PresenterButton>
-          </Tooltip>
-
-          <Tooltip title="Scoreboard" arrow>
-            <PresenterButton onClick={handleOpenPopover} variant="contained">
-              <AssignmentIcon fontSize="large" />
-            </PresenterButton>
-          </Tooltip>
-
-          <Tooltip title="Next Slide" arrow>
-            <PresenterButton onClick={socketSetSlideNext} variant="contained">
-              <ChevronRightIcon fontSize="large" />
-            </PresenterButton>
-          </Tooltip>
-        </ToolBarContainer>
-      </PresenterFooter>
-      <Popover
-        open={Boolean(anchorEl)}
-        anchorEl={anchorEl}
-        onClose={handleClose}
-        anchorOrigin={{
-          vertical: 'bottom',
-          horizontal: 'center',
-        }}
-        transformOrigin={{
-          vertical: 'top',
-          horizontal: 'center',
-        }}
-      >
-        <List>
-          {/**  TODO:
-           *    Fix scoreboard
-           */}
-          {teams && teams.map((team) => <ListItem key={team.id}>{team.name} score: 20</ListItem>)}
-        </List>
-      </Popover>
-    </PresenterContainer>
-  )
-}
-
-export default PresenterViewPage
-function componentDidMount() {
-  throw new Error('Function not implemented.')
-}
diff --git a/client/src/pages/views/ParticipantViewPage.test.tsx b/client/src/pages/views/TeamViewPage.test.tsx
similarity index 85%
rename from client/src/pages/views/ParticipantViewPage.test.tsx
rename to client/src/pages/views/TeamViewPage.test.tsx
index e25ab6b9ec8f6309ce60812d296c37ffab3042e6..10574f7e51df7dabf9f07754e9d8595d1c489559 100644
--- a/client/src/pages/views/ParticipantViewPage.test.tsx
+++ b/client/src/pages/views/TeamViewPage.test.tsx
@@ -3,7 +3,7 @@ import React from 'react'
 import { Provider } from 'react-redux'
 import { BrowserRouter } from 'react-router-dom'
 import store from '../../store'
-import ParticipantViewPage from './ParticipantViewPage'
+import TeamViewPage from './TeamViewPage'
 import mockedAxios from 'axios'
 
 it('renders participant view page', () => {
@@ -16,7 +16,7 @@ it('renders participant view page', () => {
   render(
     <BrowserRouter>
       <Provider store={store}>
-        <ParticipantViewPage />
+        <TeamViewPage />
       </Provider>
     </BrowserRouter>
   )
diff --git a/client/src/pages/views/TeamViewPage.tsx b/client/src/pages/views/TeamViewPage.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..13791b3acd7b1ee5688ba3314aa4daa6e04f7272
--- /dev/null
+++ b/client/src/pages/views/TeamViewPage.tsx
@@ -0,0 +1,33 @@
+import React, { useEffect } from 'react'
+import { useHistory, useParams } from 'react-router-dom'
+import { getPresentationCompetition } from '../../actions/presentation'
+import { useAppDispatch, useAppSelector } from '../../hooks'
+import { ViewParams } from '../../interfaces/ViewParams'
+import { socketConnect, socketJoinPresentation } from '../../sockets'
+import SlideDisplay from '../presentationEditor/components/SlideDisplay'
+import { PresentationBackground, PresentationContainer } from './styled'
+
+const TeamViewPage: React.FC = () => {
+  const history = useHistory()
+  const code = useAppSelector((state) => state.presentation.code)
+  const viewTypes = useAppSelector((state) => state.types.viewTypes)
+  const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Team')?.id
+  const { competitionId }: ViewParams = useParams()
+  const dispatch = useAppDispatch()
+  useEffect(() => {
+    dispatch(getPresentationCompetition(competitionId))
+    if (code && code !== '') {
+      socketConnect()
+      socketJoinPresentation()
+    }
+  }, [])
+  return (
+    <PresentationBackground>
+      <PresentationContainer>
+        {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />}
+      </PresentationContainer>
+    </PresentationBackground>
+  )
+}
+
+export default TeamViewPage
diff --git a/client/src/pages/views/ViewSelectPage.tsx b/client/src/pages/views/ViewSelectPage.tsx
index 9a0264f3da7651543841a28c5a5ad0f73c3f5aa3..d69dc8b4243d680647802fe9d6f72acbd23618ba 100644
--- a/client/src/pages/views/ViewSelectPage.tsx
+++ b/client/src/pages/views/ViewSelectPage.tsx
@@ -1,5 +1,5 @@
 import { CircularProgress, Typography } from '@material-ui/core'
-import React, { useEffect, useState } from 'react'
+import React, { useEffect } from 'react'
 import { Redirect, useHistory, useParams } from 'react-router-dom'
 import { loginCompetition } from '../../actions/competitionLogin'
 import { useAppDispatch, useAppSelector } from '../../hooks'
@@ -11,56 +11,47 @@ interface ViewSelectParams {
 const ViewSelectPage: React.FC = () => {
   const dispatch = useAppDispatch()
   const history = useHistory()
-  const [loading, setLoading] = useState(true)
-  const [error, setError] = useState(false)
-  const [viewTypeId, setViewTypeId] = useState(undefined)
-  const [competitionId, setCompetitionId] = useState<number | undefined>(undefined)
+  const competitionId = useAppSelector((state) => state.competitionLogin.data?.competition_id)
+  const errorMessage = useAppSelector((state) => state.competitionLogin.errors?.message)
+  const loading = useAppSelector((state) => state.competitionLogin.loading)
   const { code }: ViewSelectParams = useParams()
-  const viewType = useAppSelector((state) => state.types.viewTypes.find((viewType) => viewType.id === viewTypeId)?.name)
+  const viewType = useAppSelector((state) => state.competitionLogin.data?.view)
 
-  const renderView = (viewTypeId: number | undefined) => {
+  const renderView = () => {
     //Renders the correct view depending on view type
     if (competitionId) {
       switch (viewType) {
         case 'Team':
-          return <Redirect to={`/team/${competitionId}`} />
+          return <Redirect to={`/team/competition-id=${competitionId}`} />
         case 'Judge':
-          return <Redirect to={`/judge/${competitionId}`} />
+          return <Redirect to={`/judge/competition-id=${competitionId}`} />
         case 'Audience':
-          return <Redirect to={`/audience/${competitionId}`} />
+          return <Redirect to={`/audience/competition-id=${competitionId}`} />
         case 'Operator':
-          return <Redirect to={`/operator/${competitionId}`} />
+          return <Redirect to={`/operator/competition-id=${competitionId}`} />
         default:
-          return <Typography>Inkorrekt vy</Typography>
+          return (
+            <ViewSelectContainer>
+              <ViewSelectButtonGroup>
+                <Typography variant="h4">Inkorrekt vy</Typography>
+              </ViewSelectButtonGroup>
+            </ViewSelectContainer>
+          )
       }
     }
   }
-
   useEffect(() => {
-    dispatch(loginCompetition(code, history))
-    /*     axios
-      .post('/api/auth/login/code', { code })
-      .then((response) => {
-        setLoading(false)
-        setViewTypeId(response.data.view_type_id)
-        setCompetitionId(response.data.competition_id)
-        dispatch(getPresentationCompetition(response.data.competition_id))
-        dispatch(setPresentationCode(code))
-      })
-      .catch(() => {
-        setLoading(false)
-        setError(true)
-      }) */
+    dispatch(loginCompetition(code, history, false))
   }, [])
 
   return (
     <>
-      {!loading && renderView(viewTypeId)}
-      {(loading || error) && (
+      {renderView()}
+      {(loading || errorMessage) && (
         <ViewSelectContainer>
           <ViewSelectButtonGroup>
             {loading && <CircularProgress />}
-            {error && <Typography>Något gick fel, dubbelkolla koden och försök igen</Typography>}
+            {errorMessage && <Typography variant="h4">{errorMessage}</Typography>}
           </ViewSelectButtonGroup>
         </ViewSelectContainer>
       )}
diff --git a/client/src/pages/views/components/SocketTest.tsx b/client/src/pages/views/components/SocketTest.tsx
index d99f5b2aa740d9a2690b3aadeae6e1050b92d089..01a0a6f29b51d9a194cb397fdc73c720202e0c1c 100644
--- a/client/src/pages/views/components/SocketTest.tsx
+++ b/client/src/pages/views/components/SocketTest.tsx
@@ -2,13 +2,13 @@ import React, { useEffect } from 'react'
 import { connect } from 'react-redux'
 import { useAppDispatch } from '../../../hooks'
 import {
+  socketConnect,
   socketEndPresentation,
   socketJoinPresentation,
   socketSetSlideNext,
   socketSetSlidePrev,
   socketStartPresentation,
   socketStartTimer,
-  socket_connect,
 } from '../../../sockets'
 
 const mapStateToProps = (state: any) => {
@@ -27,7 +27,7 @@ const SocketTest: React.FC = (props: any) => {
   const dispatch = useAppDispatch()
 
   useEffect(() => {
-    socket_connect()
+    socketConnect()
     // dispatch(getPresentationCompetition('1')) // TODO: Use ID of item_code gotten from auth/login/<code> api call
     // dispatch(getPresentationTeams('1')) // TODO: Use ID of item_code gotten from auth/login/<code> api call
   }, [])
diff --git a/client/src/pages/views/styled.tsx b/client/src/pages/views/styled.tsx
index 8f63892ade7928842c12d4dc73df988a505f4cea..4b01d63ab8df48957ab88619424a089f96f36ebd 100644
--- a/client/src/pages/views/styled.tsx
+++ b/client/src/pages/views/styled.tsx
@@ -1,4 +1,4 @@
-import { AppBar, Button, Card, Drawer, Paper, Toolbar, Typography } from '@material-ui/core'
+import { AppBar, Button, Card, Drawer, Toolbar, Typography } from '@material-ui/core'
 import styled from 'styled-components'
 
 export const JudgeAppBar = styled(AppBar)`
@@ -35,7 +35,7 @@ export const ViewSelectButtonGroup = styled.div`
   margin-right: auto;
 `
 
-export const PresenterHeader = styled.div`
+export const OperatorHeader = styled.div`
   display: flex;
   justify-content: space-between;
   height: 120px;
@@ -43,7 +43,7 @@ export const PresenterHeader = styled.div`
   position: absolute;
 `
 
-export const PresenterFooter = styled.div`
+export const OperatorFooter = styled.div`
   display: flex;
   justify-content: space-between;
   height: 140px;
@@ -52,7 +52,7 @@ export const PresenterFooter = styled.div`
   width: 100%;
 `
 
-export const PresenterButton = styled(Button)`
+export const OperatorButton = styled(Button)`
   width: 100px;
   height: 100px;
   margin-left: 16px;
@@ -66,7 +66,7 @@ export const SlideCounter = styled(Button)`
   margin-top: 16px;
 `
 
-export const PresenterContainer = styled.div`
+export const OperatorContainer = styled.div`
   display: flex;
   flex-direction: column;
   justify-content: space-between;
@@ -127,7 +127,7 @@ export const InnerContent = styled.div`
   max-width: calc(((100vh - 64px) / 9) * 16);
 `
 
-export const PresenterContent = styled.div`
+export const OperatorContent = styled.div`
   height: 100%;
   width: 100%;
   display: flex;
@@ -135,7 +135,7 @@ export const PresenterContent = styled.div`
   background-color: rgba(0, 0, 0, 0.08);
 `
 
-export const PresenterInnerContent = styled.div`
+export const OperatorInnerContent = styled.div`
   height: 100%;
   width: 100%;
   /* Makes sure width is not bigger than where a 16:9 display can fit 
@@ -143,10 +143,20 @@ export const PresenterInnerContent = styled.div`
   max-width: calc(((100vh - 260px) / 9) * 16);
 `
 
-export const ParticipantContainer = styled.div`
+export const PresentationContainer = styled.div`
+  height: 100%;
+  width: 100%;
   max-width: calc((100vh / 9) * 16);
 `
 
+export const PresentationBackground = styled.div`
+  height: 100%;
+  width: 100%;
+  background-color: rgba(0, 0, 0, 0.08);
+  display: flex;
+  justify-content: center;
+`
+
 interface ScoreHeaderPaperProps {
   $rightDrawerWidth: number
 }
diff --git a/client/src/reducers/competitionLoginReducer.ts b/client/src/reducers/competitionLoginReducer.ts
index c8802ef7b64929815baa8155bc4fee49359968c9..6d425f97209c810cd1646c3f9722dd9ec5666ff8 100644
--- a/client/src/reducers/competitionLoginReducer.ts
+++ b/client/src/reducers/competitionLoginReducer.ts
@@ -1,6 +1,12 @@
 import { AnyAction } from 'redux'
 import Types from '../actions/types'
 
+interface CompetitionLoginData {
+  competition_id: number
+  team_id: number | null
+  view: string
+}
+
 interface UIError {
   message: string
 }
@@ -9,20 +15,33 @@ interface CompetitionLoginState {
   loading: boolean
   errors: null | UIError
   authenticated: boolean
+  data: CompetitionLoginData | null
+  initialized: boolean
 }
 
 const initialState: CompetitionLoginState = {
   loading: false,
   errors: null,
   authenticated: false,
+  data: null,
+  initialized: false,
 }
 
 export default function (state = initialState, action: AnyAction) {
   switch (action.type) {
+    case Types.SET_COMPETITION_LOGIN_DATA:
+      return {
+        ...state,
+        data: action.payload as CompetitionLoginData,
+        authenticated: true,
+        initialized: true,
+      }
+
     case Types.SET_COMPETITION_LOGIN_AUTHENTICATED:
       return {
         ...state,
         authenticated: true,
+        initialized: true,
       }
     case Types.SET_COMPETITION_LOGIN_ERRORS:
       return {
diff --git a/client/src/reducers/editorReducer.ts b/client/src/reducers/editorReducer.ts
index 88e6e3687ea6f4348ebd5956e677ef26319e33c2..4f245d1d05638cc059cf8d26921642d8239c169a 100644
--- a/client/src/reducers/editorReducer.ts
+++ b/client/src/reducers/editorReducer.ts
@@ -5,6 +5,7 @@ import { RichCompetition } from '../interfaces/ApiRichModels'
 interface EditorState {
   competition: RichCompetition
   activeSlideId: number
+  activeViewTypeId: number
   loading: boolean
 }
 
@@ -19,6 +20,7 @@ const initialState: EditorState = {
     background_image: undefined,
   },
   activeSlideId: -1,
+  activeViewTypeId: -1,
   loading: true,
 }
 
@@ -35,6 +37,11 @@ export default function (state = initialState, action: AnyAction) {
         ...state,
         activeSlideId: action.payload as number,
       }
+    case Types.SET_EDITOR_VIEW_ID:
+      return {
+        ...state,
+        activeViewTypeId: action.payload as number,
+      }
     default:
       return state
   }
diff --git a/client/src/sockets.ts b/client/src/sockets.ts
index 4392021df3c89d3d981096e38e1576d155c89b21..e5addeb8973ee5e346c44e1a3ca40b417e18db4d 100644
--- a/client/src/sockets.ts
+++ b/client/src/sockets.ts
@@ -18,9 +18,19 @@ interface SetTimerInterface {
 
 let socket: SocketIOClient.Socket
 
-export const socket_connect = () => {
+export const socketConnect = () => {
   if (!socket) {
-    socket = io('localhost:5000')
+    const token = localStorage.competitionToken
+    console.log(token)
+    socket = io('localhost:5000', {
+      transportOptions: {
+        polling: {
+          extraHeaders: {
+            Authorization: token,
+          },
+        },
+      },
+    })
 
     socket.on('set_slide', (data: SetSlideInterface) => {
       setCurrentSlideByOrder(data.slide_order)(store.dispatch)
diff --git a/client/src/utils/SecureRoute.tsx b/client/src/utils/SecureRoute.tsx
index cfdf52f602668222e24e5e20e095e6a62da59e5e..e2885501748c468eb898e833481ae219516c5946 100644
--- a/client/src/utils/SecureRoute.tsx
+++ b/client/src/utils/SecureRoute.tsx
@@ -1,42 +1,45 @@
-import React, { useEffect } from 'react'
+import React from 'react'
 import { Redirect, Route, RouteProps } from 'react-router-dom'
 import { useAppSelector } from '../hooks'
 import { CheckAuthenticationAdmin } from './checkAuthenticationAdmin'
 import { CheckAuthenticationCompetition } from './checkAuthenticationCompetition'
 
 interface SecureRouteProps extends RouteProps {
-  login?: boolean
   component: React.ComponentType<any>
   rest?: any
   authLevel: 'competition' | 'admin' | 'login'
 }
+
 /** Utility component to use for authentication, replace all routes that should be private with secure routes*/
-const SecureRoute: React.FC<SecureRouteProps> = ({
-  login,
-  component: Component,
-  authLevel,
-  ...rest
-}: SecureRouteProps) => {
-  const authenticated = useAppSelector((state) => state.user.authenticated)
+const SecureRoute: React.FC<SecureRouteProps> = ({ component: Component, authLevel, ...rest }: SecureRouteProps) => {
+  const userAuthenticated = useAppSelector((state) => state.user.authenticated)
+  const compAuthenticated = useAppSelector((state) => state.competitionLogin.authenticated)
   const [initialized, setInitialized] = React.useState(false)
-  useEffect(() => {
-    const waitForAuthentication = async () => {
-      if (authLevel === 'admin' || authLevel === 'login') {
-        await CheckAuthenticationAdmin()
-      } else {
-        await CheckAuthenticationCompetition()
-      }
-      console.log('initialized')
-      setInitialized(true)
+  const compInitialized = useAppSelector((state) => state.competitionLogin.initialized)
+  React.useEffect(() => {
+    if (authLevel === 'admin' || authLevel === 'login') {
+      CheckAuthenticationAdmin().then(() => setInitialized(true))
+    } else {
+      CheckAuthenticationCompetition().then(() => setInitialized(true))
     }
-    waitForAuthentication()
   }, [])
+
   if (initialized) {
     if (authLevel === 'login')
       return (
-        <Route {...rest} render={(props) => (authenticated ? <Redirect to="/admin" /> : <Component {...props} />)} />
+        <Route
+          {...rest}
+          render={(props) => (userAuthenticated ? <Redirect to="/admin" /> : <Component {...props} />)}
+        />
+      )
+    else if (authLevel === 'competition' && compInitialized)
+      return (
+        <Route {...rest} render={(props) => (compAuthenticated ? <Component {...props} /> : <Redirect to="/" />)} />
+      )
+    else
+      return (
+        <Route {...rest} render={(props) => (userAuthenticated ? <Component {...props} /> : <Redirect to="/" />)} />
       )
-    else return <Route {...rest} render={(props) => (authenticated ? <Component {...props} /> : <Redirect to="/" />)} />
   } else return null
 }
 export default SecureRoute
diff --git a/client/src/utils/checkAuthenticationAdmin.ts b/client/src/utils/checkAuthenticationAdmin.ts
index 3565f8e3b93bb8ff83114e166618a22f823d335e..f8f94e2d0c42fbdbaa46283af6b3e2378d1a69be 100644
--- a/client/src/utils/checkAuthenticationAdmin.ts
+++ b/client/src/utils/checkAuthenticationAdmin.ts
@@ -9,6 +9,7 @@ const UnAuthorized = async () => {
 }
 
 export const CheckAuthenticationAdmin = async () => {
+  console.log('checkAuthenticationAdmin')
   const authToken = localStorage.token
   if (authToken) {
     const decodedToken: any = jwtDecode(authToken)
diff --git a/client/src/utils/checkAuthenticationCompetition.ts b/client/src/utils/checkAuthenticationCompetition.ts
index ef3e6c0056b9f8225a232724e7f79ba77016b9fe..db0c32360a9928459dd4cac4e65bfb1715a8353f 100644
--- a/client/src/utils/checkAuthenticationCompetition.ts
+++ b/client/src/utils/checkAuthenticationCompetition.ts
@@ -1,6 +1,7 @@
 import axios from 'axios'
 import jwtDecode from 'jwt-decode'
 import { logoutCompetition } from '../actions/competitionLogin'
+import { setPresentationCode } from '../actions/presentation'
 import Types from '../actions/types'
 import store from '../store'
 
@@ -9,17 +10,25 @@ const UnAuthorized = async () => {
 }
 
 export const CheckAuthenticationCompetition = async () => {
-  console.log('checkAuthComp')
   const authToken = localStorage.competitionToken
   if (authToken) {
     const decodedToken: any = jwtDecode(authToken)
-    console.log(decodedToken)
     if (decodedToken.exp * 1000 >= Date.now()) {
       axios.defaults.headers.common['Authorization'] = authToken
+      console.log(decodedToken.user_claims)
       await axios
         .get('/api/auth/test')
         .then((res) => {
           store.dispatch({ type: Types.SET_COMPETITION_LOGIN_AUTHENTICATED })
+          store.dispatch({
+            type: Types.SET_COMPETITION_LOGIN_DATA,
+            payload: {
+              competition_id: decodedToken.user_claims.competition_id,
+              team_id: decodedToken.user_claims.team_id,
+              view: res.data.view,
+            },
+          })
+          setPresentationCode(decodedToken.user_claims.code)(store.dispatch)
         })
         .catch((error) => {
           console.log(error)
diff --git a/client/src/utils/uploadImage.ts b/client/src/utils/uploadImage.ts
new file mode 100644
index 0000000000000000000000000000000000000000..151a34a400f2d2e632b1f18b8f249206c043a02f
--- /dev/null
+++ b/client/src/utils/uploadImage.ts
@@ -0,0 +1,16 @@
+import axios from 'axios'
+import { getEditorCompetition } from '../actions/editor'
+import { Media } from '../interfaces/ApiModels'
+import store from '../store'
+
+export const uploadFile = async (formData: FormData, competitionId: string) => {
+  // Uploads the file to the server and creates a Media object in database.
+  // Returns media object data.
+  return await axios
+    .post(`/api/media/images`, formData)
+    .then((response) => {
+      getEditorCompetition(competitionId)(store.dispatch, store.getState)
+      return response.data as Media
+    })
+    .catch(console.log)
+}
diff --git a/server/app/apis/alternatives.py b/server/app/apis/alternatives.py
index 0ce74d53b0a742ea31689d826f898e1b12f33b41..94f6d6b1725106a3cf5994570e4d3d5829ba2dbe 100644
--- a/server/app/apis/alternatives.py
+++ b/server/app/apis/alternatives.py
@@ -4,14 +4,19 @@ from app.apis import item_response, list_response, protect_route
 from app.core.dto import QuestionAlternativeDTO
 from flask_restx import Resource
 from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = QuestionAlternativeDTO.api
 schema = QuestionAlternativeDTO.schema
 list_schema = QuestionAlternativeDTO.list_schema
 
-question_alternative_parser = reqparse.RequestParser()
-question_alternative_parser.add_argument("text", type=str, default=None, location="json")
-question_alternative_parser.add_argument("value", type=int, default=None, location="json")
+alternative_parser_add = reqparse.RequestParser()
+alternative_parser_add.add_argument("text", type=str, required=True, location="json")
+alternative_parser_add.add_argument("value", type=int, required=True, location="json")
+
+alternative_parser_edit = reqparse.RequestParser()
+alternative_parser_edit.add_argument("text", type=str, default=sentinel, location="json")
+alternative_parser_edit.add_argument("value", type=int, default=sentinel, location="json")
 
 
 @api.route("")
@@ -24,7 +29,7 @@ class QuestionAlternativeList(Resource):
 
     @protect_route(allowed_roles=["*"])
     def post(self, competition_id, slide_id, question_id):
-        args = question_alternative_parser.parse_args(strict=True)
+        args = alternative_parser_add.parse_args(strict=True)
         item = dbc.add.question_alternative(**args, question_id=question_id)
         return item_response(schema.dump(item))
 
@@ -39,7 +44,7 @@ class QuestionAlternatives(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, slide_id, question_id, alternative_id):
-        args = question_alternative_parser.parse_args(strict=True)
+        args = alternative_parser_edit.parse_args(strict=True)
         item = dbc.get.question_alternative(competition_id, slide_id, question_id, alternative_id)
         item = dbc.edit.default(item, **args)
         return item_response(schema.dump(item))
diff --git a/server/app/apis/answers.py b/server/app/apis/answers.py
index 8f72d3bde8610c255083df9deefc69b89a68560a..3990e4e1d7b75fa35d13cc592906e4c4aa921024 100644
--- a/server/app/apis/answers.py
+++ b/server/app/apis/answers.py
@@ -4,19 +4,20 @@ from app.apis import item_response, list_response, protect_route
 from app.core.dto import QuestionAnswerDTO
 from flask_restx import Resource
 from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = QuestionAnswerDTO.api
 schema = QuestionAnswerDTO.schema
 list_schema = QuestionAnswerDTO.list_schema
 
-question_answer_parser = reqparse.RequestParser()
-question_answer_parser.add_argument("answer", type=str, required=True, location="json")
-question_answer_parser.add_argument("score", type=int, required=True, location="json")
-question_answer_parser.add_argument("question_id", type=int, required=True, location="json")
+answer_parser_add = reqparse.RequestParser()
+answer_parser_add.add_argument("answer", type=str, required=True, location="json")
+answer_parser_add.add_argument("score", type=int, required=True, location="json")
+answer_parser_add.add_argument("question_id", type=int, required=True, location="json")
 
-question_answer_edit_parser = reqparse.RequestParser()
-question_answer_edit_parser.add_argument("answer", type=str, default=None, location="json")
-question_answer_edit_parser.add_argument("score", type=int, default=None, location="json")
+answer_parser_edit = reqparse.RequestParser()
+answer_parser_edit.add_argument("answer", type=str, default=sentinel, location="json")
+answer_parser_edit.add_argument("score", type=int, default=sentinel, location="json")
 
 
 @api.route("")
@@ -29,7 +30,7 @@ class QuestionAnswerList(Resource):
 
     @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def post(self, competition_id, team_id):
-        args = question_answer_parser.parse_args(strict=True)
+        args = answer_parser_add.parse_args(strict=True)
         item = dbc.add.question_answer(**args, team_id=team_id)
         return item_response(schema.dump(item))
 
@@ -44,7 +45,7 @@ class QuestionAnswers(Resource):
 
     @protect_route(allowed_roles=["*"], allowed_views=["*"])
     def put(self, competition_id, team_id, answer_id):
-        args = question_answer_edit_parser.parse_args(strict=True)
+        args = answer_parser_edit.parse_args(strict=True)
         item = dbc.get.question_answer(competition_id, team_id, answer_id)
         item = dbc.edit.default(item, **args)
         return item_response(schema.dump(item))
diff --git a/server/app/apis/auth.py b/server/app/apis/auth.py
index 62795e3afd0ee1f846e3e24aa612784e9b56d9fe..a3be209155aa5fc03b1dcd16478bd94e51f45826 100644
--- a/server/app/apis/auth.py
+++ b/server/app/apis/auth.py
@@ -17,14 +17,14 @@ list_schema = AuthDTO.list_schema
 
 login_parser = reqparse.RequestParser()
 login_parser.add_argument("email", type=inputs.email(), required=True, location="json")
-login_parser.add_argument("password", required=True, location="json")
+login_parser.add_argument("password", type=str, required=True, location="json")
 
 create_user_parser = login_parser.copy()
 create_user_parser.add_argument("city_id", type=int, required=True, location="json")
 create_user_parser.add_argument("role_id", type=int, required=True, location="json")
 
 login_code_parser = reqparse.RequestParser()
-login_code_parser.add_argument("code", type=str, location="json")
+login_code_parser.add_argument("code", type=str, required=True, location="json")
 
 
 def get_user_claims(item_user):
@@ -32,7 +32,14 @@ def get_user_claims(item_user):
 
 
 def get_code_claims(item_code):
-    return {"view": item_code.view_type.name, "competition_id": item_code.competition_id, "team_id": item_code.team_id}
+    return {"view": item_code.view_type.name, "competition_id": item_code.competition_id, "team_id": item_code.team_id, "code": item_code.code}
+
+
+@api.route("/test")
+class AuthSignup(Resource):
+    @protect_route(allowed_roles=["Admin"], allowed_views=["*"])
+    def get(self):
+        return "ok"
 
 
 @api.route("/signup")
@@ -102,7 +109,7 @@ class AuthLoginCode(Resource):
 
         response = {
             "competition_id": item_code.competition_id,
-            "view_type_id": item_code.view_type_id,
+            "view": item_code.view_type.name,
             "team_id": item_code.team_id,
             "access_token": access_token,
         }
diff --git a/server/app/apis/competitions.py b/server/app/apis/competitions.py
index d1fd95722f026cb3aa67e9bb8354a6823af9bbee..c5ff37c9131a7a9ec4bc1f394a9e1f5b5727460e 100644
--- a/server/app/apis/competitions.py
+++ b/server/app/apis/competitions.py
@@ -6,32 +6,35 @@ from app.core.dto import CompetitionDTO
 from app.database.models import Competition
 from flask_restx import Resource
 from flask_restx import reqparse
-from app.core.parsers import search_parser
+from app.core.parsers import search_parser, sentinel
 
 api = CompetitionDTO.api
 schema = CompetitionDTO.schema
 rich_schema = CompetitionDTO.rich_schema
 list_schema = CompetitionDTO.list_schema
 
-competition_parser = reqparse.RequestParser()
-competition_parser.add_argument("name", type=str, location="json")
-competition_parser.add_argument("year", type=int, location="json")
-competition_parser.add_argument("city_id", type=int, location="json")
+competition_parser_add = reqparse.RequestParser()
+competition_parser_add.add_argument("name", type=str, required=True, location="json")
+competition_parser_add.add_argument("year", type=int, required=True, location="json")
+competition_parser_add.add_argument("city_id", type=int, required=True, location="json")
 
-competition_edit_parser = competition_parser.copy()
-competition_edit_parser.add_argument("background_image_id", default=None, type=int, location="json")
+competition_parser_edit = reqparse.RequestParser()
+competition_parser_edit.add_argument("name", type=str, default=sentinel, location="json")
+competition_parser_edit.add_argument("year", type=int, default=sentinel, location="json")
+competition_parser_edit.add_argument("city_id", type=int, default=sentinel, location="json")
+competition_parser_edit.add_argument("background_image_id", default=sentinel, type=int, location="json")
 
-competition_search_parser = search_parser.copy()
-competition_search_parser.add_argument("name", type=str, default=None, location="args")
-competition_search_parser.add_argument("year", type=int, default=None, location="args")
-competition_search_parser.add_argument("city_id", type=int, default=None, location="args")
+competition_parser_search = search_parser.copy()
+competition_parser_search.add_argument("name", type=str, default=sentinel, location="args")
+competition_parser_search.add_argument("year", type=int, default=sentinel, location="args")
+competition_parser_search.add_argument("city_id", type=int, default=sentinel, location="args")
 
 
 @api.route("")
 class CompetitionsList(Resource):
     @protect_route(allowed_roles=["*"])
     def post(self):
-        args = competition_parser.parse_args(strict=True)
+        args = competition_parser_add.parse_args(strict=True)
 
         # Add competition
         item = dbc.add.competition(**args)
@@ -52,9 +55,9 @@ class Competitions(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id):
-        args = competition_edit_parser.parse_args(strict=True)
+        args = competition_parser_edit.parse_args(strict=True)
         item = dbc.get.one(Competition, competition_id)
-        item = dbc.edit.competition(item, **args)
+        item = dbc.edit.default(item, **args)
 
         return item_response(schema.dump(item))
 
@@ -70,7 +73,7 @@ class Competitions(Resource):
 class CompetitionSearch(Resource):
     @protect_route(allowed_roles=["*"])
     def get(self):
-        args = competition_search_parser.parse_args(strict=True)
+        args = competition_parser_search.parse_args(strict=True)
         items, total = dbc.search.competition(**args)
         return list_response(list_schema.dump(items), total)
 
diff --git a/server/app/apis/components.py b/server/app/apis/components.py
index c22ce4ad671329538e05a6a6ee7bb5fd9026ca38..a1982763a5ec37b8bb02bb8e6a73e164355417a8 100644
--- a/server/app/apis/components.py
+++ b/server/app/apis/components.py
@@ -4,24 +4,31 @@ from app.apis import item_response, list_response, protect_route
 from app.core.dto import ComponentDTO
 from flask_restx import Resource
 from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = ComponentDTO.api
 schema = ComponentDTO.schema
 list_schema = ComponentDTO.list_schema
 
+component_parser_add = reqparse.RequestParser()
+component_parser_add.add_argument("x", type=str, default=0, location="json")
+component_parser_add.add_argument("y", type=int, default=0, location="json")
+component_parser_add.add_argument("w", type=int, default=1, location="json")
+component_parser_add.add_argument("h", type=int, default=1, location="json")
+component_parser_add.add_argument("type_id", type=int, required=True, location="json")
+component_parser_add.add_argument("view_type_id", type=int, required=True, location="json")
+component_parser_add.add_argument("text", type=str, default=None, location="json")
+component_parser_add.add_argument("media_id", type=int, default=None, location="json")
+component_parser_add.add_argument("question_id", type=int, default=None, location="json")
 
-component_parser = reqparse.RequestParser()
-component_parser.add_argument("x", type=str, default=None, location="json")
-component_parser.add_argument("y", type=int, default=None, location="json")
-component_parser.add_argument("w", type=int, default=None, location="json")
-component_parser.add_argument("h", type=int, default=None, location="json")
-
-component_edit_parser = component_parser.copy()
-component_edit_parser.add_argument("text", type=str, location="json")
-component_edit_parser.add_argument("media_id", type=str, location="json")
-
-component_create_parser = component_edit_parser.copy()
-component_create_parser.add_argument("type_id", type=int, required=True, location="json")
+component_parser_edit = reqparse.RequestParser()
+component_parser_edit.add_argument("x", type=str, default=sentinel, location="json")
+component_parser_edit.add_argument("y", type=int, default=sentinel, location="json")
+component_parser_edit.add_argument("w", type=int, default=sentinel, location="json")
+component_parser_edit.add_argument("h", type=int, default=sentinel, location="json")
+component_parser_edit.add_argument("text", type=str, default=sentinel, location="json")
+component_parser_edit.add_argument("media_id", type=int, default=sentinel, location="json")
+component_parser_edit.add_argument("question_id", type=int, default=sentinel, location="json")
 
 
 @api.route("/<component_id>")
@@ -34,10 +41,10 @@ class ComponentByID(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, slide_id, component_id):
-        args = component_edit_parser.parse_args(strict=True)
+        args = component_parser_edit.parse_args(strict=True)
         item = dbc.get.component(competition_id, slide_id, component_id)
-        args_without_none = {key: value for key, value in args.items() if value is not None}
-        item = dbc.edit.default(item, **args_without_none)
+        args_without_sentinel = {key: value for key, value in args.items() if value is not sentinel}
+        item = dbc.edit.default(item, **args_without_sentinel)
         return item_response(schema.dump(item))
 
     @protect_route(allowed_roles=["*"])
@@ -57,6 +64,6 @@ class ComponentList(Resource):
 
     @protect_route(allowed_roles=["*"])
     def post(self, competition_id, slide_id):
-        args = component_create_parser.parse_args()
+        args = component_parser_add.parse_args()
         item = dbc.add.component(slide_id=slide_id, **args)
         return item_response(schema.dump(item))
diff --git a/server/app/apis/media.py b/server/app/apis/media.py
index c7de8c4d4c1cbd3f482d386e654a9bfd0063370b..49d20608840e320ef3d73d9df848748e6da33617 100644
--- a/server/app/apis/media.py
+++ b/server/app/apis/media.py
@@ -10,6 +10,7 @@ from flask_restx import Resource
 from flask_uploads import UploadNotAllowed
 from sqlalchemy import exc
 import app.core.files as files
+from app.core.parsers import sentinel
 
 api = MediaDTO.api
 image_set = MediaDTO.image_set
@@ -17,7 +18,7 @@ schema = MediaDTO.schema
 list_schema = MediaDTO.list_schema
 
 media_parser_search = search_parser.copy()
-media_parser_search.add_argument("filename", type=str, default=None, location="args")
+media_parser_search.add_argument("filename", type=str, default=sentinel, location="args")
 
 
 @api.route("/images")
diff --git a/server/app/apis/questions.py b/server/app/apis/questions.py
index de40a310db5f11a1b0c03cb20e1546f74682af70..b14849d224501e48f9cce8a108bfd24f29657e99 100644
--- a/server/app/apis/questions.py
+++ b/server/app/apis/questions.py
@@ -4,15 +4,21 @@ from app.apis import item_response, list_response, protect_route
 from app.core.dto import QuestionDTO
 from flask_restx import Resource
 from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = QuestionDTO.api
 schema = QuestionDTO.schema
 list_schema = QuestionDTO.list_schema
 
-question_parser = reqparse.RequestParser()
-question_parser.add_argument("name", type=str, default=None, location="json")
-question_parser.add_argument("total_score", type=int, default=None, location="json")
-question_parser.add_argument("type_id", type=int, default=None, location="json")
+question_parser_add = reqparse.RequestParser()
+question_parser_add.add_argument("name", type=str, default=None, location="json")
+question_parser_add.add_argument("total_score", type=int, default=None, location="json")
+question_parser_add.add_argument("type_id", type=int, required=True, location="json")
+
+question_parser_edit = reqparse.RequestParser()
+question_parser_edit.add_argument("name", type=str, default=sentinel, location="json")
+question_parser_edit.add_argument("total_score", type=int, default=sentinel, location="json")
+question_parser_edit.add_argument("type_id", type=int, default=sentinel, location="json")
 
 
 @api.route("/questions")
@@ -34,7 +40,7 @@ class QuestionListForSlide(Resource):
 
     @protect_route(allowed_roles=["*"])
     def post(self, competition_id, slide_id):
-        args = question_parser.parse_args(strict=True)
+        args = question_parser_add.parse_args(strict=True)
         item = dbc.add.question(slide_id=slide_id, **args)
         return item_response(schema.dump(item))
 
@@ -49,7 +55,7 @@ class QuestionById(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, slide_id, question_id):
-        args = question_parser.parse_args(strict=True)
+        args = question_parser_edit.parse_args(strict=True)
 
         item_question = dbc.get.question(competition_id, slide_id, question_id)
         item_question = dbc.edit.default(item_question, **args)
diff --git a/server/app/apis/slides.py b/server/app/apis/slides.py
index 52553796260493507bcc47ef32f8977f241a2a88..52ce4cce1d20fc277c3ee9ec46ea3566a51ec633 100644
--- a/server/app/apis/slides.py
+++ b/server/app/apis/slides.py
@@ -4,16 +4,17 @@ from app.apis import item_response, list_response, protect_route
 from app.core.dto import SlideDTO
 from flask_restx import Resource
 from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = SlideDTO.api
 schema = SlideDTO.schema
 list_schema = SlideDTO.list_schema
 
-slide_parser = reqparse.RequestParser()
-slide_parser.add_argument("order", type=int, default=None, location="json")
-slide_parser.add_argument("title", type=str, default=None, location="json")
-slide_parser.add_argument("timer", type=int, default=None, location="json")
-slide_parser.add_argument("background_image_id", default=None, type=int, location="json")
+slide_parser_edit = reqparse.RequestParser()
+slide_parser_edit.add_argument("order", type=int, default=sentinel, location="json")
+slide_parser_edit.add_argument("title", type=str, default=sentinel, location="json")
+slide_parser_edit.add_argument("timer", type=int, default=sentinel, location="json")
+slide_parser_edit.add_argument("background_image_id", default=sentinel, type=int, location="json")
 
 
 @api.route("")
@@ -40,10 +41,10 @@ class Slides(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, slide_id):
-        args = slide_parser.parse_args(strict=True)
+        args = slide_parser_edit.parse_args(strict=True)
 
         item_slide = dbc.get.slide(competition_id, slide_id)
-        item_slide = dbc.edit.slide(item_slide, **args)
+        item_slide = dbc.edit.default(item_slide, **args)
 
         return item_response(schema.dump(item_slide))
 
@@ -60,7 +61,7 @@ class Slides(Resource):
 class SlideOrder(Resource):
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, slide_id):
-        args = slide_parser.parse_args(strict=True)
+        args = slide_parser_edit.parse_args(strict=True)
         order = args.get("order")
 
         item_slide = dbc.get.slide(competition_id, slide_id)
diff --git a/server/app/apis/teams.py b/server/app/apis/teams.py
index c951ae53e6b7839d1457e60ccce60ea398ee617d..71ca715d55d21de75f07db4241e5ef0bb14e1050 100644
--- a/server/app/apis/teams.py
+++ b/server/app/apis/teams.py
@@ -3,14 +3,17 @@ import app.database.controller as dbc
 from app.apis import item_response, list_response, protect_route
 from app.core.dto import TeamDTO
 from flask_restx import Resource, reqparse
-from flask_restx import reqparse
+from app.core.parsers import sentinel
 
 api = TeamDTO.api
 schema = TeamDTO.schema
 list_schema = TeamDTO.list_schema
 
-team_parser = reqparse.RequestParser()
-team_parser.add_argument("name", type=str, location="json")
+team_parser_add = reqparse.RequestParser()
+team_parser_add.add_argument("name", type=str, required=True, location="json")
+
+team_parser_edit = reqparse.RequestParser()
+team_parser_edit.add_argument("name", type=str, default=sentinel, location="json")
 
 
 @api.route("")
@@ -23,7 +26,7 @@ class TeamsList(Resource):
 
     @protect_route(allowed_roles=["*"])
     def post(self, competition_id):
-        args = team_parser.parse_args(strict=True)
+        args = team_parser_add.parse_args(strict=True)
         item_team = dbc.add.team(args["name"], competition_id)
         return item_response(schema.dump(item_team))
 
@@ -45,7 +48,7 @@ class Teams(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self, competition_id, team_id):
-        args = team_parser.parse_args(strict=True)
+        args = team_parser_edit.parse_args(strict=True)
         name = args.get("name")
 
         item_team = dbc.get.team(competition_id, team_id)
diff --git a/server/app/apis/users.py b/server/app/apis/users.py
index 50470db724ebf3648a2ff3a206a87b53650417ee..dc26ac5b64e9a4270215374de84f3c71cae66f9e 100644
--- a/server/app/apis/users.py
+++ b/server/app/apis/users.py
@@ -5,23 +5,23 @@ from app.core.dto import UserDTO
 from flask_jwt_extended import get_jwt_identity
 from flask_restx import Resource
 from flask_restx import inputs, reqparse
-from app.core.parsers import search_parser
+from app.core.parsers import search_parser, sentinel
 
 api = UserDTO.api
 schema = UserDTO.schema
 list_schema = UserDTO.list_schema
 
-user_parser = reqparse.RequestParser()
-user_parser.add_argument("email", type=inputs.email(), location="json")
-user_parser.add_argument("name", type=str, location="json")
-user_parser.add_argument("city_id", type=int, location="json")
-user_parser.add_argument("role_id", type=int, location="json")
+user_parser_edit = reqparse.RequestParser()
+user_parser_edit.add_argument("email", type=inputs.email(), default=sentinel, location="json")
+user_parser_edit.add_argument("name", type=str, default=sentinel, location="json")
+user_parser_edit.add_argument("city_id", type=int, default=sentinel, location="json")
+user_parser_edit.add_argument("role_id", type=int, default=sentinel, location="json")
 
 user_search_parser = search_parser.copy()
-user_search_parser.add_argument("name", type=str, default=None, location="args")
-user_search_parser.add_argument("email", type=str, default=None, location="args")
-user_search_parser.add_argument("city_id", type=int, default=None, location="args")
-user_search_parser.add_argument("role_id", type=int, default=None, location="args")
+user_search_parser.add_argument("name", type=str, default=sentinel, location="args")
+user_search_parser.add_argument("email", type=str, default=sentinel, location="args")
+user_search_parser.add_argument("city_id", type=int, default=sentinel, location="args")
+user_search_parser.add_argument("role_id", type=int, default=sentinel, location="args")
 
 
 def _edit_user(item_user, args):
@@ -47,7 +47,7 @@ class UsersList(Resource):
 
     @protect_route(allowed_roles=["*"])
     def put(self):
-        args = user_parser.parse_args(strict=True)
+        args = user_parser_edit.parse_args(strict=True)
         item = dbc.get.user(get_jwt_identity())
         item = _edit_user(item, args)
         return item_response(schema.dump(item))
@@ -63,7 +63,7 @@ class Users(Resource):
 
     @protect_route(allowed_roles=["Admin"])
     def put(self, ID):
-        args = user_parser.parse_args(strict=True)
+        args = user_parser_edit.parse_args(strict=True)
         item = dbc.get.user(ID)
         item = _edit_user(item, args)
         return item_response(schema.dump(item))
diff --git a/server/app/core/parsers.py b/server/app/core/parsers.py
index c695dd230b208d95fff4eaba14f12c9732042376..160d67a0af7b58483202c00c1ec6b97097de0633 100644
--- a/server/app/core/parsers.py
+++ b/server/app/core/parsers.py
@@ -1,5 +1,22 @@
 from flask_restx import inputs, reqparse
 
+
+class Sentinel:
+    """
+    Sentinel is used as default argument to parsers if it isn't necessary to
+    supply a value. This is used instead of None so that None can be supplied
+    as value.
+    """
+
+    def __repr__(self):
+        return "Sentinel"
+
+    def __bool__(self):
+        return False
+
+
+sentinel = Sentinel()
+
 ###SEARCH####
 search_parser = reqparse.RequestParser()
 search_parser.add_argument("page", type=int, default=0, location="args")
diff --git a/server/app/core/schemas.py b/server/app/core/schemas.py
index 0abe02526ef28041e7c0722fc5aa0b0bc5e7f55d..4008b8869cc084022d4d46386d89ec29ca1765d2 100644
--- a/server/app/core/schemas.py
+++ b/server/app/core/schemas.py
@@ -161,6 +161,8 @@ class ComponentSchema(BaseSchema):
     h = ma.auto_field()
     slide_id = ma.auto_field()
     type_id = ma.auto_field()
+    view_type_id = ma.auto_field()
 
     text = fields.fields.String()
     media = fields.Nested(MediaSchema, many=False)
+    question_id = fields.fields.Integer()
\ No newline at end of file
diff --git a/server/app/core/sockets.py b/server/app/core/sockets.py
index 66c40b627a6a88f03228c22410a7c4258745a0bd..280529fc102a29fc706b24ec68f268d324520d86 100644
--- a/server/app/core/sockets.py
+++ b/server/app/core/sockets.py
@@ -1,11 +1,12 @@
+import logging
+
 import app.database.controller as dbc
 from app.core import db
-from app.database.models import Competition, Slide, Team, ViewType, Code
+from app.database.models import Code, Competition, Slide, Team, ViewType
 from flask.globals import request
-from flask_socketio import SocketIO, emit, join_room
-import logging
 from flask_jwt_extended import verify_jwt_in_request
 from flask_jwt_extended.utils import get_jwt_claims
+from flask_socketio import SocketIO, emit, join_room
 
 logger = logging.getLogger(__name__)
 logger.propagate = False
@@ -69,6 +70,7 @@ def disconnect():
     logger.info(f"Client '{request.sid}' disconnected")
 
 
+@protect_route(allowed_views=["Operator"])
 @sio.on("start_presentation")
 def start_presentation(data):
     competition_id = data["competition_id"]
@@ -91,6 +93,7 @@ def start_presentation(data):
     logger.info(f"Client '{request.sid}' started competition '{competition_id}'")
 
 
+@protect_route(allowed_views=["Operator"])
 @sio.on("end_presentation")
 def end_presentation(data):
     competition_id = data["competition_id"]
@@ -155,8 +158,8 @@ def join_presentation(data):
     logger.info(f"Client '{request.sid}' joined competition '{competition_id}'")
 
 
-@sio.on("set_slide")
 @protect_route(allowed_views=["Operator"])
+@sio.on("set_slide")
 def set_slide(data):
     competition_id = data["competition_id"]
     slide_order = data["slide_order"]
@@ -195,6 +198,7 @@ def set_slide(data):
     logger.info(f"Client '{request.sid}' set slide '{slide_order}' in competition '{competition_id}'")
 
 
+@protect_route(allowed_views=["Operator"])
 @sio.on("set_timer")
 def set_timer(data):
     competition_id = data["competition_id"]
diff --git a/server/app/database/controller/add.py b/server/app/database/controller/add.py
index 57e41705cb06f500c8678510ac1ba0629eb9c0e7..6c5ea14bcd143a4bac5d0f214fc3d14f8f73bfe0 100644
--- a/server/app/database/controller/add.py
+++ b/server/app/database/controller/add.py
@@ -20,6 +20,7 @@ from app.database.models import (
     Question,
     QuestionAlternative,
     QuestionAnswer,
+    QuestionComponent,
     QuestionType,
     Role,
     Slide,
@@ -37,6 +38,8 @@ from sqlalchemy.orm import relation
 from sqlalchemy.orm.session import sessionmaker
 from flask import current_app
 
+from app.database.types import ID_IMAGE_COMPONENT, ID_QUESTION_COMPONENT, ID_TEXT_COMPONENT
+
 
 def db_add(item):
     """
@@ -59,7 +62,7 @@ def db_add(item):
     return item
 
 
-def component(type_id, slide_id, x=0, y=0, w=0, h=0, **data):
+def component(type_id, slide_id, view_type_id, x=0, y=0, w=0, h=0, **data):
     """
     Adds a component to the slide at the specified coordinates with the
     provided size and data .
@@ -79,12 +82,15 @@ def component(type_id, slide_id, x=0, y=0, w=0, h=0, **data):
         w *= ratio
         h *= ratio
 
-    if type_id == 1:
-        item = db_add(TextComponent(slide_id, type_id, x, y, w, h))
+    if type_id == ID_TEXT_COMPONENT:
+        item = db_add(TextComponent(slide_id, type_id, view_type_id, x, y, w, h))
         item.text = data.get("text")
-    elif type_id == 2:
-        item = db_add(ImageComponent(slide_id, type_id, x, y, w, h))
+    elif type_id == ID_IMAGE_COMPONENT:
+        item = db_add(ImageComponent(slide_id, type_id, view_type_id, x, y, w, h))
         item.media_id = data.get("media_id")
+    elif type_id == ID_QUESTION_COMPONENT:
+        item = db_add(QuestionComponent(slide_id, type_id, view_type_id, x, y, w, h))
+        item.question_id = data.get("question_id")
     else:
         abort(codes.BAD_REQUEST, f"Invalid type_id{type_id}")
 
diff --git a/server/app/database/controller/copy.py b/server/app/database/controller/copy.py
index 7e9d28d02381dfe36e2a0c7792745618b595588e..a32ba1deda39c231bfa7ea2b26f91337e0ee2bec 100644
--- a/server/app/database/controller/copy.py
+++ b/server/app/database/controller/copy.py
@@ -4,6 +4,7 @@ This file contains functionality to copy and duplicate data to the database.
 
 from app.database.controller import add, get, search, utils
 from app.database.models import Question
+from app.database.types import ID_IMAGE_COMPONENT, ID_QUESTION_COMPONENT, ID_TEXT_COMPONENT
 
 
 def _alternative(item_old, question_id):
@@ -38,13 +39,16 @@ def _component(item_component, item_slide_new):
     component item to the specified slide.
     """
     data = {}
-    if item_component.type_id == 1:
+    if item_component.type_id == ID_TEXT_COMPONENT:
         data["text"] = item_component.text
-    elif item_component.type_id == 2:
+    elif item_component.type_id == ID_IMAGE_COMPONENT:
         data["media_id"] = item_component.media_id
+    elif item_component.type_id == ID_QUESTION_COMPONENT:
+        data["question_id"] = item_component.question_id
     add.component(
         item_component.type_id,
         item_slide_new.id,
+        item_component.view_type_id,
         item_component.x,
         item_component.y,
         item_component.w,
diff --git a/server/app/database/controller/edit.py b/server/app/database/controller/edit.py
index 94bc6008a1f5b8173df1ddbba7d6745f7c6ea5f0..efb4909696cf2ae911a2451e1427b60b460f1153 100644
--- a/server/app/database/controller/edit.py
+++ b/server/app/database/controller/edit.py
@@ -3,6 +3,7 @@ This file contains functionality to get data from the database.
 """
 
 from app.core import db
+from app.core.parsers import sentinel
 
 
 def switch_order(item1, item2):
@@ -46,22 +47,8 @@ def default(item, **kwargs):
     for key, value in kwargs.items():
         if not hasattr(item, key):
             raise AttributeError(f"Item of type {type(item)} has no attribute '{key}'")
-        if value is not None:
+        if value is not sentinel:
             setattr(item, key, value)
     db.session.commit()
     db.session.refresh(item)
     return item
-
-
-def competition(item, **kwargs):
-    if kwargs["background_image_id"] == -1:
-        item.background_image_id = None
-        del kwargs["background_image_id"]
-    return default(item, **kwargs)
-
-
-def slide(item, **kwargs):
-    if kwargs["background_image_id"] == -1:
-        item.background_image_id = None
-        del kwargs["background_image_id"]
-    return default(item, **kwargs)
\ No newline at end of file
diff --git a/server/app/database/models.py b/server/app/database/models.py
index b697b830cf2a8c4d55d3fb69a5be56ceececa50e..f9f18438ad07edf951cebd24ad7ab92e9b854299 100644
--- a/server/app/database/models.py
+++ b/server/app/database/models.py
@@ -1,7 +1,7 @@
 from app.core import bcrypt, db
 from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property
 
-from app.database.types import ID_IMAGE_COMPONENT, ID_TEXT_COMPONENT
+from app.database.types import ID_IMAGE_COMPONENT, ID_QUESTION_COMPONENT, ID_TEXT_COMPONENT
 
 STRING_SIZE = 254
 
@@ -199,13 +199,14 @@ class Component(db.Model):
 
     __mapper_args__ = {"polymorphic_on": type_id}
 
-    def __init__(self, slide_id, type_id, x=0, y=0, w=1, h=1):
+    def __init__(self, slide_id, type_id, view_type_id, x=0, y=0, w=1, h=1):
         self.x = x
         self.y = y
         self.w = w
         self.h = h
         self.slide_id = slide_id
         self.type_id = type_id
+        self.view_type_id = view_type_id
 
 
 class TextComponent(Component):
@@ -223,6 +224,13 @@ class ImageComponent(Component):
     __mapper_args__ = {"polymorphic_identity": ID_IMAGE_COMPONENT}
 
 
+class QuestionComponent(Component):
+    question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=True)
+
+    # __tablename__ = None
+    __mapper_args__ = {"polymorphic_identity": ID_QUESTION_COMPONENT}
+
+
 class Code(db.Model):
     id = db.Column(db.Integer, primary_key=True)
     code = db.Column(db.Text, unique=True)
diff --git a/server/app/database/types.py b/server/app/database/types.py
index 236e50f5278d03684f2cbdcc05c2e7637e21a057..f53835eccf10599eb9ab81d8af1426e02a21e405 100644
--- a/server/app/database/types.py
+++ b/server/app/database/types.py
@@ -1,2 +1,3 @@
 ID_TEXT_COMPONENT = 1
 ID_IMAGE_COMPONENT = 2
+ID_QUESTION_COMPONENT = 3
\ No newline at end of file
diff --git a/server/populate.py b/server/populate.py
index 6a4be4ef42cbe14d938466282c6db2addb92dc57..e0bb0bd94faf1b210069d7507d48e3f740157209 100644
--- a/server/populate.py
+++ b/server/populate.py
@@ -86,7 +86,13 @@ def _add_items():
                 y = random.randrange(1, 500)
                 w = random.randrange(150, 400)
                 h = random.randrange(150, 400)
-                dbc.add.component(1, item_slide.id, x, y, w, h, text=f"hej{k}")
+                dbc.add.component(1, item_slide.id, 1, x, y, w, h, text=f"hej{k}")
+            for k in range(3):
+                x = random.randrange(1, 500)
+                y = random.randrange(1, 500)
+                w = random.randrange(150, 400)
+                h = random.randrange(150, 400)
+                dbc.add.component(1, item_slide.id, 3, x, y, w, h, text=f"hej{k}")
 
         # item_slide = dbc.add.slide(item_comp)
         # item_slide.title = f"Slide {len(item_comp.slides)}"
diff --git a/server/tests/test_helpers.py b/server/tests/test_helpers.py
index 5dabdbbe5508538291ce9eb52e078c21c8995132..f55aa68251a5a3b9ea73411c959939acc93f1bc6 100644
--- a/server/tests/test_helpers.py
+++ b/server/tests/test_helpers.py
@@ -73,7 +73,7 @@ def add_default_values():
             # dbc.add.question(name=f"Q{i+1}", total_score=i + 1, type_id=1, slide_id=item_slide.id)
 
             # Add text component
-            dbc.add.component(1, item_slide.id, i, 2 * i, 3 * i, 4 * i, text="Text")
+            dbc.add.component(1, item_slide.id, 1, i, 2 * i, 3 * i, 4 * i, text="Text")
 
 
 def get_body(response):