Skip to content
Snippets Groups Projects
Commit ddf50536 authored by Emil's avatar Emil
Browse files

feat: add question component

parent 212f9dd2
No related branches found
No related tags found
1 merge request!126Resolve "Show question components in editor"
export enum ComponentTypes {
Text = 1,
Image,
QuestionAlternative,
Question,
}
......@@ -93,6 +93,16 @@ export interface TextComponent extends Component {
font: string
}
export interface QuestionAlternativeComponent extends Component {
export interface QuestionComponent extends Component {
id: number
x: number
y: number
w: number
h: number
slide_id: number
type_id: number
view_type_id: number
text: string
media: Media
question_id: number
}
import { Typography } from '@material-ui/core'
import React from 'react'
import { QuestionComponent } from '../../../interfaces/ApiModels'
type QuestionComponentProps = {
component: QuestionComponent
width: number
height: number
}
const QuestionComponentDisplay = ({ component, width, height }: QuestionComponentProps) => {
return (
<div>
<Typography>Frågekomponent</Typography>
</div>
)
}
export default QuestionComponentDisplay
......@@ -4,13 +4,14 @@ import React, { useEffect, useState } from 'react'
import { Rnd } from 'react-rnd'
import { ComponentTypes } from '../../../enum/ComponentTypes'
import { useAppSelector } from '../../../hooks'
import { Component, ImageComponent, QuestionAlternativeComponent, TextComponent } from '../../../interfaces/ApiModels'
import { Component, ImageComponent, QuestionComponent, TextComponent } from '../../../interfaces/ApiModels'
import { Position, Size } from '../../../interfaces/Components'
import CheckboxComponent from './CheckboxComponent'
import ImageComponentDisplay from './ImageComponentDisplay'
import { HoverContainer } from './styled'
import FormatAlignCenterIcon from '@material-ui/icons/FormatAlignCenter'
import TextComponentDisplay from './TextComponentDisplay'
import QuestionComponentDisplay from './QuestionComponentDisplay'
type RndComponentProps = {
component: Component
......@@ -86,6 +87,16 @@ const RndComponent = ({ component, width, height, scale }: RndComponentProps) =>
/>
</HoverContainer>
)
case ComponentTypes.Question:
return (
<HoverContainer hover={hover}>
<QuestionComponentDisplay
height={currentSize.h * scale}
width={currentSize.w * scale}
component={component as QuestionComponent}
/>
</HoverContainer>
)
default:
break
}
......
......@@ -36,13 +36,11 @@ const SlideSettings: React.FC = () => {
</SettingsList>
{activeSlide?.questions[0] && <QuestionSettings activeSlide={activeSlide} competitionId={competitionId} />}
{
// Choose answer alternatives depending on the slide type
// Choose answer alternatives, depending on the slide type
}
{activeSlide?.questions[0]?.type_id === 1 && (
<Instructions activeSlide={activeSlide} competitionId={competitionId} />
)}
{activeSlide?.questions[0]?.type_id === 2 && (
{(activeSlide?.questions[0]?.type_id === 1 || activeSlide?.questions[0]?.type_id === 2) && (
<Instructions activeSlide={activeSlide} competitionId={competitionId} />
)}
{activeSlide?.questions[0]?.type_id === 3 && (
......
......@@ -15,8 +15,8 @@ import {
import axios from 'axios'
import React, { useState } from 'react'
import { getEditorCompetition } from '../../../../actions/editor'
import { useAppDispatch } from '../../../../hooks'
import { RichSlide } from '../../../../interfaces/ApiRichModels'
import { useAppDispatch, useAppSelector } from '../../../../hooks'
import { RichQuestion, RichSlide } from '../../../../interfaces/ApiRichModels'
import { Center, FirstItem } from '../styled'
type SlideTypeProps = {
......@@ -30,6 +30,11 @@ const SlideType = ({ activeSlide, competitionId }: SlideTypeProps) => {
// For "slide type" dialog
const [selectedSlideType, setSelectedSlideType] = useState(0)
const [slideTypeDialog, setSlideTypeDialog] = useState(false)
const components = useAppSelector(
(state) => state.editor.competition.slides.find((slide) => slide.id === state.editor.activeSlideId)?.components
)
const questionComponentId = components?.find((qCompId) => qCompId.type_id === 3)?.id
const openSlideTypeDialog = (type_id: number) => {
setSelectedSlideType(type_id)
setSlideTypeDialog(true)
......@@ -41,6 +46,7 @@ const SlideType = ({ activeSlide, competitionId }: SlideTypeProps) => {
const updateSlideType = async () => {
closeSlideTypeDialog()
if (activeSlide) {
deleteQuestionComponent(questionComponentId)
if (activeSlide.questions[0] && activeSlide.questions[0].type_id !== selectedSlideType) {
if (selectedSlideType === 0) {
// Change slide type from a question type to information
......@@ -67,6 +73,7 @@ const SlideType = ({ activeSlide, competitionId }: SlideTypeProps) => {
})
.then(() => {
dispatch(getEditorCompetition(competitionId))
createQuestionComponent()
})
.catch(console.log)
}
......@@ -80,11 +87,38 @@ const SlideType = ({ activeSlide, competitionId }: SlideTypeProps) => {
})
.then(() => {
dispatch(getEditorCompetition(competitionId))
createQuestionComponent()
})
.catch(console.log)
}
}
}
const createQuestionComponent = () => {
axios
.post(`/api/competitions/${competitionId}/slides/${activeSlide.id}/components`, {
x: 0,
y: 0,
w: 400,
h: 250,
type_id: 3,
view_type_id: 1,
question_id: activeSlide.questions[0].id,
})
.then(() => {
dispatch(getEditorCompetition(competitionId))
})
.catch(console.log)
}
const deleteQuestionComponent = (componentId: number | undefined) => {
if (componentId) {
axios
.delete(`/api/competitions/${competitionId}/slides/${activeSlide.id}/components/${componentId}`)
.catch(console.log)
}
}
return (
<FirstItem>
<ListItem>
......
import { Typography } from '@material-ui/core'
import React from 'react'
import { Rnd } from 'react-rnd'
import { ComponentTypes } from '../../../enum/ComponentTypes'
import { useAppSelector } from '../../../hooks'
import { Component, ImageComponent, TextComponent } from '../../../interfaces/ApiModels'
import ImageComponentDisplay from '../../presentationEditor/components/ImageComponentDisplay'
import TextComponentDisplay from '../../presentationEditor/components/TextComponentDisplay'
import { SlideContainer } from './styled'
type PresentationComponentProps = {
component: Component
......
......@@ -11,7 +11,7 @@ schema = ComponentDTO.schema
list_schema = ComponentDTO.list_schema
component_parser_add = reqparse.RequestParser()
component_parser_add.add_argument("x", type=str, default=0, location="json")
component_parser_add.add_argument("x", type=int, default=0, location="json")
component_parser_add.add_argument("y", type=int, default=0, location="json")
component_parser_add.add_argument("w", type=int, default=1, location="json")
component_parser_add.add_argument("h", type=int, default=1, location="json")
......@@ -22,7 +22,7 @@ component_parser_add.add_argument("media_id", type=int, default=None, location="
component_parser_add.add_argument("question_id", type=int, default=None, location="json")
component_parser_edit = reqparse.RequestParser()
component_parser_edit.add_argument("x", type=str, default=sentinel, location="json")
component_parser_edit.add_argument("x", type=int, default=sentinel, location="json")
component_parser_edit.add_argument("y", type=int, default=sentinel, location="json")
component_parser_edit.add_argument("w", type=int, default=sentinel, location="json")
component_parser_edit.add_argument("h", type=int, default=sentinel, location="json")
......
......@@ -12,7 +12,7 @@ from app.database.models import City, QuestionType, Role
def _add_items():
media_types = ["Image", "Video"]
question_types = ["Boolean", "Multiple", "Text"]
component_types = ["Text", "Image"]
component_types = ["Text", "Image", "Question"]
view_types = ["Team", "Judge", "Audience", "Operator"]
roles = ["Admin", "Editor"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment