diff --git a/src/components/timeline/InteractiveTimeline.tsx b/src/components/timeline/InteractiveTimeline.tsx index ea94d6b..5710932 100644 --- a/src/components/timeline/InteractiveTimeline.tsx +++ b/src/components/timeline/InteractiveTimeline.tsx @@ -10,12 +10,12 @@ interface Props { // Define major time periods with matching category colors const timePeriods = [ - { start: 1775, end: 1785, name: 'Early Life', color: 'primary.50' }, - { start: 1786, end: 1800, name: 'Juvenilia & Early Drafts', color: 'primary.100' }, - { start: 1801, end: 1817, name: 'Publication Years', color: 'primary.200' }, - { start: 1818, end: 1900, name: 'Victorian Reception', color: 'warning.50' }, - { start: 1901, end: 2000, name: '20th Century', color: 'success.50' }, - { start: 2001, end: new Date().getFullYear(), name: 'Contemporary', color: 'success.100' } + { start: 1775, end: 1785, name: 'Early Life', color: 'rgba(74, 93, 82, 0.1)' }, + { start: 1786, end: 1800, name: 'Juvenilia & Early Drafts', color: 'rgba(74, 93, 82, 0.15)' }, + { start: 1801, end: 1817, name: 'Publication Years', color: 'rgba(74, 93, 82, 0.2)' }, + { start: 1818, end: 1900, name: 'Victorian Reception', color: 'rgba(74, 93, 82, 0.25)' }, + { start: 1901, end: 2000, name: '20th Century', color: 'rgba(74, 93, 82, 0.3)' }, + { start: 2001, end: new Date().getFullYear(), name: 'Contemporary', color: 'rgba(74, 93, 82, 0.35)' } ]; // Timeline data focused on course texts and their context @@ -307,15 +307,25 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) const getEventColor = (type: string) => { switch (type) { case 'works': - return { main: 'primary.main', light: 'primary.50' }; + return { + main: '#4A5D52', + light: '#E5E9E7' + }; case 'context': - return { main: 'secondary.main', light: 'secondary.50' }; + return { + main: '#5B6E65', + light: '#D5DCD8' + }; case 'legacy': - return { main: 'warning.main', light: 'warning.50' }; - case 'adaptations': - return { main: 'success.main', light: 'success.50' }; - default: - return { main: 'grey.500', light: 'grey.50' }; + return { + main: '#6B7F75', + light: '#C5CEC9' + }; + default: // adaptations + return { + main: '#7C8F86', + light: '#B5C0BA' + }; } }; @@ -351,11 +361,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) onClick={() => toggleFilter('works')} variant={activeFilters.includes('works') ? 'contained' : 'outlined'} sx={{ - color: activeFilters.includes('works') ? 'white' : 'primary.main', - borderColor: 'primary.main', + color: activeFilters.includes('works') ? 'white' : 'sage.700', + borderColor: 'sage.300', + bgcolor: activeFilters.includes('works') ? '#4A5D52' : 'transparent', '&:hover': { - borderColor: 'primary.dark', - bgcolor: activeFilters.includes('works') ? 'primary.dark' : 'primary.50' + borderColor: 'sage.400', + bgcolor: activeFilters.includes('works') ? '#3A4D42' : 'sage.50' } }} > @@ -365,12 +376,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) onClick={() => toggleFilter('context')} variant={activeFilters.includes('context') ? 'contained' : 'outlined'} sx={{ - color: activeFilters.includes('context') ? 'white' : 'secondary.main', - borderColor: 'secondary.main', - bgcolor: activeFilters.includes('context') ? 'secondary.main' : 'transparent', + color: activeFilters.includes('context') ? 'white' : 'sage.700', + borderColor: 'sage.300', + bgcolor: activeFilters.includes('context') ? '#5B6E65' : 'transparent', '&:hover': { - borderColor: 'secondary.dark', - bgcolor: activeFilters.includes('context') ? 'secondary.dark' : 'secondary.50' + borderColor: 'sage.400', + bgcolor: activeFilters.includes('context') ? '#4B5E55' : 'sage.50' } }} > @@ -380,12 +391,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) onClick={() => toggleFilter('legacy')} variant={activeFilters.includes('legacy') ? 'contained' : 'outlined'} sx={{ - color: activeFilters.includes('legacy') ? 'white' : 'warning.main', - borderColor: 'warning.main', - bgcolor: activeFilters.includes('legacy') ? 'warning.main' : 'transparent', + color: activeFilters.includes('legacy') ? 'white' : 'sage.700', + borderColor: 'sage.300', + bgcolor: activeFilters.includes('legacy') ? '#6B7F75' : 'transparent', '&:hover': { - borderColor: 'warning.dark', - bgcolor: activeFilters.includes('legacy') ? 'warning.dark' : 'warning.50' + borderColor: 'sage.400', + bgcolor: activeFilters.includes('legacy') ? '#5B6F65' : 'sage.50' } }} > @@ -395,12 +406,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) onClick={() => toggleFilter('adaptations')} variant={activeFilters.includes('adaptations') ? 'contained' : 'outlined'} sx={{ - color: activeFilters.includes('adaptations') ? 'white' : 'success.main', - borderColor: 'success.main', - bgcolor: activeFilters.includes('adaptations') ? 'success.main' : 'transparent', + color: activeFilters.includes('adaptations') ? 'white' : 'sage.700', + borderColor: 'sage.300', + bgcolor: activeFilters.includes('adaptations') ? '#7C8F86' : 'transparent', '&:hover': { - borderColor: 'success.dark', - bgcolor: activeFilters.includes('adaptations') ? 'success.dark' : 'success.50' + borderColor: 'sage.400', + bgcolor: activeFilters.includes('adaptations') ? '#6C7F76' : 'sage.50' } }} > @@ -411,14 +422,14 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) {/* Timeline Container */} - {/* Navigation Buttons Container */} + {/* Navigation Buttons */} `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`, width: 40, height: 40, pointerEvents: 'auto', + color: 'sage.700', '&:hover': { - bgcolor: 'grey.50', + bgcolor: 'sage.50', + borderColor: 'sage.300', boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}` }, '&:active': { - bgcolor: 'grey.100' + bgcolor: 'sage.100' } }} > @@ -457,19 +470,21 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) top: '50%', transform: 'translate(50%, -50%)', zIndex: 3, - bgcolor: 'background.paper', + bgcolor: 'white', border: '1px solid', - borderColor: 'divider', + borderColor: 'sage.200', boxShadow: theme => `0 2px 8px ${alpha(theme.palette.common.black, 0.15)}`, width: 40, height: 40, pointerEvents: 'auto', + color: 'sage.700', '&:hover': { - bgcolor: 'grey.50', + bgcolor: 'sage.50', + borderColor: 'sage.300', boxShadow: theme => `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}` }, '&:active': { - bgcolor: 'grey.100' + bgcolor: 'sage.100' } }} > @@ -508,18 +523,17 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) display: 'inline-block', bgcolor: period.color, border: '1px solid', - borderColor: 'divider', + borderColor: 'sage.200', px: 2, py: 0.5, borderRadius: '16px', - whiteSpace: 'nowrap', - fontFamily: 'cormorant', + whiteSpace: 'nowrap' }} > theme.palette.text.primary, fontWeight: 500, fontSize: '0.875rem' }} @@ -538,8 +552,10 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) sx={{ position: 'relative', height: 400, - bgcolor: 'background.paper', + bgcolor: 'white', borderRadius: 4, + border: '1px solid', + borderColor: 'sage.200', boxShadow: theme => `0 2px 12px ${alpha(theme.palette.common.black, 0.08)}`, overflow: 'hidden', cursor: 'pointer', @@ -558,12 +574,11 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) bgcolor: 'sage.400', borderRadius: 4, border: '2px solid', - borderColor: 'background.paper', + borderColor: 'white', '&:hover': { bgcolor: 'sage.500' } - }, - scrollBehavior: 'smooth' + } }} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} @@ -571,24 +586,25 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) onMouseLeave={handleMouseLeave} > - {/* Time Period Backgrounds */} - {timePeriods.map((period) => { - const startPos = ((period.start - actualMinYear) / timeSpan) * 100; - const width = ((period.end - period.start) / timeSpan) * 100; - return ( - - ); - })} + {/* Single Continuous Background */} + {/* Year Markers */} {yearMarkers.map((year) => { const isDecade = year % 10 === 0; @@ -611,29 +627,24 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) transform: 'translateX(-50%)', display: 'flex', flexDirection: 'column', - alignItems: 'center' + alignItems: 'center', + zIndex: 1 }} > {year} @@ -643,18 +654,40 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) })} - {/* Timeline Base Line */} + {/* Timeline Base Lines */} + > + {/* White line */} + + {/* Sage line */} + + {/* Events */} {filteredEvents.map((event, index) => { @@ -673,11 +706,12 @@ export default function InteractiveTimeline({ events = timelineEvents }: Props) left: `${position}%`, top: `${verticalPosition}%`, transform: 'translate(-50%, -50%)', - zIndex: isSelected ? 2 : 1, + zIndex: isSelected ? 10 : 5, transition: 'all 0.3s ease', cursor: 'pointer', '&: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 */} {selectedEvent && ( - + {selectedEvent.title} - + {selectedEvent.year} - + - + {selectedEvent.description} {selectedEvent.significance && ( - - + + Historical Significance - + {selectedEvent.significance} diff --git a/src/pages/Timeline.tsx b/src/pages/Timeline.tsx index 083e037..e42b622 100644 --- a/src/pages/Timeline.tsx +++ b/src/pages/Timeline.tsx @@ -1,42 +1,16 @@ import React, { useState } from 'react'; -import { Box, Typography, Paper, Grid, Chip, IconButton, Tooltip, Tabs, Tab } from '@mui/material'; -import { Help } from '@mui/icons-material'; +import { Box, Typography, Paper, Grid, Chip } from '@mui/material'; import { TimelineEvent } from '../types/timeline'; import InteractiveTimeline from '../components/timeline/InteractiveTimeline'; - -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; -} - -function TabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; - - return ( - - ); -} +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "../components/ui/tabs"; export default function Timeline() { 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 const timelineEvents: TimelineEvent[] = [ @@ -184,139 +158,166 @@ export default function Timeline() { .sort((a, b) => a.year - b.year); return ( - - - - - - - +
+
+

+ Literary Timeline & Historical Context +

+

+ Explore the chronological development of Austen's works and their historical context, from early drafts to modern adaptations. +

+
- - - + + + Interactive Timeline + Basic Timeline + - - - - - Literary Timeline & Historical Context - - - - - - - + + + - - - Discover how Austen's novels interact with their historical moment and continue to inspire contemporary retellings. - - - setSelectedType('all')} - color={selectedType === 'all' ? 'primary' : 'default'} - /> - setSelectedType('works')} - color={selectedType === 'works' ? 'primary' : 'default'} - /> - setSelectedType('context')} - color={selectedType === 'context' ? 'secondary' : 'default'} - /> - setSelectedType('legacy')} - color={selectedType === 'legacy' ? 'warning' : 'default'} - /> - setSelectedType('adaptations')} - color={selectedType === 'adaptations' ? 'success' : 'default'} - /> - - - - - {filteredEvents.map((event, index) => ( - - + + + + Filter events by category to focus on specific aspects of Austen's literary journey and influence. + + + setSelectedType('all')} sx={{ - p: 3, - position: 'relative', - '&::before': { - content: '""', - position: 'absolute', - left: 0, - top: 0, - bottom: 0, - width: 4, - backgroundColor: event.type === 'works' - ? 'primary.main' - : event.type === 'context' - ? 'secondary.main' - : event.type === 'legacy' - ? 'warning.main' - : 'success.main' + bgcolor: selectedType === 'all' ? '#4A5D52' : 'transparent', + color: selectedType === 'all' ? 'white' : 'sage.700', + border: '1px solid', + borderColor: selectedType === 'all' ? '#4A5D52' : 'sage.300', + '&:hover': { + bgcolor: selectedType === 'all' ? '#3A4D42' : 'sage.50' } }} - > - - - - {event.title} - - - {event.year} - - - {event.description} - - {event.significance && ( - - Significance: {event.significance} - - )} - - + setSelectedType('works')} + sx={{ + bgcolor: selectedType === 'works' ? '#5B6E65' : 'transparent', + color: selectedType === 'works' ? 'white' : 'sage.700', + border: '1px solid', + borderColor: selectedType === 'works' ? '#5B6E65' : 'sage.300', + '&:hover': { + bgcolor: selectedType === 'works' ? '#4B5E55' : 'sage.50' + } + }} + /> + setSelectedType('context')} + sx={{ + bgcolor: selectedType === 'context' ? '#6B7F75' : 'transparent', + color: selectedType === 'context' ? 'white' : 'sage.700', + border: '1px solid', + borderColor: selectedType === 'context' ? '#6B7F75' : 'sage.300', + '&:hover': { + bgcolor: selectedType === 'context' ? '#5B6F65' : 'sage.50' + } + }} + /> + 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' + } + }} + /> + 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' + } + }} + /> + + + + + {filteredEvents.map((event, index) => ( + + - - - - ))} - - - - + }} + > + + + + {event.title} + + + {event.year} + + + {event.description} + + {event.significance && ( + + Significance: {event.significance} + + )} + + + + + + ))} + + + + +
); }