Profession page init [AI]
This commit is contained in:
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
78
src/pages/ProfessionPage.tsx
Normal file
78
src/pages/ProfessionPage.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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}>
|
||||||
|
|||||||
@@ -44,4 +44,14 @@ export interface ScoreVariable {
|
|||||||
export interface Profession extends UniqueItem {
|
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;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user