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 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 />}>

View file

@ -7,7 +7,7 @@ interface CreateSurveyButtonProps {
const SaveButton: React.FC<CreateSurveyButtonProps> = ({onClick}) => { const SaveButton: React.FC<CreateSurveyButtonProps> = ({onClick}) => {
return ( return (
<button onClick={onClick} className={styles.createSurveyButton}> <button onClick={onClick} className={styles.createSurveyButton} >
Сохранить Сохранить
</button> </button>
); );

View file

@ -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

View file

@ -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;

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