Skip to content
Snippets Groups Projects
Commit ec7cae30 authored by Albin Henriksson's avatar Albin Henriksson
Browse files

Add competition login

parent 018e3af6
No related branches found
No related tags found
1 merge request!93Resolve "Competition login"
This commit is part of merge request !93. Comments created here will be created in the context of that merge request.
......@@ -5,16 +5,19 @@ import { AccountLoginModel } from './../interfaces/FormModels'
import Types from './types'
export const loginCompetition = (code: string, history: History) => async (dispatch: AppDispatch) => {
dispatch({ type: Types.LOADING_COMPETITION_LOGIN })
await axios
.post('/api/auth/login/code', { code })
.then((res) => {
console.log(code, res.data[0])
dispatch({ type: Types.CLEAR_COMPETITION_LOGIN_ERRORS }) // no error
// history.push('/admin') //redirecting to admin page after login success
if (res.data && res.data[0] && res.data[0].view_type_id) {
history.push(`/${code}`)
}
})
.catch((err) => {
dispatch({ type: Types.SET_COMPETITION_LOGIN_ERRORS, payload: err && err.response && err.response.data })
console.log(err)
})
}
export default {
LOADING_UI: 'LOADING_UI',
LOADING_USER: 'LOADING_USER',
LOADING_COMPETITION_LOGIN: 'LOADING_COMPETITION_LOGIN',
SET_ROLES: 'SET_ROLES',
SET_USER: 'SET_USER',
SET_SEARCH_USERS: 'SET_SEARCH_USERS',
......@@ -9,6 +10,8 @@ export default {
SET_SEARCH_USERS_TOTAL_COUNT: 'SET_SEARCH_USERS_TOTAL_COUNT',
SET_ERRORS: 'SET_ERRORS',
CLEAR_ERRORS: 'CLEAR_ERRORS',
SET_COMPETITION_LOGIN_ERRORS: 'SET_COMPETITION_LOGIN_ERRORS',
CLEAR_COMPETITION_LOGIN_ERRORS: 'CLEAR_COMPETITION_LOGIN_ERRORS',
SET_UNAUTHENTICATED: 'SET_UNAUTHENTICATED',
SET_AUTHENTICATED: 'SET_AUTHENTICATED',
SET_COMPETITIONS: 'SET_COMPETITIONS',
......
import { Button, TextField } from '@material-ui/core'
import { Button, TextField, Typography } from '@material-ui/core'
import { Alert, AlertTitle } from '@material-ui/lab'
import { Formik, FormikHelpers } from 'formik'
import React, { useEffect, useState } from 'react'
......@@ -83,7 +83,8 @@ const AdminLogin: React.FC = () => {
{errors.message && (
<Alert severity="error">
<AlertTitle>Error</AlertTitle>
{errors.message}
<Typography>Någonting gick fel. Kontrollera</Typography>
<Typography>dina användaruppgifter och försök igen</Typography>
</Alert>
)}
{loading && <CenteredCircularProgress color="secondary" />}
......
import { Button, TextField } from '@material-ui/core'
import { Button, TextField, Typography } from '@material-ui/core'
import { Alert, AlertTitle } from '@material-ui/lab'
import axios from 'axios'
import { Formik, FormikHelpers } from 'formik'
import { useHistory } from 'react-router-dom'
import React, { useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import * as Yup from 'yup'
import { loginCompetition } from '../../../actions/competitionLogin'
import { useAppDispatch } from '../../../hooks'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { CompetitionLoginModel } from '../../../interfaces/FormModels'
import { LoginForm } from './styled'
import { CenteredCircularProgress, LoginForm } from './styled'
interface CompetitionLoginFormModel {
model: CompetitionLoginModel
error?: string
}
interface ServerResponse {
code: number
interface formError {
message: string
}
const competitionSchema: Yup.SchemaOf<CompetitionLoginFormModel> = Yup.object({
model: Yup.object()
.shape({
code: Yup.string().required('Mata in kod').min(6, 'Koden måste vara minst 6 tecken'),
code: Yup.string().required('Mata in kod').length(6, 'Koden måste vara 6 tecken'),
})
.required(),
error: Yup.string().optional(),
......@@ -32,27 +31,13 @@ const competitionSchema: Yup.SchemaOf<CompetitionLoginFormModel> = Yup.object({
const CompetitionLogin: React.FC = () => {
const dispatch = useAppDispatch()
const history = useHistory()
const errors = useAppSelector((state) => state.competitionLogin.errors)
const loading = useAppSelector((state) => state.competitionLogin.loading)
const competitionInitialValues: CompetitionLoginFormModel = {
model: { code: '' },
}
const handleCompetitionSubmit = async (
values: CompetitionLoginFormModel,
actions: FormikHelpers<CompetitionLoginFormModel>
) => {
const handleCompetitionSubmit = async (values: CompetitionLoginFormModel) => {
dispatch(loginCompetition(values.model.code, history))
/* await axios
.post<ServerResponse>(`users/login`, { code: values.model.code })
.then(() => {
actions.resetForm()
})
.catch(({ response }) => {
console.log(response.data.message)
actions.setFieldError('error', response.data.message)
})
.finally(() => {
actions.setSubmitting(false)
}) */
}
return (
<Formik
......@@ -74,14 +59,14 @@ const CompetitionLogin: React.FC = () => {
<Button type="submit" fullWidth variant="contained" color="secondary" disabled={!formik.isValid}>
Anslut till tävling
</Button>
{formik.errors.error ? (
{errors && errors.message && (
<Alert severity="error">
<AlertTitle>Error</AlertTitle>
{formik.errors.error}
<Typography>En tävling med den koden hittades ej.</Typography>
<Typography>kontrollera koden och försök igen</Typography>
</Alert>
) : (
<div />
)}
{loading && <CenteredCircularProgress color="secondary" />}
</LoginForm>
)}
</Formik>
......
......@@ -14,6 +14,7 @@ import { socket_connect } from '../../sockets'
import { SlideListItem } from '../presentationEditor/styled'
import JudgeScoreDisplay from './components/JudgeScoreDisplay'
import SlideDisplay from './components/SlideDisplay'
import { useHistory } from 'react-router-dom'
import {
Content,
JudgeAnswersLabel,
......@@ -41,6 +42,7 @@ const useStyles = makeStyles((theme: Theme) =>
const JudgeViewPage: React.FC = () => {
const classes = useStyles()
const history = useHistory()
const { id, code }: ViewParams = useParams()
const dispatch = useAppDispatch()
const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0)
......@@ -50,12 +52,13 @@ const JudgeViewPage: React.FC = () => {
setActiveSlideIndex(index)
dispatch(setCurrentSlide(slides[index]))
}
useEffect(() => {
socket_connect()
dispatch(getPresentationCompetition(id))
dispatch(getPresentationTeams(id))
dispatch(setPresentationCode(code))
//hides the url so people can't sneak peak
history.push('judge')
}, [])
return (
......
......@@ -5,6 +5,7 @@ import { useHistory } from 'react-router-dom'
const ParticipantViewPage: React.FC = () => {
const history = useHistory()
useEffect(() => {
//hides the url so people can't sneak peak
history.push('participant')
}, [])
return <SlideDisplay />
......
......@@ -46,31 +46,27 @@ import {
/**
* Presentation is an active competition
*/
type PresenterViewPageProps = {
competitionId: number
}
const PresenterViewPage = ({ competitionId }: PresenterViewPageProps) => {
const PresenterViewPage: React.FC = () => {
// for dialog alert
const [openAlert, setOpen] = React.useState(false)
const theme = useTheme()
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))
const teams = useAppSelector((state) => state.presentation.teams)
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
const { code }: ViewParams = useParams()
const { id, code }: ViewParams = useParams()
const presentation = useAppSelector((state) => state.presentation)
const history = useHistory()
const dispatch = useAppDispatch()
useEffect(() => {
dispatch(getPresentationCompetition(competitionId.toString()))
dispatch(getPresentationTeams(competitionId.toString()))
dispatch(getPresentationCompetition(id))
dispatch(getPresentationTeams(id))
dispatch(setPresentationCode(code))
socket_connect()
socketSetSlide // Behövs denna?
setTimeout(startCompetition, 500) // Ghetto, wait for everything to load
// console.log(competitionId)
// console.log(id)
}, [])
const handleOpenPopover = (event: React.MouseEvent<HTMLButtonElement>) => {
......@@ -85,7 +81,7 @@ const PresenterViewPage = ({ competitionId }: PresenterViewPageProps) => {
const startCompetition = () => {
socketStartPresentation()
console.log('started competition for')
console.log(competitionId)
console.log(id)
}
const handleVerifyExit = () => {
......
......@@ -15,27 +15,23 @@ interface ViewSelectParams {
code: string
}
const ViewSelectPage: React.FC = () => {
const url = useRouteMatch().url
const [loading, setLoading] = useState(true)
const [error, setError] = useState(false)
const [viewType, setViewType] = useState(undefined)
const [viewTypeId, setViewTypeId] = useState(undefined)
const [competitionId, setCompetitionId] = useState<number | undefined>(undefined)
const { code }: ViewSelectParams = useParams()
const viewType = useAppSelector((state) => state.types.viewTypes.find((viewType) => viewType.id === viewTypeId)?.name)
const renderView = (viewTypeId: number | undefined) => {
//Renders the correct view depending on view type
// TODO: use state instead of hard-coded values
//const viewTypes = useAppSelector(state => state.types.viewTypes)
if (competitionId) {
switch (viewTypeId) {
case 1:
switch (viewType) {
case 'Team':
return <ParticipantViewPage />
case 2:
case 'Judge':
return <JudgeViewPage />
case 3:
case 'Audience':
return <AudienceViewPage />
case 4:
return <PresenterViewPage competitionId={competitionId} />
default:
return <Typography>Inkorrekt vy</Typography>
}
......@@ -47,8 +43,8 @@ const ViewSelectPage: React.FC = () => {
.post('/api/auth/login/code', { code })
.then((response) => {
setLoading(false)
setViewType(response.data[0].view_type_id)
setCompetitionId(response.data[0].pointer)
setViewTypeId(response.data[0].view_type_id)
setCompetitionId(response.data[0].competition_id)
})
.catch(() => {
setLoading(false)
......@@ -60,7 +56,7 @@ const ViewSelectPage: React.FC = () => {
<ViewSelectContainer>
<ViewSelectButtonGroup>
{loading && <CircularProgress />}
{!loading && renderView(viewType)}
{!loading && renderView(viewTypeId)}
{error && <Typography>Något gick fel, dubbelkolla koden och försök igen</Typography>}
</ViewSelectButtonGroup>
</ViewSelectContainer>
......
......@@ -2,6 +2,7 @@
import { combineReducers } from 'redux'
import citiesReducer from './citiesReducer'
import competitionLoginReducer from './competitionLoginReducer'
import competitionsReducer from './competitionsReducer'
import editorReducer from './editorReducer'
import presentationReducer from './presentationReducer'
......@@ -24,5 +25,6 @@ const allReducers = combineReducers({
searchUsers: searchUserReducer,
types: typesReducer,
statistics: statisticsReducer,
competitionLogin: competitionLoginReducer,
})
export default allReducers
import { AnyAction } from 'redux'
import Types from '../actions/types'
interface UIError {
message: string
}
interface UserState {
loading: boolean
errors: null | UIError
}
const initialState: UserState = {
loading: false,
errors: null,
}
export default function (state = initialState, action: AnyAction) {
switch (action.type) {
case Types.SET_COMPETITION_LOGIN_ERRORS:
return {
errors: action.payload as UIError,
loading: false,
}
case Types.CLEAR_COMPETITION_LOGIN_ERRORS:
return {
loading: false,
errors: null,
}
case Types.LOADING_COMPETITION_LOGIN:
return {
...state,
loading: true,
}
default:
return state
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment