diff --git a/src/API/common.ts b/src/API/common.ts index 8931fd6..3ad575d 100644 --- a/src/API/common.ts +++ b/src/API/common.ts @@ -1,7 +1,8 @@ -import {useEffect, useState} from "react"; +import {useEffect, useMemo, useState} from "react"; import {DEBUG_MODE} from "../utils/common"; import {ApiResponse, PageResponse} from "../types/api.ts"; import {PageControl} from "../types/common.ts"; +import {Institution} from "../types/survey.ts"; export function hostUrl(url: string){ return DEBUG_MODE? "http://localhost:8000"+url: url; @@ -144,3 +145,43 @@ export function useData(application:string, endpoint: string, id: string|numb } +export function useCachedData(application: string, endpoint: string) { + const [cache, setCache] = useState>(new Map()); + + useEffect(() => { + // Очистка кеша или другие побочные эффекты при необходимости + return () => { + setCache(new Map()); + }; + }, []); + + return (id: string | number, needLoad: boolean = true): T | undefined | null => { + const cachedData = cache.has(id)?cache.get(id):null; + + if (cachedData !== null) { + return cachedData; + } + + if (needLoad) { + getFetch(`/${application}/${endpoint}/${id}`).then((r) => { + if (r.success) { + const data = r.body as T; + setCache((prevCache) => { + const newCache = new Map(prevCache); + newCache.set(id, data); + return newCache; + }); + } else { + setCache((prevCache) => { + const newCache = new Map(prevCache); + newCache.set(id, undefined); + return newCache; + }); + } + }); + } + + return null; + }; +} + diff --git a/src/components/LoadingList.tsx b/src/components/LoadingList.tsx index 8da8db8..f1d9986 100644 --- a/src/components/LoadingList.tsx +++ b/src/components/LoadingList.tsx @@ -1,7 +1,7 @@ -import {ReactElement} from "react"; import {UniqueItem} from "../types/common.ts"; +import {JSX} from "react"; -export function LoadingList({data, listElement}: {data: UniqueItem[]|null, listElement(e:UniqueItem, i:number):ReactElement}) { +export function LoadingList({data, listElement}: {data: UniqueItem[]|null, listElement(e:UniqueItem, i:number):unknown}) { if (data === null){ return
Идёт загрузка...
} diff --git a/src/pages/ProfessionPage.tsx b/src/pages/ProfessionPage.tsx index 776f375..ff0c2a1 100644 --- a/src/pages/ProfessionPage.tsx +++ b/src/pages/ProfessionPage.tsx @@ -1,9 +1,8 @@ -import { useParams } from 'react-router-dom'; -import { useData, useDataPage } from '../API/common'; +import {Link, useParams} from 'react-router-dom'; +import {useCachedData, useData, useDataPage} from '../API/common'; import { Institution, Profession, Specialty } from '../types/survey'; import ReactMarkdown from 'react-markdown'; import { LoadingData } from '../components/LoadingData'; -import { useEffect, useMemo, useState } from 'react'; import { LoadingList } from '../components/LoadingList'; @@ -13,29 +12,7 @@ export function ProfessionPage() { const profession = useData('surveys', 'professions', professionId || 0); const specialties = useDataPage('surveys', 'specialties', { profession: professionId || 0 }, !!profession); - const [institutionCache, setInstitutionCache] = useState>(new Map()); // Кеширование учебных заведений - const institutionsToLoad = useMemo(() => { - if (!specialties.items) return []; - return specialties.items - .map(specialty => specialty.institution) - .filter(id => !institutionCache.has(id)); - }, [specialties.items, institutionCache]); - - useEffect(() => { - if (institutionsToLoad.length > 0) { - Promise.all( - institutionsToLoad.map(id => - useData('surveys', 'institutions', id, true) - ) - ).then(newInstitutions => { - setInstitutionCache(prev => { - const newCache = new Map(prev); - newInstitutions.forEach(institution => institution && newCache.set(institution.id, institution)); - return newCache; - }); - }); - } - }, [institutionsToLoad]); + const institutions = useCachedData("surveys", "institutions"); return (
@@ -45,14 +22,14 @@ export function ProfessionPage() { {profession?.description || ''}
-

Где можно обучиться

+ {specialties.items != null ?

Где можно обучиться

:null} ( + listElement={specialty => ( )} /> @@ -67,12 +44,14 @@ function SpecialtyBlock({ institution, }: { specialty: Specialty; - institution: Institution | undefined; + institution: Institution | undefined | null; }) { return (
-

{specialty.name}

-

Учебное заведение: {institution?.name || 'Загрузка...'}

+

Учебное заведение: {institution?.name || 'Загрузка...'}

+

{specialty.name}

+ {specialty.link?Открыть сайт:null} +
); } \ No newline at end of file diff --git a/src/pages/SurveyPage.tsx b/src/pages/SurveyPage.tsx index c9bb587..60d2e12 100644 --- a/src/pages/SurveyPage.tsx +++ b/src/pages/SurveyPage.tsx @@ -106,9 +106,11 @@ export function SurveyPage() { /> )} /> - {isCompleted && ( - - )} + <> + {isCompleted && ( + + )} +
); @@ -125,7 +127,7 @@ function QuestionBlock({ }) { switch (question.questionType) { case QuestionType.AgreementQuestion: - const agreementQuestion = question as AgreementQuestion; + { const agreementQuestion = question as AgreementQuestion; return (
{agreementQuestion.question} @@ -139,10 +141,10 @@ function QuestionBlock({ onClick={() => onAnswer(`${question.questionType}_${question.id}`, 0)}>Не согласен
- ); + ); } case QuestionType.QuestionPair: - const pairQuestion = question as QuestionPair; + { const pairQuestion = question as QuestionPair; return (
{pairQuestion.statements.map((statement) => ( @@ -156,7 +158,7 @@ function QuestionBlock({ ))}
- ); + ); } default: return null; diff --git a/src/types/common.ts b/src/types/common.ts index 33bb8c1..2631507 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -9,4 +9,8 @@ export interface PageControl{ hasPrevious: boolean; nextPage(): void; previousPage(): void; -} \ No newline at end of file +} + +export interface CachedData{ + +} diff --git a/src/types/survey.ts b/src/types/survey.ts index e270f5e..15c1c3d 100644 --- a/src/types/survey.ts +++ b/src/types/survey.ts @@ -49,7 +49,7 @@ export interface Profession extends UniqueItem { export interface Specialty extends UniqueItem { name: string; institution: number; - profession: number; + link?: string; } export interface Institution extends UniqueItem {