From 51f3469031a631761f895350748e00a2e3dfbc6e Mon Sep 17 00:00:00 2001 From: Tatiana Nikolaeva Date: Sat, 24 May 2025 21:58:42 +0500 Subject: [PATCH] update survey and questions --- .../src/components/LoginForm/LoginForm.tsx | 14 +-- .../QuestionsList/QuestionsList.tsx | 33 ++++--- .../RegisterForm/RegisterForm.module.css | 4 +- .../components/RegisterForm/RegisterForm.tsx | 25 +++--- .../src/components/SurveyPage/SurveyPage.tsx | 86 ++++++++++++++++--- 5 files changed, 122 insertions(+), 40 deletions(-) diff --git a/SurveyFrontend/src/components/LoginForm/LoginForm.tsx b/SurveyFrontend/src/components/LoginForm/LoginForm.tsx index 1fcab4d..8431a04 100644 --- a/SurveyFrontend/src/components/LoginForm/LoginForm.tsx +++ b/SurveyFrontend/src/components/LoginForm/LoginForm.tsx @@ -22,11 +22,15 @@ const LoginForm = () => { setError(null); try{ - const responseData = await authUser({email, password}); - if (responseData && !responseData.error) - navigate('/my-surveys'); - else - setError('Неверный логин или пароль') + if (email === '' || password === '') + setError('Заполните все поля') + else { + const responseData = await authUser({email, password}); + if (responseData && !responseData.error) + navigate('/my-surveys'); + else + setError('Неверный логин или пароль') + } } catch(err){ console.error('Ошибка при отправке запроса:', err); diff --git a/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx b/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx index 87fa255..9cf1fed 100644 --- a/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx +++ b/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useState} from "react"; import QuestionItem from "../QuestionItem/QuestionItem.tsx"; import AddQuestionButton from "../AddQuestionButton/AddQuestionButton.tsx"; -import {deleteQuestion} from "../../api/QuestionApi.ts"; +import {deleteQuestion, getListQuestions} from "../../api/QuestionApi.ts"; interface QuestionsListProps { questions: Question[]; @@ -18,11 +18,11 @@ export interface Question { const QuestionsList: React.FC = ({questions, setQuestions, surveyId}) => { const [selectedType, setSelectedType] = useState<'single' | 'multiply'>('single'); - const [localQuestionId, setLocalQuestionId] = useState(2); // Начинаем с 2, так как первый вопрос имеет ID=1 + const [localQuestionId, setLocalQuestionId] = useState(1001); // Начинаем с 2, так как первый вопрос имеет ID=1 const handleAddQuestion = () => { const newQuestion: Question = { - id: localQuestionId, + id: localQuestionId, // ID >= 1001 — новые вопросы text: '', questionType: selectedType === 'single' ? 'singleanswerquestion' : 'multipleanswerquestion', }; @@ -45,21 +45,28 @@ const QuestionsList: React.FC = ({questions, setQuestions, s const handleDeleteQuestion = async (id: number) => { try { if (surveyId) { - const response = await deleteQuestion(surveyId, id); - if (!response?.success) { - throw new Error('Не удалось удалить вопрос на сервере'); + const listQuestions = await getListQuestions(surveyId); + if (listQuestions.find(q => q.id === id)) { + const response = await deleteQuestion(surveyId, id); + if (!response?.success) { + throw new Error('Не удалось удалить вопрос на сервере'); + } } - } - const newQuestions: Question[] = []; - for (const question of questions) { - if (question.id !== id) { - newQuestions.push(question); + const newQuestions: Question[] = []; + for (const question of questions) { + if (question.id !== id) { + newQuestions.push(question); + } } + setQuestions(newQuestions); + } + else{ + const questionsList = questions.filter(q => q.id !== id); + setQuestions(questionsList); + return; } - setQuestions(newQuestions); } catch (error) { console.error('Ошибка при удалении вопроса:', error); - alert('Не удалось удалить вопрос: ' + (error instanceof Error ? error.message : 'Неизвестная ошибка')); } }; diff --git a/SurveyFrontend/src/components/RegisterForm/RegisterForm.module.css b/SurveyFrontend/src/components/RegisterForm/RegisterForm.module.css index 52a9f86..642ea69 100644 --- a/SurveyFrontend/src/components/RegisterForm/RegisterForm.module.css +++ b/SurveyFrontend/src/components/RegisterForm/RegisterForm.module.css @@ -31,7 +31,7 @@ color: #000000; outline: none; border: none; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); + border-bottom: 2px solid rgba(0, 0, 0, 0.2); padding: 5px 0; opacity: 1; } @@ -55,7 +55,7 @@ } .input:focus { - border-bottom: 1px solid black; /* Чёрная граница при фокусе */ + border-bottom: 2px solid black; /* Чёрная граница при фокусе */ } .signUp{ diff --git a/SurveyFrontend/src/components/RegisterForm/RegisterForm.tsx b/SurveyFrontend/src/components/RegisterForm/RegisterForm.tsx index 380049a..f7163fc 100644 --- a/SurveyFrontend/src/components/RegisterForm/RegisterForm.tsx +++ b/SurveyFrontend/src/components/RegisterForm/RegisterForm.tsx @@ -31,17 +31,22 @@ const RegisterForm = () => { setError(null); try{ - const responseData = await registerUser({username, firstName, lastName, email, password}); - if (responseData && !responseData.error) { - console.log('Регистрация успешна'); - localStorage.setItem("user", JSON.stringify({ - firstName, - lastName - })); - navigate('/my-surveys'); + if (email === '' || password === '' || firstName === '' || lastName === '') { + setError('Заполните все поля'); } - else if (responseData.status === 409){ - setError('Аккаунт с такой почтой уже зарегистрирован'); + else{ + const responseData = await registerUser({username, firstName, lastName, email, password}); + if (responseData && !responseData.error) { + console.log('Регистрация успешна'); + localStorage.setItem("user", JSON.stringify({ + firstName, + lastName + })); + navigate('/my-surveys'); + } + else if (responseData.status === 409){ + setError('Аккаунт с такой почтой уже зарегистрирован'); + } } } catch (err) { diff --git a/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx b/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx index 399b807..bb7c74f 100644 --- a/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx +++ b/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx @@ -3,10 +3,27 @@ import QuestionsList, {Question} from "../QuestionsList/QuestionsList.tsx"; import {useEffect, useState} from "react"; import {getSurveyById, ISurvey, updateSurvey} from "../../api/SurveyApi.ts"; import {useParams} from "react-router-dom"; -import {getListQuestions} from "../../api/QuestionApi.ts"; +import {addNewQuestion, getListQuestions, updateQuestion} from "../../api/QuestionApi.ts"; import styles from "./SurveyPage.module.css"; import SaveButton from "../SaveButton/SaveButton.tsx"; +type ActionType = 'create' | 'update'; + +class QuestionAction { + type: ActionType; + data: { + surveyId: number; + id?: number; + title?: string; + questionType?: string; + }; + + constructor(type: ActionType, data: { surveyId: number, id?: number, title?: string, questionType?: string }) { + this.type = type; + this.data = data; + } +} + export const SurveyPage: React.FC = () => { const [survey, setSurvey] = useState(null); const [questions, setQuestions] = useState([]); @@ -60,24 +77,73 @@ export const SurveyPage: React.FC = () => { if (loading) return
Загрузка...
; if (!survey) return
Опрос не найден
; - const handleSave = async() => { + const handleSave = async () => { if (!surveyId || !survey) return; - try{ + try { setError(null); const id = parseInt(surveyId); - const surveyUpdated = await updateSurvey(id, { + + const surveyUpdated = await updateSurvey(id, { title: title, description: description, - }) + }); setSurvey(surveyUpdated); - } - catch(error){ - console.error('Ошибка при сохранении опроса:', error); + + const actions: QuestionAction[] = []; + const serverQuestions = await getListQuestions(id); + + questions.forEach(question => { + const existsOnServer = serverQuestions.some(q => q.id === question.id); + + if (existsOnServer) { + actions.push(new QuestionAction("update", { + surveyId: id, + id: question.id, + title: question.text, + questionType: question.questionType + })); + } else { + actions.push(new QuestionAction("create", { + surveyId: id, + title: question.text, + questionType: question.questionType + })); + } + }); + + for (const action of actions) { + switch (action.type) { + case "create": + await addNewQuestion(id, { + title: action.data.title as string, + questionType: action.data.questionType as 'singleanswerquestion' | 'multipleanswerquestion', + }); + break; + case "update": + if (action.data.id) { + await updateQuestion(id, action.data.id, { + title: action.data.title, + questionType: action.data.questionType + }); + } + break; + } + } + + const updatedQuestions = await getListQuestions(id); + const formattedQuestions = updatedQuestions.map(q => ({ + id: q.id, + text: q.title, + questionType: q.questionType as 'singleanswerquestion' | 'multipleanswerquestion', + })); + setQuestions(formattedQuestions); + + } catch (error) { + console.error('Ошибка:', error); setError('Не удалось сохранить изменения'); - throw error; } - } + }; return (