US-015: Modify EducationTile: richer content, panel trigger

- Show richer inline content: MPharm research score (75.1%), Mary Seacole score (78%), A-level grades
- Each education entry is now clickable -> opens detail panel
- Hover state: border color shift to teal with shadow deepening
- Use documents data from documents.ts for accurate content
- Maintains existing visual hierarchy and spacing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 23:59:54 +00:00
parent 9ed77f99a8
commit 03b4c6cafb
+114 -43
View File
@@ -1,63 +1,134 @@
import { useState } from 'react'
import { Card, CardHeader } from '../Card' import { Card, CardHeader } from '../Card'
import { useDetailPanel } from '@/contexts/DetailPanelContext'
import { documents } from '@/data/documents'
/** /**
* Education tile - displays academic qualifications * Education tile - displays academic qualifications
* Full-width card below Career Activity * Full-width card below Career Activity
* Each entry is clickable to open detail panel
*/ */
export function EducationTile() { export function EducationTile() {
// Education entries from CV, presented in reverse chronological order const { openPanel } = useDetailPanel()
const educationEntries = [ const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
{
degree: 'MPharm (Hons) — 2:1', // Filter to main education entries in reverse chronological order
detail: 'University of East Anglia · 2015', const educationDocuments = [
}, documents.find((d) => d.id === 'doc-mary-seacole')!,
{ documents.find((d) => d.id === 'doc-mpharm')!,
degree: 'NHS Leadership Academy — Mary Seacole Programme', documents.find((d) => d.id === 'doc-alevels')!,
detail: '2018 · 78%',
},
{
degree: 'A-Levels: Mathematics (A*), Chemistry (B), Politics (C)',
detail: 'Highworth Grammar School · 20092011',
},
] ]
// Build rich inline content for each entry
const getInlineContent = (doc: typeof educationDocuments[0]) => {
switch (doc.id) {
case 'doc-mpharm':
return {
title: 'MPharm (Hons) — 2:1',
institution: 'University of East Anglia',
year: '2015',
extra: 'Research project: 75.1% (Distinction)',
}
case 'doc-mary-seacole':
return {
title: 'NHS Leadership Academy — Mary Seacole Programme',
institution: 'NHS Leadership Academy',
year: '2018',
extra: 'Programme score: 78%',
}
case 'doc-alevels':
return {
title: 'A-Levels',
institution: 'Highworth Grammar School',
year: '20092011',
extra: 'Mathematics A* · Chemistry B · Politics C',
}
default:
return {
title: doc.title,
institution: doc.institution,
year: doc.date,
extra: doc.classification,
}
}
}
return ( return (
<Card full tileId="education"> <Card full tileId="education">
<CardHeader dotColor="purple" title="EDUCATION" /> <CardHeader dotColor="purple" title="EDUCATION" />
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
{educationEntries.map((entry, index) => ( {educationDocuments.map((doc, index) => {
<div const content = getInlineContent(doc)
key={index} const isHovered = hoveredIndex === index
style={{
padding: '7px 10px', return (
background: 'var(--surface)', <button
border: '1px solid var(--border-light)', key={doc.id}
borderRadius: 'var(--radius-sm)', onClick={() => openPanel({ type: 'education', document: doc })}
fontSize: '11.5px', onMouseEnter={() => setHoveredIndex(index)}
color: 'var(--text-primary)', onMouseLeave={() => setHoveredIndex(null)}
}}
>
<span
style={{ style={{
display: 'block', padding: '10px 12px',
fontWeight: 600, background: 'var(--surface)',
border: `1px solid ${isHovered ? 'var(--accent)' : 'var(--border-light)'}`,
borderRadius: 'var(--radius-sm)',
fontSize: '12px',
color: 'var(--text-primary)',
cursor: 'pointer',
textAlign: 'left',
transition: 'border-color 150ms ease-out, box-shadow 150ms ease-out',
boxShadow: isHovered
? '0 2px 8px rgba(26,43,42,0.08)'
: '0 1px 2px rgba(26,43,42,0.05)',
}} }}
> >
{entry.degree} <div
</span> style={{
<span display: 'flex',
style={{ justifyContent: 'space-between',
color: 'var(--text-secondary)', alignItems: 'baseline',
fontSize: '11px', gap: '12px',
marginTop: '2px', marginBottom: '4px',
display: 'block', }}
}} >
> <span style={{ fontWeight: 600, fontSize: '12.5px' }}>
{entry.detail} {content.title}
</span> </span>
</div> <span
))} style={{
fontFamily: 'var(--font-geist-mono)',
fontSize: '10px',
color: 'var(--text-tertiary)',
whiteSpace: 'nowrap',
}}
>
{content.year}
</span>
</div>
<div
style={{
color: 'var(--text-secondary)',
fontSize: '11px',
marginBottom: '4px',
}}
>
{content.institution}
</div>
{content.extra && (
<div
style={{
color: 'var(--text-tertiary)',
fontSize: '10.5px',
fontFamily: 'var(--font-geist-mono)',
}}
>
{content.extra}
</div>
)}
</button>
)
})}
</div> </div>
</Card> </Card>
) )