diff --git a/client/src/actions/roles.ts b/client/src/actions/roles.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0160353b184755b33f003592ad127880af2803d7
--- /dev/null
+++ b/client/src/actions/roles.ts
@@ -0,0 +1,15 @@
+import axios from 'axios'
+import { AppDispatch } from './../store'
+import Types from './types'
+
+export const getRoles = () => async (dispatch: AppDispatch) => {
+  await axios
+    .get('/misc/roles')
+    .then((res) => {
+      dispatch({
+        type: Types.SET_ROLES,
+        payload: res.data.items,
+      })
+    })
+    .catch((err) => console.log(err))
+}
diff --git a/client/src/actions/searchUser.ts b/client/src/actions/searchUser.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fb4bf122e40d13952537c3e942bf351f10f99604
--- /dev/null
+++ b/client/src/actions/searchUser.ts
@@ -0,0 +1,39 @@
+import axios from 'axios'
+import { UserFilterParams } from '../interfaces/UserData'
+import { AppDispatch, RootState } from './../store'
+import Types from './types'
+
+export const getSearchUsers = () => async (dispatch: AppDispatch, getState: () => RootState) => {
+  const currentParams: UserFilterParams = getState().searchUsers.filterParams
+  // Send params in snake-case for api
+  const params = {
+    page_size: currentParams.pageSize,
+    role_id: currentParams.roleId,
+    city_id: currentParams.cityId,
+    name: currentParams.name,
+    page: currentParams.page,
+    email: currentParams.email,
+  }
+  await axios
+    .get('/users/search', { params })
+    .then((res) => {
+      dispatch({
+        type: Types.SET_SEARCH_USERS,
+        payload: res.data.items,
+      })
+      dispatch({
+        type: Types.SET_SEARCH_USERS_TOTAL_COUNT,
+        payload: res.data.total_count,
+      })
+      dispatch({
+        type: Types.SET_SEARCH_USERS_COUNT,
+        payload: res.data.count,
+      })
+    })
+    .catch((err) => {
+      console.log(err)
+    })
+}
+export const setFilterParams = (params: UserFilterParams) => (dispatch: AppDispatch) => {
+  dispatch({ type: Types.SET_SEARCH_USERS_FILTER_PARAMS, payload: params })
+}
diff --git a/client/src/actions/types.ts b/client/src/actions/types.ts
index 40e9430369e7314b77e7dcc133132e98de1f67f6..b72a35862f4c42161a25997a6065662d1020e8f1 100644
--- a/client/src/actions/types.ts
+++ b/client/src/actions/types.ts
@@ -1,7 +1,12 @@
 export default {
   LOADING_UI: 'LOADING_UI',
   LOADING_USER: 'LOADING_USER',
+  SET_ROLES: 'SET_ROLES',
   SET_USER: 'SET_USER',
+  SET_SEARCH_USERS: 'SET_SEARCH_USERS',
+  SET_SEARCH_USERS_FILTER_PARAMS: 'SET_SEARCH_USERS_FILTER_PARAMS',
+  SET_SEARCH_USERS_COUNT: 'SET_SEARCH_USERS_COUNT',
+  SET_SEARCH_USERS_TOTAL_COUNT: 'SET_SEARCH_USERS_TOTAL_COUNT',
   SET_ERRORS: 'SET_ERRORS',
   CLEAR_ERRORS: 'SET_ERRORS',
   SET_UNAUTHENTICATED: 'SET_UNAUTHENTICATED',
diff --git a/client/src/interfaces/Role.ts b/client/src/interfaces/Role.ts
index 4165fe7beddd0d6787ccf67aabc5409dd8612623..08a54dfcb012ee03398d17d4a7153ab040cde909 100644
--- a/client/src/interfaces/Role.ts
+++ b/client/src/interfaces/Role.ts
@@ -1,9 +1,4 @@
-import { City } from './City'
-
-export interface Competition {
-  name: string
-  city: City
-  style_id: number
-  year: number
+export interface Role {
   id: number
+  name: string
 }
diff --git a/client/src/interfaces/SearchUserFilterParams.ts b/client/src/interfaces/SearchUserFilterParams.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8d7230d83d12d164a0db4683b4db7b791d835a81
--- /dev/null
+++ b/client/src/interfaces/SearchUserFilterParams.ts
@@ -0,0 +1,8 @@
+export interface SearchUSerFilterParams {
+  name?: string
+  year?: number
+  cityId?: number
+  styleId?: number
+  page: number
+  pageSize: number
+}
diff --git a/client/src/interfaces/UserData.ts b/client/src/interfaces/UserData.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0c7394699b314c49e8f19bb259b6d73dd610bcf
--- /dev/null
+++ b/client/src/interfaces/UserData.ts
@@ -0,0 +1,16 @@
+export interface UserData {
+  id: number
+  name?: string
+  email: string
+  role_id: number
+  city_id: number
+}
+
+export interface UserFilterParams {
+  name?: string
+  email?: string
+  cityId?: number
+  roleId?: number
+  page: number
+  pageSize: number
+}
diff --git a/client/src/interfaces/models.ts b/client/src/interfaces/models.ts
index 91920bd635e522072ff206b8e03554bb788c969f..70d4cc08b5f8e449ad251526389dd84fe42a4d3e 100644
--- a/client/src/interfaces/models.ts
+++ b/client/src/interfaces/models.ts
@@ -12,3 +12,18 @@ export interface AddCompetitionModel {
 export interface CompetitionLoginModel {
   code: string
 }
+
+export interface AddUserModel {
+  email: string
+  password: string
+  role: string
+  city: string
+  name?: string
+}
+
+export interface EditUserModel {
+  email: string
+  role: string
+  city: string
+  name?: string
+}
diff --git a/client/src/pages/admin/AdminPage.tsx b/client/src/pages/admin/AdminPage.tsx
index 3d2b94b87d67a9d325ee18d42e9f8d4aa80a9978..270e2dd0c8c3ec20a57fbe628605b8ecf574d205 100644
--- a/client/src/pages/admin/AdminPage.tsx
+++ b/client/src/pages/admin/AdminPage.tsx
@@ -19,6 +19,7 @@ import { logoutUser } from '../../actions/user'
 import { useAppDispatch } from '../../hooks'
 import CompetitionManager from './components/CompetitionManager'
 import Regions from './components/Regions'
+import UserManager from './components/UserManager'
 import { LeftDrawer } from './styled'
 
 const drawerWidth = 250
@@ -112,9 +113,7 @@ const AdminView: React.FC = () => {
             <Regions />
           </Route>
           <Route path={`${path}/användare`}>
-            <Typography variant="h1" noWrap>
-              Användare
-            </Typography>
+            <UserManager />
           </Route>
           <Route path={`${path}/tävlingshanterare`}>
             <CompetitionManager />
diff --git a/client/src/pages/admin/components/AddUser.tsx b/client/src/pages/admin/components/AddUser.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..81c6adc96b26e230acf1ee2b73b68b28c293d7be
--- /dev/null
+++ b/client/src/pages/admin/components/AddUser.tsx
@@ -0,0 +1,220 @@
+import { Button, FormControl, InputLabel, MenuItem, Popover, TextField } from '@material-ui/core'
+import { Alert, AlertTitle } from '@material-ui/lab'
+import axios from 'axios'
+import { Formik, FormikHelpers } from 'formik'
+import React from 'react'
+import * as Yup from 'yup'
+import { getSearchUsers } from '../../../actions/searchUser'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
+import { City } from '../../../interfaces/City'
+import { AddUserModel } from '../../../interfaces/models'
+import { Role } from '../../../interfaces/Role'
+import { AddCompetitionButton, AddCompetitionContent, AddCompetitionForm } from './styled'
+
+interface ServerResponse {
+  code: number
+  message: string
+}
+
+interface AddUserFormModel {
+  model: AddUserModel
+  error?: string
+}
+
+const noRoleSelected = 'Välj roll'
+const noCitySelected = 'Välj stad'
+
+const userSchema: Yup.SchemaOf<AddUserFormModel> = Yup.object({
+  model: Yup.object()
+    .shape({
+      name: Yup.string(), //.required('Namn krävs'),
+      email: Yup.string().email().required('Email krävs'),
+      password: Yup.string()
+        .required('Lösenord krävs.')
+        .min(6, 'Lösenord måste vara minst 6 tecken.')
+        .matches(/[a-zA-Z]/, 'Lösenord får enbart innehålla a-z, A-Z.'),
+      role: Yup.string().required('Roll krävs').notOneOf([noCitySelected], 'Välj en roll'),
+      city: Yup.string().required('Stad krävs').notOneOf([noRoleSelected], 'Välj en stad'),
+    })
+    .required(),
+  error: Yup.string().optional(),
+})
+
+const AddUser: React.FC = (props: any) => {
+  const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
+  const [selectedRole, setSelectedRole] = React.useState<Role | undefined>()
+  const roles = useAppSelector((state) => state.roles.roles)
+
+  const [selectedCity, setSelectedCity] = React.useState<City | undefined>()
+  const cities = useAppSelector((state) => state.cities.cities)
+
+  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
+    setAnchorEl(event.currentTarget)
+  }
+  const handleClose = () => {
+    setAnchorEl(null)
+  }
+
+  const open = Boolean(anchorEl)
+  const dispatch = useAppDispatch()
+  const id = open ? 'simple-popover' : undefined
+  const handleCompetitionSubmit = async (values: AddUserFormModel, actions: FormikHelpers<AddUserFormModel>) => {
+    const params = {
+      email: values.model.email,
+      password: values.model.password,
+      //name: values.model.name,
+      city_id: selectedCity?.id as number,
+      role_id: selectedRole?.id as number,
+    }
+    await axios
+      .post<ServerResponse>('/auth/signup', params)
+      .then(() => {
+        actions.resetForm()
+        setAnchorEl(null)
+        dispatch(getSearchUsers())
+        setSelectedCity(undefined)
+        setSelectedRole(undefined)
+      })
+      .catch(({ response }) => {
+        console.warn(response.data)
+        if (response.data && response.data.message)
+          actions.setFieldError('error', response.data && response.data.message)
+        else actions.setFieldError('error', 'Something went wrong, please try again')
+      })
+      .finally(() => {
+        actions.setSubmitting(false)
+      })
+  }
+
+  const userInitialValues: AddUserFormModel = {
+    model: { email: '', password: '', name: '', city: noCitySelected, role: noRoleSelected },
+  }
+  return (
+    <div>
+      <AddCompetitionButton color="secondary" variant="contained" onClick={handleClick}>
+        Ny Användare
+      </AddCompetitionButton>
+      <Popover
+        id={id}
+        open={open}
+        anchorEl={anchorEl}
+        onClose={handleClose}
+        anchorOrigin={{
+          vertical: 'bottom',
+          horizontal: 'center',
+        }}
+        transformOrigin={{
+          vertical: 'top',
+          horizontal: 'center',
+        }}
+      >
+        <AddCompetitionContent>
+          <Formik initialValues={userInitialValues} validationSchema={userSchema} onSubmit={handleCompetitionSubmit}>
+            {(formik) => (
+              <AddCompetitionForm onSubmit={formik.handleSubmit}>
+                <TextField
+                  label="Email"
+                  name="model.email"
+                  helperText={formik.touched.model?.email ? formik.errors.model?.email : ''}
+                  error={Boolean(formik.touched.model?.email && formik.errors.model?.email)}
+                  onChange={formik.handleChange}
+                  onBlur={formik.handleBlur}
+                  margin="normal"
+                />
+                <TextField
+                  label="Lösenord"
+                  name="model.password"
+                  helperText={formik.touched.model?.password ? formik.errors.model?.password : ''}
+                  error={Boolean(formik.touched.model?.password && formik.errors.model?.password)}
+                  onChange={formik.handleChange}
+                  onBlur={formik.handleBlur}
+                  margin="normal"
+                />
+                <TextField
+                  label="Namn"
+                  name="model.name"
+                  helperText={formik.touched.model?.name ? formik.errors.model?.name : ''}
+                  error={Boolean(formik.touched.model?.name && formik.errors.model?.name)}
+                  onChange={formik.handleChange}
+                  onBlur={formik.handleBlur}
+                  margin="normal"
+                />
+                <FormControl>
+                  <InputLabel shrink id="demo-customized-select-native">
+                    Region
+                  </InputLabel>
+                  <TextField
+                    select
+                    name="model.city"
+                    id="standard-select-currency"
+                    value={selectedCity ? selectedCity.name : noCitySelected}
+                    onChange={formik.handleChange}
+                    onBlur={formik.handleBlur}
+                    error={Boolean(formik.errors.model?.city && formik.touched.model?.city)}
+                    helperText={formik.touched.model?.city && formik.errors.model?.city}
+                    margin="normal"
+                  >
+                    <MenuItem value={noCitySelected} onClick={() => setSelectedCity(undefined)}>
+                      {noCitySelected}
+                    </MenuItem>
+                    {cities &&
+                      cities.map((city) => (
+                        <MenuItem key={city.name} value={city.name} onClick={() => setSelectedCity(city)}>
+                          {city.name}
+                        </MenuItem>
+                      ))}
+                  </TextField>
+                </FormControl>
+
+                <FormControl>
+                  <InputLabel shrink id="demo-customized-select-native">
+                    Roll
+                  </InputLabel>
+                  <TextField
+                    select
+                    name="model.role"
+                    id="standard-select-currency"
+                    value={selectedRole ? selectedRole.name : noRoleSelected}
+                    onChange={formik.handleChange}
+                    onBlur={formik.handleBlur}
+                    error={Boolean(formik.errors.model?.role && formik.touched.model?.role)}
+                    helperText={formik.touched.model?.role && formik.errors.model?.role}
+                    margin="normal"
+                  >
+                    <MenuItem value={noRoleSelected} onClick={() => setSelectedRole(undefined)}>
+                      {noRoleSelected}
+                    </MenuItem>
+                    {roles &&
+                      roles.map((role) => (
+                        <MenuItem key={role.name} value={role.name} onClick={() => setSelectedRole(role)}>
+                          {role.name}
+                        </MenuItem>
+                      ))}
+                  </TextField>
+                </FormControl>
+
+                <Button
+                  type="submit"
+                  fullWidth
+                  variant="contained"
+                  color="secondary"
+                  disabled={!formik.isValid || !formik.values.model?.name || !formik.values.model?.city}
+                >
+                  Lägg till
+                </Button>
+                {formik.errors.error && (
+                  <Alert severity="error">
+                    <AlertTitle>Error</AlertTitle>
+                    {formik.errors.error}
+                  </Alert>
+                )}
+              </AddCompetitionForm>
+            )}
+          </Formik>
+        </AddCompetitionContent>
+      </Popover>
+    </div>
+  )
+}
+
+export default AddUser
diff --git a/client/src/pages/admin/components/Regions.test.tsx b/client/src/pages/admin/components/Regions.test.tsx
deleted file mode 100644
index 6f7fb873cba29a4a56f736b0ee7d7789ba420428..0000000000000000000000000000000000000000
--- a/client/src/pages/admin/components/Regions.test.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { render } from '@testing-library/react'
-import React from 'react'
-import Regions from './Regions'
-
-it('renders regions', () => {
-  render(<Regions />)
-})
diff --git a/client/src/pages/admin/components/Regions.tsx b/client/src/pages/admin/components/Regions.tsx
index d58802d06e8c53261a10e183c31984ca767e2f99..103c2b1d820643a3fe80b2a2e241e42505eb6e5d 100644
--- a/client/src/pages/admin/components/Regions.tsx
+++ b/client/src/pages/admin/components/Regions.tsx
@@ -1,12 +1,122 @@
-import Typography from '@material-ui/core/Typography'
-import React from 'react'
+import { Button, Menu, TextField, Typography } from '@material-ui/core'
+import FormControl from '@material-ui/core/FormControl'
+import Paper from '@material-ui/core/Paper'
+import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
+import Table from '@material-ui/core/Table'
+import TableBody from '@material-ui/core/TableBody'
+import TableCell from '@material-ui/core/TableCell'
+import TableContainer from '@material-ui/core/TableContainer'
+import TableHead from '@material-ui/core/TableHead'
+import TableRow from '@material-ui/core/TableRow'
+import MoreHorizIcon from '@material-ui/icons/MoreHoriz'
+import axios from 'axios'
+import React, { useEffect } from 'react'
+import { getCities } from '../../../actions/cities'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
+import { RemoveCompetition, TopBar } from './styled'
+
+const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    table: {
+      width: '100%',
+    },
+    margin: {
+      margin: theme.spacing(1),
+    },
+  })
+)
+
+const UserManager: React.FC = (props: any) => {
+  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
+  const [activeId, setActiveId] = React.useState<number | undefined>(undefined)
+  const citiesTotal = useAppSelector((state) => state.cities.total)
+  const cities = useAppSelector((state) => state.cities.cities)
+  const [newCity, setNewCity] = React.useState()
+  const classes = useStyles()
+  const dispatch = useAppDispatch()
+  const handleClose = () => {
+    setAnchorEl(null)
+    setActiveId(undefined)
+  }
+
+  useEffect(() => {
+    dispatch(getCities())
+  }, [])
+
+  const handleDeleteCity = async () => {
+    if (activeId) {
+      await axios
+        .delete(`/misc/cities/${activeId}`)
+        .then(() => {
+          setAnchorEl(null)
+          dispatch(getCities())
+        })
+        .catch(({ response }) => {
+          console.warn(response.data)
+        })
+    }
+  }
+
+  const handleClick = (event: React.MouseEvent<HTMLButtonElement>, id: number) => {
+    setAnchorEl(event.currentTarget)
+    setActiveId(id)
+  }
+
+  const handleAddCity = async () => {
+    await axios
+      .post(`/misc/cities`, { name: newCity })
+      .then(() => {
+        setAnchorEl(null)
+        dispatch(getCities())
+      })
+      .catch(({ response }) => {
+        console.warn(response.data)
+      })
+  }
+
+  const handleChange = (event: any) => {
+    setNewCity(event.target.value)
+  }
 
-const Regions: React.FC = () => {
   return (
-    <Typography variant="h1" noWrap>
-      Regions
-    </Typography>
+    <div>
+      <TopBar>
+        <FormControl className={classes.margin}>
+          <TextField className={classes.margin} value={newCity} onChange={handleChange} label="Region"></TextField>
+          <Button color="primary" variant="contained" onClick={handleAddCity}>
+            Lägg till
+          </Button>
+        </FormControl>
+      </TopBar>
+      <TableContainer component={Paper}>
+        <Table className={classes.table} aria-label="simple table">
+          <TableHead>
+            <TableRow>
+              <TableCell>Regioner</TableCell>
+              <TableCell align="right"></TableCell>
+            </TableRow>
+          </TableHead>
+          <TableBody>
+            {cities &&
+              cities.map((row) => (
+                <TableRow key={row.name}>
+                  <TableCell scope="row">{row.name}</TableCell>
+                  <TableCell align="right">
+                    <Button onClick={(event) => handleClick(event, row.id)}>
+                      <MoreHorizIcon />
+                    </Button>
+                  </TableCell>
+                </TableRow>
+              ))}
+          </TableBody>
+        </Table>
+        {(!cities || cities.length === 0) && <Typography>Inga regioner hittades</Typography>}
+      </TableContainer>
+      <Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
+        <RemoveCompetition onClick={handleDeleteCity}>Ta bort</RemoveCompetition>
+      </Menu>
+    </div>
   )
 }
 
-export default Regions
+export default UserManager
diff --git a/client/src/pages/admin/components/UserManager.tsx b/client/src/pages/admin/components/UserManager.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..bc3d55d480a38cc4d0c92a56d84b3e2d7ae2bb18
--- /dev/null
+++ b/client/src/pages/admin/components/UserManager.tsx
@@ -0,0 +1,201 @@
+import { Button, Menu, TablePagination, TextField, Typography } from '@material-ui/core'
+import FormControl from '@material-ui/core/FormControl'
+import InputLabel from '@material-ui/core/InputLabel'
+import MenuItem from '@material-ui/core/MenuItem'
+import Paper from '@material-ui/core/Paper'
+import Select from '@material-ui/core/Select'
+import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
+import Table from '@material-ui/core/Table'
+import TableBody from '@material-ui/core/TableBody'
+import TableCell from '@material-ui/core/TableCell'
+import TableContainer from '@material-ui/core/TableContainer'
+import TableHead from '@material-ui/core/TableHead'
+import TableRow from '@material-ui/core/TableRow'
+import MoreHorizIcon from '@material-ui/icons/MoreHoriz'
+import axios from 'axios'
+import React, { useEffect } from 'react'
+import { getCities } from '../../../actions/cities'
+import { getRoles } from '../../../actions/roles'
+import { getSearchUsers, setFilterParams } from '../../../actions/searchUser'
+import { useAppDispatch, useAppSelector } from '../../../hooks'
+import { UserFilterParams } from '../../../interfaces/UserData'
+import AddUser from './AddUser'
+import { FilterContainer, RemoveCompetition, TopBar } from './styled'
+
+const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    table: {
+      width: '100%',
+    },
+    margin: {
+      margin: theme.spacing(1),
+    },
+  })
+)
+
+const UserManager: React.FC = (props: any) => {
+  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
+  const [activeId, setActiveId] = React.useState<number | undefined>(undefined)
+  const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined)
+  const users = useAppSelector((state) => state.searchUsers.users)
+  const filterParams = useAppSelector((state) => state.searchUsers.filterParams)
+  const usersTotal = useAppSelector((state) => state.searchUsers.total)
+  const cities = useAppSelector((state) => state.cities.cities)
+  const roles = useAppSelector((state) => state.roles.roles)
+  const classes = useStyles()
+  const noFilterText = 'Alla'
+  const dispatch = useAppDispatch()
+  const handleClick = (event: React.MouseEvent<HTMLButtonElement>, id: number) => {
+    setAnchorEl(event.currentTarget)
+    setActiveId(id)
+  }
+
+  const handleClose = () => {
+    setAnchorEl(null)
+    setActiveId(undefined)
+  }
+
+  useEffect(() => {
+    dispatch(getCities())
+    dispatch(getRoles())
+    dispatch(getSearchUsers())
+  }, [])
+
+  const onSearchChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+    if (timerHandle) {
+      clearTimeout(timerHandle)
+      setTimerHandle(undefined)
+    }
+    //Only updates filter and api 100ms after last input was made
+    setTimerHandle(window.setTimeout(() => dispatch(getSearchUsers()), 100))
+    dispatch(setFilterParams({ ...filterParams, email: event.target.value }))
+  }
+
+  const handleDeleteUsers = async () => {
+    if (activeId) {
+      await axios
+        .delete(`/auth/delete/${activeId}`)
+        .then(() => {
+          setAnchorEl(null)
+          dispatch(getSearchUsers())
+        })
+        .catch(({ response }) => {
+          console.warn(response.data)
+        })
+    }
+  }
+
+  const handleFilterChange = (newParams: UserFilterParams) => {
+    dispatch(setFilterParams(newParams))
+    dispatch(getSearchUsers())
+  }
+
+  return (
+    <div>
+      <TopBar>
+        <FilterContainer>
+          <TextField
+            className={classes.margin}
+            value={filterParams.email || ''}
+            onChange={onSearchChange}
+            label="Sök"
+          ></TextField>
+          <FormControl className={classes.margin}>
+            <InputLabel shrink id="demo-customized-select-native">
+              Region
+            </InputLabel>
+            <Select
+              labelId="demo-customized-select-label"
+              id="demo-customized-select"
+              value={filterParams.cityId ? cities.find((city) => filterParams.cityId === city.id)?.name : noFilterText}
+            >
+              <MenuItem value={noFilterText} onClick={() => handleFilterChange({ ...filterParams, cityId: undefined })}>
+                {noFilterText}
+              </MenuItem>
+              {cities &&
+                cities.map((city) => (
+                  <MenuItem
+                    key={city.name}
+                    value={city.name}
+                    onClick={() => handleFilterChange({ ...filterParams, cityId: city.id })}
+                  >
+                    {city.name}
+                  </MenuItem>
+                ))}
+            </Select>
+          </FormControl>
+          <FormControl className={classes.margin}>
+            <InputLabel shrink id="demo-customized-select-native">
+              Roles
+            </InputLabel>
+            <Select
+              labelId="demo-customized-select-label"
+              id="demo-customized-select"
+              value={filterParams.roleId ? roles.find((role) => filterParams.roleId === role.id)?.name : noFilterText}
+            >
+              <MenuItem value={noFilterText} onClick={() => handleFilterChange({ ...filterParams, roleId: undefined })}>
+                {noFilterText}
+              </MenuItem>
+              {cities &&
+                cities.map((role) => (
+                  <MenuItem
+                    key={role.name}
+                    value={role.name}
+                    onClick={() => handleFilterChange({ ...filterParams, roleId: role.id })}
+                  >
+                    {role.name}
+                  </MenuItem>
+                ))}
+            </Select>
+          </FormControl>
+        </FilterContainer>
+        <AddUser />
+      </TopBar>
+      <TableContainer component={Paper}>
+        <Table className={classes.table} aria-label="simple table">
+          <TableHead>
+            <TableRow>
+              <TableCell>Email</TableCell>
+              <TableCell>Namn</TableCell>
+              <TableCell>Region</TableCell>
+              <TableCell>Roll</TableCell>
+              <TableCell align="right"></TableCell>
+            </TableRow>
+          </TableHead>
+          <TableBody>
+            {users &&
+              users.map((row) => (
+                <TableRow key={row.email}>
+                  <TableCell scope="row">{row.email}</TableCell>
+                  <TableCell scope="row">{row.name}</TableCell>
+                  <TableCell>{cities.find((city) => city.id === row.city_id)?.name || ''}</TableCell>
+                  <TableCell>{roles.find((role) => role.id === row.role_id)?.name || ''}</TableCell>
+                  <TableCell align="right">
+                    <Button onClick={(event) => handleClick(event, row.id)}>
+                      <MoreHorizIcon />
+                    </Button>
+                  </TableCell>
+                </TableRow>
+              ))}
+          </TableBody>
+        </Table>
+        {(!users || users.length === 0) && <Typography>Inga tävlingar hittades med nuvarande filter</Typography>}
+      </TableContainer>
+      <TablePagination
+        component="div"
+        rowsPerPageOptions={[]}
+        rowsPerPage={filterParams.pageSize}
+        count={usersTotal}
+        page={filterParams.page}
+        onChangePage={(event, newPage) => handleFilterChange({ ...filterParams, page: newPage })}
+      />
+      <Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
+        <MenuItem>Redigera</MenuItem>
+        <MenuItem>Byt lösenord</MenuItem>
+        <RemoveCompetition onClick={handleDeleteUsers}>Ta bort</RemoveCompetition>
+      </Menu>
+    </div>
+  )
+}
+
+export default UserManager
diff --git a/client/src/reducers/allReducers.ts b/client/src/reducers/allReducers.ts
index b12b534633d0b7d71eab7f82533bdd2d0096a3a0..3c9f2b6cecf5166e9c21c8366b97345a2e2827ec 100644
--- a/client/src/reducers/allReducers.ts
+++ b/client/src/reducers/allReducers.ts
@@ -3,6 +3,8 @@
 import { combineReducers } from 'redux'
 import citiesReducer from './citiesReducer'
 import competitionsReducer from './competitionsReducer'
