diff --git a/.gitignore b/.gitignore
index 2dcb4d9f42f23b7af576b707bd66f202bed1e826..51cc949e137154da9a41a28c542629235625a18b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,6 @@ __pycache__
 *.db
 */env
 *.coverage
+*/coverage
 htmlcov
 .pytest_cache
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 22158c9dda3cc8462343d3ce101686335a257da2..df39c2057c01130eecf18b74915e8ddb13fb7c4c 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -17,7 +17,7 @@
             "type": "npm",
             "script": "test:coverage:html",
             "path": "client/",
-            "group": "test",
+            "group": "build",
             "problemMatcher": [],
         },
         {
diff --git a/client/package-lock.json b/client/package-lock.json
index 67ccc686f7c33388184249845f2f6a1fbe71a2da..d6c2bd5b526c987718af784449b39680387b5b9b 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -1753,6 +1753,14 @@
         "react-transition-group": "^4.4.0"
       }
     },
+    "@material-ui/icons": {
+      "version": "4.11.2",
+      "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz",
+      "integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==",
+      "requires": {
+        "@babel/runtime": "^7.4.4"
+      }
+    },
     "@material-ui/lab": {
       "version": "4.0.0-alpha.57",
       "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.57.tgz",
diff --git a/client/package.json b/client/package.json
index 4fcc3e71b81b72b12d839de649445948698e986f..4d2df9fcb423cf855346e2cfe6a3ca81057520c7 100644
--- a/client/package.json
+++ b/client/package.json
@@ -4,6 +4,7 @@
   "private": true,
   "dependencies": {
     "@material-ui/core": "^4.11.3",
+    "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "^4.0.0-alpha.57",
     "@testing-library/jest-dom": "^5.11.9",
     "@testing-library/react": "^11.2.5",
@@ -63,11 +64,12 @@
     "collectCoverageFrom": [
       "src/**/*.{js,jsx,tsx,ts}",
       "!src/index.tsx",
-      "!src/reportWebVitals.ts"
+      "!src/reportWebVitals.ts",
+      "!src/components/TestConnection.tsx"
     ],
     "coverageReporters": [
       "text",
-      "cobertura", 
+      "cobertura",
       "html"
     ]
   },
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 2df0f43f64eb8aba54fb4a1b4a081177f209c91e..1e8c051e2d67e0a74f4ef26ab737a7427cf23b52 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,8 +1,6 @@
 import React from 'react'
-import { BrowserRouter, Route, Switch } from 'react-router-dom'
 import './App.css'
-import LoginForm from './components/Login'
-import TestConnection from './components/TestConnection'
+import Main from './Main'
 
 const App: React.FC = () => {
   return (
@@ -11,15 +9,7 @@ const App: React.FC = () => {
         rel="stylesheet"
         href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
       />
-      <h1>Application</h1>
-      <TestConnection />
-      <BrowserRouter>
-        <Switch>
-          <Route path="/">
-            <LoginForm />
-          </Route>
-        </Switch>
-      </BrowserRouter>
+      <Main />
     </div>
   )
 }
diff --git a/client/src/Main.tsx b/client/src/Main.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..a44422fdc2886602b51f32c09c3a11c3fca3a8b7
--- /dev/null
+++ b/client/src/Main.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+import { BrowserRouter, Route, Switch } from 'react-router-dom'
+import AdminView from './components/AdminView'
+import LoginForm from './components/Login'
+
+const Main = () => {
+  return (
+    <BrowserRouter>
+      <Switch>
+        <Route exact path="/" component={LoginForm} />
+        <Route path="/admin" component={AdminView} />
+      </Switch>
+    </BrowserRouter>
+  )
+}
+
+export default Main
diff --git a/client/src/components/AdminView.css b/client/src/components/AdminView.css
new file mode 100644
index 0000000000000000000000000000000000000000..1ad0b7ee6dd4647d7f8f7d07b6853ed5ceac4026
--- /dev/null
+++ b/client/src/components/AdminView.css
@@ -0,0 +1,10 @@
+.background {
+  background: linear-gradient(to top, #efd5ff 0%, #3d55b3 100%);
+  height: 100%;
+}
+
+.top-bar {
+  display:flex;
+  justify-content: space-between;
+  align-items: flex-start;
+}
\ No newline at end of file
diff --git a/client/src/components/AdminView.test.tsx b/client/src/components/AdminView.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..cdc460499c777bd4ee6a456b93d751272e98ebeb
--- /dev/null
+++ b/client/src/components/AdminView.test.tsx
@@ -0,0 +1,12 @@
+import { render } from '@testing-library/react'
+import React from 'react'
+import { BrowserRouter } from 'react-router-dom'
+import AdminView from './AdminView'
+
+it('renders admin view', () => {
+  render(
+    <BrowserRouter>
+      <AdminView />
+    </BrowserRouter>
+  )
+})
diff --git a/client/src/components/AdminView.tsx b/client/src/components/AdminView.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..54551b640789e676461065c686d424bafa290efd
--- /dev/null
+++ b/client/src/components/AdminView.tsx
@@ -0,0 +1,139 @@
+import {
+  AppBar,
+  Button,
+  CssBaseline,
+  Divider,
+  Drawer,
+  List,
+  ListItem,
+  ListItemIcon,
+  ListItemText,
+  Toolbar,
+  Typography
+} from '@material-ui/core'
+import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
+import DashboardIcon from '@material-ui/icons/Dashboard'
+import MailIcon from '@material-ui/icons/Mail'
+import React from 'react'
+import { Link, Route, Switch, useRouteMatch } from 'react-router-dom'
+import './AdminView.css'
+import CompetitionManager from './CompetitionManager'
+import Regions from './Regions'
+
+const drawerWidth = 240
+const menuItems = ['Startsida', 'Regioner', 'Användare', 'Tävlingshanterare']
+
+const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    root: {
+      display: 'flex'
+    },
+    appBar: {
+      width: `calc(100% - ${drawerWidth}px)`,
+      marginLeft: drawerWidth
+    },
+    drawer: {
+      width: drawerWidth,
+      flexShrink: 0,
+      marginRight: drawerWidth
+    },
+    drawerPaper: {
+      width: drawerWidth
+    },
+    // necessary for content to be below app bar
+    toolbar: theme.mixins.toolbar,
+    content: {
+      flexGrow: 1,
+      backgroundColor: theme.palette.background.default,
+      paddingLeft: theme.spacing(30)
+    }
+  })
+)
+
+const AdminView: React.FC = (props) => {
+  const classes = useStyles()
+  const [openIndex, setOpenIndex] = React.useState(0)
+  const match = useRouteMatch()
+  console.log(match)
+  const { path, url } = match
+  return (
+    <div className={classes.root}>
+      <CssBaseline />
+      <AppBar position="fixed" className={classes.appBar}>
+        <Toolbar>
+          <Typography variant="h5" noWrap>
+            {menuItems[openIndex]}
+          </Typography>
+        </Toolbar>
+      </AppBar>
+      <Drawer
+        className={(classes.drawer, 'background')}
+        variant="permanent"
+        classes={{
+          paper: classes.drawerPaper
+        }}
+        anchor="left"
+      >
+        <div className="background">
+          <div className={classes.toolbar} />
+          <Divider />
+          <List>
+            {menuItems.map((text, index) => (
+              <ListItem
+                button
+                component={Link}
+                key={text}
+                to={`${url}/${text.toLowerCase()}`}
+                selected={index === openIndex}
+                onClick={() => setOpenIndex(index)}
+              >
+                <ListItemIcon>
+                  {text === 'Dashboard' ? <DashboardIcon /> : <MailIcon />}
+                </ListItemIcon>
+                <ListItemText primary={text} />
+              </ListItem>
+            ))}
+          </List>
+          <Divider />
+          <List>
+            <ListItem>
+              <Button
+                component={Link}
+                to="/"
+                type="submit"
+                fullWidth
+                variant="contained"
+                color="primary"
+              >
+                Logga ut
+              </Button>
+            </ListItem>
+          </List>
+        </div>
+      </Drawer>
+      <main className={classes.content}>
+        <div className={classes.toolbar} />
+        <Switch>
+          <Route exact path={[path, `${path}/startsida`]}>
+            <Typography variant="h1" noWrap>
+              Startsida
+            </Typography>
+          </Route>
+          <Route path={`${path}/regioner`}>
+            <Regions />
+          </Route>
+          <Route path={`${path}/användare`}>
+            <Typography variant="h1" noWrap>
+              Användare
+            </Typography>
+          </Route>
+          <Route path={`${path}/tävlingshanterare`}>
+            <CompetitionManager />
+          </Route>
+        </Switch>
+      </main>
+    </div>
+  )
+}
+
+export default AdminView
diff --git a/client/src/components/CompetitionManager.test.tsx b/client/src/components/CompetitionManager.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b7156f680329a98c468dfa3a751448191a8b088b
--- /dev/null
+++ b/client/src/components/CompetitionManager.test.tsx
@@ -0,0 +1,7 @@
+import { render } from '@testing-library/react'
+import React from 'react'
+import CompetitionManager from './CompetitionManager'
+
+it('renders competition manager', () => {
+  render(<CompetitionManager />)
+})
diff --git a/client/src/components/CompetitionManager.tsx b/client/src/components/CompetitionManager.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2d140fa35968cb8b227e5802b426fea7ce4bb144
--- /dev/null
+++ b/client/src/components/CompetitionManager.tsx
@@ -0,0 +1,12 @@
+import { Typography } from '@material-ui/core'
+import React from 'react'
+
+const CompetitionManager: React.FC = (props) => {
+  return (
+    <Typography variant="h1" noWrap>
+      Tävlingshanterare
+    </Typography>
+  )
+}
+
+export default CompetitionManager
diff --git a/client/src/components/Login.test.tsx b/client/src/components/Login.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..12a6c79c133e96598a6e583ddcbd555e1799df97
--- /dev/null
+++ b/client/src/components/Login.test.tsx
@@ -0,0 +1,7 @@
+import { render } from '@testing-library/react'
+import React from 'react'
+import LoginForm from './Login'
+
+it('renders login form', () => {
+  render(<LoginForm />)
+})
diff --git a/client/src/components/Login.tsx b/client/src/components/Login.tsx
index 75123ff3b18582b09daa7305927ecf9aa6cf3568..91af9b78d06d4bdde2d1b42939bad82fe0f1c968 100644
--- a/client/src/components/Login.tsx
+++ b/client/src/components/Login.tsx
@@ -28,12 +28,10 @@ interface ServerResponse {
 const schema: Yup.SchemaOf<LoginFormModel> = Yup.object({
   model: Yup.object()
     .shape({
-      email: Yup.string()
-        .email('Email not valid')
-        .required('Email is required'),
+      email: Yup.string().email('Email inte giltig').required('Email krävs'),
       password: Yup.string()
-        .required('Password is required')
-        .min(6, 'Password must be at least 6 characters')
+        .required('Lösenord krävs')
+        .min(6, 'Lösenord måste vara minst 6 karaktärer')
     })
     .required(),
   error: Yup.string().optional()
@@ -69,7 +67,7 @@ const LoginForm: React.FC = (props) => {
         {(formik) => (
           <form onSubmit={formik.handleSubmit} className="login-form">
             <TextField
-              label="Email Address"
+              label="Email Adress"
               name="model.email"
               helperText={
                 formik.touched.model?.email ? formik.errors.model?.email : ''
@@ -80,7 +78,7 @@ const LoginForm: React.FC = (props) => {
               margin="normal"
             />
             <TextField
-              label="Password"
+              label="Lösenord"
               name="model.password"
               type="password"
               helperText={
diff --git a/client/src/components/Regions.test.tsx b/client/src/components/Regions.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6f7fb873cba29a4a56f736b0ee7d7789ba420428
--- /dev/null
+++ b/client/src/components/Regions.test.tsx
@@ -0,0 +1,7 @@
+import { render } from '@testing-library/react'
+import React from 'react'
+import Regions from './Regions'
+
+it('renders regions', () => {
+  render(<Regions />)
+})
diff --git a/client/src/components/Regions.tsx b/client/src/components/Regions.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..f40c834414113e7e4e4cd8f832ed37642f1c6996
--- /dev/null
+++ b/client/src/components/Regions.tsx
@@ -0,0 +1,12 @@
+import Typography from '@material-ui/core/Typography'
+import React from 'react'
+
+const Regions: React.FC = (props) => {
+  return (
+    <Typography variant="h1" noWrap>
+      Regions
+    </Typography>
+  )
+}
+
+export default Regions