Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tddd96-grupp11/teknikattan-scoring-system
1 result
Show changes
Commits on Source (7)
Showing
with 646 additions and 96 deletions
......@@ -6,4 +6,5 @@ __pycache__
htmlcov
.pytest_cache
/.idea
.vs/
\ No newline at end of file
.vs/
*/static
\ No newline at end of file
client:setup:
image: node:10
image: node
stage: setup
only:
refs:
......@@ -9,14 +9,14 @@ client:setup:
- cd client
- npm install
artifacts:
name: "artifacts"
name: 'artifacts'
untracked: true
expire_in: 15 mins
paths:
- client/.npm/
- client/node_modules/
cache:
key: "$CI_COMMIT_REF_SLUG"
key: '$CI_COMMIT_REF_SLUG'
paths:
- client/.npm/
- client/node_modules/
......@@ -24,7 +24,7 @@ client:setup:
client:linting:
image: node:10
stage: test
needs: ["client:setup"]
needs: ['client:setup']
allow_failure: true
only:
refs:
......@@ -39,7 +39,7 @@ client:linting:
client:test:
image: node:10
stage: test
needs: ["client:setup"]
needs: ['client:setup']
only:
refs:
- dev
......@@ -56,7 +56,7 @@ client:test:
client:report:
image: python
stage: report
needs: ["client:test"]
needs: ['client:test']
only:
refs:
- merge_requests
......
......@@ -1125,6 +1125,49 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
"@devexpress/dx-chart-core": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/@devexpress/dx-chart-core/-/dx-chart-core-2.7.5.tgz",
"integrity": "sha512-ZSpBN7SjnOhBOcvmuYZ5U+XyUYKlsTrYXCYMfFH2qXwvqh0e0UbhzW1FPfDXdWqx0Y52MtPX0HJrBC4QqH7Bcg==",
"requires": {
"d3-array": "^2.4.0",
"d3-scale": "^3.2.0",
"d3-shape": "^1.3.7"
}
},
"@devexpress/dx-core": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/@devexpress/dx-core/-/dx-core-2.7.5.tgz",
"integrity": "sha512-VQQkz0uUqQ7YuVZeBEx1JFqpSSe5Bz9Qy2T0XAbilBQ8IItj74xjzaFMCNjuASAKXOJGtG0RUh+BOKrMGV7jlg=="
},
"@devexpress/dx-react-chart": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/@devexpress/dx-react-chart/-/dx-react-chart-2.7.5.tgz",
"integrity": "sha512-j3nPsHrMiCbgm6olZCykxHOxxJ2XXG0CVihMYGOoyenM74Ed+NIaLi1bk2VtxKZdEPB5UrWgU10rd9SLH45BsQ==",
"requires": {
"@devexpress/dx-chart-core": "2.7.5",
"d3-scale": "^3.2.0",
"d3-shape": "^1.3.7"
}
},
"@devexpress/dx-react-chart-material-ui": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/@devexpress/dx-react-chart-material-ui/-/dx-react-chart-material-ui-2.7.5.tgz",
"integrity": "sha512-uS450uSP1D6mZ2jgtueShqaATNRVqJEwqhgyRQUXL/gQyTrTCvM61TC5NLyEYCOW6RkiHK1BabWbhJlVATZbeg==",
"requires": {
"clsx": "^1.0.4",
"prop-types": "^15.7.2"
}
},
"@devexpress/dx-react-core": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/@devexpress/dx-react-core/-/dx-react-core-2.7.5.tgz",
"integrity": "sha512-YwJ4l8nnMs/vghqamo8OzirDnrbT1ZNIcMP5xJFJJQIyfYAXvGGDS4yLeYI4cwitBg/d2O4jMOReXDB8tUaDDQ==",
"requires": {
"@devexpress/dx-core": "2.7.5",
"prop-types": "^15.7.2"
}
},
"@emotion/hash": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
......@@ -5416,6 +5459,73 @@
"type": "^1.0.1"
}
},
"d3-array": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
"requires": {
"internmap": "^1.0.0"
}
},
"d3-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
"integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
},
"d3-format": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
"integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
},
"d3-interpolate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
"integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
"requires": {
"d3-color": "1 - 2"
}
},
"d3-path": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
},
"d3-scale": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.4.tgz",
"integrity": "sha512-PG6gtpbPCFqKbvdBEswQcJcTzHC8VEd/XzezF5e68KlkT4/ggELw/nR1tv863jY6ufKTvDlzCMZvhe06codbbA==",
"requires": {
"d3-array": "^2.3.0",
"d3-format": "1 - 2",
"d3-interpolate": "1.2.0 - 2",
"d3-time": "1 - 2",
"d3-time-format": "2 - 3"
}
},
"d3-shape": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
"requires": {
"d3-path": "1"
}
},
"d3-time": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
"integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
"requires": {
"d3-array": "2"
}
},
"d3-time-format": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
"integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
"requires": {
"d3-time": "1 - 2"
}
},
"damerau-levenshtein": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
......@@ -8492,6 +8602,11 @@
"side-channel": "^1.0.4"
}
},
"internmap": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
......
......@@ -3,6 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@devexpress/dx-react-chart": "^2.7.5",
"@devexpress/dx-react-chart-material-ui": "^2.7.5",
"@devexpress/dx-react-core": "^2.7.5",
"@material-ui/core": "^4.11.3",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.57",
......
export default {
get: jest.fn().mockImplementation(),
post: jest.fn().mockImplementation(),
defaults: { headers: { common: { Authorization: '' } } },
}
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { getCities } from './cities'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches no actions when failing to get cities', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting cities failed'))
})
const store = mockStore({ competitions: { filterParams: [] } })
await getCities()(store.dispatch)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled()
})
import Types from './types.js'
export function axiosPost(
path: any,
data: any,
config = undefined,
startCB = undefined,
successCB = undefined,
errorCB = undefined
) {
return {
type: Types.AXIOS_POST,
path,
data,
config,
startCB,
successCB,
errorCB,
}
}
export function axiosPostSuccess(path: any, data: any, previousAction: any) {
return {
type: Types.AXIOS_POST_SUCCESS,
path,
data,
previousAction,
}
}
export function axiosPostError(path: any, data: any, previousAction: any) {
return {
type: Types.AXIOS_POST_ERROR,
path,
data,
previousAction,
}
}
export function axiosGet(
path: any,
data: any,
config = undefined,
startCB = undefined,
successCB = undefined,
errorCB = undefined
) {
return {
type: Types.AXIOS_GET,
path,
data,
config,
startCB,
successCB,
errorCB,
}
}
export function axiosGetSuccess(path: any, data: any, previousAction: any) {
return {
type: Types.AXIOS_GET_SUCCESS,
path,
data,
previousAction,
}
}
export function axiosGetError(path: any, data: any, previousAction: any) {
return {
type: Types.AXIOS_GET_ERROR,
path,
data,
previousAction,
}
}
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { CompetitionFilterParams } from './../interfaces/FilterParams'
import { getCompetitions, setFilterParams } from './competitions'
import Types from './types'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches correct actions when getting competitions', async () => {
const compRes: any = {
data: {
items: [
{
id: 21,
name: 'ggff',
year: 2021,
style_id: 1,
city: { name: 'city_name', id: 5 },
},
{
id: 22,
name: 'sssss',
year: 2021,
style_id: 1,
city: { name: 'city_name', id: 5 },
},
],
count: 2,
total_count: 3,
},
}
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.resolve(compRes)
})
const expectedActions = [
{ type: Types.SET_COMPETITIONS, payload: compRes.data.items },
{ type: Types.SET_COMPETITIONS_TOTAL, payload: compRes.data.total_count },
{ type: Types.SET_COMPETITIONS_COUNT, payload: compRes.data.count },
]
const store = mockStore({ competitions: { filterParams: [] } })
await getCompetitions()(store.dispatch, store.getState as any)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches correct actions when setting filterParams', () => {
const testFilterParams: CompetitionFilterParams = {
page: 0,
pageSize: 3,
name: 'name',
cityId: 0,
styleId: 0,
year: 2000,
}
const expectedActions = [{ type: Types.SET_COMPETITIONS_FILTER_PARAMS, payload: testFilterParams }]
const store = mockStore({})
setFilterParams(testFilterParams)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches no actions when failing to get competitions', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting competitions failed'))
})
const store = mockStore({ competitions: { filterParams: [] } })
await getCompetitions()(store.dispatch, store.getState as any)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled()
})
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { Slide } from '../interfaces/Slide'
import {
getPresentationCompetition,
getPresentationTeams,
setCurrentSlide,
setCurrentSlideNext,
setCurrentSlidePrevious,
} from './presentation'
import Types from './types'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches no actions when failing to get competitions', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting competitions failed'))
})
const store = mockStore({ competitions: { filterParams: [] } })
await getPresentationCompetition('0')(store.dispatch)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled()
})
it('dispatches no actions when failing to get teams', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting teams failed'))
})
const store = mockStore({ competitions: { filterParams: [] } })
await getPresentationTeams('0')(store.dispatch)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled()
})
it('dispatches correct actions when setting slide', () => {
const testSlide: Slide = { competition_id: 0, id: 5, order: 5, timer: 20, title: '' }
const expectedActions = [{ type: Types.SET_PRESENTATION_SLIDE, payload: testSlide }]
const store = mockStore({})
setCurrentSlide(testSlide)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches correct actions when setting previous slide', () => {
const expectedActions = [{ type: Types.SET_PRESENTATION_SLIDE_PREVIOUS }]
const store = mockStore({})
setCurrentSlidePrevious()(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches correct actions when setting next slide', () => {
const expectedActions = [{ type: Types.SET_PRESENTATION_SLIDE_NEXT }]
const store = mockStore({})
setCurrentSlideNext()(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { getRoles } from './roles'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches no actions when failing to get roles', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting roles failed'))
})
const store = mockStore({ competitions: { filterParams: [] } })
await getRoles()(store.dispatch)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled();
})
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { UserFilterParams } from './../interfaces/FilterParams'
import { getSearchUsers, setFilterParams } from './searchUser'
import Types from './types'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches correct actions when getting users', async () => {
const userRes: any = {
data: {
items: [
{
id: 21,
name: 'ggff',
email: 'email@test.com',
year: 2021,
role_id: 1,
city_id: 0,
},
{
id: 22,
name: 'sssss',
email: 'email@test.com',
year: 2021,
role_id: 1,
city_id: 0,
},
],
count: 2,
total_count: 3,
},
}
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.resolve(userRes)
})
const expectedActions = [
{ type: Types.SET_SEARCH_USERS, payload: userRes.data.items },
{ type: Types.SET_SEARCH_USERS_TOTAL_COUNT, payload: userRes.data.total_count },
{ type: Types.SET_SEARCH_USERS_COUNT, payload: userRes.data.count },
]
const store = mockStore({ searchUsers: { filterParams: [] } })
await getSearchUsers()(store.dispatch, store.getState as any)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches correct actions when setting filterParams', () => {
const testFilterParams: UserFilterParams = {
page: 0,
pageSize: 3,
name: 'name',
cityId: 0,
email: 'email@test.com',
roleId: 0,
}
const expectedActions = [{ type: Types.SET_SEARCH_USERS_FILTER_PARAMS, payload: testFilterParams }]
const store = mockStore({})
setFilterParams(testFilterParams)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches no actions when failing to get users', async () => {
console.log = jest.fn()
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject(new Error('getting users failed'))
})
const store = mockStore({ searchUsers: { filterParams: [] } })
await getSearchUsers()(store.dispatch, store.getState as any)
expect(store.getActions()).toEqual([])
expect(console.log).toHaveBeenCalled()
})
......@@ -8,7 +8,7 @@ export default {
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',
CLEAR_ERRORS: 'CLEAR_ERRORS',
SET_UNAUTHENTICATED: 'SET_UNAUTHENTICATED',
SET_AUTHENTICATED: 'SET_AUTHENTICATED',
SET_COMPETITIONS: 'SET_COMPETITIONS',
......@@ -23,10 +23,4 @@ export default {
SET_CITIES: 'SET_CITIES',
SET_CITIES_TOTAL: 'SET_CITIES_TOTAL',
SET_CITIES_COUNT: 'SET_CITIES_COUNT',
AXIOS_GET: 'AXIOS_GET',
AXIOS_GET_SUCCESS: 'AXIOS_GET_SUCCESS',
AXIOS_GET_ERROR: 'AXIOS_GET_ERROR',
AXIOS_POST: 'AXIOS_POST',
AXIOS_POST_SUCCESS: 'AXIOS_POST_SUCCESS',
AXIOS_POST_ERROR: 'AXIOS_POST_ERROR',
}
import mockedAxios from 'axios'
import expect from 'expect' // You can use any testing library
import { createMemoryHistory } from 'history'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import Types from './types'
import { loginUser, logoutUser } from './user'
const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
it('dispatches correct actions when logging in user', async () => {
const loginRes: any = {
data: {
access_token: 'TEST_ACCESS_TOKEN',
},
}
const userDataRes: any = {
data: {
name: 'test_name',
},
}
;(mockedAxios.post as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.resolve(loginRes)
})
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.resolve(userDataRes)
})
const expectedActions = [
{ type: Types.LOADING_UI },
{ type: Types.LOADING_USER },
{ type: Types.CLEAR_ERRORS },
{ type: Types.SET_USER, payload: { name: 'test_name' } },
]
const store = mockStore({})
const history = createMemoryHistory()
await loginUser({ email: 'test@email.com', password: 'testpassword' }, history)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
})
it('dispatches correct action when logging out user', async () => {
const store = mockStore({})
await logoutUser()(store.dispatch)
expect(store.getActions()).toEqual([{ type: Types.SET_UNAUTHENTICATED }])
})
it('dispatches correct action when failing to log in user', async () => {
console.log = jest.fn()
const errorMessage = 'getting teams failed'
;(mockedAxios.post as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject({ response: { data: errorMessage } })
})
const store = mockStore({ competitions: { filterParams: [] } })
const history = createMemoryHistory()
const expectedActions = [{ type: Types.LOADING_UI }, { type: Types.SET_ERRORS, payload: errorMessage }]
await loginUser({ email: 'test@email.com', password: 'testpassword' }, history)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
expect(console.log).toHaveBeenCalled()
})
it('dispatches correct actions when failing to get user data', async () => {
console.log = jest.fn()
const loginRes: any = {
data: {
access_token: 'TEST_ACCESS_TOKEN',
},
}
;(mockedAxios.post as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.resolve(loginRes)
})
const errorMessage = 'getting teams failed'
;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => {
return Promise.reject({ response: { data: errorMessage } })
})
const store = mockStore({ competitions: { filterParams: [] } })
const history = createMemoryHistory()
const expectedActions = [{ type: Types.LOADING_UI }, { type: Types.LOADING_USER }, { type: Types.CLEAR_ERRORS }]
await loginUser({ email: 'test@email.com', password: 'testpassword' }, history)(store.dispatch)
expect(store.getActions()).toEqual(expectedActions)
expect(console.log).toHaveBeenCalled()
})
......@@ -17,10 +17,10 @@ export const loginUser = (userData: AccountLoginModel, history: History) => asyn
history.push('/admin') //redirecting to admin page after login success
})
.catch((err) => {
console.error(err)
console.log(err)
dispatch({
type: Types.SET_ERRORS,
payload: err.response.data,
payload: err && err.response && err.response.data,
})
})
}
......@@ -30,7 +30,6 @@ export const getUserData = () => async (dispatch: AppDispatch) => {
await axios
.get('/users')
.then((res) => {
console.log(res.data)
dispatch({
type: Types.SET_USER,
payload: res.data,
......
......@@ -23,6 +23,7 @@ import { getRoles } from '../../actions/roles'
import { logoutUser } from '../../actions/user'
import { useAppDispatch, useAppSelector } from '../../hooks'
import CompetitionManager from './competitions/CompetitionManager'
import Dashboard from './dashboard/Dashboard'
import RegionManager from './regions/Regions'
import { LeftDrawer } from './styled'
import UserManager from './users/UserManager'
......@@ -45,7 +46,9 @@ const useStyles = makeStyles((theme: Theme) =>
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
paddingLeft: theme.spacing(31),
paddingTop: theme.spacing(2),
paddingLeft: theme.spacing(35),
paddingRight: theme.spacing(5),
},
})
)
......@@ -138,9 +141,7 @@ const AdminView: React.FC = () => {
<div className={classes.toolbar} />
<Switch>
<Route exact path={[path, `${path}/startsida`]}>
<Typography variant="h1" noWrap>
Startsida
</Typography>
<Dashboard />
</Route>
<Route path={`${path}/regioner`}>
<RegionManager />
......
import { createStyles, makeStyles, Paper, Theme, Typography } from '@material-ui/core'
import Grid from '@material-ui/core/Grid'
import React from 'react'
import CurrentUser from './components/CurrentUser'
import NumberOfCompetitions from './components/NumberOfCompetitions'
import NumberOfRegions from './components/NumberOfRegions'
import NumberOfUsers from './components/NumberOfUsers'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
})
)
const Dashboard: React.FC = () => {
const classes = useStyles()
return (
<div className={classes.root}>
<div>
<Grid container spacing={3}>
<Grid item xs={4}>
<Paper className={classes.paper}>
<CurrentUser />
</Paper>
</Grid>
<Grid item xs>
<Paper className={classes.paper}>
<Typography variant="h4">Antal Användare:</Typography>
<NumberOfUsers />
</Paper>
</Grid>
<Grid item xs>
<Paper className={classes.paper}>
<Typography variant="h4">Antal Regioner:</Typography>
<NumberOfRegions />
</Paper>
</Grid>
<Grid item xs>
<Paper className={classes.paper}>
<Typography variant="h4">Antal Tävlingar:</Typography>
<NumberOfCompetitions />
</Paper>
</Grid>
</Grid>
</div>
</div>
)
}
export default Dashboard
import { Box, Typography } from '@material-ui/core'
import React from 'react'
import { useAppSelector } from '../../../../hooks'
const CurrentUser: React.FC = () => {
const currentUser = useAppSelector((state: { user: { userInfo: any } }) => state.user.userInfo)
return (
<div>
<Box display="flex" flexDirection="column" alignContent="flex-start">
<div>
<Typography variant="h2">
Välkommen{currentUser && currentUser.name ? `, ${currentUser.name}` : ''}!
</Typography>
</div>
<div>
<Typography variant="h6">Email: {currentUser && currentUser.email}</Typography>
</div>
<div>
<Typography variant="h6">Region: {currentUser && currentUser.city && currentUser.city.name}</Typography>
</div>
<div>
<Typography variant="h6">Roll: {currentUser && currentUser.role && currentUser.role.name}</Typography>
</div>
</Box>
</div>
)
}
export default CurrentUser
import { Box, Typography } from '@material-ui/core'
import React, { useEffect } from 'react'
import { getSearchUsers } from '../../../../actions/searchUser'
import { useAppDispatch, useAppSelector } from '../../../../hooks'
const NumberOfCompetitions: React.FC = () => {
const cities = useAppSelector((state) => state.cities.cities)
const dispatch = useAppDispatch()
const handleCount = () => {
if (cities.length >= 1000000) {
;<div>{cities.length / 1000000 + 'M'}</div>
} else if (cities.length >= 1000) {
;<div>{cities.length / 1000 + 'K'}</div>
}
return <div>{cities.length}</div>
}
useEffect(() => {
dispatch(getSearchUsers())
}, [])
return (
<div>
<Box width="100%" height="100%">
<div>
<Typography variant="h4">{handleCount()}</Typography>
</div>
</Box>
</div>
)
}
export default NumberOfCompetitions
import { Box, Typography } from '@material-ui/core'
import React, { useEffect } from 'react'
import { getSearchUsers } from '../../../../actions/searchUser'
import { useAppDispatch, useAppSelector } from '../../../../hooks'
const NumberOfRegions: React.FC = () => {
const competitionTotal = useAppSelector((state) => state.competitions.total)
const dispatch = useAppDispatch()
const handleCount = () => {
if (competitionTotal >= 1000000) {
;<div>{competitionTotal / 1000000 + 'M'}</div>
} else if (competitionTotal >= 1000) {
;<div>{competitionTotal / 1000 + 'K'}</div>
}
return <div>{competitionTotal}</div>
}
useEffect(() => {
dispatch(getSearchUsers())
}, [])
return (
<div>
<Box width="100%" height="100%">
<div>
<Typography variant="h4">{handleCount()}</Typography>
</div>
</Box>
</div>
)
}
export default NumberOfRegions
import { Box, Typography } from '@material-ui/core'
import React, { useEffect } from 'react'
import { getSearchUsers } from '../../../../actions/searchUser'
import { useAppDispatch, useAppSelector } from '../../../../hooks'
const NumberOfUsers: React.FC = () => {
const usersTotal = useAppSelector((state) => state.searchUsers.total)
const dispatch = useAppDispatch()
const handleCount = () => {
if (usersTotal >= 1000000) {
;<div>{usersTotal / 1000000 + 'M'}</div>
} else if (usersTotal >= 1000) {
;<div>{usersTotal / 1000 + 'K'}</div>
}
return <div>{usersTotal}</div>
}
useEffect(() => {
dispatch(getSearchUsers())
}, [])
return (
<div>
<Box width="100%" height="100%">
<div>
<Typography variant="h4">{handleCount()}</Typography>
</div>
</Box>
</div>
)
}
export default NumberOfUsers