Profession page init [AI]

This commit is contained in:
MikanD
2025-06-01 16:48:44 +03:00
parent 83af205e7e
commit 9c6272db25
4 changed files with 91 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ 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'; import { SurveyResultPage } from './pages/SurveyResultPage.tsx';
import { ProfessionPage } from './pages/ProfessionPage.tsx';
@@ -17,9 +18,10 @@ export default function App() {
<Routes> <Routes>
<Route path="/" element={<MainPage/>}/> <Route path="/" element={<MainPage/>}/>
<Route path="/surveys/results/:scoreVariableId/" element={<SurveyResultPage/>}/> <Route path="/surveys/results/:scoreVariableId/" element={<SurveyResultPage/>}/>
<Route path="/surveys/professions/:professionId/" element={<ProfessionPage/>}/>
<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="/"/>}/> */}
</Routes> </Routes>
</Router> </Router>
); );

View File

@@ -0,0 +1,78 @@
import { useParams } from 'react-router-dom';
import { 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';
export function ProfessionPage() {
const { professionId } = useParams<{ professionId: string }>();
const profession = useData<Profession>('surveys', 'professions', professionId || 0);
const specialties = useDataPage<Specialty>('surveys', 'specialties', { profession: professionId || 0 }, !!profession);
const [institutionCache, setInstitutionCache] = useState<Map<number, Institution>>(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<Institution>('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]);
return (
<div>
<LoadingData data={profession}>
<h1>{profession?.name}</h1>
<div className="description">
<ReactMarkdown>{profession?.description || ''}</ReactMarkdown>
</div>
<div className="specialties-block">
<h2>Где можно обучиться</h2>
<LoadingList
data={specialties.items}
listElement={(specialty) => (
<SpecialtyBlock
key={specialty.id}
specialty={specialty as Specialty}
institution={institutionCache.get((specialty as Specialty).institution)}
/>
)}
/>
</div>
</LoadingData>
</div>
);
}
function SpecialtyBlock({
specialty,
institution,
}: {
specialty: Specialty;
institution: Institution | undefined;
}) {
return (
<div className="specialty-block">
<h3>{specialty.name}</h3>
<p>Учебное заведение: {institution?.name || 'Загрузка...'}</p>
</div>
);
}

View File

@@ -17,8 +17,6 @@ export function SurveyResultPage() {
!!scoreVariable !!scoreVariable
); );
return ( return (
<div> <div>
<LoadingData data={survey && scoreVariable?survey:scoreVariable}> <LoadingData data={survey && scoreVariable?survey:scoreVariable}>

View File

@@ -45,3 +45,13 @@ export interface Profession extends UniqueItem {
name: string; name: string;
description: string; description: string;
} }
export interface Specialty extends UniqueItem {
name: string;
institution: number;
profession: number;
}
export interface Institution extends UniqueItem {
name: string;
}