From 0ce33754074dfeb5b9787ccee82300f3d73bbc9a Mon Sep 17 00:00:00 2001
From: Emil <Emil>
Date: Tue, 27 Apr 2021 17:01:41 +0200
Subject: [PATCH] fix: competition settings styling

---
 client/src/Main.tsx                           |   2 +-
 .../PresentationEditorPage.tsx                |  21 +-
 .../components/CompetitionSettings.tsx        | 207 +++++-------------
 .../components/SlideSettings.tsx              |  30 +--
 .../presentationEditor/components/Teams.tsx   | 100 +++++++++
 .../components/TextComponentEdit.tsx          |  11 +-
 .../slideSettingsComponents/Images.tsx        |   9 +-
 .../slideSettingsComponents/Instructions.tsx  |  11 +-
 .../QuestionSettings.tsx                      |  21 +-
 .../slideSettingsComponents/SlideType.tsx     |  98 +++++----
 .../slideSettingsComponents/Texts.tsx         |   5 +-
 .../presentationEditor/components/styled.tsx  |  23 +-
 client/src/pages/views/JudgeViewPage.tsx      |   1 -
 13 files changed, 260 insertions(+), 279 deletions(-)
 create mode 100644 client/src/pages/presentationEditor/components/Teams.tsx

diff --git a/client/src/Main.tsx b/client/src/Main.tsx
index b7c74b55..b999a977 100644
--- a/client/src/Main.tsx
+++ b/client/src/Main.tsx
@@ -22,7 +22,7 @@ const Main: React.FC = () => {
       <Switch>
         <SecureRoute login exact path="/" component={LoginPage} />
         <SecureRoute path="/admin" component={AdminPage} />
-        <SecureRoute path="/editor/competition-id=:id" component={PresentationEditorPage} />
+        <SecureRoute path="/editor/competition-id=:competitionId" component={PresentationEditorPage} />
         <Route exact path="/:code" component={ViewSelectPage} />
         <Route exact path="/participant/id=:id&code=:code" component={ParticipantViewPage} />
         <SecureRoute exact path="/presenter/id=:id&code=:code" component={PresenterViewPage} />
diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
index 5ce395e2..3c86afe9 100644
--- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx
+++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx
@@ -83,18 +83,18 @@ const useStyles = makeStyles((theme: Theme) =>
 )
 
 interface CompetitionParams {
-  id: string
+  competitionId: string
 }
 
 const PresentationEditorPage: React.FC = () => {
   const classes = useStyles()
-  const { id }: CompetitionParams = useParams()
+  const { competitionId }: CompetitionParams = useParams()
   const dispatch = useAppDispatch()
   const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
   const competition = useAppSelector((state) => state.editor.competition)
   const competitionLoading = useAppSelector((state) => state.editor.loading)
   useEffect(() => {
-    dispatch(getEditorCompetition(id))
+    dispatch(getEditorCompetition(competitionId))
     dispatch(getCities())
     dispatch(getTypes())
   }, [])
@@ -104,8 +104,8 @@ const PresentationEditorPage: React.FC = () => {
   }
 
   const createNewSlide = async () => {
-    await axios.post(`/api/competitions/${id}/slides`, { title: 'new slide' })
-    dispatch(getEditorCompetition(id))
+    await axios.post(`/api/competitions/${competitionId}/slides`, { title: 'new slide' })
+    dispatch(getEditorCompetition(competitionId))
   }
 
   const [contextState, setContextState] = React.useState<{
@@ -128,14 +128,14 @@ const PresentationEditorPage: React.FC = () => {
   }
 
   const handleRemoveSlide = async () => {
-    await axios.delete(`/api/competitions/${id}/slides/${contextState.slideId}`)
-    dispatch(getEditorCompetition(id))
+    await axios.delete(`/api/competitions/${competitionId}/slides/${contextState.slideId}`)
+    dispatch(getEditorCompetition(competitionId))
     setContextState(initialState)
   }
 
   const handleDuplicateSlide = async () => {
-    await axios.post(`/api/competitions/${id}/slides/${contextState.slideId}/copy`)
-    dispatch(getEditorCompetition(id))
+    await axios.post(`/api/competitions/${competitionId}/slides/${contextState.slideId}/copy`)
+    dispatch(getEditorCompetition(competitionId))
     setContextState(initialState)
   }
 
@@ -188,9 +188,6 @@ const PresentationEditorPage: React.FC = () => {
             <ViewButton variant="contained" color="secondary">
               Deltagarvy
             </ViewButton>
-            <ViewButton variant="contained" color="secondary">
-              Domarvy
-            </ViewButton>
           </ViewButtonGroup>
         </ToolBarContainer>
       </AppBar>
diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
index 53c2ecdb..7ea2a84f 100644
--- a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
+++ b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx
@@ -1,14 +1,7 @@
 import {
-  Button,
-  Dialog,
-  DialogActions,
-  DialogContent,
-  DialogContentText,
-  DialogTitle,
   Divider,
   FormControl,
   InputLabel,
-  List,
   ListItem,
   ListItemText,
   MenuItem,
@@ -16,84 +9,44 @@ import {
   TextField,
   Typography,
 } from '@material-ui/core'
-import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
-import CloseIcon from '@material-ui/icons/Close'
+import { Center, ImportedImage, SettingsList, PanelContainer, FirstItem, AddButton } from './styled'
 import axios from 'axios'
 import React, { useState } from 'react'
 import { useParams } from 'react-router-dom'
 import { getEditorCompetition } from '../../../actions/editor'
 import { useAppDispatch, useAppSelector } from '../../../hooks'
 import { City } from '../../../interfaces/ApiModels'
-
-const useStyles = makeStyles((theme: Theme) =>
-  createStyles({
-    textInputContainer: {
-      '& > *': {
-        margin: theme.spacing(1),
-        width: '100%',
-        background: 'white',
-      },
-    },
-    textInput: {
-      margin: theme.spacing(2),
-      width: '87%',
-      background: 'white',
-    },
-    textCenter: {
-      textAlign: 'center',
-    },
-    center: {
-      display: 'flex',
-      justifyContent: 'center',
-      background: 'white',
-    },
-    importedImage: {
-      width: 70,
-      height: 50,
-      background: 'white',
-    },
-    dropDown: {
-      margin: theme.spacing(2),
-      width: '87%',
-      background: 'white',
-    },
-    addButtons: {
-      padding: 5,
-    },
-    panelList: {
-      padding: 0,
-    },
-  })
-)
+import Teams from './Teams'
 
 interface CompetitionParams {
-  id: string
+  competitionId: string
 }
 
 const CompetitionSettings: React.FC = () => {
-  const classes = useStyles()
-  const { id }: CompetitionParams = useParams()
+  const { competitionId }: CompetitionParams = useParams()
   const dispatch = useAppDispatch()
   const competition = useAppSelector((state) => state.editor.competition)
+  const cities = useAppSelector((state) => state.cities.cities)
+
   const updateCompetitionName = async (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
     await axios
-      .put(`/api/competitions/${id}`, { name: event.target.value })
+      .put(`/api/competitions/${competitionId}`, { name: event.target.value })
       .then(() => {
-        dispatch(getEditorCompetition(id))
+        dispatch(getEditorCompetition(competitionId))
       })
       .catch(console.log)
   }
 
-  const cities = useAppSelector((state) => state.cities.cities)
   const updateCompetitionCity = async (city: City) => {
     await axios
-      .put(`/api/competitions/${id}`, { city_id: city.id })
+      .put(`/api/competitions/${competitionId}`, { city_id: city.id })
       .then(() => {
-        dispatch(getEditorCompetition(id))
+        dispatch(getEditorCompetition(competitionId))
       })
       .catch(console.log)
   }
 
+  /* Finds the right city object from a city name */
   const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
     cities.forEach((city) => {
       if (event.target.value === city.name) {
@@ -102,109 +55,55 @@ const CompetitionSettings: React.FC = () => {
     })
   }
 
-  const removeTeam = async (tid: number) => {
-    await axios
-      .delete(`/api/competitions/${id}/teams/${tid}`)
-      .then(() => {
-        dispatch(getEditorCompetition(id))
-      })
-      .catch(console.log)
-  }
-  const addTeam = async () => {
-    setAddTeamOpen(false)
-    await axios
-      .post(`/api/competitions/${id}/teams`, { name: selectedTeamName })
-      .then(() => {
-        dispatch(getEditorCompetition(id))
-      })
-      .catch(console.log)
-  }
-  // For "add team" dialog
-  const [addTeamOpen, setAddTeamOpen] = useState(false)
-  const openAddTeam = () => {
-    setAddTeamOpen(true)
-  }
-  const closeAddTeam = () => {
-    setAddTeamOpen(false)
-  }
-  let selectedTeamName = ''
-  const updateSelectedTeamName = (event: React.ChangeEvent<{ value: string }>) => {
-    selectedTeamName = event.target.value
-  }
-
   return (
-    <div className={classes.textInputContainer}>
-      <form noValidate autoComplete="off">
-        <TextField
-          className={classes.textInput}
-          id="outlined-basic"
-          label={'Tävlingsnamn'}
-          defaultValue={competition.name}
-          onChange={updateCompetitionName}
-          variant="outlined"
-        />
+    <PanelContainer>
+      <SettingsList>
+        <FirstItem>
+          <ListItem>
+            <TextField
+              id="outlined-basic"
+              label={'Tävlingsnamn'}
+              defaultValue={competition.name}
+              onChange={updateCompetitionName}
+              variant="outlined"
+              fullWidth={true}
+            />
+          </ListItem>
+        </FirstItem>
         <Divider />
-        <FormControl variant="outlined" className={classes.dropDown}>
-          <InputLabel>Region</InputLabel>
-          <Select
-            value={cities.find((city) => city.id === competition.city_id)?.name || ''}
-            label="Region"
-            onChange={handleChange}
-          >
-            {cities.map((city) => (
-              <MenuItem value={city.name} key={city.name}>
-                <Button>{city.name}</Button>
-              </MenuItem>
-            ))}
-          </Select>
-        </FormControl>
-      </form>
 
-      <List className={classes.panelList}>
         <ListItem>
-          <ListItemText className={classes.textCenter} primary="Lag" />
+          <FormControl fullWidth variant="outlined">
+            <InputLabel>Region</InputLabel>
+            <Select
+              value={cities.find((city) => city.id === competition.city_id)?.name || ''}
+              label="Region"
+              onChange={handleChange}
+            >
+              {cities.map((city) => (
+                <MenuItem value={city.name} key={city.name}>
+                  <Typography variant="button">{city.name}</Typography>
+                </MenuItem>
+              ))}
+            </Select>
+          </FormControl>
         </ListItem>
-        {competition.teams &&
-          competition.teams.map((team) => (
-            <div key={team.id}>
-              <ListItem divider button>
-                <ListItemText primary={team.name} />
-                <CloseIcon onClick={() => removeTeam(team.id)} />
-              </ListItem>
-            </div>
-          ))}
+      </SettingsList>
 
-        <ListItem className={classes.center} button onClick={openAddTeam}>
-          <Typography className={classes.addButtons} variant="button">
-            Lägg till lag
-          </Typography>
-        </ListItem>
-        <Dialog open={addTeamOpen} onClose={closeAddTeam}>
-          <DialogTitle className={classes.center}>Lägg till lag</DialogTitle>
-          <DialogContent>
-            <DialogContentText>Skriv namnet på laget och klicka sedan på bekräfta.</DialogContentText>
-            <TextField autoFocus margin="dense" label="Lagnamn" fullWidth onChange={updateSelectedTeamName} />
-          </DialogContent>
-          <DialogActions>
-            <Button onClick={closeAddTeam} color="secondary">
-              Avbryt
-            </Button>
-            <Button onClick={addTeam} color="primary">
-              Bekräfta
-            </Button>
-          </DialogActions>
-        </Dialog>
-      </List>
+      <Teams competitionId={competitionId} />
 
-      <ListItem button>
-        <img
-          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"
-          className={classes.importedImage}
-        />
-        <ListItemText className={classes.textCenter}>Välj bakgrundsbild ...</ListItemText>
-      </ListItem>
-    </div>
+      <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>
+    </PanelContainer>
   )
 }
 
diff --git a/client/src/pages/presentationEditor/components/SlideSettings.tsx b/client/src/pages/presentationEditor/components/SlideSettings.tsx
index 2f403f41..278887c1 100644
--- a/client/src/pages/presentationEditor/components/SlideSettings.tsx
+++ b/client/src/pages/presentationEditor/components/SlideSettings.tsx
@@ -7,18 +7,18 @@ import { useAppSelector } from '../../../hooks'
 import Instructions from './slideSettingsComponents/Instructions'
 import MultipleChoiceAlternatives from './slideSettingsComponents/MultipleChoiceAlternatives'
 import SlideType from './slideSettingsComponents/SlideType'
-import { Center, ImportedImage, SettingsList, SlidePanel } from './styled'
+import { Center, ImportedImage, SettingsList, PanelContainer } from './styled'
 import Timer from './slideSettingsComponents/Timer'
 import Images from './slideSettingsComponents/Images'
 import Texts from './slideSettingsComponents/Texts'
 import QuestionSettings from './slideSettingsComponents/QuestionSettings'
 
 interface CompetitionParams {
-  id: string
+  competitionId: string
 }
 
 const SlideSettings: React.FC = () => {
-  const { id }: CompetitionParams = useParams()
+  const { competitionId }: CompetitionParams = useParams()
 
   const activeSlide = useAppSelector((state) =>
     // Gets the slide with id=activeSlideId from the database.
@@ -26,26 +26,30 @@ const SlideSettings: React.FC = () => {
   )
 
   return (
-    <SlidePanel>
+    <PanelContainer>
       <SettingsList>
-        {activeSlide && <SlideType activeSlide={activeSlide} competitionId={id} />}
+        {activeSlide && <SlideType activeSlide={activeSlide} competitionId={competitionId} />}
         <Divider />
-        {activeSlide && <Timer activeSlide={activeSlide} competitionId={id} />}
+        {activeSlide && <Timer activeSlide={activeSlide} competitionId={competitionId} />}
       </SettingsList>
 
-      {activeSlide?.questions[0] && <QuestionSettings activeSlide={activeSlide} competitionId={id} />}
+      {activeSlide?.questions[0] && <QuestionSettings activeSlide={activeSlide} competitionId={competitionId} />}
       {
         // Choose answer alternatives depending on the slide type
       }
-      {activeSlide?.questions[0]?.type_id === 1 && <Instructions activeSlide={activeSlide} competitionId={id} />}
-      {activeSlide?.questions[0]?.type_id === 2 && <Instructions activeSlide={activeSlide} competitionId={id} />}
+      {activeSlide?.questions[0]?.type_id === 1 && (
+        <Instructions activeSlide={activeSlide} competitionId={competitionId} />
+      )}
+      {activeSlide?.questions[0]?.type_id === 2 && (
+        <Instructions activeSlide={activeSlide} competitionId={competitionId} />
+      )}
       {activeSlide?.questions[0]?.type_id === 3 && (
-        <MultipleChoiceAlternatives activeSlide={activeSlide} competitionId={id} />
+        <MultipleChoiceAlternatives activeSlide={activeSlide} competitionId={competitionId} />
       )}
 
-      {activeSlide && <Texts activeSlide={activeSlide} competitionId={id} />}
+      {activeSlide && <Texts activeSlide={activeSlide} competitionId={competitionId} />}
 
-      {activeSlide && <Images activeSlide={activeSlide} competitionId={id} />}
+      {activeSlide && <Images activeSlide={activeSlide} competitionId={competitionId} />}
 
       <SettingsList>
         <ListItem button>
@@ -58,7 +62,7 @@ const SlideSettings: React.FC = () => {
           </Center>
         </ListItem>
       </SettingsList>
-    </SlidePanel>
+    </PanelContainer>
   )
 }
 
diff --git a/client/src/pages/presentationEditor/components/Teams.tsx b/client/src/pages/presentationEditor/components/Teams.tsx
new file mode 100644
index 00000000..564dbc84
--- /dev/null
+++ b/client/src/pages/presentationEditor/components/Teams.tsx
@@ -0,0 +1,100 @@
+import {
+  Button,
+  Dialog,
+  DialogActions,
+  DialogContent,
+  DialogContentText,
+  DialogTitle,
+  ListItem,
+  ListItemText,
+  TextField,
+} from '@material-ui/core'
+import axios from 'axios'
+import React, { useState } from 'react'
+import { getEditorCompetition } from '../../../actions/editor'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
+import { Center, Clickable } from './styled'
+import { AddButton, SettingsList } from './styled'
+import CloseIcon from '@material-ui/icons/Close'
+
+type TeamsProps = {
+  competitionId: string
+}
+
+const Teams = ({ competitionId }: TeamsProps) => {
+  const dispatch = useAppDispatch()
+  const competition = useAppSelector((state) => state.editor.competition)
+  const addTeam = async () => {
+    setAddTeamOpen(false)
+    await axios
+      .post(`/api/competitions/${competitionId}/teams`, { name: selectedTeamName })
+      .then(() => {
+        dispatch(getEditorCompetition(competitionId))
+      })
+      .catch(console.log)
+  }
+  // For "add team" dialog
+  const [addTeamOpen, setAddTeamOpen] = useState(false)
+  const openAddTeam = () => {
+    setAddTeamOpen(true)
+  }
+  const closeAddTeam = () => {
+    setAddTeamOpen(false)
+  }
+  let selectedTeamName = ''
+  const updateSelectedTeamName = (event: React.ChangeEvent<{ value: string }>) => {
+    selectedTeamName = event.target.value
+  }
+
+  const removeTeam = async (tid: number) => {
+    await axios
+      .delete(`/api/competitions/${competitionId}/teams/${tid}`)
+      .then(() => {
+        dispatch(getEditorCompetition(competitionId))
+      })
+      .catch(console.log)
+  }
+
+  return (
+    <SettingsList>
+      <ListItem divider>
+        <Center>
+          <ListItemText primary="Lag" />
+        </Center>
+      </ListItem>
+      {competition.teams &&
+        competition.teams.map((team) => (
+          <div key={team.id}>
+            <ListItem divider>
+              <ListItemText primary={team.name} />
+              <Clickable>
+                <CloseIcon onClick={() => removeTeam(team.id)} />
+              </Clickable>
+            </ListItem>
+          </div>
+        ))}
+      <ListItem button onClick={openAddTeam}>
+        <Center>
+          <AddButton variant="button">Lägg till lag</AddButton>
+        </Center>
+      </ListItem>
+      <Dialog open={addTeamOpen} onClose={closeAddTeam}>
+        <DialogTitle>Lägg till lag</DialogTitle>
+        <DialogContent>
+          <DialogContentText>Skriv namnet på laget och klicka sedan på bekräfta.</DialogContentText>
+          <TextField autoFocus margin="dense" label="Lagnamn" fullWidth onChange={updateSelectedTeamName} />
+        </DialogContent>
+        <DialogActions>
+          <Button onClick={closeAddTeam} color="secondary">
+            Avbryt
+          </Button>
+          <Button onClick={addTeam} color="primary">
+            Bekräfta
+          </Button>
+        </DialogActions>
+      </Dialog>
+    </SettingsList>
+  )
+}
+
+export default Teams
diff --git a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
index 8ef64b27..b03696f3 100644
--- a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
+++ b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx
@@ -12,12 +12,11 @@ type ImageComponentProps = {
 }
 
 interface CompetitionParams {
-  id: string
+  competitionId: string
 }
 
 const TextComponentEdit = ({ component }: ImageComponentProps) => {
-  const { id }: CompetitionParams = useParams()
-  const competitionId = useAppSelector((state) => state.editor.competition.id)
+  const { competitionId }: CompetitionParams = useParams()
   const [content, setContent] = useState('')
   const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined)
   const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
@@ -40,14 +39,14 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => {
         await axios.put(`/api/competitions/${competitionId}/slides/${activeSlideId}/components/${component.id}`, {
           text: newText,
         })
-        dispatch(getEditorCompetition(id))
+        dispatch(getEditorCompetition(competitionId))
       }, 250)
     )
   }
 
   const handleDeleteText = async (componentId: number) => {
-    await axios.delete(`/api/competitions/${id}/slides/${activeSlideId}/components/${componentId}`)
-    dispatch(getEditorCompetition(id))
+    await axios.delete(`/api/competitions/${competitionId}/slides/${activeSlideId}/components/${componentId}`)
+    dispatch(getEditorCompetition(competitionId))
   }
 
   return (
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
index 0a0d1233..6080b225 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx
@@ -2,14 +2,13 @@
  */
 import { ListItem, ListItemText, Typography } from '@material-ui/core'
 import CloseIcon from '@material-ui/icons/Close'
-import React, { useState } from 'react'
-import { useDispatch } from 'react-redux'
+import React from 'react'
 import { Center, HiddenInput, SettingsList, AddImageButton, ImportedImage, AddButton } from '../styled'
 import axios from 'axios'
 import { getEditorCompetition } from '../../../../actions/editor'
 import { RichSlide } from '../../../../interfaces/ApiRichModels'
 import { ImageComponent, Media } from '../../../../interfaces/ApiModels'
-import { useAppSelector } from '../../../../hooks'
+import { useAppDispatch, useAppSelector } from '../../../../hooks'
 
 type ImagesProps = {
   activeSlide: RichSlide
@@ -17,7 +16,7 @@ type ImagesProps = {
 }
 
 const Images = ({ activeSlide, competitionId }: ImagesProps) => {
-  const dispatch = useDispatch()
+  const dispatch = useAppDispatch()
 
   const uploadFile = async (formData: FormData) => {
     // Uploads the file to the server and creates a Media object in database.
@@ -107,7 +106,7 @@ const Images = ({ activeSlide, competitionId }: ImagesProps) => {
           </div>
         ))}
 
-      <ListItem button>
+      <ListItem button style={{ padding: 0 }}>
         <HiddenInput accept="image/*" id="contained-button-file" multiple type="file" onChange={handleFileSelected} />
         <AddImageButton htmlFor="contained-button-file">
           <AddButton variant="button">Lägg till bild</AddButton>
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
index 97b27c9d..858dd75e 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Instructions.tsx
@@ -1,9 +1,8 @@
 import { ListItem, ListItemText, TextField, withStyles } from '@material-ui/core'
 import axios from 'axios'
 import React from 'react'
-import { useDispatch } from 'react-redux'
 import { getEditorCompetition } from '../../../../actions/editor'
-import { useAppDispatch, useAppSelector } from '../../../../hooks'
+import { useAppDispatch } from '../../../../hooks'
 import { RichSlide } from '../../../../interfaces/ApiRichModels'
 import { Center, SettingsList } from '../styled'
 
@@ -13,12 +12,10 @@ type InstructionsProps = {
 }
 
 const Instructions = ({ activeSlide, competitionId }: InstructionsProps) => {
-  const dispatch = useDispatch()
+  const dispatch = useAppDispatch()
   const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined)
-  const activeSlideId = useAppSelector((state) => state.editor.activeSlideId)
 
   const updateInstructionsText = async (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
-    /* TODO: Implement instructions field in question and add put API
     if (timerHandle) {
       clearTimeout(timerHandle)
       setTimerHandle(undefined)
@@ -29,10 +26,11 @@ const Instructions = ({ activeSlide, competitionId }: InstructionsProps) => {
         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
             .put(
               `/api/competitions/${competitionId}/slides/${activeSlide.id}/questions/${activeSlide.questions[0].id}`,
               {
-                name: event.target.value,
+                instructions: event.target.value,
               }
             )
             .then(() => {
@@ -42,7 +40,6 @@ const Instructions = ({ activeSlide, competitionId }: InstructionsProps) => {
         }
       }, 250)
     )
-    */
   }
 
   return (
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
index 62afda68..2bc10b35 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/QuestionSettings.tsx
@@ -1,7 +1,6 @@
 import { ListItem, ListItemText, TextField } from '@material-ui/core'
 import axios from 'axios'
 import React, { useEffect, useState } from 'react'
-import { useDispatch } from 'react-redux'
 import { getEditorCompetition } from '../../../../actions/editor'
 import { useAppDispatch } from '../../../../hooks'
 import { RichSlide } from '../../../../interfaces/ApiRichModels'
@@ -13,7 +12,7 @@ type QuestionSettingsProps = {
 }
 
 const QuestionSettings = ({ activeSlide, competitionId }: QuestionSettingsProps) => {
-  const dispatch = useDispatch()
+  const dispatch = useAppDispatch()
 
   const updateQuestion = async (
     updateTitle: boolean,
@@ -57,16 +56,14 @@ const QuestionSettings = ({ activeSlide, competitionId }: QuestionSettingsProps)
         </Center>
       </ListItem>
       <ListItem divider>
-        <Center>
-          <TextField
-            id="outlined-basic"
-            defaultValue={''}
-            label="Frågans titel"
-            onChange={(event) => updateQuestion(true, event)}
-            variant="outlined"
-            fullWidth={true}
-          />
-        </Center>
+        <TextField
+          id="outlined-basic"
+          defaultValue={''}
+          label="Frågans titel"
+          onChange={(event) => updateQuestion(true, event)}
+          variant="outlined"
+          fullWidth={true}
+        />
       </ListItem>
       <ListItem>
         <Center>
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/SlideType.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/SlideType.tsx
index 3194f7c9..bc251b91 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/SlideType.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/SlideType.tsx
@@ -5,6 +5,7 @@ import {
   DialogContent,
   DialogContentText,
   DialogTitle,
+  FormControl,
   InputLabel,
   ListItem,
   MenuItem,
@@ -16,7 +17,7 @@ import React, { useState } from 'react'
 import { getEditorCompetition } from '../../../../actions/editor'
 import { useAppDispatch } from '../../../../hooks'
 import { RichSlide } from '../../../../interfaces/ApiRichModels'
-import { Center, FormControlDropdown, SlideTypeInputLabel } from '../styled'
+import { Center, FirstItem } from '../styled'
 
 type SlideTypeProps = {
   activeSlide: RichSlide
@@ -85,52 +86,55 @@ const SlideType = ({ activeSlide, competitionId }: SlideTypeProps) => {
     }
   }
   return (
-    <ListItem>
-      <FormControlDropdown variant="outlined">
-        <SlideTypeInputLabel>Sidtyp</SlideTypeInputLabel>
-        <Select fullWidth={true} value={activeSlide?.questions[0]?.type_id || 0} label="Sidtyp">
-          <MenuItem value={0}>
-            <Typography variant="button" onClick={() => openSlideTypeDialog(0)}>
-              Informationssida
-            </Typography>
-          </MenuItem>
-          <MenuItem value={1}>
-            <Typography variant="button" onClick={() => openSlideTypeDialog(1)}>
-              Skriftlig fråga
-            </Typography>
-          </MenuItem>
-          <MenuItem value={2}>
-            <Typography variant="button" onClick={() => openSlideTypeDialog(2)}>
-              Praktisk fråga
-            </Typography>
-          </MenuItem>
-          <MenuItem value={3}>
-            <Typography variant="button" onClick={() => openSlideTypeDialog(3)}>
-              Flervalsfråga
-            </Typography>
-          </MenuItem>
-        </Select>
-      </FormControlDropdown>
-      <Dialog open={slideTypeDialog} onClose={closeSlideTypeDialog}>
-        <Center>
-          <DialogTitle color="secondary">Varning!</DialogTitle>
-        </Center>
-        <DialogContent>
-          <DialogContentText>
-            Om du ändrar sidtypen kommer eventuella frågeinställningar gå förlorade. Det inkluderar: frågans namn, poäng
-            och svarsalternativ.{' '}
-          </DialogContentText>
-        </DialogContent>
-        <DialogActions>
-          <Button onClick={closeSlideTypeDialog} color="secondary">
-            Avbryt
-          </Button>
-          <Button onClick={updateSlideType} color="primary">
-            Bekräfta
-          </Button>
-        </DialogActions>
-      </Dialog>
-    </ListItem>
+    <FirstItem>
+      <ListItem>
+        <FormControl fullWidth variant="outlined">
+          <InputLabel>Sidtyp</InputLabel>
+          <Select fullWidth={true} value={activeSlide?.questions[0]?.type_id || 0} label="Sidtyp">
+            <MenuItem value={0}>
+              <Typography variant="button" onClick={() => openSlideTypeDialog(0)}>
+                Informationssida
+              </Typography>
+            </MenuItem>
+            <MenuItem value={1}>
+              <Typography variant="button" onClick={() => openSlideTypeDialog(1)}>
+                Skriftlig fråga
+              </Typography>
+            </MenuItem>
+            <MenuItem value={2}>
+              <Typography variant="button" onClick={() => openSlideTypeDialog(2)}>
+                Praktisk fråga
+              </Typography>
+            </MenuItem>
+            <MenuItem value={3}>
+              <Typography variant="button" onClick={() => openSlideTypeDialog(3)}>
+                Flervalsfråga
+              </Typography>
+            </MenuItem>
+          </Select>
+        </FormControl>
+
+        <Dialog open={slideTypeDialog} onClose={closeSlideTypeDialog}>
+          <Center>
+            <DialogTitle color="secondary">Varning!</DialogTitle>
+          </Center>
+          <DialogContent>
+            <DialogContentText>
+              Om du ändrar sidtypen kommer eventuella frågeinställningar gå förlorade. Det inkluderar: frågans namn,
+              poäng och svarsalternativ.{' '}
+            </DialogContentText>
+          </DialogContent>
+          <DialogActions>
+            <Button onClick={closeSlideTypeDialog} color="secondary">
+              Avbryt
+            </Button>
+            <Button onClick={updateSlideType} color="primary">
+              Bekräfta
+            </Button>
+          </DialogActions>
+        </Dialog>
+      </ListItem>
+    </FirstItem>
   )
 }
 
diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
index dd0b4084..39cf09af 100644
--- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
+++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx
@@ -1,13 +1,12 @@
 import { Divider, ListItem, ListItemText, Typography } from '@material-ui/core'
 import React from 'react'
-import { useAppSelector } from '../../../../hooks'
+import { useAppDispatch, useAppSelector } from '../../../../hooks'
 import { TextComponent } from '../../../../interfaces/ApiModels'
 import { RichSlide } from '../../../../interfaces/ApiRichModels'
 import { AddButton, Center, SettingsList, TextCard } from '../styled'
 import TextComponentEdit from '../TextComponentEdit'
 import axios from 'axios'
 import { getEditorCompetition } from '../../../../actions/editor'
-import { useDispatch } from 'react-redux'
 
 type TextsProps = {
   activeSlide: RichSlide
@@ -22,7 +21,7 @@ const Texts = ({ activeSlide, competitionId }: TextsProps) => {
         ?.components.filter((component) => component.type_id === 1) as TextComponent[]
   )
 
-  const dispatch = useDispatch()
+  const dispatch = useAppDispatch()
   const handleAddText = async () => {
     if (activeSlide) {
       await axios.post(`/api/competitions/${competitionId}/slides/${activeSlide?.id}/components`, {
diff --git a/client/src/pages/presentationEditor/components/styled.tsx b/client/src/pages/presentationEditor/components/styled.tsx
index af2108d6..7255c2bb 100644
--- a/client/src/pages/presentationEditor/components/styled.tsx
+++ b/client/src/pages/presentationEditor/components/styled.tsx
@@ -54,25 +54,15 @@ export const ToolbarPadding = styled.div`
   padding-top: 55px;
 `
 
-export const FormControlDropdown = styled(FormControl)`
-  width: 100%;
-  margin-top: 10px;
-`
-
-export const SlideTypeInputLabel = styled(InputLabel)`
+export const FirstItem = styled.div`
   width: 100%;
+  padding-top: 10px;
 `
 
 export const AlternativeTextField = styled(TextField)`
   width: 87%;
 `
 
-export const NoPadding = styled.div`
-  padding: 0;
-  height: 100%;
-  width: 100%;
-`
-
 export const Center = styled.div`
   display: flex;
   justify-content: center;
@@ -81,16 +71,13 @@ export const Center = styled.div`
   width: 100%;
 `
 
-export const SlidePanel = styled.div`
+export const PanelContainer = styled.div`
   padding: 10px;
   width: 100%;
 `
 
 export const AddButton = styled(Typography)`
-  padding-left: 8px;
-  padding-right: 8px;
-  padding-top: 7px;
-  padding-bottom: 7px;
+  padding: 7px 8px 7px 8px;
 `
 
 export const ImportedImage = styled.img`
@@ -103,7 +90,7 @@ export const Clickable = styled.div`
 `
 
 export const AddImageButton = styled.label`
-  padding: 0;
+  padding: 8px 13px 8px 13px;
   cursor: 'pointer';
   display: flex;
   justify-content: center;
diff --git a/client/src/pages/views/JudgeViewPage.tsx b/client/src/pages/views/JudgeViewPage.tsx
index 0d16daac..de5abe40 100644
--- a/client/src/pages/views/JudgeViewPage.tsx
+++ b/client/src/pages/views/JudgeViewPage.tsx
@@ -1,7 +1,6 @@
 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 { useParams } from 'react-router-dom'
 import { getPresentationCompetition, setCurrentSlide, setPresentationCode } from '../../actions/presentation'
 import { useAppDispatch, useAppSelector } from '../../hooks'
 import { ViewParams } from '../../interfaces/ViewParams'
-- 
GitLab