+import rolesReducer from './rolesReducer'
+import searchUserReducer from './searchUserReducer'
 import uiReducer from './uiReducer'
 import userReducer from './userReducer'
 
@@ -12,5 +14,7 @@ const allReducers = combineReducers({
   UI: uiReducer,
   competitions: competitionsReducer,
   cities: citiesReducer,
+  roles: rolesReducer,
+  searchUsers: searchUserReducer,
 })
 export default allReducers
diff --git a/client/src/reducers/rolesReducer.ts b/client/src/reducers/rolesReducer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..652d4afcf12c1f58aad0c1b9cf21ab36e2ca96da
--- /dev/null
+++ b/client/src/reducers/rolesReducer.ts
@@ -0,0 +1,19 @@
+import { AnyAction } from 'redux'
+import Types from '../actions/types'
+import { Role } from '../interfaces/Role'
+
+interface RoleState {
+  roles: Role[]
+}
+const initialState: RoleState = {
+  roles: [],
+}
+
+export default function (state = initialState, action: AnyAction) {
+  switch (action.type) {
+    case Types.SET_ROLES:
+      return { ...state, roles: action.payload as Role[] }
+    default:
+      return state
+  }
+}
diff --git a/client/src/reducers/searchUserReducer.ts b/client/src/reducers/searchUserReducer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9b77d68af26b3fbf2f0b428c8a6a959f6e9c5991
--- /dev/null
+++ b/client/src/reducers/searchUserReducer.ts
@@ -0,0 +1,44 @@
+import { AnyAction } from 'redux'
+import Types from '../actions/types'
+import { UserData, UserFilterParams } from '../interfaces/UserData'
+
+interface SearchUserState {
+  users: UserData[]
+  total: number
+  count: number
+  filterParams: UserFilterParams
+}
+
+const initialState: SearchUserState = {
+  users: [],
+  total: 0,
+  count: 0,
+  filterParams: { pageSize: 10, page: 0 },
+}
+
+export default function (state = initialState, action: AnyAction) {
+  switch (action.type) {
+    case Types.SET_SEARCH_USERS:
+      return {
+        ...state,
+        users: action.payload as UserData[],
+      }
+    case Types.SET_SEARCH_USERS_FILTER_PARAMS:
+      return {
+        ...state,
+        filterParams: action.payload as UserFilterParams,
+      }
+    case Types.SET_SEARCH_USERS_TOTAL_COUNT:
+      return {
+        ...state,
+        total: action.payload as number,
+      }
+    case Types.SET_SEARCH_USERS_COUNT:
+      return {
+        ...state,
+        count: action.payload as number,
+      }
+    default:
+      return state
+  }
+}