add result page
This commit is contained in:
1107
package-lock.json
generated
1107
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.6.0"
|
"react-router-dom": "^7.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const createQueryString = (params: Record<string, string | number | boolean | un
|
|||||||
return filteredParams.join('&');
|
return filteredParams.join('&');
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useDataPage<T>(application:string, endpoint: string, params:{[key:string]:string|number}={}) {
|
export function useDataPage<T>(application:string, endpoint: string, params:{[key:string]:string|number}={}, needLoad:boolean=true):PageControl<T> {
|
||||||
const [data, setData] = useState<T[]|null>(null);
|
const [data, setData] = useState<T[]|null>(null);
|
||||||
// const [previousUrl, setPreviousUrl] = useState<string|undefined>(undefined)
|
// const [previousUrl, setPreviousUrl] = useState<string|undefined>(undefined)
|
||||||
// const [nextUrl, setNextUrl] = useState<string|undefined>(undefined)
|
// const [nextUrl, setNextUrl] = useState<string|undefined>(undefined)
|
||||||
@@ -67,7 +67,7 @@ export function useDataPage<T>(application:string, endpoint: string, params:{[ke
|
|||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
()=>{
|
()=>{
|
||||||
if (data === null){
|
if (data === null && needLoad){
|
||||||
getFetch(`/${application}/${endpoint}/?${createQueryString(params)}`).then((r)=>{
|
getFetch(`/${application}/${endpoint}/?${createQueryString(params)}`).then((r)=>{
|
||||||
if (r.success){
|
if (r.success){
|
||||||
const pageData = r.body as PageResponse<T>;
|
const pageData = r.body as PageResponse<T>;
|
||||||
@@ -110,8 +110,8 @@ export function useDataPage<T>(application:string, endpoint: string, params:{[ke
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
items: data,
|
items: data,
|
||||||
hasPrevious: undefined,//previousUrl !== undefined,
|
hasPrevious: false,//previousUrl !== undefined,
|
||||||
hasNext: undefined,//nextUrl !== undefined,
|
hasNext: false,//nextUrl !== undefined,
|
||||||
nextPage,
|
nextPage,
|
||||||
previousPage
|
previousPage
|
||||||
} as PageControl<T>
|
} as PageControl<T>
|
||||||
@@ -119,25 +119,25 @@ export function useDataPage<T>(application:string, endpoint: string, params:{[ke
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useData<T>(application:string, endpoint: string, id: string|number) {
|
export function useData<T>(application:string, endpoint: string, id: string|number, needLoad:boolean=true): T|null|undefined {
|
||||||
|
|
||||||
const [data, setData] = useState<T | null | undefined>(null);
|
const [data, setData] = useState<T | null | undefined>(null);
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
()=>{
|
()=>{
|
||||||
if (data === null){
|
if (data === null && needLoad){
|
||||||
getFetch(`/${application}/${endpoint}/${id}`).then((r)=>{
|
getFetch(`/${application}/${endpoint}/${id}`).then((r)=>{
|
||||||
if (r.success){
|
if (r.success){
|
||||||
const pageData = r.body as T;
|
const pageData = r.body as T;
|
||||||
setData(pageData);
|
setData(pageData);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setData(null);
|
setData(undefined);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[data, application, endpoint, id]
|
[data, application, endpoint, id, needLoad]
|
||||||
)
|
)
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
// App.tsx
|
// App.tsx
|
||||||
import {BrowserRouter as Router, Routes, Route, Navigate, Link} from 'react-router-dom';
|
import {BrowserRouter as Router, Routes, Route, Navigate, Link} from 'react-router-dom';
|
||||||
import React from "react";
|
|
||||||
import {MainPage} from "./pages/MainPage.tsx";
|
import {MainPage} from "./pages/MainPage.tsx";
|
||||||
import {SurveyPage} from "./pages/SurveyPage.tsx";
|
import {SurveyPage} from "./pages/SurveyPage.tsx";
|
||||||
import {DashboardPage} from "./pages/DashboardPage.tsx";
|
import {DashboardPage} from "./pages/DashboardPage.tsx";
|
||||||
|
import { SurveyResultPage } from './pages/SurveyResultPage.tsx';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<MainPage/>}/>
|
<Route path="/" element={<MainPage/>}/>
|
||||||
|
<Route path="/surveys/results/:scoreVariableId/" element={<SurveyResultPage/>}/>
|
||||||
<Route path="/surveys/:surveyId/" element={<SurveyPage/>}/>
|
<Route path="/surveys/:surveyId/" element={<SurveyPage/>}/>
|
||||||
<Route path="/dashboard/" element={<DashboardPage/>}/>
|
<Route path="/dashboard/" element={<DashboardPage/>}/>
|
||||||
<Route path="*" element={<Navigate to="/"/>}/>
|
<Route path="*" element={<Navigate to="/"/>}/>
|
||||||
|
|||||||
@@ -132,11 +132,11 @@ function QuestionBlock({
|
|||||||
<div className={`question agreement ${answered !== undefined ? "answered" : "unanswered"}`}>
|
<div className={`question agreement ${answered !== undefined ? "answered" : "unanswered"}`}>
|
||||||
{agreementQuestion.question}
|
{agreementQuestion.question}
|
||||||
<button
|
<button
|
||||||
className={answered === 1 ? "selected" : ""}
|
className={`answer ${answered === 1 ? "selected" : "idle"}`}
|
||||||
disabled={answered===1}
|
disabled={answered===1}
|
||||||
onClick={() => onAnswer(`${question.questionType}_${question.id}`, 1)}>Согласен</button>
|
onClick={() => onAnswer(`${question.questionType}_${question.id}`, 1)}>Согласен</button>
|
||||||
<button
|
<button
|
||||||
className={answered === 0 ? "selected" : ""}
|
className={`answer ${answered === 0 ? "selected" : "idle"}`}
|
||||||
disabled={answered === 0}
|
disabled={answered === 0}
|
||||||
onClick={() => onAnswer(`${question.questionType}_${question.id}`, 0)}>Не согласен</button>
|
onClick={() => onAnswer(`${question.questionType}_${question.id}`, 0)}>Не согласен</button>
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ function QuestionBlock({
|
|||||||
<div className={`question pair ${answered !== undefined ? "answered" : "unanswered"}`}>
|
<div className={`question pair ${answered !== undefined ? "answered" : "unanswered"}`}>
|
||||||
{pairQuestion.statements.map((statement) => (
|
{pairQuestion.statements.map((statement) => (
|
||||||
<button
|
<button
|
||||||
className={answered === statement.id ? "selected" : ""}
|
className={`answer ${answered === statement.id ? "selected" : "idle"}`}
|
||||||
disabled={answered === statement.id}
|
disabled={answered === statement.id}
|
||||||
key={statement.id}
|
key={statement.id}
|
||||||
onClick={() => onAnswer(`${question.questionType}_${question.id}`, statement.id)}
|
onClick={() => onAnswer(`${question.questionType}_${question.id}`, statement.id)}
|
||||||
|
|||||||
31
src/pages/SurveyResultPage.tsx
Normal file
31
src/pages/SurveyResultPage.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useData } from '../API/common';
|
||||||
|
import { ScoreVariable, Survey } from '../types/survey';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import { LoadingData } from '../components/LoadingData';
|
||||||
|
|
||||||
|
export function SurveyResultPage() {
|
||||||
|
const { scoreVariableId } = useParams<{ scoreVariableId: string }>();
|
||||||
|
const scoreVariable = useData<ScoreVariable>('surveys', 'score-variables', scoreVariableId || 0);
|
||||||
|
const survey = useData<Survey>('surveys', 'surveys', scoreVariable?.survey || 0, !!scoreVariable);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<LoadingData data={survey && scoreVariable?null:scoreVariable}>
|
||||||
|
<h1>{survey?.title}</h1>
|
||||||
|
<div className={"result"}>
|
||||||
|
<h2>Ваш результат</h2>
|
||||||
|
<p>{scoreVariable?.title}</p>
|
||||||
|
</div>
|
||||||
|
<div className={"description"}>
|
||||||
|
<ReactMarkdown>{scoreVariable?.description}</ReactMarkdown>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>Подходящие профессии</h3>
|
||||||
|
<p>Здесь будет список профессий.</p>
|
||||||
|
</div>
|
||||||
|
</LoadingData>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -17,8 +17,7 @@ export enum QuestionType{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Question extends UniqueItem{
|
export interface Question extends UniqueItem{
|
||||||
questionType: QuestionType,
|
questionType: QuestionType
|
||||||
answer?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -39,5 +38,5 @@ export interface ScoreVariable {
|
|||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
survey: string;
|
survey: number;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user