Skip to content
Snippets Groups Projects
Commit 0be2a771 authored by Carl Schönfelder's avatar Carl Schönfelder
Browse files

Resolve "Improve admin style"

parent f3019db1
No related branches found
No related tags found
1 merge request!49Resolve "Improve admin style"
Pipeline #39297 passed
client/public/favicon.ico

3.78 KiB | W: | H:

client/public/favicon.ico

402 KiB | W: | H:

client/public/favicon.ico
client/public/favicon.ico
client/public/favicon.ico
client/public/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
......@@ -5,10 +5,7 @@
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
......@@ -24,7 +21,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Teknikåttan</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
......
......@@ -12,7 +12,10 @@ import {
} 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 ExitToAppIcon from '@material-ui/icons/ExitToApp'
import LocationCityIcon from '@material-ui/icons/LocationCity'
import PeopleIcon from '@material-ui/icons/People'
import SettingsOverscanIcon from '@material-ui/icons/SettingsOverscan'
import React from 'react'
import { Link, Route, Switch, useRouteMatch } from 'react-router-dom'
import { logoutUser } from '../../actions/user'
......@@ -21,9 +24,13 @@ import CompetitionManager from './components/CompetitionManager'
import Regions from './components/Regions'
import UserManager from './components/UserManager'
import { LeftDrawer } from './styled'
const drawerWidth = 250
const menuItems = ['Startsida', 'Regioner', 'Användare', 'Tävlingshanterare']
const menuItems = [
{ text: 'Startsida', icon: DashboardIcon },
{ text: 'Regioner', icon: LocationCityIcon },
{ text: 'Användare', icon: PeopleIcon },
{ text: 'Tävlingshanterare', icon: SettingsOverscanIcon },
]
const useStyles = makeStyles((theme: Theme) =>
createStyles({
......@@ -61,7 +68,7 @@ const AdminView: React.FC = () => {
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<Typography variant="h5" noWrap>
{menuItems[openIndex]}
{menuItems[openIndex].text}
</Typography>
</Toolbar>
</AppBar>
......@@ -77,24 +84,31 @@ const AdminView: React.FC = () => {
<div className={classes.toolbar} />
<Divider />
<List>
{menuItems.map((text, index) => (
{menuItems.map((value, index) => (
<ListItem
button
component={Link}
key={text}
to={`${url}/${text.toLowerCase()}`}
key={value.text}
to={`${url}/${value.text.toLowerCase()}`}
selected={index === openIndex}
onClick={() => setOpenIndex(index)}
>
<ListItemIcon>{index === 0 ? <DashboardIcon /> : <MailIcon />}</ListItemIcon>
<ListItemText primary={text} />
<ListItemIcon>{React.createElement(value.icon)}</ListItemIcon>
<ListItemText primary={value.text} />
</ListItem>
))}
</List>
<Divider />
<List>
<ListItem>
<Button onClick={handleLogout} type="submit" fullWidth variant="contained" color="primary">
<Button
onClick={handleLogout}
type="submit"
fullWidth
variant="contained"
color="primary"
endIcon={<ExitToAppIcon></ExitToAppIcon>}
>
Logga ut
</Button>
</ListItem>
......
......@@ -8,8 +8,7 @@ import { getCompetitions } from '../../../actions/competitions'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { City } from '../../../interfaces/City'
import { AddCompetitionModel } from '../../../interfaces/models'
import { AddCompetitionButton, AddCompetitionContent, AddCompetitionForm } from './styled'
import { AddButton, AddContent, AddForm } from './styled'
interface ServerResponse {
code: number
message: string
......@@ -84,9 +83,9 @@ const AddCompetition: React.FC = (props: any) => {
}
return (
<div>
<AddCompetitionButton color="secondary" variant="contained" onClick={handleClick}>
<AddButton color="default" variant="contained" onClick={handleClick}>
Ny Tävling
</AddCompetitionButton>
</AddButton>
<Popover
id={id}
open={open}
......@@ -101,14 +100,14 @@ const AddCompetition: React.FC = (props: any) => {
horizontal: 'center',
}}
>
<AddCompetitionContent>
<AddContent>
<Formik
initialValues={competitionInitialValues}
validationSchema={competitionSchema}
onSubmit={handleCompetitionSubmit}
>
{(formik) => (
<AddCompetitionForm onSubmit={formik.handleSubmit}>
<AddForm onSubmit={formik.handleSubmit}>
<TextField
label="Namn"
name="model.name"
......@@ -170,10 +169,10 @@ const AddCompetition: React.FC = (props: any) => {
{formik.errors.error}
</Alert>
)}
</AddCompetitionForm>
</AddForm>
)}
</Formik>
</AddCompetitionContent>
</AddContent>
</Popover>
</div>
)
......
import { Button, Grid, TextField } from '@material-ui/core'
import FormControl from '@material-ui/core/FormControl'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import AddIcon from '@material-ui/icons/Add'
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 { getCities } from '../../../actions/cities'
import { useAppDispatch } from '../../../hooks'
import { AddForm } from './styled'
interface AddRegionModel {
city: ''
}
interface ServerResponse {
code: number
message: string
}
interface AddRegionFormModel {
model: AddRegionModel
error?: string
}
const useStyles = makeStyles((theme: Theme) =>
createStyles({
table: {
width: '100%',
},
margin: {
margin: theme.spacing(1),
},
button: {
width: '40px',
height: '40px',
marginTop: '20px',
},
})
)
const schema: Yup.SchemaOf<AddRegionFormModel> = Yup.object({
model: Yup.object()
.shape({
city: Yup.string()
.required('Minst två bokstäver krävs')
.min(2)
.matches(/[a-zA-Z]/, 'Namnet får enbart innehålla a-z, A-Z.'),
})
.required(),
error: Yup.string().optional(),
})
const AddRegion: React.FC = (props: any) => {
const classes = useStyles()
const dispatch = useAppDispatch()
const handleSubmit = async (values: AddRegionFormModel, actions: FormikHelpers<AddRegionFormModel>) => {
const params = {
name: values.model.city,
}
await axios
.post<ServerResponse>('/misc/cities', params)
.then(() => {
actions.resetForm()
dispatch(getCities())
})
.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 initValues: AddRegionFormModel = {
model: { city: '' },
}
return (
<Formik initialValues={initValues} validationSchema={schema} onSubmit={handleSubmit}>
{(formik) => (
<AddForm onSubmit={formik.handleSubmit}>
<FormControl className={classes.margin}>
<Grid container={true}>
<TextField
className={classes.margin}
helperText={formik.touched.model?.city ? formik.errors.model?.city : ''}
error={Boolean(formik.touched.model?.city && formik.errors.model?.city)}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
name="model.city"
label="Region"
></TextField>
<Button className={classes.button} color="default" variant="contained" type="submit">
<AddIcon></AddIcon>
</Button>
</Grid>
</FormControl>
{formik.errors.error && (
<Alert severity="error">
<AlertTitle>Error</AlertTitle>
{formik.errors.error}
</Alert>
)}
</AddForm>
)}
</Formik>
)
}
export default AddRegion
import { Button, FormControl, InputLabel, MenuItem, Popover, TextField } from '@material-ui/core'
import PersonAddIcon from '@material-ui/icons/PersonAdd'
import { Alert, AlertTitle } from '@material-ui/lab'
import axios from 'axios'
import { Formik, FormikHelpers } from 'formik'
......@@ -9,8 +10,7 @@ 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'
import { AddButton, AddContent, AddForm } from './styled'
interface ServerResponse {
code: number
message: string
......@@ -91,9 +91,9 @@ const AddUser: React.FC = (props: any) => {
}
return (
<div>
<AddCompetitionButton color="secondary" variant="contained" onClick={handleClick}>
<AddButton color="default" variant="contained" onClick={handleClick} endIcon={<PersonAddIcon></PersonAddIcon>}>
Ny Användare
</AddCompetitionButton>
</AddButton>
<Popover
id={id}
open={open}
......@@ -108,10 +108,10 @@ const AddUser: React.FC = (props: any) => {
horizontal: 'center',
}}
>
<AddCompetitionContent>
<AddContent>
<Formik initialValues={userInitialValues} validationSchema={userSchema} onSubmit={handleCompetitionSubmit}>
{(formik) => (
<AddCompetitionForm onSubmit={formik.handleSubmit}>
<AddForm onSubmit={formik.handleSubmit}>
<TextField
label="Email"
name="model.email"
......@@ -208,10 +208,10 @@ const AddUser: React.FC = (props: any) => {
{formik.errors.error}
</Alert>
)}
</AddCompetitionForm>
</AddForm>
)}
</Formik>
</AddCompetitionContent>
</AddContent>
</Popover>
</div>
)
......
......@@ -20,7 +20,7 @@ import { getCompetitions, setFilterParams } from '../../../actions/competitions'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { CompetitionFilterParams } from '../../../interfaces/CompetitionFilterParams'
import AddCompetition from './AddCompetition'
import { FilterContainer, RemoveCompetition, TopBar, YearFilterTextField } from './styled'
import { FilterContainer, RemoveMenuItem, TopBar, YearFilterTextField } from './styled'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
......@@ -178,7 +178,7 @@ const CompetitionManager: React.FC = (props: any) => {
<Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
<MenuItem onClick={handleClose}>Starta</MenuItem>
<MenuItem onClick={handleClose}>Duplicera</MenuItem>
<RemoveCompetition onClick={handleDeleteCompetition}>Ta bort</RemoveCompetition>
<RemoveMenuItem onClick={handleDeleteCompetition}>Ta bort</RemoveMenuItem>
</Menu>
</div>
)
......
import { Button, Menu, TextField, Typography } from '@material-ui/core'
import FormControl from '@material-ui/core/FormControl'
import { Button, Menu, Typography } from '@material-ui/core'
import Paper from '@material-ui/core/Paper'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import Table from '@material-ui/core/Table'
......@@ -13,8 +12,8 @@ import axios from 'axios'
import React, { useEffect } from 'react'
import { getCities } from '../../../actions/cities'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { RemoveCompetition, TopBar } from './styled'
import AddRegion from './AddRegion'
import { RemoveMenuItem, TopBar } from './styled'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
table: {
......@@ -31,7 +30,7 @@ const UserManager: React.FC = (props: any) => {
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 [newCity, setNewCity] = React.useState<string>()
const classes = useStyles()
const dispatch = useAppDispatch()
const handleClose = () => {
......@@ -81,12 +80,7 @@ const UserManager: React.FC = (props: any) => {
return (
<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>
<AddRegion></AddRegion>
</TopBar>
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="simple table">
......@@ -113,7 +107,7 @@ const UserManager: React.FC = (props: any) => {
{(!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>
<RemoveMenuItem onClick={handleDeleteCity}>Ta bort</RemoveMenuItem>
</Menu>
</div>
)
......
......@@ -20,7 +20,7 @@ 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'
import { FilterContainer, RemoveMenuItem, TopBar } from './styled'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
......@@ -192,7 +192,7 @@ const UserManager: React.FC = (props: any) => {
<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>
<RemoveMenuItem onClick={handleDeleteUsers}>Ta bort</RemoveMenuItem>
</Menu>
</div>
)
......
......@@ -7,20 +7,20 @@ export const TopBar = styled.div`
align-items: flex-end;
`
export const AddCompetitionButton = styled(Button)`
export const AddButton = styled(Button)`
margin-bottom: 8px;
`
export const AddCompetitionForm = styled.form`
export const AddForm = styled.form`
display: flex;
flex-direction: column;
`
export const AddCompetitionContent = styled.div`
export const AddContent = styled.div`
padding: 15px;
`
export const RemoveCompetition = styled(MenuItem)`
export const RemoveMenuItem = styled(MenuItem)`
color: red;
`
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment