diff --git a/client/src/actions/editor.ts b/client/src/actions/editor.ts new file mode 100644 index 0000000000000000000000000000000000000000..d5e6fede6e777927eca7702098788c6a14b95e4b --- /dev/null +++ b/client/src/actions/editor.ts @@ -0,0 +1,169 @@ +import axios from 'axios' +import { AppDispatch } from './../store' +import Types from './types' + +export const getEditorCompetition = (id: string) => async (dispatch: AppDispatch) => { + await axios + .get(`/competitions/${id}`) + .then((res) => { + dispatch({ + type: Types.SET_EDITOR_COMPETITION, + //res.data, + payload: { + name: 'Tävling 1 (Hårdkodad)', + id: 1, + year: 1337, + city_id: 1, + slides: [ + { + competition_id: 1, + id: 1, + order: 1, + timer: 10, + title: 'Sida 1', + questions: [ + { + id: 1, + slide_id: 1, + name: 'Fråga 1 namn', + title: 'Fråga 1 titel', + total_score: 5, + type_id: 3, + question_answers: [ + { + id: 1, + question_id: 1, + team_id: 1, + data: 'question answer data 1', + score: 1, + }, + { + id: 2, + question_id: 1, + team_id: 2, + data: 'question answer data 2', + score: 3, + }, + ], + alternatives: [ + { + id: 1, + text: '1', + value: true, + question_id: 1, + }, + { + id: 2, + text: '0', + value: false, + question_id: 1, + }, + ], + }, + ], + body: 'Slide body 1', + settings: 'Slide settings 1', + }, + + { + competition_id: 1, + id: 2, + order: 2, + timer: 15, + title: 'Sida 2', + questions: [ + { + id: 2, + slide_id: 2, + name: 'Fråga 2 namn', + title: 'Fråga 2 titel', + total_score: 6, + type_id: 3, + question_answers: [ + { + id: 3, + question_id: 2, + team_id: 1, + data: 'question answer data 1', + score: 1, + }, + { + id: 4, + question_id: 2, + team_id: 2, + data: 'question answer data 2', + score: 4, + }, + ], + alternatives: [ + { + id: 1, + text: '5', + value: true, + question_id: 2, + }, + { + id: 2, + text: 'abc', + value: false, + question_id: 2, + }, + ], + }, + ], + body: 'Slide body 2', + settings: 'Slide settings 2', + }, + ], + + teams: [ + { + id: 1, + name: 'Örkelljunga IK', + question_answers: [ + { + id: 1, + question_id: 1, + team_id: 1, + data: 'question answer data 1', + score: 1, + }, + { + id: 3, + question_id: 2, + team_id: 1, + data: 'question answer data 1', + score: 1, + }, + ], + competition_id: 1, + }, + { + id: 2, + name: 'Vadstena OK', + question_answers: [ + { + id: 2, + question_id: 1, + team_id: 2, + data: 'question answer data 2', + score: 3, + }, + { + id: 4, + question_id: 2, + team_id: 2, + data: 'question answer data 2', + score: 4, + }, + ], + competition_id: 1, + }, + ], + }, + }) + }) + .catch((err) => { + console.log(err) + }) +} diff --git a/client/src/actions/types.ts b/client/src/actions/types.ts index d1084c2077290b65b27531d9d9234f5eb521eb1d..7c9cce081ce01f9cd317ca921f0352b32c4b02ee 100644 --- a/client/src/actions/types.ts +++ b/client/src/actions/types.ts @@ -15,6 +15,7 @@ export default { SET_COMPETITIONS_FILTER_PARAMS: 'SET_COMPETITIONS_FILTER_PARAMS', SET_COMPETITIONS_TOTAL: 'SET_COMPETITIONS_TOTAL', SET_COMPETITIONS_COUNT: 'SET_COMPETITIONS_COUNT', + SET_EDITOR_COMPETITION: 'SET_EDITOR_COMPETITION', SET_PRESENTATION_COMPETITION: 'SET_PRESENTATION_COMPETITION', SET_PRESENTATION_SLIDE: 'SET_PRESENTATION_SLIDE', SET_PRESENTATION_SLIDE_PREVIOUS: 'SET_PRESENTATION_SLIDE_PREVIOUS', diff --git a/client/src/interfaces/ApiModels.ts b/client/src/interfaces/ApiModels.ts index 0ffc91af0f04c49e11595d1aa5f7a40a5ae56c45..3c72e99fdacc5a81f5a7dbd461b1d22cc4dd4d14 100644 --- a/client/src/interfaces/ApiModels.ts +++ b/client/src/interfaces/ApiModels.ts @@ -3,8 +3,9 @@ export interface NameID { name: string } export interface City extends NameID {} + export interface Role extends NameID {} -export interface MediaType extends NameID {} + export interface QuestionType extends NameID {} export interface ComponentType extends NameID {} export interface ViewType extends NameID {} @@ -23,6 +24,8 @@ export interface Media { user_id: number } +export interface MediaType extends NameID {} + export interface User extends NameID { email: string role_id: number @@ -54,7 +57,7 @@ export interface QuestionAlternative { export interface QuestionAnswer { id: number question_id: number - team_id: string + team_id: number data: string score: number } diff --git a/client/src/interfaces/ApiRichModels.ts b/client/src/interfaces/ApiRichModels.ts index 3f7e012435518939f79c9bc30d43e17458215026..e21ae5fa14f709892b4d98c1685b690cd14e8284 100644 --- a/client/src/interfaces/ApiRichModels.ts +++ b/client/src/interfaces/ApiRichModels.ts @@ -1,10 +1,11 @@ -import { City, Component, Media, QuestionAnswer, QuestionType } from './ApiModels' +import { Component } from 'react' +import { Media, QuestionAlternative, QuestionAnswer, QuestionType } from './ApiModels' export interface RichCompetition { name: string id: number year: number - city: City + city_id: number slides: RichSlide[] teams: RichTeam[] } @@ -15,9 +16,9 @@ export interface RichSlide { timer: number title: string competition_id: number - question: RichQuestion[] components: Component[] medias: Media[] + questions: RichQuestion[] } export interface RichTeam { @@ -34,4 +35,6 @@ export interface RichQuestion { title: string total_score: number question_type: QuestionType + type_id: number + question_alternatives: QuestionAlternative[] } diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx index 67e38b99b38cdbbfafc8532a8e26e2cc8ec9b42f..ebc96d73452aff066c29856c4756573d28435bb2 100644 --- a/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx +++ b/client/src/pages/presentationEditor/PresentationEditorPage.test.tsx @@ -1,12 +1,41 @@ import { render } from '@testing-library/react' +import mockedAxios from 'axios' import React from 'react' +import { Provider } from 'react-redux' import { BrowserRouter } from 'react-router-dom' +import store from '../../store' import PresentationEditorPage from './PresentationEditorPage' it('renders presentation editor', () => { + const competitionRes: any = { + data: { + name: '', + id: 0, + year: 0, + city_id: 0, + slides: [], + teams: [], + }, + } + const citiesRes: any = { + data: { + items: [ + { + name: '', + city_id: 0, + }, + ], + }, + } + ;(mockedAxios.get as jest.Mock).mockImplementation((path: string, params?: any) => { + if (path.startsWith('/competitions')) return Promise.resolve(competitionRes) + return Promise.resolve(citiesRes) + }) render( - <BrowserRouter> - <PresentationEditorPage /> - </BrowserRouter> + <Provider store={store}> + <BrowserRouter> + <PresentationEditorPage /> + </BrowserRouter> + </Provider> ) }) diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx index a5209a16c623cbfa42982eb5782cc421c7e3e639..2993b12b78e9e532e71ab4573248bf1b51bcc4e8 100644 --- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx +++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx @@ -5,8 +5,11 @@ import Drawer from '@material-ui/core/Drawer' import List from '@material-ui/core/List' import ListItemText from '@material-ui/core/ListItemText' import { createStyles, makeStyles, Theme } from '@material-ui/core/styles' -import React from 'react' +import React, { useEffect } from 'react' import { useParams } from 'react-router-dom' +import { getCities } from '../../actions/cities' +import { getEditorCompetition } from '../../actions/editor' +import { useAppDispatch, useAppSelector } from '../../hooks' import { Content } from '../views/styled' import SettingsPanel from './components/SettingsPanel' import SlideEditor from './components/SlideEditor' @@ -16,15 +19,6 @@ function createSlide(name: string) { return { name } } -const slides = [ - createSlide('Sida 1'), - createSlide('Sida 2'), - createSlide('Sida 3'), - createSlide('Sida 4'), - createSlide('Sida 5'), - createSlide('Sida 6'), - createSlide('Sida 7'), -] const leftDrawerWidth = 150 const rightDrawerWidth = 390 @@ -68,14 +62,21 @@ interface CompetitionParams { const PresentationEditorPage: React.FC = () => { const classes = useStyles() - const params: CompetitionParams = useParams() + const { id }: CompetitionParams = useParams() + const dispatch = useAppDispatch() + const competition = useAppSelector((state) => state.editor.competition) + // TODO: wait for dispatch to finish + useEffect(() => { + dispatch(getEditorCompetition(id)) + dispatch(getCities()) + }, []) return ( <PresentationEditorContainer> <CssBaseline /> <AppBar position="fixed" className={classes.appBar}> <ToolBarContainer> <Typography variant="h6" noWrap> - Tävling nr: {params.id} + Tävlingsnamn: {competition.name} </Typography> <ViewButtonGroup> <ViewButton variant="contained" color="secondary"> @@ -101,9 +102,9 @@ const PresentationEditorPage: React.FC = () => { <div className={classes.toolbar} /> <Divider /> <List> - {slides.map((slide) => ( - <SlideListItem divider button key={slide.name}> - <ListItemText primary={slide.name} /> + {competition.slides.map((slide) => ( + <SlideListItem divider button key={slide.title}> + <ListItemText primary={slide.title} /> </SlideListItem> ))} </List> diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.test.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.test.tsx index 592581d4f8b3eaa884b7e0b409f39ee5ae8e5344..a655a30f0763524c61e81185065ab4974a15ae91 100644 --- a/client/src/pages/presentationEditor/components/CompetitionSettings.test.tsx +++ b/client/src/pages/presentationEditor/components/CompetitionSettings.test.tsx @@ -1,7 +1,10 @@ import { render } from '@testing-library/react' import React from 'react' +import { BrowserRouter } from 'react-router-dom' import ImageComponentDisplay from './ImageComponentDisplay' it('renders image component display', () => { - render(<ImageComponentDisplay component={{ id: 0, x: 0, y: 0, w: 0, h: 0, type: 0, media_id: 0 }} />) + render( + <ImageComponentDisplay component={{ id: 0, x: 0, y: 0, w: 0, h: 0, type: 0, media_id: 0 }} /> + ) }) diff --git a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx index 7446c6d1ee6acec3c05f2305f46f2356739877b4..2c61633f04a7aaba595e293a8f8ed9670d5c46c3 100644 --- a/client/src/pages/presentationEditor/components/CompetitionSettings.tsx +++ b/client/src/pages/presentationEditor/components/CompetitionSettings.tsx @@ -1,7 +1,23 @@ -import { Button, Divider, List, ListItem, ListItemText, TextField } from '@material-ui/core' +import { + Button, + Divider, + FormControl, + InputLabel, + List, + ListItem, + ListItemText, + MenuItem, + Select, + TextField, +} from '@material-ui/core' import { createStyles, makeStyles, Theme } from '@material-ui/core/styles' import CloseIcon from '@material-ui/icons/Close' -import React, { useState } from 'react' +import axios from 'axios' +import React from 'react' +import { useParams } from 'react-router-dom' +import { getEditorCompetition } from '../../../actions/editor' +import { useAppDispatch, useAppSelector } from '../../../hooks' +import { City } from '../../../interfaces/ApiModels' const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -31,33 +47,94 @@ const useStyles = makeStyles((theme: Theme) => height: 50, background: 'white', }, + dropDown: { + margin: theme.spacing(2), + width: '87%', + background: 'white', + }, }) ) +interface CompetitionParams { + id: string +} + const CompetitionSettings: React.FC = () => { const classes = useStyles() - const initialList = [ - { id: '1', name: 'Lag1' }, - { id: '2', name: 'Lag2' }, - { id: '3', name: 'Lag3' }, - ] - const handleClick = (id: string) => { - setTeams(teams.filter((item) => item.id !== id)) //Will not be done like this when api is used + const { id }: CompetitionParams = useParams() + const dispatch = useAppDispatch() + const competition = useAppSelector((state) => state.editor.competition) + + const updateCompetitionName = async (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => { + await axios + .put(`/competitions/${id}`, { name: event.target.value }) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) } - const [teams, setTeams] = useState(initialList) + + const handleClick = async (tid: number) => { + await axios + .delete(`/competitions/${id}/teams/${tid}`) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) + } + + const cities = useAppSelector((state) => state.cities.cities) + const updateCompetitionCity = async (city: City) => { + await axios + .put(`/competitions/${id}`, { city_id: city.id }) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) + } + + const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { + cities.forEach((city) => { + if (event.target.value === city.name) { + updateCompetitionCity(city) + } + }) + } + return ( <div className={classes.textInputContainer}> <form noValidate autoComplete="off"> - <TextField className={classes.textInput} label="Tävlingsnamn" variant="outlined" /> + <TextField + className={classes.textInput} + id="outlined-basic" + label={'Tävlingsnamn'} + defaultValue={competition.name} + onChange={updateCompetitionName} + variant="outlined" + /> <Divider /> - <TextField className={classes.textInput} label="Stad" variant="outlined" /> + <FormControl variant="outlined" className={classes.dropDown}> + <InputLabel id="region-selection-label">Region</InputLabel> + {/*TODO: fixa så cities laddar in i statet likt i CompetitionManager*/} + <Select + value={cities.find((city) => city.id === competition.city_id)?.name || ''} + label="RegionSelect" + onChange={handleChange} + > + {cities.map((city) => ( + <MenuItem value={city.name} key={city.name}> + <Button>{city.name}</Button> + </MenuItem> + ))} + </Select> + </FormControl> </form> <List> <ListItem> <ListItemText className={classes.textCenter} primary="Lag" /> </ListItem> - {teams.map((team) => ( + {competition.teams.map((team) => ( <div key={team.id}> <ListItem divider button> <ListItemText primary={team.name} /> diff --git a/client/src/pages/presentationEditor/components/SettingsPanel.test.tsx b/client/src/pages/presentationEditor/components/SettingsPanel.test.tsx index b4daa57be6bc6574d2b2617e986f50348e345246..a7a71e25921deb276cbaca2089d2ecbf58c8493c 100644 --- a/client/src/pages/presentationEditor/components/SettingsPanel.test.tsx +++ b/client/src/pages/presentationEditor/components/SettingsPanel.test.tsx @@ -1,15 +1,30 @@ import { render } from '@testing-library/react' import { mount } from 'enzyme' import React from 'react' +import { Provider } from 'react-redux' +import { BrowserRouter } from 'react-router-dom' +import store from '../../../store' import CompetitionSettings from './CompetitionSettings' import SettingsPanel from './SettingsPanel' it('renders settings panel', () => { - render(<SettingsPanel />) + render( + <Provider store={store}> + <BrowserRouter> + <SettingsPanel /> + </BrowserRouter> + </Provider> + ) }) it('renders slide settings tab', () => { - const wrapper = mount(<SettingsPanel />) + const wrapper = mount( + <Provider store={store}> + <BrowserRouter> + <SettingsPanel /> + </BrowserRouter> + </Provider> + ) const tabs = wrapper.find('.MuiTabs-flexContainer') expect(wrapper.find(CompetitionSettings).length).toEqual(1) tabs.children().at(1).simulate('click') diff --git a/client/src/pages/presentationEditor/components/SlideSettings.test.tsx b/client/src/pages/presentationEditor/components/SlideSettings.test.tsx index 4099e13080f660c88c00c7884c1603e62b41db64..a271fcf5286361804d073fa345abebe1212eb6f2 100644 --- a/client/src/pages/presentationEditor/components/SlideSettings.test.tsx +++ b/client/src/pages/presentationEditor/components/SlideSettings.test.tsx @@ -1,7 +1,16 @@ import { render } from '@testing-library/react' import React from 'react' +import { Provider } from 'react-redux' +import { BrowserRouter } from 'react-router-dom' +import store from '../../../store' import SlideSettings from './SlideSettings' it('renders slide settings', () => { - render(<SlideSettings />) + render( + <Provider store={store}> + <BrowserRouter> + <SlideSettings /> + </BrowserRouter> + </Provider> + ) }) diff --git a/client/src/pages/presentationEditor/components/SlideSettings.tsx b/client/src/pages/presentationEditor/components/SlideSettings.tsx index 4b0940214a10f2e223b03a418e0dd6209747fff0..cd611060bf16fd2e3e7d6b959cb1e0610a2fa931 100644 --- a/client/src/pages/presentationEditor/components/SlideSettings.tsx +++ b/client/src/pages/presentationEditor/components/SlideSettings.tsx @@ -10,10 +10,17 @@ import { Select, TextField, } from '@material-ui/core' -import { createStyles, makeStyles, Theme } from '@material-ui/core/styles' +import { CheckboxProps } from '@material-ui/core/Checkbox' +import { green, grey } from '@material-ui/core/colors' +import { createStyles, makeStyles, Theme, withStyles } from '@material-ui/core/styles' import CloseIcon from '@material-ui/icons/Close' import MoreHorizOutlinedIcon from '@material-ui/icons/MoreHorizOutlined' +import axios from 'axios' import React, { useState } from 'react' +import { useParams } from 'react-router-dom' +import { getEditorCompetition } from '../../../actions/editor' +import { useAppDispatch, useAppSelector } from '../../../hooks' +import { HiddenInput } from './styled' const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -58,22 +65,33 @@ const useStyles = makeStyles((theme: Theme) => }) ) +interface CompetitionParams { + id: string +} + const SlideSettings: React.FC = () => { const classes = useStyles() - - const [slideTypeSelected, selectSlideType] = React.useState('') - const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => { - selectSlideType(event.target.value as string) + const { id }: CompetitionParams = useParams() + const dispatch = useAppDispatch() + const competition = useAppSelector((state) => state.editor.competition) + let currentSlide = competition.slides[0] + // Init currentSlide if slides are not in order + for (const slide of competition.slides) { + if (slide.order === 1) { + currentSlide = slide + break + } } - const answerList = [ - { id: 'answer1', name: 'Svar 1' }, - { id: 'answer2', name: 'Svar 2' }, - ] - const handleCloseAnswerClick = (id: string) => { - setAnswers(answers.filter((item) => item.id !== id)) //Will not be done like this when api is used + const handleCloseAnswerClick = async (alternative: number) => { + await axios + // TODO: implementera API för att kunnata bort svarsalternativ + .delete(`/competitions/${id}/slide/question/alternative/${alternative}`) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) } - const [answers, setAnswers] = useState(answerList) const textList = [ { id: 'text1', name: 'Text 1' }, @@ -93,22 +111,75 @@ const SlideSettings: React.FC = () => { } const [pictures, setPictures] = useState(pictureList) + const updateSlideType = async (event: React.ChangeEvent<{ value: unknown }>) => { + await axios + // TODO: implementera API för att kunna ändra i questions->type_id + .put(`/competitions/${id}/slides/${currentSlide?.id}`, { type_id: event.target.value }) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) + } + + const updateAlternativeValue = async (event: React.ChangeEvent<HTMLInputElement>) => { + // Wheter the alternative is true or false + await axios + // TODO: implementera API för att kunna ändra i alternatives->value + .put(`/competitions/${id}/slides/${currentSlide?.id}`, { value: event.target.value }) + .then(() => { + dispatch(getEditorCompetition(id)) + }) + .catch(console.log) + } + + const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>): void => { + if (e.target.files !== null && e.target.files[0]) { + const files = Array.from(e.target.files) + const file = files[0] + const reader = new FileReader() + reader.readAsDataURL(file) + reader.onload = function () { + console.log(reader.result) + // TODO: Send image to back-end (remove console.log) + } + reader.onerror = function (error) { + console.log('Error: ', error) + } + } + } + + const handleAddText = async () => { + console.log('Add text component') + // TODO: post the new text] + setTexts([...texts, { id: 'newText', name: 'New Text' }]) + } + + const GreenCheckbox = withStyles({ + root: { + color: grey[900], + '&$checked': { + color: green[600], + }, + }, + checked: {}, + })((props: CheckboxProps) => <Checkbox color="default" {...props} />) + return ( <div className={classes.textInputContainer}> <div className={classes.whiteBackground}> <FormControl variant="outlined" className={classes.dropDown}> <InputLabel id="slide-type-selection-label">Sidtyp</InputLabel> - <Select value={slideTypeSelected} label="Sidtyp" defaultValue="informationSlide" onChange={handleChange}> - <MenuItem value="informationSlide"> + <Select value={currentSlide?.questions[0].type_id || 0} label="Sidtyp" onChange={updateSlideType}> + <MenuItem value={0}> <Button>Informationssida</Button> </MenuItem> - <MenuItem value="textQuestion"> + <MenuItem value={1}> <Button>Skriftlig fråga</Button> </MenuItem> - <MenuItem value="practicalQuestion"> + <MenuItem value={2}> <Button>Praktisk fråga</Button> </MenuItem> - <MenuItem value="multipleChoiceQuestion"> + <MenuItem value={3}> <Button>Flervalsfråga</Button> </MenuItem> </Select> @@ -123,6 +194,7 @@ const SlideSettings: React.FC = () => { helperText="Lämna blank för att inte använda timerfunktionen" label="Timer" type="number" + value={currentSlide?.timer} /> </ListItem> @@ -134,12 +206,18 @@ const SlideSettings: React.FC = () => { secondary="(Fyll i rutan höger om textfältet för att markera korrekt svar)" /> </ListItem> - {answers.map((answer) => ( - <div key={answer.id}> + {(currentSlide?.questions[0].question_alternatives || []).map((alt) => ( + <div key={alt.id}> <ListItem divider> - <TextField className={classes.textInput} label={answer.name} variant="outlined" /> - <Checkbox color="default" /> - <CloseIcon className={classes.clickableIcon} onClick={() => handleCloseAnswerClick(answer.id)} /> + <TextField + className={classes.textInput} + id="outlined-basic" + label={`Svar ${alt.id}`} + value={alt.text} + variant="outlined" + /> + <GreenCheckbox checked={alt.value} onChange={updateAlternativeValue} /> + <CloseIcon className={classes.clickableIcon} onClick={() => handleCloseAnswerClick(alt.id)} /> </ListItem> </div> ))} @@ -161,7 +239,7 @@ const SlideSettings: React.FC = () => { </ListItem> </div> ))} - <ListItem className={classes.center} button> + <ListItem className={classes.center} button onClick={handleAddText}> <Button>Lägg till text</Button> </ListItem> </List> @@ -184,7 +262,11 @@ const SlideSettings: React.FC = () => { </div> ))} <ListItem className={classes.center} button> - <Button>Lägg till bild</Button> + <HiddenInput accept="image/*" id="contained-button-file" multiple type="file" onChange={handleFileSelected} /> + + <label htmlFor="contained-button-file"> + <Button component="span">Lägg till bild</Button> + </label> </ListItem> </List> diff --git a/client/src/pages/presentationEditor/components/styled.tsx b/client/src/pages/presentationEditor/components/styled.tsx index 62239c5b9e53b2925aea7cb4d85784cc862f77d8..c4584f87468ceea090ecabca872e8000d3b58988 100644 --- a/client/src/pages/presentationEditor/components/styled.tsx +++ b/client/src/pages/presentationEditor/components/styled.tsx @@ -13,3 +13,7 @@ export const SlideEditorContainer = styled.div` width: 100%; height: 100%; ` + +export const HiddenInput = styled.input` + display: none; +` diff --git a/client/src/reducers/allReducers.ts b/client/src/reducers/allReducers.ts index d0f9e8012d5e85f9352ac239499d49fc0a7e7322..2aee46972cb6f0d33f2b128aeb6d19a9d77f106f 100644 --- a/client/src/reducers/allReducers.ts +++ b/client/src/reducers/allReducers.ts @@ -3,6 +3,7 @@ import { combineReducers } from 'redux' import citiesReducer from './citiesReducer' import competitionsReducer from './competitionsReducer' +import editorReducer from './editorReducer' import presentationReducer from './presentationReducer' import rolesReducer from './rolesReducer' import searchUserReducer from './searchUserReducer' @@ -16,6 +17,7 @@ const allReducers = combineReducers({ UI: uiReducer, competitions: competitionsReducer, cities: citiesReducer, + editor: editorReducer, presentation: presentationReducer, roles: rolesReducer, searchUsers: searchUserReducer, diff --git a/client/src/reducers/editorReducer.ts b/client/src/reducers/editorReducer.ts new file mode 100644 index 0000000000000000000000000000000000000000..606f5d69ba7cb53e6ce9d9468b632045d8965b9d --- /dev/null +++ b/client/src/reducers/editorReducer.ts @@ -0,0 +1,30 @@ +import { AnyAction } from 'redux' +import Types from '../actions/types' +import { RichCompetition } from '../interfaces/ApiRichModels' + +interface EditorState { + competition: RichCompetition +} + +const initialState: EditorState = { + competition: { + name: '', + id: 0, + year: 0, + city_id: 1, + slides: [], + teams: [], + }, +} + +export default function (state = initialState, action: AnyAction) { + switch (action.type) { + case Types.SET_EDITOR_COMPETITION: + return { + ...state, + competition: action.payload as RichCompetition, + } + default: + return state + } +} diff --git a/client/src/reducers/presentationReducer.test.ts b/client/src/reducers/presentationReducer.test.ts index cf4ded4132b1fa1cb1490a89584791032746385b..15bcd3376110f565db2ed73bc4e2d848c8063f61 100644 --- a/client/src/reducers/presentationReducer.test.ts +++ b/client/src/reducers/presentationReducer.test.ts @@ -7,10 +7,7 @@ const initialState = { competition: { name: '', id: 0, - city: { - id: 0, - name: '', - }, + city_id: 0, slides: [], year: 0, teams: [], diff --git a/client/src/reducers/presentationReducer.ts b/client/src/reducers/presentationReducer.ts index d71bcafbca4720c9d82ed41a18a6e55db6d91927..b4325680b0c1d87698a0aa798fc013528855f4f6 100644 --- a/client/src/reducers/presentationReducer.ts +++ b/client/src/reducers/presentationReducer.ts @@ -14,10 +14,7 @@ const initialState: PresentationState = { competition: { name: '', id: 0, - city: { - id: 0, - name: '', - }, + city_id: 0, slides: [], year: 0, teams: [],