US-022: Create EducationDetail renderer for detail panel

This commit is contained in:
2026-02-14 02:37:42 +00:00
parent a5deb0ea8b
commit 2f8db26cc4
2 changed files with 239 additions and 1 deletions
+4 -1
View File
@@ -8,6 +8,7 @@ import { KPIDetail } from './detail/KPIDetail'
import { ConsultationDetail } from './detail/ConsultationDetail' import { ConsultationDetail } from './detail/ConsultationDetail'
import { SkillDetail } from './detail/SkillDetail' import { SkillDetail } from './detail/SkillDetail'
import { SkillsAllDetail } from './detail/SkillsAllDetail' import { SkillsAllDetail } from './detail/SkillsAllDetail'
import { EducationDetail } from './detail/EducationDetail'
// Width mapping from content type // Width mapping from content type
const widthMap: Record<DetailPanelContent['type'], 'narrow' | 'wide'> = { const widthMap: Record<DetailPanelContent['type'], 'narrow' | 'wide'> = {
@@ -219,13 +220,15 @@ export function DetailPanel() {
{content.type === 'skill' && <SkillDetail skill={content.skill} />} {content.type === 'skill' && <SkillDetail skill={content.skill} />}
{content.type === 'skills-all' && <SkillsAllDetail category={content.category} />} {content.type === 'skills-all' && <SkillsAllDetail category={content.category} />}
{content.type === 'education' && <EducationDetail document={content.document} />}
{/* Other content types - placeholder for future stories */} {/* Other content types - placeholder for future stories */}
{content.type !== 'kpi' && {content.type !== 'kpi' &&
content.type !== 'consultation' && content.type !== 'consultation' &&
content.type !== 'career-role' && content.type !== 'career-role' &&
content.type !== 'skill' && content.type !== 'skill' &&
content.type !== 'skills-all' && ( content.type !== 'skills-all' &&
content.type !== 'education' && (
<div <div
style={{ style={{
fontFamily: 'var(--font-ui)', fontFamily: 'var(--font-ui)',
+235
View File
@@ -0,0 +1,235 @@
import { GraduationCap, Award, BookOpen, FlaskConical, type LucideIcon } from 'lucide-react'
import type { Document } from '@/types/pmr'
import { educationExtras } from '@/data/educationExtras'
interface EducationDetailProps {
document: Document
}
const sectionHeaderStyle: React.CSSProperties = {
fontSize: '12px',
fontWeight: 600,
color: 'var(--text-secondary)',
textTransform: 'uppercase',
letterSpacing: '0.05em',
marginBottom: '8px',
}
const typeIconMap: Record<string, LucideIcon> = {
Certificate: GraduationCap,
Registration: Award,
Results: BookOpen,
Research: FlaskConical,
}
export function EducationDetail({ document }: EducationDetailProps) {
const extra = educationExtras.find((e) => e.documentId === document.id)
const Icon = typeIconMap[document.type] || GraduationCap
return (
<div
style={{
fontFamily: 'var(--font-ui)',
display: 'flex',
flexDirection: 'column',
gap: '24px',
}}
>
{/* Header */}
<div>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
marginBottom: '8px',
}}
>
<div
style={{
width: '36px',
height: '36px',
borderRadius: 'var(--radius-sm)',
backgroundColor: 'var(--purple-light, rgba(124,58,237,0.08))',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
}}
>
<Icon size={18} />
</div>
<div>
<div
style={{
fontSize: '20px',
fontWeight: 700,
color: 'var(--text-primary)',
lineHeight: '1.3',
}}
>
{document.title}
</div>
</div>
</div>
{document.institution && (
<div
style={{
fontSize: '14px',
fontWeight: 600,
color: '#7C3AED',
marginBottom: '4px',
}}
>
{document.institution}
</div>
)}
<div
style={{
fontSize: '12px',
fontFamily: 'var(--font-geist)',
color: 'var(--text-tertiary)',
display: 'flex',
alignItems: 'center',
gap: '8px',
}}
>
{document.duration && <span>{document.duration}</span>}
{document.classification && (
<span
style={{
padding: '2px 8px',
backgroundColor: 'var(--purple-light, rgba(124,58,237,0.08))',
color: '#7C3AED',
fontSize: '10px',
fontWeight: 600,
borderRadius: 'var(--radius-sm)',
}}
>
{document.classification}
</span>
)}
</div>
</div>
{/* Research project (MPharm) */}
{extra?.researchDescription && (
<div>
<h3 style={sectionHeaderStyle}>Research Project</h3>
<p
style={{
fontSize: '14px',
lineHeight: '1.6',
color: 'var(--text-primary)',
margin: 0,
}}
>
{extra.researchDescription}
</p>
</div>
)}
{/* OSCE score (MPharm) */}
{extra?.osceScore && (
<div>
<h3 style={sectionHeaderStyle}>OSCE Performance</h3>
<div
style={{
display: 'inline-flex',
alignItems: 'center',
gap: '8px',
padding: '8px 14px',
backgroundColor: 'var(--success-light)',
border: '1px solid var(--success-border)',
borderRadius: 'var(--radius-sm)',
}}
>
<span
style={{
fontSize: '20px',
fontWeight: 700,
color: 'var(--success)',
}}
>
{extra.osceScore}
</span>
<span
style={{
fontSize: '12px',
color: 'var(--text-secondary)',
}}
>
Objective Structured Clinical Examination
</span>
</div>
</div>
)}
{/* Extracurricular activities (MPharm) */}
{extra?.extracurriculars && extra.extracurriculars.length > 0 && (
<div>
<h3 style={sectionHeaderStyle}>Extracurricular Activities</h3>
<ul
style={{
margin: 0,
paddingLeft: '20px',
display: 'flex',
flexDirection: 'column',
gap: '8px',
}}
>
{extra.extracurriculars.map((activity, index) => (
<li
key={index}
style={{
fontSize: '14px',
lineHeight: '1.6',
color: 'var(--text-primary)',
}}
>
{activity}
</li>
))}
</ul>
</div>
)}
{/* Programme detail (Mary Seacole) */}
{extra?.programmeDetail && (
<div>
<h3 style={sectionHeaderStyle}>Programme Overview</h3>
<p
style={{
fontSize: '14px',
lineHeight: '1.6',
color: 'var(--text-primary)',
margin: 0,
}}
>
{extra.programmeDetail}
</p>
</div>
)}
{/* Notes */}
{document.notes && (
<div>
<h3 style={sectionHeaderStyle}>Notes</h3>
<p
style={{
fontSize: '14px',
lineHeight: '1.6',
color: 'var(--text-secondary)',
margin: 0,
fontStyle: 'italic',
}}
>
{document.notes}
</p>
</div>
)}
</div>
)
}