add modal preview
This commit is contained in:
parent
5ceaac5e3d
commit
b18c49628f
@ -6,7 +6,8 @@
|
||||
"scripts": {
|
||||
"build:dev": "npx webpack --env mode=development",
|
||||
"build:prod": "npx webpack --env mode=production",
|
||||
"start": "npx webpack-dev-server"
|
||||
"start:dev": "npx webpack-dev-server --env mode=development",
|
||||
"start:prod": "npx webpack-dev-server --env mode=production"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
@ -9,6 +9,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" style="height: 100%; width: 100%;"></div>
|
||||
<script src="/dist/bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
@ -50,6 +50,31 @@
|
||||
padding: 0 1%;
|
||||
}
|
||||
}
|
||||
&__answerOptions {
|
||||
margin-top: 5%;
|
||||
&__title {
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
}
|
||||
&__list{
|
||||
margin: 5px 0;
|
||||
&__answer {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
}
|
||||
}
|
||||
&__text {
|
||||
display: block;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
border: 1px solid rgb(200, 200, 200);
|
||||
width: 100%;
|
||||
padding: 0 1%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
&__mandatory {
|
||||
margin-top: 5%;
|
||||
display: flex;
|
20
src/assets/styles/components/previewModal.module.scss
Normal file
20
src/assets/styles/components/previewModal.module.scss
Normal file
@ -0,0 +1,20 @@
|
||||
.myModal {
|
||||
&__dialog {
|
||||
&__content {
|
||||
// padding: 2%;
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 2%;
|
||||
h5 {
|
||||
font-size: 17px;
|
||||
}
|
||||
i {
|
||||
cursor: pointer;
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
&__listBtn {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 20%;
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from "react";
|
||||
import classes from "../assets/styles/components/myModal.module.scss";
|
||||
import classes from "../assets/styles/components/answerModal.module.scss";
|
||||
import MyButton from "./MyButton.jsx"
|
||||
|
||||
const MyModal = ({
|
||||
const AnswerModal = ({
|
||||
cleanStates,
|
||||
currentTypeAnswer,
|
||||
updateAnswerByForm,
|
||||
@ -10,10 +11,15 @@ const MyModal = ({
|
||||
answer,
|
||||
file,
|
||||
listTypeAnswer,
|
||||
optionAnswer,
|
||||
setOptionAnswer,
|
||||
currentOptionAnswer,
|
||||
setCurrentOptionAnswer,
|
||||
comment,
|
||||
datetime,
|
||||
mandatory,
|
||||
setMandatory,
|
||||
addOptionAnswer,
|
||||
setAnswer,
|
||||
setComment,
|
||||
setDatetime,
|
||||
@ -23,7 +29,7 @@ const MyModal = ({
|
||||
|
||||
|
||||
return (
|
||||
<div class="modal fade myModal" className={classes.myModal} id="exampleModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
||||
<div class="modal fade myModal" className={classes.myModal} id="answerModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
||||
<div class="modal-dialog myModal__dialog" className={classes.myModal__dialog}>
|
||||
<div class="modal-content" className={classes.myModal__dialog__content}>
|
||||
<div class="modal-header" className={classes.myModal__dialog__content__header}>
|
||||
@ -51,6 +57,24 @@ const MyModal = ({
|
||||
<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>
|
||||
</div>
|
||||
{[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>
|
||||
<div className={classes.myModal__dialog__content__body__answerOptions__list}>
|
||||
{optionAnswer.map((item, i) =>
|
||||
<span key={i} className={classes.myModal__dialog__content__body__answerOptions__list__answer}>{item.id}) {item.text}</span>
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className={classes.myModal__dialog__content__body__answerOptions__text}
|
||||
value={currentOptionAnswer}
|
||||
onChange={event => setCurrentOptionAnswer(event.target.value)}/>
|
||||
<MyButton
|
||||
text={'Добавить'}
|
||||
click={addOptionAnswer}
|
||||
backgroundColor={'rgb(200, 200, 200)'}
|
||||
otherStyle={{padding: '1% 2%'}}/>
|
||||
</div> : <div></div>}
|
||||
<div className={classes.myModal__dialog__content__body__mandatory}>
|
||||
<span className={classes.myModal__dialog__content__body__mandatory__title}>Обязательный вопрос</span>
|
||||
<input className={classes.myModal__dialog__content__body__mandatory__choice} type="checkbox" checked={mandatory} onChange={() => setMandatory(!mandatory)}/>
|
||||
@ -70,4 +94,4 @@ const MyModal = ({
|
||||
)
|
||||
}
|
||||
|
||||
export default MyModal;
|
||||
export default AnswerModal;
|
@ -9,6 +9,9 @@ const MyButton = (props) => {
|
||||
type="button"
|
||||
class={props.class}
|
||||
onClick={props.click}
|
||||
data-bs-target={props.target}
|
||||
data-bs-toggle={props.toggle}
|
||||
data-bs-dismiss={props.dismiss}
|
||||
style={{backgroundColor: props.backgroundColor, ...props.otherStyle}}>
|
||||
{props.text}
|
||||
</button>
|
||||
|
@ -1,13 +1,13 @@
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link, BrowserRouter, useNavigate } from "react-router-dom";
|
||||
import classes from "../assets/styles/components/navbar.module.scss"
|
||||
|
||||
const NavBar = () => {
|
||||
|
||||
return (
|
||||
<div className={classes.main}>
|
||||
<div className={classes.wrapper}>
|
||||
{/* <Link to={'/new'}>New Form</Link>
|
||||
<Link to={'/forms'}>Forms</Link> */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
26
src/components/PreviewModal.jsx
Normal file
26
src/components/PreviewModal.jsx
Normal file
@ -0,0 +1,26 @@
|
||||
import React from "react";
|
||||
import classes from "../assets/styles/components/previewModal.module.scss";
|
||||
// import MyButton from "./MyButton.jsx";
|
||||
|
||||
const PreviewModal = () => {
|
||||
return (
|
||||
<div class="modal fade" className={classes.myModal} id="previewModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
||||
<div class="modal-dialog" className={classes.myModal__dialog}>
|
||||
<div class="modal-content" className={classes.myModal__dialog__content}>
|
||||
<div class="modal-header" className={classes.myModal__dialog__content__header}>
|
||||
<h5 class="modal-title" id="exampleModalLabel">Форма</h5>
|
||||
<i class="fa-solid fa-xmark" data-bs-dismiss="modal" aria-label="Close"></i>
|
||||
</div>
|
||||
<div class="modal-body" className={classes.myModal__dialog__content__body}>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer" className={classes.myModal__dialog__content__footer}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PreviewModal;
|
@ -21,7 +21,7 @@ const Forms = () => {
|
||||
.then((r) => {
|
||||
console.log(r);
|
||||
setStateLoading(false);
|
||||
navigate("/new");
|
||||
navigate("/forms/edit");
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ import React, { useState, useContext } from "react";
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import classes from "../assets/styles/newForm.module.scss";
|
||||
import MyButton from "../components/MyButton.jsx";
|
||||
import MyModal from "../components/MyModal.jsx";
|
||||
import AnswerModal from "../components/AnswerModal.jsx";
|
||||
import PreviewModal from "../components/PreviewModal.jsx"
|
||||
import { FormsData } from "../context";
|
||||
|
||||
const NewForm = () => {
|
||||
@ -20,8 +21,10 @@ const NewForm = () => {
|
||||
const [comment, setComment] = useState("");
|
||||
const [datetime, setDatetime] = useState("");
|
||||
const [mandatory, setMandatory] = useState(false);
|
||||
const [optionAnswer, setOptionAnswer] = useState([]);
|
||||
const [file, setFile] = useState([]);
|
||||
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
|
||||
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
|
||||
|
||||
const [newForm, setNewForm] = useState(location.state ? location.state.data : []);
|
||||
|
||||
@ -47,11 +50,21 @@ const NewForm = () => {
|
||||
setAnswer("");
|
||||
setComment("");
|
||||
setDatetime("");
|
||||
setFile("");
|
||||
setOptionAnswer([])
|
||||
setFile([]);
|
||||
setCurrentTypeAnswer("");
|
||||
setCurrentOptionAnswer("")
|
||||
setMandatory(false);
|
||||
}
|
||||
|
||||
function addOptionAnswer(text) {
|
||||
setOptionAnswer([...optionAnswer, {
|
||||
id: nextID(optionAnswer),
|
||||
text: currentOptionAnswer
|
||||
}]);
|
||||
setCurrentOptionAnswer("");
|
||||
}
|
||||
|
||||
function editAnswerByForm(id) {
|
||||
const obj = newForm.find(item => item.id === id);
|
||||
setAnswer(obj.answer);
|
||||
@ -59,7 +72,8 @@ const NewForm = () => {
|
||||
setDatetime(obj.datetime);
|
||||
setFile(obj.file);
|
||||
setCurrentTypeAnswer(obj.typeAnswer);
|
||||
setMandatory(obj.mandatory)
|
||||
setOptionAnswer(obj.optionAnswer);
|
||||
setMandatory(obj.mandatory);
|
||||
setStateModal(id);
|
||||
}
|
||||
|
||||
@ -71,6 +85,7 @@ const NewForm = () => {
|
||||
item.datetime = datetime;
|
||||
item.file = file;
|
||||
item.mandatory = mandatory;
|
||||
item.optionAnswer = optionAnswer;
|
||||
item.typeAnswer = currentTypeAnswer;
|
||||
}
|
||||
return item
|
||||
@ -86,6 +101,7 @@ const NewForm = () => {
|
||||
comment: comment,
|
||||
datetime: datetime,
|
||||
mandatory: mandatory,
|
||||
optionAnswer: optionAnswer,
|
||||
file: file
|
||||
}]);
|
||||
cleanStates();
|
||||
@ -126,37 +142,44 @@ const NewForm = () => {
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.header}>
|
||||
<div className={classes.header__listBtn}>
|
||||
<MyButton text={'Предпросмотр'} backgroundColor={'rgb(225, 225, 225)'} toggle={"modal"} target={"#previewModal"}/>
|
||||
<MyButton text={'Опубликовать'} click={location.state ? updateFormByForms : saveForm}/>
|
||||
<MyButton text={<i class="fa-solid fa-ellipsis-vertical"></i>} click={() => console.log(newForm)} backgroundColor={'rgb(225, 225, 225)'}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.content}>
|
||||
<div className={classes.content__listQuestion}>
|
||||
<div className={classes.content__listQuestion__list}>
|
||||
{listTypeAnswer.map((item, i) =>
|
||||
<div className={classes.content__listQuestion__list__item} data-bs-toggle="modal" data-bs-target="#exampleModal" onClick={() => setCurrentTypeAnswer(item.id)} key={i}>
|
||||
<div className={classes.content__listQuestion__list__item} data-bs-toggle="modal" data-bs-target="#answerModal" onClick={() => setCurrentTypeAnswer(item.id)} key={i}>
|
||||
<span>{item.text}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MyModal
|
||||
<PreviewModal />
|
||||
|
||||
<AnswerModal
|
||||
stateModal={stateModal}
|
||||
currentTypeAnswer={currentTypeAnswer}
|
||||
answer={answer}
|
||||
comment={comment}
|
||||
mandatory={mandatory}
|
||||
optionAnswer={optionAnswer}
|
||||
setOptionAnswer={setOptionAnswer}
|
||||
datetime={datetime}
|
||||
file={file}
|
||||
currentOptionAnswer={currentOptionAnswer}
|
||||
listTypeAnswer={listTypeAnswer}
|
||||
setAnswer={setAnswer}
|
||||
setComment={setComment}
|
||||
setDatetime={setDatetime}
|
||||
setFile={setFile}
|
||||
setCurrentOptionAnswer={setCurrentOptionAnswer}
|
||||
setMandatory={setMandatory}
|
||||
cleanStates={cleanStates}
|
||||
saveStates={saveStates}
|
||||
addOptionAnswer={addOptionAnswer}
|
||||
updateAnswerByForm={updateAnswerByForm}
|
||||
setCurrentTypeAnswer={setCurrentTypeAnswer}/>
|
||||
|
||||
@ -182,7 +205,7 @@ const NewForm = () => {
|
||||
setDropElem(Number(event.target.id))
|
||||
}
|
||||
}}
|
||||
onDrop={(event) => {
|
||||
onDrop={() => {
|
||||
const currentElem = newForm[dragElem]
|
||||
const tNewForm = [...newForm]
|
||||
if (dragElem > dropElem) {
|
||||
|
@ -14,7 +14,7 @@ const router = createBrowserRouter([
|
||||
element: <Forms/>,
|
||||
},
|
||||
{
|
||||
path: '/new',
|
||||
path: '/forms/edit/',
|
||||
element: <NewForm/>
|
||||
}
|
||||
]);
|
||||
|
@ -5,7 +5,6 @@ const path = require('path');
|
||||
module.exports = (env) => {
|
||||
|
||||
const isDev = env.mode === 'development';
|
||||
console.log(env.mode ?? 'development', isDev ? 'style-loader' : 'Mini')
|
||||
|
||||
const cssLoader = {
|
||||
loader: "css-loader",
|
||||
@ -18,9 +17,16 @@ module.exports = (env) => {
|
||||
|
||||
const config = {
|
||||
mode: env.mode ?? 'development',
|
||||
performance: {
|
||||
hints: false,
|
||||
maxEntrypointSize: 512000,
|
||||
maxAssetSize: 512000
|
||||
},
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
filename: '[name].[contenthash].js',
|
||||
// filename: '[name].[contenthash].js',
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
clean: true
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user