storing survey data locally without saving
This commit is contained in:
parent
4d96cbaab1
commit
a75275c7de
5 changed files with 106 additions and 56 deletions
|
|
@ -9,6 +9,7 @@ import {MySurveyList} from "./components/MySurveyList/MySurveyList.tsx";
|
||||||
import AuthForm from "./pages/AuthForm/AuthForm.tsx";
|
import AuthForm from "./pages/AuthForm/AuthForm.tsx";
|
||||||
import {SurveyPage} from "./components/SurveyPage/SurveyPage.tsx";
|
import {SurveyPage} from "./components/SurveyPage/SurveyPage.tsx";
|
||||||
import CompleteSurvey from "./pages/CompleteSurvey/CompleteSurvey.tsx";
|
import CompleteSurvey from "./pages/CompleteSurvey/CompleteSurvey.tsx";
|
||||||
|
import {SurveyProvider} from './context/SurveyContext.tsx';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return(
|
return(
|
||||||
|
|
@ -18,8 +19,8 @@ const App = () => {
|
||||||
<Route path="/register" element={<AuthForm />} />
|
<Route path="/register" element={<AuthForm />} />
|
||||||
|
|
||||||
<Route path="survey/create" element={<SurveyCreateAndEditingPage />}>
|
<Route path="survey/create" element={<SurveyCreateAndEditingPage />}>
|
||||||
<Route path="questions" element={<Survey />} />
|
<Route path="questions" element={<SurveyProvider><Survey /></SurveyProvider>} />
|
||||||
<Route path="settings" element={<SettingSurvey />} />
|
<Route path="settings" element={<SurveyProvider><SettingSurvey /></SurveyProvider>} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="my-surveys" element={<MySurveysPage />}>
|
<Route path="my-surveys" element={<MySurveysPage />}>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import React, {useState} from 'react';
|
import React from 'react';
|
||||||
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
|
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
|
||||||
import styles from "./SettingSurvey.module.css";
|
import styles from "./SettingSurvey.module.css";
|
||||||
import TimeEvent from "../TimeEvent/TimeEvent.tsx";
|
import TimeEvent from "../TimeEvent/TimeEvent.tsx";
|
||||||
import SaveButton from "../SaveButton/SaveButton.tsx";
|
import SaveButton from "../SaveButton/SaveButton.tsx";
|
||||||
import {ISurvey} from "../../api/SurveyApi.ts";
|
import {ISurvey} from "../../api/SurveyApi.ts";
|
||||||
import {useLocation, useOutletContext} from "react-router-dom";
|
import {useLocation, useOutletContext} from "react-router-dom";
|
||||||
|
import {useSurveyContext} from "../../context/SurveyContext.tsx";
|
||||||
|
|
||||||
|
|
||||||
const SettingSurvey: React.FC = () => {
|
const SettingSurvey: React.FC = () => {
|
||||||
|
|
@ -14,9 +15,7 @@ const SettingSurvey: React.FC = () => {
|
||||||
survey: ISurvey;
|
survey: ISurvey;
|
||||||
setSurvey: (survey: ISurvey) => void;
|
setSurvey: (survey: ISurvey) => void;
|
||||||
}>();
|
}>();
|
||||||
|
const { tempSurvey, setTempSurvey } = useSurveyContext();
|
||||||
const [descriptionSurvey, setDescriptionSurvey] = useState('');
|
|
||||||
const [titleSurvey, setTitleSurvey] = useState('');
|
|
||||||
|
|
||||||
const handleCopyLink = () => {
|
const handleCopyLink = () => {
|
||||||
if (!survey?.id)
|
if (!survey?.id)
|
||||||
|
|
@ -31,10 +30,10 @@ const SettingSurvey: React.FC = () => {
|
||||||
<div className={styles.settingSurvey}>
|
<div className={styles.settingSurvey}>
|
||||||
{isSettingCreatePage ? (
|
{isSettingCreatePage ? (
|
||||||
<SurveyInfo
|
<SurveyInfo
|
||||||
titleSurvey={titleSurvey}
|
titleSurvey={tempSurvey.title}
|
||||||
descriptionSurvey={descriptionSurvey}
|
descriptionSurvey={tempSurvey.description}
|
||||||
setDescriptionSurvey={setDescriptionSurvey}
|
setDescriptionSurvey={(value) => setTempSurvey({ ...tempSurvey, description: value })}
|
||||||
setTitleSurvey={setTitleSurvey}
|
setTitleSurvey={(value) => setTempSurvey({ ...tempSurvey, title: value })}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<SurveyInfo
|
<SurveyInfo
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,78 @@
|
||||||
import React, {useState} from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
|
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
|
||||||
import QuestionsList, { Question } from "../QuestionsList/QuestionsList.tsx";
|
import QuestionsList, { Question } from "../QuestionsList/QuestionsList.tsx";
|
||||||
import styles from './Survey.module.css'
|
import styles from './Survey.module.css';
|
||||||
import SaveButton from "../SaveButton/SaveButton.tsx";
|
import SaveButton from "../SaveButton/SaveButton.tsx";
|
||||||
import { ISurvey, postNewSurvey } from "../../api/SurveyApi.ts";
|
import { ISurvey, postNewSurvey } from "../../api/SurveyApi.ts";
|
||||||
import { addNewQuestion } from "../../api/QuestionApi.ts";
|
import { addNewQuestion } from "../../api/QuestionApi.ts";
|
||||||
import {useNavigate} from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { addNewAnswerVariant } from "../../api/AnswerVariantsApi.ts";
|
import { addNewAnswerVariant } from "../../api/AnswerVariantsApi.ts";
|
||||||
|
import { useSurveyContext } from "../../context/SurveyContext.tsx";
|
||||||
|
|
||||||
const Survey: React.FC = () => {
|
const Survey: React.FC = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [descriptionSurvey, setDescriptionSurvey] = useState('');
|
const location = useLocation();
|
||||||
const [titleSurvey, setTitleSurvey] = useState('Название опроса');
|
const { tempSurvey, setTempSurvey, clearTempSurvey } = useSurveyContext();
|
||||||
const [survey] = useState<ISurvey | null>(null);
|
const [survey] = useState<ISurvey | null>(null);
|
||||||
|
|
||||||
const [questions, setQuestions] = useState<Question[]>([
|
const [questions, setQuestions] = useState<Question[]>(
|
||||||
{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }]},
|
tempSurvey.questions.length > 0
|
||||||
]);
|
? tempSurvey.questions
|
||||||
|
: [{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }] }]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!tempSurvey.title && !tempSurvey.description && tempSurvey.questions.length === 0) {
|
||||||
|
setTempSurvey({
|
||||||
|
title: "Название опроса",
|
||||||
|
description: "",
|
||||||
|
questions: [{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }] }]
|
||||||
|
});
|
||||||
|
setQuestions([{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }] }]);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTempSurvey({
|
||||||
|
...tempSurvey,
|
||||||
|
questions: questions,
|
||||||
|
});
|
||||||
|
}, [questions]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isCreateSurveyRoute = location.pathname.includes('/survey/create');
|
||||||
|
|
||||||
|
if (!isCreateSurveyRoute) {
|
||||||
|
clearTempSurvey();
|
||||||
|
setQuestions([{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }] }]);
|
||||||
|
}
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
try {
|
try {
|
||||||
const savedSurvey = await postNewSurvey({
|
const savedSurvey = await postNewSurvey({
|
||||||
title: titleSurvey,
|
title: tempSurvey.title,
|
||||||
description: descriptionSurvey
|
description: tempSurvey.description,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedQuestions: Question[] = [];
|
const questionPromises = questions.map(async (question) => {
|
||||||
for (const question of questions) {
|
|
||||||
const newQuestion = await addNewQuestion(savedSurvey.id, {
|
const newQuestion = await addNewQuestion(savedSurvey.id, {
|
||||||
title: question.text,
|
title: question.text,
|
||||||
questionType: question.questionType
|
questionType: question.questionType,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedQuestion: Question = {
|
if (question.answerVariants?.length > 0) {
|
||||||
...question,
|
await Promise.all(
|
||||||
id: newQuestion.id,
|
|
||||||
answerVariants: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (question.answerVariants && question.answerVariants.length > 0) {
|
|
||||||
const newVariants = await Promise.all(
|
|
||||||
question.answerVariants.map(answer =>
|
question.answerVariants.map(answer =>
|
||||||
addNewAnswerVariant(
|
addNewAnswerVariant(savedSurvey.id, newQuestion.id, { text: answer.text })
|
||||||
savedSurvey.id,
|
|
||||||
newQuestion.id,
|
|
||||||
{ text: answer.text }
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
updatedQuestion.answerVariants = newVariants.map((variant: { id: number, text: string }) => ({
|
|
||||||
id: variant.id,
|
|
||||||
text: variant.text
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
updatedQuestions.push(updatedQuestion);
|
await Promise.all(questionPromises);
|
||||||
}
|
|
||||||
|
|
||||||
setQuestions(updatedQuestions);
|
clearTempSurvey();
|
||||||
navigate('/my-surveys');
|
navigate('/my-surveys');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при сохранении:', error);
|
console.error('Ошибка при сохранении:', error);
|
||||||
|
|
@ -68,20 +82,19 @@ const Survey: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.survey}>
|
<div className={styles.survey}>
|
||||||
<SurveyInfo
|
<SurveyInfo
|
||||||
titleSurvey={titleSurvey}
|
titleSurvey={tempSurvey.title || "Название опроса"}
|
||||||
descriptionSurvey={descriptionSurvey}
|
descriptionSurvey={tempSurvey.description}
|
||||||
setDescriptionSurvey={setDescriptionSurvey}
|
setDescriptionSurvey={(value) => setTempSurvey({ ...tempSurvey, description: value })}
|
||||||
setTitleSurvey={setTitleSurvey}
|
setTitleSurvey={(value) => setTempSurvey({ ...tempSurvey, title: value })}
|
||||||
/>
|
/>
|
||||||
<QuestionsList
|
<QuestionsList
|
||||||
questions={questions}
|
questions={questions}
|
||||||
setQuestions={setQuestions}
|
setQuestions={setQuestions}
|
||||||
surveyId={survey?.id}
|
surveyId={survey?.id}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SaveButton onClick={handleSave} />
|
<SaveButton onClick={handleSave} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Survey;
|
export default Survey;
|
||||||
37
SurveyFrontend/src/context/SurveyContext.tsx
Normal file
37
SurveyFrontend/src/context/SurveyContext.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import React, {createContext, useContext, useState} from "react";
|
||||||
|
import { INewSurvey } from "../api/SurveyApi.ts";
|
||||||
|
import { Question } from "../components/QuestionsList/QuestionsList.tsx";
|
||||||
|
|
||||||
|
interface SurveyContextType {
|
||||||
|
tempSurvey: INewSurvey & { questions: Question[] };
|
||||||
|
setTempSurvey: (survey: INewSurvey & { questions: Question[] }) => void;
|
||||||
|
clearTempSurvey: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SurveyContext = createContext<SurveyContextType | undefined>(undefined);
|
||||||
|
|
||||||
|
export const SurveyProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
|
const [tempSurvey, setTempSurvey] = useState<INewSurvey & { questions: Question[] }>({
|
||||||
|
title: "",
|
||||||
|
description: "",
|
||||||
|
questions: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const clearTempSurvey = () => {
|
||||||
|
setTempSurvey({ title: "", description: "", questions: [] });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SurveyContext.Provider value={{ tempSurvey, setTempSurvey, clearTempSurvey }}>
|
||||||
|
{children}
|
||||||
|
</SurveyContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSurveyContext = () => {
|
||||||
|
const context = useContext(SurveyContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error("useSurveyContext must be used within a SurveyProvider");
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue