timeline improvements

This commit is contained in:
Harivansh Rathi 2024-12-04 18:19:38 -05:00
parent 34516c0aa5
commit cfcb36222d
2 changed files with 295 additions and 265 deletions

View file

@ -10,12 +10,12 @@ interface Props {
// Define major time periods with matching category colors // Define major time periods with matching category colors
const timePeriods = [ const timePeriods = [
{ start: 1775, end: 1785, name: 'Early Life', color: 'primary.50' }, { start: 1775, end: 1785, name: 'Early Life', color: 'rgba(74, 93, 82, 0.1)' },
{ start: 1786, end: 1800, name: 'Juvenilia & Early Drafts', color: 'primary.100' }, { start: 1786, end: 1800, name: 'Juvenilia & Early Drafts', color: 'rgba(74, 93, 82, 0.15)' },
{ start: 1801, end: 1817, name: 'Publication Years', color: 'primary.200' }, { start: 1801, end: 1817, name: 'Publication Years', color: 'rgba(74, 93, 82, 0.2)' },
{ start: 1818, end: 1900, name: 'Victorian Reception', color: 'warning.50' }, { start: 1818, end: 1900, name: 'Victorian Reception', color: 'rgba(74, 93, 82, 0.25)' },
{ start: 1901, end: 2000, name: '20th Century', color: 'success.50' }, { start: 1901, end: 2000, name: '20th Century', color: 'rgba(74, 93, 82, 0.3)' },
{ start: 2001, end: new Date().getFullYear(), name: 'Contemporary', color: 'success.100' } { start: 2001, end: new Date().getFullYear(), name: 'Contemporary', color: 'rgba(74, 93, 82, 0.35)' }
]; ];
// Timeline data focused on course texts and their context // Timeline data focused on course texts and their context
@ -307,15 +307,25 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
const getEventColor = (type: string) => { const getEventColor = (type: string) => {
switch (type) { switch (type) {
case 'works': case 'works':
return { main: 'primary.main', light: 'primary.50' }; return {
main: '#4A5D52',
light: '#E5E9E7'
};
case 'context': case 'context':
return { main: 'secondary.main', light: 'secondary.50' }; return {
main: '#5B6E65',
light: '#D5DCD8'
};
case 'legacy': case 'legacy':
return { main: 'warning.main', light: 'warning.50' }; return {
case 'adaptations': main: '#6B7F75',
return { main: 'success.main', light: 'success.50' }; light: '#C5CEC9'
default: };
return { main: 'grey.500', light: 'grey.50' }; default: // adaptations
return {
main: '#7C8F86',
light: '#B5C0BA'
};
} }
}; };
@ -351,11 +361,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
onClick={() => toggleFilter('works')} onClick={() => toggleFilter('works')}
variant={activeFilters.includes('works') ? 'contained' : 'outlined'} variant={activeFilters.includes('works') ? 'contained' : 'outlined'}
sx={{ sx={{
color: activeFilters.includes('works') ? 'white' : 'primary.main', color: activeFilters.includes('works') ? 'white' : 'sage.700',
borderColor: 'primary.main', borderColor: 'sage.300',
bgcolor: activeFilters.includes('works') ? '#4A5D52' : 'transparent',
'&:hover': { '&:hover': {
borderColor: 'primary.dark', borderColor: 'sage.400',
bgcolor: activeFilters.includes('works') ? 'primary.dark' : 'primary.50' bgcolor: activeFilters.includes('works') ? '#3A4D42' : 'sage.50'
} }
}} }}
> >
@ -365,12 +376,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
onClick={() => toggleFilter('context')} onClick={() => toggleFilter('context')}
variant={activeFilters.includes('context') ? 'contained' : 'outlined'} variant={activeFilters.includes('context') ? 'contained' : 'outlined'}
sx={{ sx={{
color: activeFilters.includes('context') ? 'white' : 'secondary.main', color: activeFilters.includes('context') ? 'white' : 'sage.700',
borderColor: 'secondary.main', borderColor: 'sage.300',
bgcolor: activeFilters.includes('context') ? 'secondary.main' : 'transparent', bgcolor: activeFilters.includes('context') ? '#5B6E65' : 'transparent',
'&:hover': { '&:hover': {
borderColor: 'secondary.dark', borderColor: 'sage.400',
bgcolor: activeFilters.includes('context') ? 'secondary.dark' : 'secondary.50' bgcolor: activeFilters.includes('context') ? '#4B5E55' : 'sage.50'
} }
}} }}
> >
@ -380,12 +391,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
onClick={() => toggleFilter('legacy')} onClick={() => toggleFilter('legacy')}
variant={activeFilters.includes('legacy') ? 'contained' : 'outlined'} variant={activeFilters.includes('legacy') ? 'contained' : 'outlined'}
sx={{ sx={{
color: activeFilters.includes('legacy') ? 'white' : 'warning.main', color: activeFilters.includes('legacy') ? 'white' : 'sage.700',
borderColor: 'warning.main', borderColor: 'sage.300',
bgcolor: activeFilters.includes('legacy') ? 'warning.main' : 'transparent', bgcolor: activeFilters.includes('legacy') ? '#6B7F75' : 'transparent',
'&:hover': { '&:hover': {
borderColor: 'warning.dark', borderColor: 'sage.400',
bgcolor: activeFilters.includes('legacy') ? 'warning.dark' : 'warning.50' bgcolor: activeFilters.includes('legacy') ? '#5B6F65' : 'sage.50'
} }
}} }}
> >
@ -395,12 +406,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
onClick={() => toggleFilter('adaptations')} onClick={() => toggleFilter('adaptations')}
variant={activeFilters.includes('adaptations') ? 'contained' : 'outlined'} variant={activeFilters.includes('adaptations') ? 'contained' : 'outlined'}
sx={{ sx={{
color: activeFilters.includes('adaptations') ? 'white' : 'success.main', color: activeFilters.includes('adaptations') ? 'white' : 'sage.700',
borderColor: 'success.main', borderColor: 'sage.300',
bgcolor: activeFilters.includes('adaptations') ? 'success.main' : 'transparent', bgcolor: activeFilters.includes('adaptations') ? '#7C8F86' : 'transparent',
'&:hover': { '&:hover': {
borderColor: 'success.dark', borderColor: 'sage.400',
bgcolor: activeFilters.includes('adaptations') ? 'success.dark' : 'success.50' bgcolor: activeFilters.includes('adaptations') ? '#6C7F76' : 'sage.50'
} }
}} }}
> >
@ -411,14 +422,14 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
{/* Timeline Container */} {/* Timeline Container */}
<Box sx={{ position: 'relative', mt: 6 }}> <Box sx={{ position: 'relative', mt: 6 }}>
{/* Navigation Buttons Container */} {/* Navigation Buttons */}
<Box <Box
sx={{ sx={{
position: 'absolute', position: 'absolute',
top: 200, // Half of the timeline height (400px) top: 200,
left: 0, left: 0,
right: 0, right: 0,
height: 0, // Zero height to not affect layout height: 0,
pointerEvents: 'none', pointerEvents: 'none',
zIndex: 3 zIndex: 3
}} }}
@ -431,19 +442,21 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
top: '50%', top: '50%',
transform: 'translate(-50%, -50%)', transform: 'translate(-50%, -50%)',
zIndex: 3, zIndex: 3,
bgcolor: 'background.paper', bgcolor: 'white',
border: '1px solid', border: '1px solid',
borderColor: 'divider', borderColor: 'sage.200',
boxShadow: theme => `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`, boxShadow: theme => `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`,
width: 40, width: 40,
height: 40, height: 40,
pointerEvents: 'auto', pointerEvents: 'auto',
color: 'sage.700',
'&:hover': { '&:hover': {
bgcolor: 'grey.50', bgcolor: 'sage.50',
borderColor: 'sage.300',
boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}` boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}`
}, },
'&:active': { '&:active': {
bgcolor: 'grey.100' bgcolor: 'sage.100'
} }
}} }}
> >
@ -457,19 +470,21 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
top: '50%', top: '50%',
transform: 'translate(50%, -50%)', transform: 'translate(50%, -50%)',
zIndex: 3, zIndex: 3,
bgcolor: 'background.paper', bgcolor: 'white',
border: '1px solid', border: '1px solid',
borderColor: 'divider', borderColor: 'sage.200',
boxShadow: theme => `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`, boxShadow: theme => `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`,
width: 40, width: 40,
height: 40, height: 40,
pointerEvents: 'auto', pointerEvents: 'auto',
color: 'sage.700',
'&:hover': { '&:hover': {
bgcolor: 'grey.50', bgcolor: 'sage.50',
borderColor: 'sage.300',
boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}` boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}`
}, },
'&:active': { '&:active': {
bgcolor: 'grey.100' bgcolor: 'sage.100'
} }
}} }}
> >
@ -508,18 +523,17 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
display: 'inline-block', display: 'inline-block',
bgcolor: period.color, bgcolor: period.color,
border: '1px solid', border: '1px solid',
borderColor: 'divider', borderColor: 'sage.200',
px: 2, px: 2,
py: 0.5, py: 0.5,
borderRadius: '16px', borderRadius: '16px',
whiteSpace: 'nowrap', whiteSpace: 'nowrap'
fontFamily: 'cormorant',
}} }}
> >
<Typography <Typography
variant="caption" variant="caption"
className="font-cormorant text-sage-800"
sx={{ sx={{
color: theme => theme.palette.text.primary,
fontWeight: 500, fontWeight: 500,
fontSize: '0.875rem' fontSize: '0.875rem'
}} }}
@ -538,8 +552,10 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
sx={{ sx={{
position: 'relative', position: 'relative',
height: 400, height: 400,
bgcolor: 'background.paper', bgcolor: 'white',
borderRadius: 4, borderRadius: 4,
border: '1px solid',
borderColor: 'sage.200',
boxShadow: theme => `0 2px 12px ${alpha(theme.palette.common.black, 0.08)}`, boxShadow: theme => `0 2px 12px ${alpha(theme.palette.common.black, 0.08)}`,
overflow: 'hidden', overflow: 'hidden',
cursor: 'pointer', cursor: 'pointer',
@ -558,12 +574,11 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
bgcolor: 'sage.400', bgcolor: 'sage.400',
borderRadius: 4, borderRadius: 4,
border: '2px solid', border: '2px solid',
borderColor: 'background.paper', borderColor: 'white',
'&:hover': { '&:hover': {
bgcolor: 'sage.500' bgcolor: 'sage.500'
} }
}, }
scrollBehavior: 'smooth'
}} }}
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove} onMouseMove={handleMouseMove}
@ -571,24 +586,25 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
onMouseLeave={handleMouseLeave} onMouseLeave={handleMouseLeave}
> >
<Box sx={{ width: '300%', height: '100%', position: 'relative' }}> <Box sx={{ width: '300%', height: '100%', position: 'relative' }}>
{/* Time Period Backgrounds */} {/* Single Continuous Background */}
{timePeriods.map((period) => { <Box
const startPos = ((period.start - actualMinYear) / timeSpan) * 100; sx={{
const width = ((period.end - period.start) / timeSpan) * 100; position: 'absolute',
return ( left: 0,
<Box right: 0,
key={period.name} top: 0,
sx={{ bottom: 0,
position: 'absolute', background: `linear-gradient(to right,
left: `${startPos}%`, rgba(74, 93, 82, 0.1) 0%,
width: `${width}%`, rgba(74, 93, 82, 0.15) 20%,
height: '100%', rgba(74, 93, 82, 0.2) 40%,
bgcolor: period.color, rgba(74, 93, 82, 0.25) 60%,
opacity: 0.5 rgba(74, 93, 82, 0.3) 80%,
}} rgba(74, 93, 82, 0.35) 100%
/> )`,
); zIndex: 0
})} }}
/>
{/* Year Markers */} {/* Year Markers */}
<Box sx={{ <Box sx={{
@ -598,7 +614,7 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
right: 0, right: 0,
height: 40, height: 40,
display: 'flex', display: 'flex',
zIndex: 2 zIndex: 1
}}> }}>
{yearMarkers.map((year) => { {yearMarkers.map((year) => {
const isDecade = year % 10 === 0; const isDecade = year % 10 === 0;
@ -611,29 +627,24 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
transform: 'translateX(-50%)', transform: 'translateX(-50%)',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center' alignItems: 'center',
zIndex: 1
}} }}
> >
<Box sx={{ <Box sx={{
width: isDecade ? 2 : 1, width: isDecade ? 2 : 1,
height: isDecade ? 10 : 6, height: isDecade ? 10 : 6,
bgcolor: isDecade ? 'primary.main' : 'text.secondary', bgcolor: isDecade ? 'sage.700' : 'sage.500',
opacity: isDecade ? 0.8 : 0.5 opacity: isDecade ? 0.8 : 0.5
}} /> }} />
<Typography <Typography
variant="caption" variant="caption"
sx={{ sx={{
color: isDecade ? 'primary.main' : 'text.secondary', color: isDecade ? 'sage.800' : 'sage.600',
mt: 0.5, mt: 0.5,
fontWeight: isDecade ? 600 : 400, fontWeight: isDecade ? 600 : 400,
bgcolor: 'rgba(255, 255, 255, 0.9)',
px: 1,
py: 0.25,
borderRadius: 1,
fontSize: isDecade ? '0.75rem' : '0.7rem', fontSize: isDecade ? '0.75rem' : '0.7rem',
boxShadow: isDecade ? '0 1px 3px rgba(0,0,0,0.1)' : 'none', backgroundColor: 'transparent'
border: isDecade ? '1px solid' : 'none',
borderColor: 'primary.100'
}} }}
> >
{year} {year}
@ -643,18 +654,40 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
})} })}
</Box> </Box>
{/* Timeline Base Line */} {/* Timeline Base Lines */}
<Box <Box
sx={{ sx={{
position: 'absolute', position: 'absolute',
top: '50%', top: '50%',
left: 0, left: 0,
right: 0, right: 0,
height: 2, display: 'flex',
bgcolor: 'grey.300', flexDirection: 'column',
transform: 'translateY(-50%)' alignItems: 'center',
transform: 'translateY(-50%)',
zIndex: 1
}} }}
/> >
{/* White line */}
<Box
sx={{
width: '100%',
height: 2,
bgcolor: 'white',
position: 'absolute'
}}
/>
{/* Sage line */}
<Box
sx={{
width: '100%',
height: 1,
bgcolor: 'sage.300',
opacity: 0.5,
position: 'absolute'
}}
/>
</Box>
{/* Events */} {/* Events */}
{filteredEvents.map((event, index) => { {filteredEvents.map((event, index) => {
@ -673,11 +706,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
left: `${position}%`, left: `${position}%`,
top: `${verticalPosition}%`, top: `${verticalPosition}%`,
transform: 'translate(-50%, -50%)', transform: 'translate(-50%, -50%)',
zIndex: isSelected ? 2 : 1, zIndex: isSelected ? 10 : 5,
transition: 'all 0.3s ease', transition: 'all 0.3s ease',
cursor: 'pointer', cursor: 'pointer',
'&:hover': { '&:hover': {
transform: 'translate(-50%, -50%) scale(1.1)' transform: 'translate(-50%, -50%) scale(1.1)',
zIndex: 15
} }
}} }}
> >
@ -835,53 +869,48 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props)
{/* Event Details Section */} {/* Event Details Section */}
{selectedEvent && ( {selectedEvent && (
<Paper <Paper
elevation={0}
sx={{ sx={{
p: 4, p: 4,
mt: 4, mt: 4,
bgcolor: 'background.paper', bgcolor: 'white',
borderRadius: 2, borderRadius: 2,
boxShadow: 2,
transition: 'all 0.3s ease',
border: '1px solid', border: '1px solid',
borderColor: 'divider' borderColor: 'sage.200',
transition: 'all 0.3s ease'
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 2 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 2 }}>
<Box> <Box>
<Typography variant="h5" gutterBottom color="primary"> <Typography variant="h5" gutterBottom className="font-cormorant text-sage-900">
{selectedEvent.title} {selectedEvent.title}
</Typography> </Typography>
<Typography variant="subtitle1" color="text.secondary"> <Typography variant="subtitle1" className="text-sage-600">
{selectedEvent.year} {selectedEvent.year}
</Typography> </Typography>
</Box> </Box>
<Chip <Chip
label={selectedEvent.type.charAt(0).toUpperCase() + selectedEvent.type.slice(1)} label={selectedEvent.type.charAt(0).toUpperCase() + selectedEvent.type.slice(1)}
color={
selectedEvent.type === 'works'
? 'primary'
: selectedEvent.type === 'context'
? 'secondary'
: selectedEvent.type === 'legacy'
? 'warning'
: 'success'
}
size="small" size="small"
sx={{
bgcolor: getEventColor(selectedEvent.type).main,
color: 'white'
}}
/> />
</Box> </Box>
<Divider sx={{ my: 2 }} /> <Divider sx={{ my: 2, borderColor: 'sage.200' }} />
<Typography variant="body1" paragraph> <Typography variant="body1" paragraph className="text-sage-700">
{selectedEvent.description} {selectedEvent.description}
</Typography> </Typography>
{selectedEvent.significance && ( {selectedEvent.significance && (
<Box sx={{ mt: 2, p: 2, bgcolor: 'grey.50', borderRadius: 1 }}> <Box sx={{ mt: 2, p: 2, bgcolor: 'sage.50', borderRadius: 1, border: '1px solid', borderColor: 'sage.200' }}>
<Typography variant="subtitle2" color="text.secondary" gutterBottom> <Typography variant="subtitle2" className="text-sage-800 font-cormorant" gutterBottom>
Historical Significance Historical Significance
</Typography> </Typography>
<Typography variant="body2" color="text.secondary"> <Typography variant="body2" className="text-sage-600">
{selectedEvent.significance} {selectedEvent.significance}
</Typography> </Typography>
</Box> </Box>

View file

@ -1,42 +1,16 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Box, Typography, Paper, Grid, Chip, IconButton, Tooltip, Tabs, Tab } from '@mui/material'; import { Box, Typography, Paper, Grid, Chip } from '@mui/material';
import { Help } from '@mui/icons-material';
import { TimelineEvent } from '../types/timeline'; import { TimelineEvent } from '../types/timeline';
import InteractiveTimeline from '../components/timeline/InteractiveTimeline'; import InteractiveTimeline from '../components/timeline/InteractiveTimeline';
import {
interface TabPanelProps { Tabs,
children?: React.ReactNode; TabsContent,
index: number; TabsList,
value: number; TabsTrigger,
} } from "../components/ui/tabs";
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`timeline-tabpanel-${index}`}
aria-labelledby={`timeline-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ py: 3 }}>
{children}
</Box>
)}
</div>
);
}
export default function Timeline() { export default function Timeline() {
const [selectedType, setSelectedType] = useState<'all' | 'works' | 'context' | 'legacy' | 'adaptations'>('all'); const [selectedType, setSelectedType] = useState<'all' | 'works' | 'context' | 'legacy' | 'adaptations'>('all');
const [tabValue, setTabValue] = useState(0);
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
setTabValue(newValue);
};
// Timeline data focused on course texts and their context // Timeline data focused on course texts and their context
const timelineEvents: TimelineEvent[] = [ const timelineEvents: TimelineEvent[] = [
@ -184,139 +158,166 @@ export default function Timeline() {
.sort((a, b) => a.year - b.year); .sort((a, b) => a.year - b.year);
return ( return (
<Box sx={{ width: '100%' }}> <div className="container mx-auto px-4 py-8 max-w-7xl">
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}> <div className="text-center mb-12">
<Tabs <h1 className="font-cormorant text-4xl md:text-5xl text-sage-900 mb-4">
value={tabValue} Literary Timeline & Historical Context
onChange={handleTabChange} </h1>
aria-label="timeline views" <p className="text-sage-600 text-lg max-w-3xl mx-auto mb-6">
sx={{ Explore the chronological development of Austen's works and their historical context, from early drafts to modern adaptations.
'& .MuiTab-root': { </p>
color: 'text.secondary', </div>
'&.Mui-selected': {
color: 'primary.main',
},
},
}}
>
<Tab label="Interactive Timeline" />
<Tab label="Basic Timeline" />
</Tabs>
</Box>
<TabPanel value={tabValue} index={0}> <Tabs defaultValue="interactive" className="w-full">
<InteractiveTimeline events={timelineEvents} /> <TabsList className="grid w-full grid-cols-2">
</TabPanel> <TabsTrigger value="interactive">Interactive Timeline</TabsTrigger>
<TabsTrigger value="basic">Basic Timeline</TabsTrigger>
</TabsList>
<TabPanel value={tabValue} index={1}> <TabsContent value="interactive">
<Box sx={{ p: 3 }}> <InteractiveTimeline events={timelineEvents} />
<Box sx={{ display: 'flex', alignItems: 'center', mb: 3 }}> </TabsContent>
<Typography variant="h4" component="h1">
Literary Timeline & Historical Context
</Typography>
<Tooltip title="Explore the chronological development of Austen's works and their historical/literary context" arrow>
<IconButton size="small" sx={{ ml: 2 }}>
<Help />
</IconButton>
</Tooltip>
</Box>
<Box sx={{ mb: 4 }}> <TabsContent value="basic">
<Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}> <Box sx={{ p: 3 }}>
Discover how Austen's novels interact with their historical moment and continue to inspire contemporary retellings. <Box sx={{ mb: 4 }}>
</Typography> <Typography variant="body1" className="text-sage-600 mb-4">
<Box sx={{ display: 'flex', gap: 1 }}> Filter events by category to focus on specific aspects of Austen's literary journey and influence.
<Chip </Typography>
label="All Events" <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
onClick={() => setSelectedType('all')} <Chip
color={selectedType === 'all' ? 'primary' : 'default'} label="All Events"
/> onClick={() => setSelectedType('all')}
<Chip
label="Austen's Works"
onClick={() => setSelectedType('works')}
color={selectedType === 'works' ? 'primary' : 'default'}
/>
<Chip
label="Historical Context"
onClick={() => setSelectedType('context')}
color={selectedType === 'context' ? 'secondary' : 'default'}
/>
<Chip
label="Legacy & Reception"
onClick={() => setSelectedType('legacy')}
color={selectedType === 'legacy' ? 'warning' : 'default'}
/>
<Chip
label="Modern Adaptations"
onClick={() => setSelectedType('adaptations')}
color={selectedType === 'adaptations' ? 'success' : 'default'}
/>
</Box>
</Box>
<Grid container spacing={3}>
{filteredEvents.map((event, index) => (
<Grid item xs={12} key={index}>
<Paper
elevation={3}
sx={{ sx={{
p: 3, bgcolor: selectedType === 'all' ? '#4A5D52' : 'transparent',
position: 'relative', color: selectedType === 'all' ? 'white' : 'sage.700',
'&::before': { border: '1px solid',
content: '""', borderColor: selectedType === 'all' ? '#4A5D52' : 'sage.300',
position: 'absolute', '&:hover': {
left: 0, bgcolor: selectedType === 'all' ? '#3A4D42' : 'sage.50'
top: 0,
bottom: 0,
width: 4,
backgroundColor: event.type === 'works'
? 'primary.main'
: event.type === 'context'
? 'secondary.main'
: event.type === 'legacy'
? 'warning.main'
: 'success.main'
} }
}} }}
> />
<Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}> <Chip
<Box> label="Austen's Works"
<Typography variant="h6" component="h2"> onClick={() => setSelectedType('works')}
{event.title} sx={{
</Typography> bgcolor: selectedType === 'works' ? '#5B6E65' : 'transparent',
<Typography variant="subtitle1" color="text.secondary" sx={{ mb: 1 }}> color: selectedType === 'works' ? 'white' : 'sage.700',
{event.year} border: '1px solid',
</Typography> borderColor: selectedType === 'works' ? '#5B6E65' : 'sage.300',
<Typography variant="body1" sx={{ mb: 2 }}> '&:hover': {
{event.description} bgcolor: selectedType === 'works' ? '#4B5E55' : 'sage.50'
</Typography> }
{event.significance && ( }}
<Typography variant="body2" color="text.secondary"> />
<strong>Significance:</strong> {event.significance} <Chip
</Typography> label="Historical Context"
)} onClick={() => setSelectedType('context')}
</Box> sx={{
<Chip bgcolor: selectedType === 'context' ? '#6B7F75' : 'transparent',
label={event.type.charAt(0).toUpperCase() + event.type.slice(1)} color: selectedType === 'context' ? 'white' : 'sage.700',
size="small" border: '1px solid',
color={ borderColor: selectedType === 'context' ? '#6B7F75' : 'sage.300',
event.type === 'works' '&:hover': {
? 'primary' bgcolor: selectedType === 'context' ? '#5B6F65' : 'sage.50'
}
}}
/>
<Chip
label="Legacy & Reception"
onClick={() => setSelectedType('legacy')}
sx={{
bgcolor: selectedType === 'legacy' ? '#7C8F86' : 'transparent',
color: selectedType === 'legacy' ? 'white' : 'sage.700',
border: '1px solid',
borderColor: selectedType === 'legacy' ? '#7C8F86' : 'sage.300',
'&:hover': {
bgcolor: selectedType === 'legacy' ? '#6C7F76' : 'sage.50'
}
}}
/>
<Chip
label="Modern Adaptations"
onClick={() => setSelectedType('adaptations')}
sx={{
bgcolor: selectedType === 'adaptations' ? '#8C9F96' : 'transparent',
color: selectedType === 'adaptations' ? 'white' : 'sage.700',
border: '1px solid',
borderColor: selectedType === 'adaptations' ? '#8C9F96' : 'sage.300',
'&:hover': {
bgcolor: selectedType === 'adaptations' ? '#7C8F86' : 'sage.50'
}
}}
/>
</Box>
</Box>
<Grid container spacing={3}>
{filteredEvents.map((event, index) => (
<Grid item xs={12} key={index}>
<Paper
elevation={0}
sx={{
p: 3,
position: 'relative',
border: '1px solid',
borderColor: 'sage.200',
borderRadius: 2,
'&::before': {
content: '""',
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: 4,
backgroundColor: event.type === 'works'
? '#4A5D52'
: event.type === 'context' : event.type === 'context'
? 'secondary' ? '#5B6E65'
: event.type === 'legacy' : event.type === 'legacy'
? 'warning' ? '#6B7F75'
: 'success' : '#7C8F86'
} }
sx={{ ml: 2 }} }}
/> >
</Box> <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
</Paper> <Box>
</Grid> <Typography variant="h6" component="h2" className="font-cormorant text-sage-900">
))} {event.title}
</Grid> </Typography>
</Box> <Typography variant="subtitle1" className="text-sage-600 mb-1">
</TabPanel> {event.year}
</Box> </Typography>
<Typography variant="body1" className="text-sage-700 mb-2">
{event.description}
</Typography>
{event.significance && (
<Typography variant="body2" className="text-sage-600">
<strong>Significance:</strong> {event.significance}
</Typography>
)}
</Box>
<Chip
label={event.type.charAt(0).toUpperCase() + event.type.slice(1)}
size="small"
sx={{
bgcolor: event.type === 'works' ? '#4A5D52' :
event.type === 'context' ? '#5B6E65' :
event.type === 'legacy' ? '#6B7F75' :
'#7C8F86',
color: 'white',
ml: 2
}}
/>
</Box>
</Paper>
</Grid>
))}
</Grid>
</Box>
</TabsContent>
</Tabs>
</div>
); );
} }