diff --git a/client/src/actions/competitions.ts b/client/src/actions/competitions.ts index a758fd635550306eecb09e8100d5e17cb09a8ce1..7d248e46c05df64e948b483c5092616c4a828f35 100644 --- a/client/src/actions/competitions.ts +++ b/client/src/actions/competitions.ts @@ -1,5 +1,5 @@ import axios from 'axios' -import { CompetitionFilterParams } from '../interfaces/CompetitionFilterParams' +import { CompetitionFilterParams } from '../interfaces/FilterParams' import { AppDispatch, RootState } from './../store' import Types from './types' diff --git a/client/src/actions/searchUser.ts b/client/src/actions/searchUser.ts index fb4bf122e40d13952537c3e942bf351f10f99604..c6211056bda8250f1b5c849450d018ef4bd42819 100644 --- a/client/src/actions/searchUser.ts +++ b/client/src/actions/searchUser.ts @@ -1,5 +1,5 @@ import axios from 'axios' -import { UserFilterParams } from '../interfaces/UserData' +import { UserFilterParams } from '../interfaces/FilterParams' import { AppDispatch, RootState } from './../store' import Types from './types' diff --git a/client/src/actions/user.ts b/client/src/actions/user.ts index b543a68ae0631036e3a2df1f1312698c733f5bfa..72d764c861db49024c5fbcf00e3291efc35b2609 100644 --- a/client/src/actions/user.ts +++ b/client/src/actions/user.ts @@ -1,10 +1,10 @@ import axios from 'axios' import { History } from 'history' import { AppDispatch } from '../store' -import { AdminLoginData } from './../interfaces/AdminLoginData' +import { AccountLoginModel } from './../interfaces/FormModels' import Types from './types' -export const loginUser = (userData: AdminLoginData, history: History) => async (dispatch: AppDispatch) => { +export const loginUser = (userData: AccountLoginModel, history: History) => async (dispatch: AppDispatch) => { dispatch({ type: Types.LOADING_UI }) await axios .post('/auth/login', userData) diff --git a/client/src/interfaces/AdminLoginData.ts b/client/src/interfaces/AdminLoginData.ts deleted file mode 100644 index 70f61036d73c599f650abcca254c3ba5c6594992..0000000000000000000000000000000000000000 --- a/client/src/interfaces/AdminLoginData.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface AdminLoginData { - email: string - password: string -} diff --git a/client/src/interfaces/ApiModels.ts b/client/src/interfaces/ApiModels.ts new file mode 100644 index 0000000000000000000000000000000000000000..194fb2e727449b39befe2e1d43ee9913cca1ee00 --- /dev/null +++ b/client/src/interfaces/ApiModels.ts @@ -0,0 +1,74 @@ +interface NameID { + id: number + name: string +} +export interface City extends NameID {} +export interface Role extends NameID {} +export interface MediaType extends NameID {} +export interface QuestionType extends NameID {} + +export interface Media { + id: number + filename: string + mediatype_id: number + user_id: number +} + +export interface User extends NameID { + email: string + role_id: number + city_id: number +} + +export interface Competition extends NameID { + city_id: number + year: number +} + +export interface Team extends NameID { + competition_id: number +} + +export interface Question extends NameID { + slide_id: number + title: string + total_score: number + type_id: number +} + +export interface QuestionAlternative { + id: number + text: string + value: boolean + question_id: number +} +export interface QuestionAnswer { + id: number + question_id: number + team_id: string + data: string + score: number +} + +export interface Component { + id: number + x: number + y: number + w: number + h: number + type: number +} + +export interface ImageComponent extends Component { + media_id: number +} + +export interface TextComponent extends Component { + text: string + font: string +} + +export interface QuestionAlternativeComponent extends Component { + question_alternative_id: number + font: string +} diff --git a/client/src/interfaces/ApiRichModels.ts b/client/src/interfaces/ApiRichModels.ts new file mode 100644 index 0000000000000000000000000000000000000000..3f7e012435518939f79c9bc30d43e17458215026 --- /dev/null +++ b/client/src/interfaces/ApiRichModels.ts @@ -0,0 +1,37 @@ +import { City, Component, Media, QuestionAnswer, QuestionType } from './ApiModels' + +export interface RichCompetition { + name: string + id: number + year: number + city: City + slides: RichSlide[] + teams: RichTeam[] +} + +export interface RichSlide { + id: number + order: number + timer: number + title: string + competition_id: number + question: RichQuestion[] + components: Component[] + medias: Media[] +} + +export interface RichTeam { + id: number + name: string + question_answers: QuestionAnswer[] + competition_id: number +} + +export interface RichQuestion { + id: number + slide_id: number + name: string + title: string + total_score: number + question_type: QuestionType +} diff --git a/client/src/interfaces/City.ts b/client/src/interfaces/City.ts deleted file mode 100644 index e5190b6b56284e97015a66b1c2febd0548bd236a..0000000000000000000000000000000000000000 --- a/client/src/interfaces/City.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface City { - id: number - name: string -} diff --git a/client/src/interfaces/Competition.ts b/client/src/interfaces/Competition.ts deleted file mode 100644 index d36d97da1bc824f996fb7c46e88eaa71aa720995..0000000000000000000000000000000000000000 --- a/client/src/interfaces/Competition.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface Competition { - name: string - id: number - city_id: number - year: number -} diff --git a/client/src/interfaces/CompetitionFilterParams.ts b/client/src/interfaces/CompetitionFilterParams.ts deleted file mode 100644 index 839460527a548572cf4dc26015f477e33e871187..0000000000000000000000000000000000000000 --- a/client/src/interfaces/CompetitionFilterParams.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface CompetitionFilterParams { - name?: string - year?: number - cityId?: number - styleId?: number - page: number - pageSize: number -} diff --git a/client/src/interfaces/FilterParams.ts b/client/src/interfaces/FilterParams.ts new file mode 100644 index 0000000000000000000000000000000000000000..eca6551f4705aa3e4dfe6c96878fc9d3039fd983 --- /dev/null +++ b/client/src/interfaces/FilterParams.ts @@ -0,0 +1,26 @@ +export interface CompetitionFilterParams { + name?: string + year?: number + cityId?: number + styleId?: number + page: number + pageSize: number +} + +export interface SearchUserFilterParams { + name?: string + year?: number + cityId?: number + styleId?: number + page: number + pageSize: 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/FormModels.ts similarity index 64% rename from client/src/interfaces/models.ts rename to client/src/interfaces/FormModels.ts index 70d4cc08b5f8e449ad251526389dd84fe42a4d3e..294887131ab91c4715d3fe39f03121d1c835b11b 100644 --- a/client/src/interfaces/models.ts +++ b/client/src/interfaces/FormModels.ts @@ -1,18 +1,31 @@ +export interface ServerResponse { + code: number + message: string +} +export interface FormModel<T> { + model: T + error?: string +} + +//#region LOGIN export interface AccountLoginModel { email: string password: string } +export interface CompetitionLoginModel { + code: string +} + +//#endregion + +////ADD//// export interface AddCompetitionModel { name: string city: string year: number } -export interface CompetitionLoginModel { - code: string -} - export interface AddUserModel { email: string password: string @@ -21,6 +34,11 @@ export interface AddUserModel { name?: string } +export interface AddCityModel { + name: string +} + +////EDIT//// export interface EditUserModel { email: string role: string diff --git a/client/src/interfaces/Role.ts b/client/src/interfaces/Role.ts deleted file mode 100644 index 08a54dfcb012ee03398d17d4a7153ab040cde909..0000000000000000000000000000000000000000 --- a/client/src/interfaces/Role.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Role { - id: number - name: string -} diff --git a/client/src/interfaces/SearchUserFilterParams.ts b/client/src/interfaces/SearchUserFilterParams.ts deleted file mode 100644 index 8d7230d83d12d164a0db4683b4db7b791d835a81..0000000000000000000000000000000000000000 --- a/client/src/interfaces/SearchUserFilterParams.ts +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index a0c7394699b314c49e8f19bb259b6d73dd610bcf..0000000000000000000000000000000000000000 --- a/client/src/interfaces/UserData.ts +++ /dev/null @@ -1,16 +0,0 @@ -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/pages/admin/AdminPage.tsx b/client/src/pages/admin/AdminPage.tsx index 10e38f65bce156a82bca6512c577b8c4199d8391..8b0fb81cbfeb9418217184a7425ab15859a07221 100644 --- a/client/src/pages/admin/AdminPage.tsx +++ b/client/src/pages/admin/AdminPage.tsx @@ -16,8 +16,10 @@ 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 React, { useEffect } from 'react' import { Link, Route, Switch, useRouteMatch } from 'react-router-dom' +import { getCities } from '../../actions/cities' +import { getRoles } from '../../actions/roles' import { logoutUser } from '../../actions/user' import { useAppDispatch } from '../../hooks' import CompetitionManager from './components/CompetitionManager' @@ -62,6 +64,12 @@ const AdminView: React.FC = () => { dispatch(logoutUser()) } const dispatch = useAppDispatch() + + useEffect(() => { + dispatch(getCities()) + dispatch(getRoles()) + }, []) + return ( <div className={classes.root}> <CssBaseline /> diff --git a/client/src/pages/admin/components/AddCompetition.tsx b/client/src/pages/admin/components/AddCompetition.tsx index 7bc82f00bbe7a21712b5a4b3b3b0b22b17de5bda..65cb7c266d1e5d5c48fba2ead6b3fff5bfdc855b 100644 --- a/client/src/pages/admin/components/AddCompetition.tsx +++ b/client/src/pages/admin/components/AddCompetition.tsx @@ -6,21 +6,15 @@ import React from 'react' import * as Yup from 'yup' import { getCompetitions } from '../../../actions/competitions' import { useAppDispatch, useAppSelector } from '../../../hooks' -import { City } from '../../../interfaces/City' -import { AddCompetitionModel } from '../../../interfaces/models' +import { City } from '../../../interfaces/ApiModels' +import { AddCompetitionModel, FormModel } from '../../../interfaces/FormModels' import { AddButton, AddContent, AddForm } from './styled' -interface ServerResponse { - code: number - message: string -} -interface AddCompetitionFormModel { - model: AddCompetitionModel - error?: string -} +type formType = FormModel<AddCompetitionModel> + const noCitySelected = 'Välj stad' -const competitionSchema: Yup.SchemaOf<AddCompetitionFormModel> = Yup.object({ +const competitionSchema: Yup.SchemaOf<formType> = Yup.object({ model: Yup.object() .shape({ name: Yup.string().required('Namn krävs'), @@ -50,17 +44,14 @@ const AddCompetition: React.FC = (props: any) => { const dispatch = useAppDispatch() const id = open ? 'simple-popover' : undefined const currentYear = new Date().getFullYear() - const handleCompetitionSubmit = async ( - values: AddCompetitionFormModel, - actions: FormikHelpers<AddCompetitionFormModel> - ) => { + const handleCompetitionSubmit = async (values: formType, actions: FormikHelpers<formType>) => { const params = { name: values.model.name, year: values.model.year, city_id: selectedCity?.id as number, } await axios - .post<ServerResponse>('/competitions', params) + .post('/competitions', params) .then(() => { actions.resetForm() setAnchorEl(null) @@ -78,7 +69,7 @@ const AddCompetition: React.FC = (props: any) => { }) } - const competitionInitialValues: AddCompetitionFormModel = { + const competitionInitialValues: formType = { model: { name: '', city: userCity?.name ? userCity.name : noCitySelected, year: currentYear }, } return ( diff --git a/client/src/pages/admin/components/AddRegion.tsx b/client/src/pages/admin/components/AddRegion.tsx index 658fe63fdbc5e36d3eb2f63c50e428565a89295d..7f0ccf4e3cc1a43f23a7173b6de883c047899054 100644 --- a/client/src/pages/admin/components/AddRegion.tsx +++ b/client/src/pages/admin/components/AddRegion.tsx @@ -9,20 +9,9 @@ import React from 'react' import * as Yup from 'yup' import { getCities } from '../../../actions/cities' import { useAppDispatch } from '../../../hooks' +import { AddCityModel, FormModel } from '../../../interfaces/FormModels' 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: { @@ -39,7 +28,9 @@ const useStyles = makeStyles((theme: Theme) => }) ) -const schema: Yup.SchemaOf<AddRegionFormModel> = Yup.object({ +type formType = FormModel<AddCityModel> + +const schema: Yup.SchemaOf<formType> = Yup.object({ model: Yup.object() .shape({ city: Yup.string() @@ -55,12 +46,12 @@ const AddRegion: React.FC = (props: any) => { const classes = useStyles() const dispatch = useAppDispatch() - const handleSubmit = async (values: AddRegionFormModel, actions: FormikHelpers<AddRegionFormModel>) => { + const handleSubmit = async (values: formType, actions: FormikHelpers<formType>) => { const params = { - name: values.model.city, + name: values.model.name, } await axios - .post<ServerResponse>('/misc/cities', params) + .post('/misc/cities', params) .then(() => { actions.resetForm() dispatch(getCities()) @@ -76,8 +67,8 @@ const AddRegion: React.FC = (props: any) => { }) } - const initValues: AddRegionFormModel = { - model: { city: '' }, + const initValues: formType = { + model: { name: '' }, } return ( @@ -88,8 +79,8 @@ const AddRegion: React.FC = (props: any) => { <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)} + 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} name="model.city" diff --git a/client/src/pages/admin/components/AddUser.tsx b/client/src/pages/admin/components/AddUser.tsx index f55caa3a83b552536c78d3741fbe5e85bb603707..8880f4003e7162e0e6c93657265506ab9d39cce9 100644 --- a/client/src/pages/admin/components/AddUser.tsx +++ b/client/src/pages/admin/components/AddUser.tsx @@ -7,24 +7,16 @@ 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 { City, Role } from '../../../interfaces/ApiModels' +import { AddUserModel, FormModel } from '../../../interfaces/FormModels' import { AddButton, AddContent, AddForm } from './styled' -interface ServerResponse { - code: number - message: string -} -interface AddUserFormModel { - model: AddUserModel - error?: string -} +type formType = FormModel<AddUserModel> const noRoleSelected = 'Välj roll' const noCitySelected = 'Välj stad' -const userSchema: Yup.SchemaOf<AddUserFormModel> = Yup.object({ +const userSchema: Yup.SchemaOf<formType> = Yup.object({ model: Yup.object() .shape({ name: Yup.string(), //.required('Namn krävs'), @@ -58,7 +50,7 @@ const AddUser: React.FC = (props: any) => { const open = Boolean(anchorEl) const dispatch = useAppDispatch() const id = open ? 'simple-popover' : undefined - const handleCompetitionSubmit = async (values: AddUserFormModel, actions: FormikHelpers<AddUserFormModel>) => { + const handleCompetitionSubmit = async (values: formType, actions: FormikHelpers<formType>) => { const params = { email: values.model.email, password: values.model.password, @@ -67,7 +59,7 @@ const AddUser: React.FC = (props: any) => { role_id: selectedRole?.id as number, } await axios - .post<ServerResponse>('/auth/signup', params) + .post('/auth/signup', params) .then(() => { actions.resetForm() setAnchorEl(null) @@ -86,7 +78,7 @@ const AddUser: React.FC = (props: any) => { }) } - const userInitialValues: AddUserFormModel = { + const userInitialValues: formType = { model: { email: '', password: '', name: '', city: noCitySelected, role: noRoleSelected }, } return ( diff --git a/client/src/pages/admin/components/CompetitionManager.tsx b/client/src/pages/admin/components/CompetitionManager.tsx index f41c17058f1f69d37aadb29b323496bf048b389a..07d7f32d3c617d60a89929cfa5d0575a44c23297 100644 --- a/client/src/pages/admin/components/CompetitionManager.tsx +++ b/client/src/pages/admin/components/CompetitionManager.tsx @@ -15,10 +15,9 @@ import MoreHorizIcon from '@material-ui/icons/MoreHoriz' import axios from 'axios' import React, { useEffect } from 'react' import { Link } from 'react-router-dom' -import { getCities } from '../../../actions/cities' import { getCompetitions, setFilterParams } from '../../../actions/competitions' import { useAppDispatch, useAppSelector } from '../../../hooks' -import { CompetitionFilterParams } from '../../../interfaces/CompetitionFilterParams' +import { CompetitionFilterParams } from '../../../interfaces/FilterParams' import AddCompetition from './AddCompetition' import { FilterContainer, RemoveMenuItem, TopBar, YearFilterTextField } from './styled' @@ -55,7 +54,6 @@ const CompetitionManager: React.FC = (props: any) => { } useEffect(() => { - dispatch(getCities()) dispatch(getCompetitions()) }, []) diff --git a/client/src/pages/admin/components/UserManager.tsx b/client/src/pages/admin/components/UserManager.tsx index d85290b2305808cfd35063d3ed7d403b19b57b18..e2f2412f96ad5963314a07aac3d68f1760d52f79 100644 --- a/client/src/pages/admin/components/UserManager.tsx +++ b/client/src/pages/admin/components/UserManager.tsx @@ -14,11 +14,9 @@ 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 { UserFilterParams } from '../../../interfaces/FilterParams' import AddUser from './AddUser' import { FilterContainer, RemoveMenuItem, TopBar } from './styled' @@ -56,8 +54,6 @@ const UserManager: React.FC = (props: any) => { } useEffect(() => { - dispatch(getCities()) - dispatch(getRoles()) dispatch(getSearchUsers()) }, []) diff --git a/client/src/pages/login/components/AdminLogin.tsx b/client/src/pages/login/components/AdminLogin.tsx index cdff4d3fd14a422f22461e1cccd3b1acf26f1e84..39892ba1f4c975e1c53e5583aa50927d029c0644 100644 --- a/client/src/pages/login/components/AdminLogin.tsx +++ b/client/src/pages/login/components/AdminLogin.tsx @@ -6,7 +6,7 @@ import { useHistory } from 'react-router-dom' import * as Yup from 'yup' import { loginUser } from '../../../actions/user' import { useAppDispatch, useAppSelector } from '../../../hooks' -import { AccountLoginModel } from '../../../interfaces/models' +import { AccountLoginModel } from '../../../interfaces/FormModels' import { CenteredCircularProgress, LoginForm } from './styled' interface AccountLoginFormModel { diff --git a/client/src/pages/login/components/CompetitionLogin.tsx b/client/src/pages/login/components/CompetitionLogin.tsx index 9ebf658f80d4281739f45105cb27349a04b25fc3..75f73c5be187569fcc5adec2baf591a7cbdd62d3 100644 --- a/client/src/pages/login/components/CompetitionLogin.tsx +++ b/client/src/pages/login/components/CompetitionLogin.tsx @@ -4,7 +4,7 @@ import axios from 'axios' import { Formik, FormikHelpers } from 'formik' import React from 'react' import * as Yup from 'yup' -import { CompetitionLoginModel } from '../../../interfaces/models' +import { CompetitionLoginModel } from '../../../interfaces/FormModels' import { LoginForm } from './styled' interface CompetitionLoginFormModel { diff --git a/client/src/reducers/citiesReducer.ts b/client/src/reducers/citiesReducer.ts index 1c9542ff0c6ec2059a56f1ff5b5ac58c046114c6..7f5555b3eb002559df3952dfbac31d178ffd6271 100644 --- a/client/src/reducers/citiesReducer.ts +++ b/client/src/reducers/citiesReducer.ts @@ -1,6 +1,6 @@ import { AnyAction } from 'redux' import Types from '../actions/types' -import { City } from '../interfaces/City' +import { City } from '../interfaces/ApiModels' interface CityState { cities: City[] diff --git a/client/src/reducers/competitionsReducer.ts b/client/src/reducers/competitionsReducer.ts index b3003d4a366a95665779b4fc1fafbd7af8cd352e..bb788da5439874f8f9963dfbb756a222012697e6 100644 --- a/client/src/reducers/competitionsReducer.ts +++ b/client/src/reducers/competitionsReducer.ts @@ -1,7 +1,7 @@ import { AnyAction } from 'redux' import Types from '../actions/types' -import { Competition } from '../interfaces/Competition' -import { CompetitionFilterParams } from './../interfaces/CompetitionFilterParams' +import { Competition } from '../interfaces/ApiModels' +import { CompetitionFilterParams } from './../interfaces/FilterParams' interface CompetitionState { competitions: Competition[] diff --git a/client/src/reducers/rolesReducer.ts b/client/src/reducers/rolesReducer.ts index 652d4afcf12c1f58aad0c1b9cf21ab36e2ca96da..5028ae04cb13a4b1bf44536cd42bf3f8935b268c 100644 --- a/client/src/reducers/rolesReducer.ts +++ b/client/src/reducers/rolesReducer.ts @@ -1,6 +1,6 @@ import { AnyAction } from 'redux' import Types from '../actions/types' -import { Role } from '../interfaces/Role' +import { Role } from '../interfaces/ApiModels' interface RoleState { roles: Role[] diff --git a/client/src/reducers/searchUserReducer.ts b/client/src/reducers/searchUserReducer.ts index 9b77d68af26b3fbf2f0b428c8a6a959f6e9c5991..e0c1250683ae273318a4bcd6e4a3f5ae5f6324bd 100644 --- a/client/src/reducers/searchUserReducer.ts +++ b/client/src/reducers/searchUserReducer.ts @@ -1,9 +1,10 @@ import { AnyAction } from 'redux' import Types from '../actions/types' -import { UserData, UserFilterParams } from '../interfaces/UserData' +import { User } from '../interfaces/ApiModels' +import { UserFilterParams } from '../interfaces/FilterParams' interface SearchUserState { - users: UserData[] + users: User[] total: number count: number filterParams: UserFilterParams @@ -21,7 +22,7 @@ export default function (state = initialState, action: AnyAction) { case Types.SET_SEARCH_USERS: return { ...state, - users: action.payload as UserData[], + users: action.payload as User[], } case Types.SET_SEARCH_USERS_FILTER_PARAMS: return { diff --git a/client/src/reducers/userReducer.ts b/client/src/reducers/userReducer.ts index 9a26b1c9f8d62a61733299ccfff48c24d67310d1..2b340ae61d155504c81c886126e64db589c68745 100644 --- a/client/src/reducers/userReducer.ts +++ b/client/src/reducers/userReducer.ts @@ -1,7 +1,6 @@ import { AnyAction } from 'redux' import Types from '../actions/types' -import { City } from '../interfaces/City' -import { Competition } from './../interfaces/Competition' +import { City, Competition } from '../interfaces/ApiModels' interface UserInfo { name: string