create ViewForm page
This commit is contained in:
parent
16a82736a4
commit
90aec8fad0
22
src/App.jsx
22
src/App.jsx
@ -1,18 +1,37 @@
|
||||
import React, { useState } from "react";
|
||||
import { Outlet, useNavigate } from "react-router-dom";
|
||||
import { FormsData, UserData } from "./context";
|
||||
import { FormsData, UserData, TypeAnswerData } from "./context";
|
||||
import classes from "./assets/styles/app.module.scss"
|
||||
import NavBar from "./components/NavBar.jsx";
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import InputText from "./components/typeAnswer/InputText.jsx";
|
||||
import TextArea from "./components/typeAnswer/TextArea.jsx";
|
||||
import YesNo from "./components/typeAnswer/YesNo.jsx"
|
||||
import InputDate from "./components/typeAnswer/InputDate.jsx";
|
||||
import InputMultipleRadio from "./components/typeAnswer/InputMultipleRadio.jsx";
|
||||
import InputRadio from "./components/typeAnswer/InputRadio.jsx";
|
||||
import DropDownList from "./components/typeAnswer/DropDownList.jsx";
|
||||
import InputFile from "./components/typeAnswer/InputFile.jsx";
|
||||
|
||||
const App = () => {
|
||||
const navigate = useNavigate();
|
||||
const [forms, setForms] = useState([]);
|
||||
const [user, setUser] = useState(false);
|
||||
const [listTypeAnswer, setListTypeAnswer] = useState([
|
||||
{id: 1, text: 'Краткий ответ', typeTag: InputText},
|
||||
{id: 2, text: 'Расширенный ответ', typeTag: TextArea},
|
||||
{id: 3, text: 'Выбор из вариантов', typeTag: InputRadio},
|
||||
{id: 4, text: 'Множественный выбор', typeTag: InputMultipleRadio},
|
||||
{id: 5, text: 'Выпадающий список', typeTag: DropDownList},
|
||||
{id: 6, text: 'Да/Нет', typeTag: YesNo},
|
||||
{id: 7, text: 'Файл', typeTag: InputFile},
|
||||
{id: 8, text: 'Дата', typeTag: InputDate}
|
||||
]);
|
||||
|
||||
return (
|
||||
<UserData.Provider value={{ user, setUser }}>
|
||||
<FormsData.Provider value={{ forms, setForms }}>
|
||||
<TypeAnswerData.Provider value={{ listTypeAnswer, setListTypeAnswer }}>
|
||||
<div className={classes.main}>
|
||||
<div className={classes.container}>
|
||||
<div className={classes.header}>
|
||||
@ -23,6 +42,7 @@ const App = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TypeAnswerData.Provider>
|
||||
</FormsData.Provider>
|
||||
</UserData.Provider>
|
||||
)
|
||||
|
@ -53,6 +53,7 @@
|
||||
height: 25%;
|
||||
width: 100%;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
position: relative;
|
||||
&:hover {
|
||||
background-color: rgba(240, 240, 240, 0.8);
|
||||
}
|
||||
@ -72,6 +73,13 @@
|
||||
width: 33.3%;
|
||||
text-align: center;
|
||||
}
|
||||
i {
|
||||
position: absolute;
|
||||
font-size: 15px;
|
||||
right: 30px;
|
||||
top: calc(50% - 7px);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
src/assets/styles/generatingFormFields.module.scss
Normal file
19
src/assets/styles/generatingFormFields.module.scss
Normal file
@ -0,0 +1,19 @@
|
||||
.item {
|
||||
padding: 10px 20px;
|
||||
border-top: 1px solid rgb(200, 200, 200);
|
||||
&__question {
|
||||
&__text {
|
||||
font-size: 15px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
}
|
||||
&__comment {
|
||||
font-size: 11px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-style: italic;
|
||||
color: rgb(200, 200, 200);
|
||||
}
|
||||
}
|
||||
&__answer {
|
||||
|
||||
}
|
||||
}
|
27
src/assets/styles/viewForm.module.scss
Normal file
27
src/assets/styles/viewForm.module.scss
Normal file
@ -0,0 +1,27 @@
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 70%;
|
||||
min-height: 80%;
|
||||
box-shadow: 0 0 5px 1px rgb(200, 200, 200);
|
||||
&__header {
|
||||
|
||||
}
|
||||
&__content {
|
||||
|
||||
}
|
||||
&__footer {
|
||||
|
||||
}
|
||||
}
|
22
src/components/GeneratingFormFields.jsx
Normal file
22
src/components/GeneratingFormFields.jsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React, { useState } from "react";
|
||||
import classes from "../assets/styles/generatingFormFields.module.scss";
|
||||
|
||||
const GeneratingFormFields = ({newForm, listTypeAnswer}) => {
|
||||
return (
|
||||
newForm.map((item, i) =>
|
||||
<div className={classes.item} key={i}>
|
||||
<div className={classes.item__question}>
|
||||
<p className={classes.item__question__text}>{i + 1}) {item.question}</p>
|
||||
<p className={classes.item__question__comment}>{item.comment}</p>
|
||||
</div>
|
||||
<div className={classes.item__answer}>
|
||||
{
|
||||
listTypeAnswer.find(type => type.id === item.typeAnswer).typeTag({postfix: i, answers: item.optionAnswer})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default GeneratingFormFields;
|
@ -1,10 +1,8 @@
|
||||
import React from "react";
|
||||
import classes from "../assets/styles/components/previewModal.module.scss";
|
||||
import GeneratingFormFields from "./GeneratingFormFields.jsx";
|
||||
|
||||
const PreviewModal = ({newForm, listTypeAnswer}) => {
|
||||
// const [file, setFile] = useState('');
|
||||
// const [value, setValue] = useState('');
|
||||
|
||||
return (
|
||||
<div class="modal fade modal-lg" 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}>
|
||||
@ -14,19 +12,7 @@ const PreviewModal = ({newForm, listTypeAnswer}) => {
|
||||
<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}>
|
||||
{newForm.map((item, i) =>
|
||||
<div className={classes.myModal__dialog__content__body__item} key={i}>
|
||||
<div className={classes.myModal__dialog__content__body__item__question}>
|
||||
<p className={classes.myModal__dialog__content__body__item__question__text}>{i + 1}) {item.question}</p>
|
||||
<p className={classes.myModal__dialog__content__body__item__question__comment}>{item.comment}</p>
|
||||
</div>
|
||||
<div className={classes.myModal__dialog__content__body__item__answer}>
|
||||
{
|
||||
listTypeAnswer.find(type => type.id === item.typeAnswer).typeTag({postfix: i, answers: item.optionAnswer})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<GeneratingFormFields newForm={newForm} listTypeAnswer={listTypeAnswer}/>
|
||||
</div>
|
||||
<div class="modal-footer" className={classes.myModal__dialog__content__footer}>
|
||||
|
||||
|
@ -3,3 +3,5 @@ import { createContext } from "react";
|
||||
export const FormsData = createContext([]);
|
||||
|
||||
export const UserData = createContext(false);
|
||||
|
||||
export const TypeAnswerData = createContext();
|
@ -8,7 +8,7 @@ import { FormsData } from "../context";
|
||||
const Forms = () => {
|
||||
const navigate = useNavigate()
|
||||
const {forms, setForms} = useContext(FormsData);
|
||||
const [stateLoading, setStateLoading] = useState(false)
|
||||
const [stateLoading, setStateLoading] = useState(false);
|
||||
|
||||
const response = ms => {
|
||||
return new Promise(r => setTimeout(() => r('response end'), ms))
|
||||
@ -27,7 +27,7 @@ const Forms = () => {
|
||||
}
|
||||
|
||||
function editForm(item) {
|
||||
navigate("/new", {
|
||||
navigate("/forms/edit", {
|
||||
state: {
|
||||
id: item.id,
|
||||
data: item.listAnswer
|
||||
@ -58,6 +58,11 @@ const Forms = () => {
|
||||
<div className={classes.listForms__forms__item__title} onClick={() => editForm(item)}>{item.title}</div>
|
||||
<div className={classes.listForms__forms__item__answers}>{item.answers}</div>
|
||||
<div className={classes.listForms__forms__item__update}>{item.update}</div>
|
||||
<i class="fa-solid fa-ellipsis-vertical" id="action" data-bs-toggle="dropdown"></i>
|
||||
<ul class="dropdown-menu" aria-labelledby="action">
|
||||
<li><a class="dropdown-item" onClick={() => navigate(`/forms/${item.id}/`)}>Открыть</a></li>
|
||||
<li><a class="dropdown-item" onClick={() => navigator.clipboard.writeText(`http://localhost:3000/forms/${item.id}/`)}>Скопировать ссылку</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -4,15 +4,7 @@ import classes from "../assets/styles/newForm.module.scss";
|
||||
import MyButton from "../components/MyButton.jsx";
|
||||
import AnswerModal from "../components/AnswerModal.jsx";
|
||||
import PreviewModal from "../components/PreviewModal.jsx"
|
||||
import { FormsData } from "../context";
|
||||
import InputText from "../components/typeAnswer/InputText.jsx"
|
||||
import TextArea from "../components/typeAnswer/TextArea.jsx";
|
||||
import YesNo from "../components/typeAnswer/YesNo.jsx"
|
||||
import InputDate from "../components/typeAnswer/InputDate.jsx";
|
||||
import InputMultipleRadio from "../components/typeAnswer/InputMultipleRadio.jsx";
|
||||
import InputRadio from "../components/typeAnswer/InputRadio.jsx";
|
||||
import DropDownList from "../components/typeAnswer/DropDownList.jsx";
|
||||
import InputFile from "../components/typeAnswer/InputFile.jsx";
|
||||
import { FormsData, TypeAnswerData } from "../context";
|
||||
|
||||
const NewForm = () => {
|
||||
const navigate = useNavigate();
|
||||
@ -21,6 +13,7 @@ const NewForm = () => {
|
||||
const [dropElem, setDropElem] = useState(null);
|
||||
|
||||
const {forms, setForms} = useContext(FormsData);
|
||||
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
||||
|
||||
const nextID = (list) => {
|
||||
return list.length ? list.at(-1).id + 1 : 1
|
||||
@ -38,17 +31,6 @@ const NewForm = () => {
|
||||
|
||||
const [stateModal, setStateModal] = useState(false)
|
||||
|
||||
const [listTypeAnswer, setListTypeAnswer] = useState([
|
||||
{id: 1, text: 'Краткий ответ', typeTag: InputText},
|
||||
{id: 2, text: 'Расширенный ответ', typeTag: TextArea},
|
||||
{id: 3, text: 'Выбор из вариантов', typeTag: InputRadio},
|
||||
{id: 4, text: 'Множественный выбор', typeTag: InputMultipleRadio},
|
||||
{id: 5, text: 'Выпадающий список', typeTag: DropDownList},
|
||||
{id: 6, text: 'Да/Нет', typeTag: YesNo},
|
||||
{id: 7, text: 'Файл', typeTag: InputFile},
|
||||
{id: 8, text: 'Дата', typeTag: InputDate}
|
||||
]);
|
||||
|
||||
function removeAnswerByForm(id) {
|
||||
setNewForm([...newForm.filter(item => item.id !== id)]);
|
||||
}
|
||||
|
@ -7,11 +7,42 @@ const Profile = () => {
|
||||
const [edit, setEdit] = useState(true);
|
||||
const {user, setUser} = useContext(UserData);
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [phone, setPhone] = useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [surname, setSurname] = useState("");
|
||||
const [patronymic, setPatronymic] = useState("");
|
||||
const [email, setEmail] = useState(user.email);
|
||||
const [phone, setPhone] = useState(user.phone);
|
||||
const [name, setName] = useState(user.name);
|
||||
const [surname, setSurname] = useState(user.surname);
|
||||
const [patronymic, setPatronymic] = useState(user.patronymic);
|
||||
|
||||
function choiceInput(key) {
|
||||
switch (key) {
|
||||
case "email":
|
||||
return {get: email, set: setEmail}
|
||||
case "phone":
|
||||
return {get: phone, set: setPhone}
|
||||
case "name":
|
||||
return {get: name, set: setName}
|
||||
case "surname":
|
||||
return {get: surname, set: setSurname}
|
||||
case "patronymic":
|
||||
return {get: patronymic, set: setPatronymic}
|
||||
}
|
||||
}
|
||||
|
||||
function editUser() {
|
||||
if (edit) {
|
||||
setEdit(!edit)
|
||||
}
|
||||
else {
|
||||
setUser({
|
||||
email: email,
|
||||
phone: phone,
|
||||
name: name,
|
||||
surname: surname,
|
||||
patronymic: patronymic
|
||||
})
|
||||
setEdit(!edit)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.main}>
|
||||
@ -27,7 +58,7 @@ const Profile = () => {
|
||||
<span>Сохранить <i class="fa-solid fa-floppy-disk"></i></span>
|
||||
}
|
||||
backgroundColor={edit ? "rgb(200, 200, 200)" : ""}
|
||||
click={() => setEdit(!edit)}/>
|
||||
click={() => editUser()}/>
|
||||
</div>
|
||||
<div className={classes.profile__wrapper__body}>
|
||||
{Object.keys(user).map(key => key !== "password" ? <div className={classes.profile__wrapper__body__item}>
|
||||
@ -36,9 +67,10 @@ const Profile = () => {
|
||||
<input
|
||||
type="text"
|
||||
class="form-control shadow-none"
|
||||
value={user[key]}
|
||||
value={choiceInput(key).get}
|
||||
pattern={key === "email" ? "+[7-8]{1}[0-9]{3} [0-9]{3}-[0-9]{2}-[0-9]{2}" : ""}
|
||||
disabled={edit}
|
||||
onChange={(e) => choiceInput(key).set(e.target.value)}
|
||||
required={key !== "patronymic" ? true : false}/>
|
||||
</div>
|
||||
</div> : <div></div>)}
|
||||
|
41
src/pages/ViewForm.jsx
Normal file
41
src/pages/ViewForm.jsx
Normal file
@ -0,0 +1,41 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import classes from "../assets/styles/viewForm.module.scss";
|
||||
import { FormsData, TypeAnswerData } from "../context";
|
||||
import GeneratingFormFields from "../components/GeneratingFormFields.jsx";
|
||||
|
||||
const ViewForm = () => {
|
||||
const navigate = useNavigate();
|
||||
const { formId } = useParams();
|
||||
const {forms, setForms} = useContext(FormsData);
|
||||
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
||||
|
||||
function newForm() {
|
||||
const searchForm = forms.find(item => item.id === Number(formId))
|
||||
|
||||
if (searchForm) {
|
||||
return searchForm.listAnswer
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.main}>
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.form}>
|
||||
<div className={classes.form__header}>
|
||||
|
||||
</div>
|
||||
<div className={classes.form__content}>
|
||||
<GeneratingFormFields newForm={newForm()} listTypeAnswer={listTypeAnswer}/>
|
||||
</div>
|
||||
<div className={classes.form__footer}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ViewForm;
|
@ -6,6 +6,7 @@ import NewForm from '../pages/NewForm.jsx';
|
||||
import Home from "../pages/Home.jsx";
|
||||
import App from "../App.jsx";
|
||||
import Profile from "../pages/Profile.jsx";
|
||||
import ViewForm from "../pages/ViewForm.jsx";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@ -30,6 +31,10 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: '/profile',
|
||||
element: <Profile/>
|
||||
},
|
||||
{
|
||||
path: '/forms/:formId',
|
||||
element: <ViewForm/>
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user