From 88dcb63232f65401f13558be1a48daad92810daf Mon Sep 17 00:00:00 2001 From: Tatiana Nikolaeva Date: Mon, 2 Jun 2025 13:08:23 +0500 Subject: [PATCH] AnswerApi and CompletionApi --- SurveyFrontend/src/api/AnswerApi.ts | 109 +++++------------- SurveyFrontend/src/api/AnswerVariantsApi.ts | 94 +++++++++++++++ SurveyFrontend/src/api/AuthApi.ts | 2 - SurveyFrontend/src/api/CompletionApi.ts | 60 ++++++++++ SurveyFrontend/src/api/QuestionApi.ts | 10 +- .../components/QuestionItem/QuestionItem.tsx | 6 +- .../QuestionsList/QuestionsList.tsx | 4 +- .../src/components/Survey/Survey.tsx | 2 +- .../src/components/SurveyPage/SurveyPage.tsx | 10 +- 9 files changed, 195 insertions(+), 102 deletions(-) create mode 100644 SurveyFrontend/src/api/AnswerVariantsApi.ts create mode 100644 SurveyFrontend/src/api/CompletionApi.ts diff --git a/SurveyFrontend/src/api/AnswerApi.ts b/SurveyFrontend/src/api/AnswerApi.ts index f29d5b4..adeef06 100644 --- a/SurveyFrontend/src/api/AnswerApi.ts +++ b/SurveyFrontend/src/api/AnswerApi.ts @@ -1,94 +1,37 @@ import {BASE_URL, createRequestConfig, handleResponse} from "./BaseApi.ts"; -export interface INewAnswer{ - text: string; -} - -export interface IAnswerVariant extends INewAnswer{ - surveyId: number; - id: number; - questionId: number; -} - -export const getAnswerVariants = async (surveyId: number, questionId: number) => { - try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants`, { - ...createRequestConfig('GET') - }) - return await handleResponse(response) - }catch(err){ - console.error(`Error receiving response options: ${err}`); - throw err; - } -} - -export const addNewAnswerVariant = async (surveyId: number, questionId: number, answer: INewAnswer) => { - const token = localStorage.getItem("token"); - if (!token) { - throw new Error("Токен отсутствует"); - } - - try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants`, { - ...createRequestConfig('POST'), - body: JSON.stringify({ - text: answer.text, - }), - }) - - if (!response.ok) { - throw new Error(`Ошибка: ${response.status}`); - } - return await handleResponse(response) - } - catch(err){ - console.error(`Error adding a new response option: ${err}`); - throw err; - } -} - -export const updateAnswerVariant = async (surveyId: number, questionId: number, id: number, answer: INewAnswer): Promise => { - const token = localStorage.getItem("token"); - if (!token) { - throw new Error("Токен отсутствует"); - } - - try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants/${id}`, { - ...createRequestConfig('PUT'), - body: JSON.stringify({ - text: answer.text, - }) - }) - if (!response.ok) { - const errorData = await response.json().catch(() => null); - throw new Error(`Ошибка ${response.status}: ${errorData?.message || 'Неизвестная ошибка'}`); - } - return await handleResponse(response) - } - catch(err){ - console.error(`Error updating the response option: ${err}`); - throw err; - } -} - -export const deleteAnswerVariant = async (surveyId: number, questionId: number, id: number) => { +export const getAnswer = async (id: number) => { const token = localStorage.getItem("token"); if (!token) { throw new Error('Токен отсутствует'); } + try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants/${id}`, { - ...createRequestConfig('DELETE'), + const response = await fetch(`${BASE_URL}/questions/${id}/answers`, { + ...createRequestConfig('GET'), }) - const responseData = await handleResponse(response); - if (response.ok && !responseData){ - return {success: true}; - } - return responseData; + return await handleResponse(response) } - catch(err){ - console.error(`Error deleting a answer: ${err}`); - throw err; + catch (error) { + console.error(`error when receiving the response: ${error}`); + throw error; + } +} + +export const getCompletionsAnswer = async (id: number) => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error('Токен отсутствует'); + } + + try{ + const response = await fetch(`${BASE_URL}/questions/${id}/answers`, { + ...createRequestConfig('GET'), + }) + return await handleResponse(response) + } + catch (error) { + console.error(`error when receiving the selected response: ${error}`); + throw error; } } \ No newline at end of file diff --git a/SurveyFrontend/src/api/AnswerVariantsApi.ts b/SurveyFrontend/src/api/AnswerVariantsApi.ts new file mode 100644 index 0000000..e09e84c --- /dev/null +++ b/SurveyFrontend/src/api/AnswerVariantsApi.ts @@ -0,0 +1,94 @@ +import {BASE_URL, createRequestConfig, handleResponse} from "./BaseApi.ts"; + +export interface INewAnswer{ + text: string; +} + +export interface IAnswerVariant extends INewAnswer{ + surveyId: number; + id: number; + questionId: number; +} + +export const getAnswerVariants = async (surveyId: number, questionId: number) => { + try{ + const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants`, { + ...createRequestConfig('GET') + }) + return await handleResponse(response) + }catch(err){ + console.error(`Error receiving response options: ${err}`); + throw err; + } +} + +export const addNewAnswerVariant = async (surveyId: number, questionId: number, answer: INewAnswer) => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error("Токен отсутствует"); + } + + try{ + const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${questionId}/answerVariants`, { + ...createRequestConfig('POST'), + body: JSON.stringify({ + text: answer.text, + }), + }) + + if (!response.ok) { + throw new Error(`Ошибка: ${response.status}`); + } + return await handleResponse(response) + } + catch(err){ + console.error(`Error adding a new response option: ${err}`); + throw err; + } +} + +export const updateAnswerVariant = async (id: number, answer: INewAnswer): Promise => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error("Токен отсутствует"); + } + + try{ + const response = await fetch(`${BASE_URL}/answerVariants/${id}`, { + ...createRequestConfig('PUT'), + body: JSON.stringify({ + text: answer.text, + }) + }) + if (!response.ok) { + const errorData = await response.json().catch(() => null); + throw new Error(`Ошибка ${response.status}: ${errorData?.message || 'Неизвестная ошибка'}`); + } + return await handleResponse(response) + } + catch(err){ + console.error(`Error updating the response option: ${err}`); + throw err; + } +} + +export const deleteAnswerVariant = async (id: number) => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error('Токен отсутствует'); + } + try{ + const response = await fetch(`${BASE_URL}/answerVariants/${id}`, { + ...createRequestConfig('DELETE'), + }) + const responseData = await handleResponse(response); + if (response.ok && !responseData){ + return {success: true}; + } + return responseData; + } + catch(err){ + console.error(`Error deleting a answer: ${err}`); + throw err; + } +} \ No newline at end of file diff --git a/SurveyFrontend/src/api/AuthApi.ts b/SurveyFrontend/src/api/AuthApi.ts index 749d189..6347d46 100644 --- a/SurveyFrontend/src/api/AuthApi.ts +++ b/SurveyFrontend/src/api/AuthApi.ts @@ -26,8 +26,6 @@ export const getCurrentUser = async () => { } }); - console.log(response); - if (response.status === 401) { localStorage.removeItem("token"); localStorage.removeItem("user"); diff --git a/SurveyFrontend/src/api/CompletionApi.ts b/SurveyFrontend/src/api/CompletionApi.ts new file mode 100644 index 0000000..c2e4ad9 --- /dev/null +++ b/SurveyFrontend/src/api/CompletionApi.ts @@ -0,0 +1,60 @@ +import {BASE_URL, createRequestConfig, handleResponse} from "./BaseApi.ts"; +export interface IAnswer{ + questionId: number; + answerText: string; +} + +export const getAllCompletions = async (surveyId: number) => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error('Токен отсутствует'); + } + try{ + const response = await fetch(`${BASE_URL}/surveys/${surveyId}/completions`, { + ...createRequestConfig('GET'), + }) + return await handleResponse(response); + } + catch (error) { + console.error(`Error when receiving all selected responses: ${error}`); + throw error; + } +} + +export const addNewCompletion = async (surveyId: number, answer: IAnswer) => { + try{ + const response = await fetch(`${BASE_URL}/surveys/${surveyId}/completions`, { + ...createRequestConfig('POST'), + body: JSON.stringify({ + questionId: answer.questionId, + answerText: answer.answerText, + }) + }) + if (!response.ok) { + throw new Error(`Ошибка: ${response.status}`); + } + return await handleResponse(response) + } + catch (error) { + console.error(`Error when adding a new survey passage: ${error}`); + throw error; + } +} + +export const getCompletionById = async (id: number) => { + const token = localStorage.getItem("token"); + if (!token) { + throw new Error('Токен отсутствует'); + } + + try{ + const response = await fetch(`${BASE_URL}/completions/${id}`, { + ...createRequestConfig('GET'), + }) + return await handleResponse(response); + } + catch (error) { + console.error(`Error when receiving a completed survey by id: ${error}`); + throw error; + } +} \ No newline at end of file diff --git a/SurveyFrontend/src/api/QuestionApi.ts b/SurveyFrontend/src/api/QuestionApi.ts index 90593b6..92defc5 100644 --- a/SurveyFrontend/src/api/QuestionApi.ts +++ b/SurveyFrontend/src/api/QuestionApi.ts @@ -1,5 +1,5 @@ import {BASE_URL, createRequestConfig, handleResponse} from "./BaseApi.ts"; -import {IAnswerVariant} from "./AnswerApi.ts"; +import {IAnswerVariant} from "./AnswerVariantsApi.ts"; export interface INewQuestion{ title: string; @@ -45,14 +45,14 @@ export const getListQuestions = async (surveyId: number): Promise = } } -export const updateQuestion = async (surveyId: number, id: number, question: Partial): Promise => { +export const updateQuestion = async (id: number, question: Partial): Promise => { const token = localStorage.getItem("token"); if (!token) { throw new Error("Токен отсутствует"); } try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${id}`, { + const response = await fetch(`${BASE_URL}/questions/${id}`, { ...createRequestConfig('PUT'), body: JSON.stringify({ title: question.title, @@ -70,14 +70,14 @@ export const updateQuestion = async (surveyId: number, id: number, question: Par } } -export const deleteQuestion = async (surveyId: number, id: number) => { +export const deleteQuestion = async (id: number) => { const token = localStorage.getItem("token"); if (!token) { throw new Error("Токен отсутствует"); } try{ - const response = await fetch(`${BASE_URL}/surveys/${surveyId}/questions/${id}`, { + const response = await fetch(`${BASE_URL}/questions/${id}`, { ...createRequestConfig('DELETE'), }) const responseData = await handleResponse(response); diff --git a/SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx b/SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx index 18627bf..fc1cd8b 100644 --- a/SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx +++ b/SurveyFrontend/src/components/QuestionItem/QuestionItem.tsx @@ -9,7 +9,7 @@ import { deleteAnswerVariant, getAnswerVariants, updateAnswerVariant -} from "../../api/AnswerApi.ts"; +} from "../../api/AnswerVariantsApi.ts"; import {useLocation} from "react-router-dom"; import TextareaAutosize from "react-textarea-autosize"; @@ -123,8 +123,6 @@ const QuestionItem: React.FC = ({ if (surveyId && newAnswerVariants[index].id) { try { await updateAnswerVariant( - surveyId, - questionId, newAnswerVariants[index].id!, { text: value } ); @@ -139,7 +137,7 @@ const QuestionItem: React.FC = ({ if (surveyId && answerToDelete.id) { try { - await deleteAnswerVariant(surveyId, questionId, answerToDelete.id); + await deleteAnswerVariant(answerToDelete.id); const newAnswerVariants = initialAnswerVariants.filter((_, i) => i !== index); onAnswerVariantsChange(newAnswerVariants); setSelectedAnswers(selectedAnswers.filter((i) => i !== index)); diff --git a/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx b/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx index d755eb7..fa40be2 100644 --- a/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx +++ b/SurveyFrontend/src/components/QuestionsList/QuestionsList.tsx @@ -2,7 +2,7 @@ import React from "react"; import QuestionItem from "../QuestionItem/QuestionItem.tsx"; import AddQuestionButton from "../AddQuestionButton/AddQuestionButton.tsx"; import {addNewQuestion, deleteQuestion, getListQuestions} from "../../api/QuestionApi.ts"; -import {addNewAnswerVariant} from "../../api/AnswerApi.ts"; +import {addNewAnswerVariant} from "../../api/AnswerVariantsApi.ts"; import {useLocation} from "react-router-dom"; import styles from './QuestionsList.module.css' @@ -72,7 +72,7 @@ const QuestionsList: React.FC = ({questions, setQuestions, s if (surveyId) { const listQuestions = await getListQuestions(surveyId); if (listQuestions.find(q => q.id === id)) { - const response = await deleteQuestion(surveyId, id); + const response = await deleteQuestion(id); if (!response?.success) { throw new Error('Не удалось удалить вопрос на сервере'); } diff --git a/SurveyFrontend/src/components/Survey/Survey.tsx b/SurveyFrontend/src/components/Survey/Survey.tsx index 802e0d4..4706224 100644 --- a/SurveyFrontend/src/components/Survey/Survey.tsx +++ b/SurveyFrontend/src/components/Survey/Survey.tsx @@ -6,7 +6,7 @@ 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 {addNewAnswerVariant} from "../../api/AnswerApi.ts"; +import {addNewAnswerVariant} from "../../api/AnswerVariantsApi.ts"; const Survey: React.FC = () => { const navigate = useNavigate(); diff --git a/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx b/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx index 16c2db9..8f70177 100644 --- a/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx +++ b/SurveyFrontend/src/components/SurveyPage/SurveyPage.tsx @@ -6,7 +6,7 @@ import {useOutletContext} from "react-router-dom"; import { addNewQuestion, getListQuestions, updateQuestion, deleteQuestion } from "../../api/QuestionApi.ts"; import styles from "./SurveyPage.module.css"; import SaveButton from "../SaveButton/SaveButton.tsx"; -import { addNewAnswerVariant, deleteAnswerVariant, getAnswerVariants, IAnswerVariant, updateAnswerVariant } from "../../api/AnswerApi.ts"; +import { addNewAnswerVariant, deleteAnswerVariant, getAnswerVariants, IAnswerVariant, updateAnswerVariant } from "../../api/AnswerVariantsApi.ts"; type ActionType = | 'update-survey' @@ -118,14 +118,14 @@ class ActionQueue { } private async handleUpdateQuestion(data: QuestionActionData & { id: number }) { - return await updateQuestion(data.surveyId, data.id, { + return await updateQuestion(data.id, { title: data.title, questionType: data.questionType }); } private async handleDeleteQuestion(data: QuestionActionData & { id: number }) { - return await deleteQuestion(data.surveyId, data.id); + return await deleteQuestion(data.id); } private async handleCreateAnswer(data: AnswerActionData) { @@ -136,7 +136,7 @@ class ActionQueue { private async handleUpdateAnswer(data: AnswerActionData & { id: number }) { try { - const result = await updateAnswerVariant(data.surveyId, data.questionId, data.id, { + const result = await updateAnswerVariant(data.id, { text: data.text }); return result; @@ -148,7 +148,7 @@ class ActionQueue { } private async handleDeleteAnswer(data: AnswerActionData & { id: number }) { - return await deleteAnswerVariant(data.surveyId, data.questionId, data.id); + return await deleteAnswerVariant(data.id); } }