markdown and video
All checks were successful
publish-main / release-image (push) Successful in 3m31s
All checks were successful
publish-main / release-image (push) Successful in 3m31s
This commit is contained in:
parent
e02aa76b9a
commit
006c9bc4ea
@ -32,6 +32,7 @@
|
|||||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
|
"@uiw/react-markdown-editor": "^5.12.1",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
@ -50,6 +50,21 @@
|
|||||||
padding: 0 1%;
|
padding: 0 1%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&__video {
|
||||||
|
margin-top: 5%;
|
||||||
|
&__title {
|
||||||
|
display: block;
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
}
|
||||||
|
&__link {
|
||||||
|
display: block;
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
border: 1px solid rgb(200, 200, 200);
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 1%;
|
||||||
|
}
|
||||||
|
}
|
||||||
&__answerOptions {
|
&__answerOptions {
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
&__title {
|
&__title {
|
||||||
|
3
src/assets/styles/components/markDown.module.scss
Normal file
3
src/assets/styles/components/markDown.module.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.main {
|
||||||
|
border: 1px solid rgb(200, 200, 200);
|
||||||
|
}
|
@ -2,15 +2,48 @@
|
|||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
border-top: 1px solid rgb(200, 200, 200);
|
border-top: 1px solid rgb(200, 200, 200);
|
||||||
&__question {
|
&__question {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
&__text {
|
&__text {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
|
width: 100%;
|
||||||
|
// overflow-x: auto;
|
||||||
|
// &::-webkit-scrollbar {
|
||||||
|
// height: 7px;
|
||||||
|
// border: 1px solid rgb(200, 200, 200);
|
||||||
|
// }
|
||||||
|
// &::-webkit-scrollbar-thumb {
|
||||||
|
// background-color: rgb(200, 200, 200);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
&__comment {
|
&__comment {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: rgb(200, 200, 200);
|
color: rgb(200, 200, 200);
|
||||||
|
width: 100%;
|
||||||
|
// overflow-x: auto;
|
||||||
|
// &::-webkit-scrollbar {
|
||||||
|
// height: 7px;
|
||||||
|
// border: 1px solid rgb(200, 200, 200);
|
||||||
|
// }
|
||||||
|
// &::-webkit-scrollbar-thumb {
|
||||||
|
// background-color: rgb(200, 200, 200);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
&__video {
|
||||||
|
iframe {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
height: 7px;
|
||||||
|
border: 1px solid rgb(200, 200, 200);
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgb(200, 200, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&__answer {
|
&__answer {
|
||||||
|
@ -130,6 +130,7 @@
|
|||||||
|
|
||||||
&__list {
|
&__list {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
@ -141,7 +142,7 @@
|
|||||||
&__item {
|
&__item {
|
||||||
padding: 1%;
|
padding: 1%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 25%;
|
min-height: 25%;
|
||||||
border-bottom: 1px solid rgb(220, 220, 220);
|
border-bottom: 1px solid rgb(220, 220, 220);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -152,6 +153,14 @@
|
|||||||
}
|
}
|
||||||
&__answer {
|
&__answer {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
|
overflow-x: auto;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
height: 7px;
|
||||||
|
border: 1px solid rgb(200, 200, 200);
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgb(200, 200, 200);
|
||||||
|
}
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import classes from "../assets/styles/components/answerModal.module.scss";
|
import classes from "../assets/styles/components/answerModal.module.scss";
|
||||||
import MyButton from "./MyButton.jsx"
|
import MyButton from "./MyButton.jsx";
|
||||||
|
import MarkDowm from "./MarkDown.jsx";
|
||||||
|
|
||||||
const AnswerModal = ({
|
const AnswerModal = ({
|
||||||
cleanStates,
|
cleanStates,
|
||||||
@ -10,6 +11,8 @@ const AnswerModal = ({
|
|||||||
addFormBlock,
|
addFormBlock,
|
||||||
question,
|
question,
|
||||||
file,
|
file,
|
||||||
|
video,
|
||||||
|
setVideo,
|
||||||
listTypeAnswer,
|
listTypeAnswer,
|
||||||
optionAnswer,
|
optionAnswer,
|
||||||
setOptionAnswer,
|
setOptionAnswer,
|
||||||
@ -40,7 +43,7 @@ const AnswerModal = ({
|
|||||||
<div class="modal-body" className={classes.myModal__dialog__content__body}>
|
<div class="modal-body" className={classes.myModal__dialog__content__body}>
|
||||||
<div className={classes.myModal__dialog__content__body__answer}>
|
<div className={classes.myModal__dialog__content__body__answer}>
|
||||||
<span className={classes.myModal__dialog__content__body__answer__title}>Вопрос</span>
|
<span className={classes.myModal__dialog__content__body__answer__title}>Вопрос</span>
|
||||||
<textarea className={classes.myModal__dialog__content__body__answer__text} value={question} onChange={event => setQuestion(event.target.value)}></textarea>
|
<MarkDowm mkValue={question} setMkValue={setQuestion}></MarkDowm>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
multiple
|
multiple
|
||||||
@ -48,12 +51,16 @@ const AnswerModal = ({
|
|||||||
className={classes.myModal__dialog__content__body__answer__file}
|
className={classes.myModal__dialog__content__body__answer__file}
|
||||||
value={file}
|
value={file}
|
||||||
onChange={event => setFile(event.target.value)}
|
onChange={event => setFile(event.target.value)}
|
||||||
></input>
|
></input>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.myModal__dialog__content__body__comment}>
|
<div className={classes.myModal__dialog__content__body__comment}>
|
||||||
<span className={classes.myModal__dialog__content__body__comment__title}>Комментарий</span>
|
<span className={classes.myModal__dialog__content__body__comment__title}>Комментарий</span>
|
||||||
<textarea className={classes.myModal__dialog__content__body__comment__text} value={comment} onChange={event => setComment(event.target.value)}></textarea>
|
<textarea className={classes.myModal__dialog__content__body__comment__text} value={comment} onChange={event => setComment(event.target.value)}></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={classes.myModal__dialog__content__body__video}>
|
||||||
|
<span className={classes.myModal__dialog__content__body__video__title}>Видео</span>
|
||||||
|
<input type="text" className={classes.myModal__dialog__content__body__video__link} placeholder="Ссылка на видео" value={video} onChange={(e) => setVideo(e.target.value)}/>
|
||||||
|
</div>
|
||||||
{[3, 4, 5].find(item => item === currentTypeAnswer) ? <div className={classes.myModal__dialog__content__body__answerOptions}>
|
{[3, 4, 5].find(item => item === currentTypeAnswer) ? <div className={classes.myModal__dialog__content__body__answerOptions}>
|
||||||
<span className={classes.myModal__dialog__content__body__answerOptions__title}>Варианты ответа</span>
|
<span className={classes.myModal__dialog__content__body__answerOptions__title}>Варианты ответа</span>
|
||||||
<div className={classes.myModal__dialog__content__body__answerOptions__list}>
|
<div className={classes.myModal__dialog__content__body__answerOptions__list}>
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import classes from "../assets/styles/generatingFormFields.module.scss";
|
import classes from "../assets/styles/generatingFormFields.module.scss";
|
||||||
|
import MarkdownEditor from "@uiw/react-markdown-editor";
|
||||||
|
|
||||||
const GeneratingFormFields = ({listBlock, listTypeAnswer, answers, updateAnswersForm}) => {
|
const GeneratingFormFields = ({listBlock, listTypeAnswer, answers, updateAnswersForm}) => {
|
||||||
return (
|
return (
|
||||||
listBlock.map((item, i) =>
|
listBlock.map((item, i) =>
|
||||||
<div className={classes.item} key={i}>
|
<div className={classes.item} key={i}>
|
||||||
<div className={classes.item__question}>
|
<div className={classes.item__question}>
|
||||||
<p className={classes.item__question__text}>{i + 1}) {item.question}</p>
|
<p className={classes.item__question__text}>{i + 1}) <MarkdownEditor.Markdown source={item.question}/></p>
|
||||||
<p className={classes.item__question__comment}>{item.comment}</p>
|
<p className={classes.item__question__comment}>{item.comment}</p>
|
||||||
|
<div className={classes.item__question__video}>
|
||||||
|
{item.video ? <iframe
|
||||||
|
width="300"
|
||||||
|
height="150"
|
||||||
|
src={item.video}
|
||||||
|
frameborder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
referrerpolicy="strict-origin-when-cross-origin"
|
||||||
|
allowfullscreen
|
||||||
|
></iframe> : <span></span>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.item__answer}>
|
<div className={classes.item__answer}>
|
||||||
{
|
{
|
||||||
|
18
src/components/MarkDown.jsx
Normal file
18
src/components/MarkDown.jsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import MarkdownEditor from '@uiw/react-markdown-editor';
|
||||||
|
import classes from "../assets/styles/components/markDown.module.scss"
|
||||||
|
|
||||||
|
const MarkDown = ({mkValue, setMkValue}) => {
|
||||||
|
return (
|
||||||
|
<div className={classes.main} data-color-mode="light">
|
||||||
|
<MarkdownEditor
|
||||||
|
value={mkValue}
|
||||||
|
onChange={(value, viewUpdate) => setMkValue(value)}
|
||||||
|
enablePreview={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MarkDown;
|
@ -36,13 +36,13 @@ const Forms = () => {
|
|||||||
async function createForm() {
|
async function createForm() {
|
||||||
setStateLoading(true);
|
setStateLoading(true);
|
||||||
const response = await createFormApi(cookies.token);
|
const response = await createFormApi(cookies.token);
|
||||||
console.log("response", response)
|
|
||||||
setStateLoading(false);
|
setStateLoading(false);
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
const token = await newFormTokenApi(cookies.token, response.data.id)
|
const token = await newFormTokenApi(cookies.token, response.data.id)
|
||||||
|
|
||||||
navigate(`/forms/${response.data.id}/edit`)
|
navigate(`/forms/${response.data.id}/edit`)
|
||||||
|
// navigate(`/forms/1/edit`)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(response)
|
console.log(response)
|
||||||
|
@ -9,6 +9,7 @@ import { FormsData, TypeAnswerData } from "../context";
|
|||||||
import { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
|
import { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
|
||||||
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi, updateOrderBlockApi } from "../hooks/api/formApi.js";
|
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi, updateOrderBlockApi } from "../hooks/api/formApi.js";
|
||||||
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
||||||
|
import MarkDown from "../components/MarkDown.jsx";
|
||||||
|
|
||||||
const NewForm = () => {
|
const NewForm = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -30,6 +31,7 @@ const NewForm = () => {
|
|||||||
const [mandatory, setMandatory] = useState(false);
|
const [mandatory, setMandatory] = useState(false);
|
||||||
const [optionAnswer, setOptionAnswer] = useState([]);
|
const [optionAnswer, setOptionAnswer] = useState([]);
|
||||||
const [file, setFile] = useState([]);
|
const [file, setFile] = useState([]);
|
||||||
|
const [video, setVideo] = useState("");
|
||||||
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
|
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
|
||||||
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
|
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
|
||||||
|
|
||||||
@ -50,6 +52,7 @@ const NewForm = () => {
|
|||||||
setComment("");
|
setComment("");
|
||||||
setOptionAnswer([])
|
setOptionAnswer([])
|
||||||
setFile([]);
|
setFile([]);
|
||||||
|
setVideo("");
|
||||||
setCurrentTypeAnswer("");
|
setCurrentTypeAnswer("");
|
||||||
setCurrentOptionAnswer("")
|
setCurrentOptionAnswer("")
|
||||||
setMandatory(false);
|
setMandatory(false);
|
||||||
@ -86,6 +89,7 @@ const NewForm = () => {
|
|||||||
setQuestion(obj.question);
|
setQuestion(obj.question);
|
||||||
setComment(obj.comment);
|
setComment(obj.comment);
|
||||||
setFile(obj.file);
|
setFile(obj.file);
|
||||||
|
setVideo(obj.video);
|
||||||
setCurrentTypeAnswer(obj.typeAnswer);
|
setCurrentTypeAnswer(obj.typeAnswer);
|
||||||
setOptionAnswer(obj.optionAnswer);
|
setOptionAnswer(obj.optionAnswer);
|
||||||
setMandatory(obj.mandatory);
|
setMandatory(obj.mandatory);
|
||||||
@ -98,13 +102,12 @@ const NewForm = () => {
|
|||||||
question: question,
|
question: question,
|
||||||
comment: comment,
|
comment: comment,
|
||||||
file: file,
|
file: file,
|
||||||
|
video: video,
|
||||||
mandatory: mandatory,
|
mandatory: mandatory,
|
||||||
optionAnswer: optionAnswer,
|
optionAnswer: optionAnswer,
|
||||||
typeAnswer: currentTypeAnswer,
|
typeAnswer: currentTypeAnswer,
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(stateModal)
|
|
||||||
|
|
||||||
const response = await updateBlockApi(cookies.token, stateModal, data);
|
const response = await updateBlockApi(cookies.token, stateModal, data);
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
@ -129,7 +132,8 @@ const NewForm = () => {
|
|||||||
comment: comment,
|
comment: comment,
|
||||||
mandatory: mandatory,
|
mandatory: mandatory,
|
||||||
optionAnswer: optionAnswer,
|
optionAnswer: optionAnswer,
|
||||||
file: file
|
file: file,
|
||||||
|
video: video
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await addFormBlockApi(cookies.token, formId, newBlock)
|
const response = await addFormBlockApi(cookies.token, formId, newBlock)
|
||||||
@ -259,6 +263,8 @@ const NewForm = () => {
|
|||||||
optionAnswer={optionAnswer}
|
optionAnswer={optionAnswer}
|
||||||
setOptionAnswer={setOptionAnswer}
|
setOptionAnswer={setOptionAnswer}
|
||||||
file={file}
|
file={file}
|
||||||
|
video={video}
|
||||||
|
setVideo={setVideo}
|
||||||
currentOptionAnswer={currentOptionAnswer}
|
currentOptionAnswer={currentOptionAnswer}
|
||||||
listTypeAnswer={listTypeAnswer}
|
listTypeAnswer={listTypeAnswer}
|
||||||
setQuestion={setQuestion}
|
setQuestion={setQuestion}
|
||||||
|
Loading…
Reference in New Issue
Block a user