storing survey data locally without saving

This commit is contained in:
Tatiana Nikolaeva 2025-06-03 14:30:29 +05:00
parent 4d96cbaab1
commit a75275c7de
5 changed files with 106 additions and 56 deletions

View file

@ -9,6 +9,7 @@ import {MySurveyList} from "./components/MySurveyList/MySurveyList.tsx";
import AuthForm from "./pages/AuthForm/AuthForm.tsx";
import {SurveyPage} from "./components/SurveyPage/SurveyPage.tsx";
import CompleteSurvey from "./pages/CompleteSurvey/CompleteSurvey.tsx";
import {SurveyProvider} from './context/SurveyContext.tsx';
const App = () => {
return(
@ -18,8 +19,8 @@ const App = () => {
<Route path="/register" element={<AuthForm />} />
<Route path="survey/create" element={<SurveyCreateAndEditingPage />}>
<Route path="questions" element={<Survey />} />
<Route path="settings" element={<SettingSurvey />} />
<Route path="questions" element={<SurveyProvider><Survey /></SurveyProvider>} />
<Route path="settings" element={<SurveyProvider><SettingSurvey /></SurveyProvider>} />
</Route>
<Route path="my-surveys" element={<MySurveysPage />}>

View file

@ -1,10 +1,11 @@
import React, {useState} from 'react';
import React from 'react';
import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
import styles from "./SettingSurvey.module.css";
import TimeEvent from "../TimeEvent/TimeEvent.tsx";
import SaveButton from "../SaveButton/SaveButton.tsx";
import {ISurvey} from "../../api/SurveyApi.ts";
import {useLocation, useOutletContext} from "react-router-dom";
import {useSurveyContext} from "../../context/SurveyContext.tsx";
const SettingSurvey: React.FC = () => {
@ -14,9 +15,7 @@ const SettingSurvey: React.FC = () => {
survey: ISurvey;
setSurvey: (survey: ISurvey) => void;
}>();
const [descriptionSurvey, setDescriptionSurvey] = useState('');
const [titleSurvey, setTitleSurvey] = useState('');
const { tempSurvey, setTempSurvey } = useSurveyContext();
const handleCopyLink = () => {
if (!survey?.id)
@ -31,10 +30,10 @@ const SettingSurvey: React.FC = () => {
<div className={styles.settingSurvey}>
{isSettingCreatePage ? (
<SurveyInfo
titleSurvey={titleSurvey}
descriptionSurvey={descriptionSurvey}
setDescriptionSurvey={setDescriptionSurvey}
setTitleSurvey={setTitleSurvey}
titleSurvey={tempSurvey.title}
descriptionSurvey={tempSurvey.description}
setDescriptionSurvey={(value) => setTempSurvey({ ...tempSurvey, description: value })}
setTitleSurvey={(value) => setTempSurvey({ ...tempSurvey, title: value })}
/>
) : (
<SurveyInfo

View file

@ -1,64 +1,78 @@
import React, {useState} from "react";
import React, { useState, useEffect } from "react";
import SurveyInfo from "../SurveyInfo/SurveyInfo.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 { ISurvey, postNewSurvey } from "../../api/SurveyApi.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 { useSurveyContext } from "../../context/SurveyContext.tsx";
const Survey: React.FC = () => {
const navigate = useNavigate();
const [descriptionSurvey, setDescriptionSurvey] = useState('');
const [titleSurvey, setTitleSurvey] = useState('Название опроса');
const location = useLocation();
const { tempSurvey, setTempSurvey, clearTempSurvey } = useSurveyContext();
const [survey] = useState<ISurvey | null>(null);
const [questions, setQuestions] = useState<Question[]>([
{ id: 1, text: '', questionType: 'SingleAnswerQuestion', answerVariants: [{ text: '' }]},
]);
const [questions, setQuestions] = useState<Question[]>(
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 () => {
try {
const savedSurvey = await postNewSurvey({
title: titleSurvey,
description: descriptionSurvey
title: tempSurvey.title,
description: tempSurvey.description,
});
const updatedQuestions: Question[] = [];
for (const question of questions) {
const questionPromises = questions.map(async (question) => {
const newQuestion = await addNewQuestion(savedSurvey.id, {
title: question.text,
questionType: question.questionType
questionType: question.questionType,
});
const updatedQuestion: Question = {
...question,
id: newQuestion.id,
answerVariants: []
};
if (question.answerVariants && question.answerVariants.length > 0) {
const newVariants = await Promise.all(
if (question.answerVariants?.length > 0) {
await Promise.all(
question.answerVariants.map(answer =>
addNewAnswerVariant(
savedSurvey.id,
newQuestion.id,
{ text: answer.text }
)
addNewAnswerVariant(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');
} catch (error) {
console.error('Ошибка при сохранении:', error);
@ -68,20 +82,19 @@ const Survey: React.FC = () => {
return (
<div className={styles.survey}>
<SurveyInfo
titleSurvey={titleSurvey}
descriptionSurvey={descriptionSurvey}
setDescriptionSurvey={setDescriptionSurvey}
setTitleSurvey={setTitleSurvey}
titleSurvey={tempSurvey.title || "Название опроса"}
descriptionSurvey={tempSurvey.description}
setDescriptionSurvey={(value) => setTempSurvey({ ...tempSurvey, description: value })}
setTitleSurvey={(value) => setTempSurvey({ ...tempSurvey, title: value })}
/>
<QuestionsList
questions={questions}
setQuestions={setQuestions}
surveyId={survey?.id}
/>
<SaveButton onClick={handleSave} />
</div>
);
}
};
export default Survey;

View 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;
};