course-schedule #2

Merged
jare2473 merged 5 commits from course-schedule into main 2025-09-05 10:50:24 +02:00
4 changed files with 1140 additions and 0 deletions
Showing only changes of commit 581e16db2b - Show all commits

View File

@@ -6,6 +6,7 @@ import Layout from './Layout';
import { RoomBooking } from './pages/RoomBooking';
import { NewBooking } from './pages/NewBooking';
import { BookingSettings } from './pages/BookingSettings';
import { CourseSchedule } from './pages/CourseSchedule';
import { TestSession } from './pages/TestSession';
import FullScreenLoader from './components/FullScreenLoader';
@@ -115,6 +116,7 @@ const AppRoutes = () => {
<Route path="/" element={<Layout />}>
<Route index element={<RoomBooking bookings={bookings} showSuccessBanner={showSuccessBanner} lastCreatedBooking={lastCreatedBooking} onDismissBanner={() => setShowSuccessBanner(false)} onBookingUpdate={updateBooking} onBookingDelete={deleteBooking} showDeleteBanner={showDeleteBanner} lastDeletedBooking={lastDeletedBooking} onDismissDeleteBanner={() => setShowDeleteBanner(false)} />} />
<Route path="new-booking" element={<NewBooking addBooking={addBooking} />} />
<Route path="course-schedule" element={<CourseSchedule />} />
<Route path="booking-settings" element={<BookingSettings />} />
</Route>
</Routes>

View File

@@ -31,6 +31,7 @@ const Header = () => {
<div className={styles.menu}>
{/* Menu items */}
<Link onClick={handleClick} to="/">Lokalbokning</Link>
<Link onClick={handleClick} to="/course-schedule">Schema</Link>
<Link onClick={handleClick} to="/booking-settings">Booking Settings</Link>
</div>
)}

View File

@@ -0,0 +1,817 @@
import React, { useState, useEffect } from 'react';
import styles from './CourseSchedule.module.css';
const scheduleData = [
// Week 45
{
week: 45,
activities: [
{
id: 1,
date: '2024-11-04',
time: '13:00-14:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 1',
description: 'Introduktion till kursen, Konceptuell modellering och databasmodellering, UML analysmönster.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 2,
date: '2024-11-05',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 1',
description: 'Handledning.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 3,
date: '2024-11-06',
time: '13:00-14:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 1 grp 1',
description: 'Konceptuell modellering. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 4,
date: '2024-11-06',
time: '15:00-16:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 1 grp 2',
description: 'Konceptuell modellering. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 5,
date: '2024-11-07',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 2',
description: 'Handledning.',
teacher: 'Anders Thelemyr, Workneh Yilma Ayele'
},
{
id: 6,
date: '2024-11-07',
time: '15:00-16:45',
location: '',
type: 'Handledning',
title: 'Handledning 3',
description: 'INSTÄLLD.',
teacher: 'Ann Maria Dorotea Bergholtz',
cancelled: true
}
]
},
// Week 46
{
week: 46,
activities: [
{
id: 7,
date: '2024-11-11',
time: '16:00-17:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 2',
description: 'Syntetisk databasdesign: Översättning från UML till relationsmodellen.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 8,
date: '2024-11-12',
time: '13:00-14:45',
location: 'Aula NOD',
type: 'Introduktion',
title: 'Introduktion 1',
description: 'Introduktion till DBMS och projekt Databasdesign. Vi löser en mindre uppgift som liknar den som skall göras i projekt Databasdesign.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 9,
date: '2024-11-13',
time: '10:00-11:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 2 grp 1',
description: 'Relationsmodellen och syntetisk databasdesign. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 10,
date: '2024-11-13',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 4',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Workneh Yilma Ayele'
},
{
id: 11,
date: '2024-11-13',
time: '15:00-16:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 2 grp 2',
description: 'Relationsmodellen och syntetisk databasdesign. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 12,
date: '2024-11-15',
time: '13:00-15:45',
location: '',
type: 'Handledning',
title: 'Handledning 5',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Anders Thelemyr, Workneh Yilma Ayele'
}
]
},
// Week 47
{
week: 47,
activities: [
{
id: 13,
date: '2024-11-18',
time: '13:00-14:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 3',
description: 'SQL I : inledande operatorer',
teacher: 'Anders Thelemyr'
},
{
id: 14,
date: '2024-11-18',
time: '14:45-15:45',
location: 'L30',
type: 'Info',
title: 'Info om år 3 EIT frivillig SVL',
description: '',
teacher: ''
},
{
id: 15,
date: '2024-11-19',
time: '12:00-17:00',
location: 'G10:6',
type: 'Redovisning',
title: 'Redovisning 1 grp 1',
description: 'Redov. första delen av Projekt Databasdesign. Tidsschema per grupp för Red 1 (och även Red 2) kommer på kurswebbplatsen senast dagen efter deadline för projektgruppsanmälan.',
teacher: 'Ann Maria Dorotea Bergholtz',
important: true
},
{
id: 16,
date: '2024-11-19',
time: '12:00-17:00',
location: 'G10:7',
type: 'Redovisning',
title: 'Redovisning 1 grp 2',
description: 'Redov. första delen av Projekt Databasdesign. Tidsschema per grupp för Red 1 (och även Red 2) kommer på kurswebbplatsen senast dagen efter deadline för projektgruppsanmälan.',
teacher: 'Anders Thelemyr',
important: true
},
{
id: 17,
date: '2024-11-19',
time: '12:00-17:00',
location: 'G10:8',
type: 'Redovisning',
title: 'Redovisning 1 grp 3',
description: 'Redov. första delen av Projekt Databasdesign. Tidsschema per grupp för Red 1 (och även Red 2) kommer på kurswebbplatsen senast dagen efter deadline för projektgruppsanmälan.',
teacher: 'Workneh Yilma Ayele',
important: true
},
{
id: 18,
date: '2024-11-20',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 6',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Jennifer Skopac, Melle Carnesten'
},
{
id: 19,
date: '2024-11-22',
time: '08:00-09:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 3 grp 1',
description: 'SQL introduktion - enkla operatorer. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 20,
date: '2024-11-22',
time: '13:00-14:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 3 grp 2',
description: 'SQL introduktion - enkla operatorer. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
}
]
},
// Week 48
{
week: 48,
activities: [
{
id: 21,
date: '2024-11-25',
time: '10:00-11:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 4',
description: 'SQL II: avancerade operatorer.',
teacher: 'Anders Thelemyr'
},
{
id: 22,
date: '2024-11-25',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 7',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Jennifer Skopac, Melle Carnesten'
},
{
id: 23,
date: '2024-11-27',
time: '15:00-16:45',
location: '',
type: 'Handledning',
title: 'Handledning 8',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Melle Carnesten, Workneh Yilma Ayele'
},
{
id: 24,
date: '2024-11-29',
time: '11:00-12:00',
location: 'L30',
type: 'Info',
title: 'Info om år 3 MarkIT frivillig',
description: '',
teacher: ''
},
{
id: 25,
date: '2024-11-29',
time: '13:00-14:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 4 grp 1',
description: 'SQL fortsättning. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 26,
date: '2024-11-29',
time: '15:00-16:45',
location: 'Aula NOD',
type: 'Lektion',
title: 'Lektion 4 grp 2',
description: 'SQL fortsättning. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
}
]
},
// Week 49
{
week: 49,
activities: [
{
id: 27,
date: '2024-12-02',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 9',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Jennifer Skopac, Melle Carnesten'
},
{
id: 28,
date: '2024-12-03',
time: '15:00-16:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 5',
description: 'Frågespråk för relationsmodellen: relationsalgebra.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 29,
date: '2024-12-04',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 10',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Edwin Sundberg, Workneh Yilma Ayele'
},
{
id: 30,
date: '2024-12-06',
time: '10:00-11:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 5 grp 1',
description: 'Relationsalgebra. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 31,
date: '2024-12-06',
time: '15:00-16:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 5 grp 2',
description: 'Relationsalgebra. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
}
]
},
// Week 50
{
week: 50,
activities: [
{
id: 32,
date: '2024-12-10',
time: '13:00-18:00',
location: 'G10:6',
type: 'Redovisning',
title: 'Redovisning 2 grp 1',
description: 'Redov. av de fem första frågorna för projekt Frågespråk, både SQL och relationsalgebra.',
teacher: 'Ann Maria Dorotea Bergholtz',
important: true
},
{
id: 33,
date: '2024-12-10',
time: '13:00-18:00',
location: 'G10:7',
type: 'Redovisning',
title: 'Redovisning 2 grp 2',
description: 'Redov. av de fem första frågorna för projekt Frågespråk, både SQL och relationsalgebra.',
teacher: 'Anders Thelemyr',
important: true
},
{
id: 34,
date: '2024-12-10',
time: '13:00-18:00',
location: 'G10:8',
type: 'Redovisning',
title: 'Redovisning 2 grp 3',
description: 'Redov. av de fem första frågorna för projekt Frågespråk, både SQL och relationsalgebra.',
teacher: 'Workneh Yilma Ayele',
important: true
},
{
id: 35,
date: '2024-12-12',
time: '10:00-11:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 6',
description: 'Analytisk databasdesign: normalisering.',
teacher: 'Ann Maria Dorotea Bergholtz'
}
]
},
// Week 51
{
week: 51,
activities: [
{
id: 36,
date: '2024-12-16',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 11',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Edwin Sundberg'
},
{
id: 37,
date: '2024-12-17',
time: '10:00-12:45',
location: '',
type: 'Handledning',
title: 'Handledning 12',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Edwin Sundberg, Workneh Yilma Ayele'
},
{
id: 38,
date: '2024-12-17',
time: '13:00-15:00',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 8',
description: 'Alternativ till relationsmodellen - noSQL-ansatser.',
teacher: 'Martin Duneld'
},
{
id: 39,
date: '2024-12-18',
time: '10:00-11:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 6 grp 1',
description: 'Analytisk databasdesign: normalisering. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Anders Thelemyr'
},
{
id: 40,
date: '2024-12-18',
time: '13:00-14:45',
location: 'Lilla Hörsalen',
type: 'Lektion',
title: 'Lektion 6 grp 2',
description: 'Analytisk databasdesign: normalisering. Anmälan till lektionsdeltagande krävs. Lektionsgruppsanmälan görs i Daisy.',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 41,
date: '2024-12-19',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 14',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Edwin Sundberg, Melle Carnesten'
},
{
id: 42,
date: '2024-12-19',
time: '15:00-16:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 7',
description: 'Databashanteringssystem.',
teacher: 'Anders Thelemyr'
},
{
id: 43,
date: '2024-12-20',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 13',
description: 'Handledning. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Anders Thelemyr, Edwin Sundberg'
}
]
},
// Week 52
{
week: 52,
activities: [
{
id: 44,
date: '2024-12-23',
time: '13:00-15:00',
location: '',
type: 'Handledning',
title: 'Handledning',
description: 'Zoom-handledning!!!',
teacher: 'Edwin Sundberg, Jennifer Skopac'
}
]
},
// Week 2 (January)
{
week: 2,
activities: [
{
id: 45,
date: '2025-01-07',
time: '15:00-16:45',
location: '',
type: 'Handledning',
title: 'Handledning 15',
description: 'Projekthandledning (ej labb). Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Edwin Sundberg, Jennifer Skopac'
},
{
id: 46,
date: '2025-01-08',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 16',
description: 'Projekthandledning (ej labb). Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Edwin Sundberg, Workneh Yilma Ayele'
},
{
id: 47,
date: '2025-01-08',
time: '13:00-14:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 9',
description: 'Embedded SQL och intro till Labb.',
teacher: 'Nikos Dimitrakas'
},
{
id: 48,
date: '2025-01-09',
time: '09:00-11:45',
location: '',
type: 'Laboration',
title: 'Laboration',
description: 'Öronmärkt tillfälle för arbete på plats i NOD med laborationen i "Embedded SQL i Java". Under tillfället kan labbgrupper, som behöver, få hjälp med labben genom att ställa sig i kö via handledningssystemet.',
teacher: 'Anders Thelemyr, Edwin Sundberg, Nikos Dimitrakas'
},
{
id: 49,
date: '2025-01-10',
time: '09:00-11:45',
location: '',
type: 'Laboration',
title: 'Laboration',
description: 'Öronmärkt tillfälle för arbete på plats i NOD med laborationen i "Embedded SQL i Java". Under tillfället kan labbgrupper, som behöver, få hjälp med labben genom att ställa sig i kö via handledningssystemet.',
teacher: 'Anders Thelemyr, Edwin Sundberg, Nikos Dimitrakas'
}
]
},
// Week 3 (January)
{
week: 3,
activities: [
{
id: 50,
date: '2025-01-13',
time: '09:00-11:45',
location: '',
type: 'Laboration',
title: 'Laboration',
description: 'Öronmärkt tillfälle för arbete på plats i NOD med laborationen i "Embedded SQL i Java". Under tillfället kan labbgrupper, som behöver, få hjälp med labben genom att ställa sig i kö via handledningssystemet.',
teacher: 'Anders Thelemyr, Edwin Sundberg, Nikos Dimitrakas'
},
{
id: 51,
date: '2025-01-13',
time: '15:00-16:45',
location: 'Aula NOD',
type: 'Föreläsning',
title: 'Föreläsning 10',
description: 'Genomgång av en exempeltentamen',
teacher: 'Ann Maria Dorotea Bergholtz'
},
{
id: 52,
date: '2025-01-14',
time: '10:00-11:45',
location: '',
type: 'Handledning',
title: 'Handledning 18',
description: 'Handledning för projekt och ev. kvarvarande övriga uppgifter. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Edwin Sundberg, Jennifer Skopac, Melle Carnesten'
},
{
id: 53,
date: '2025-01-17',
time: '13:00-14:45',
location: '',
type: 'Handledning',
title: 'Handledning 17',
description: 'Handledning för projekt och ev. kvarvarande övriga uppgifter. Via handledning.dsv.su.se - ange zoomid eller plats i NOD. Använd helst ingen passcode om Zoom används.',
teacher: 'Adrian Olbricht, Edwin Sundberg, Jennifer Skopac, Melle Carnesten'
}
]
}
];
const examData = [
{
id: 'exam1',
date: '2025-01-16',
time: '13:00-17:00',
type: 'Tentamen',
title: 'Tentamen (4hp)',
location: 'Aula NOD + flera salar',
important: true,
isExam: true
},
{
id: 'exam2',
date: '2025-01-19',
time: '',
type: 'Projektarbete',
title: 'Projektarbete (3.5hp)',
location: '',
important: true,
isExam: true
}
];
export function CourseSchedule() {
const [expandedActivity, setExpandedActivity] = useState(null);
const [currentWeek, setCurrentWeek] = useState(null);
useEffect(() => {
// Get current week number (simplified)
const now = new Date();
const week = Math.ceil(((now - new Date(now.getFullYear(), 0, 1)) / 86400000 + new Date(now.getFullYear(), 0, 1).getDay() + 1) / 7);
setCurrentWeek(week);
}, []);
const toggleActivity = (activityId) => {
setExpandedActivity(expandedActivity === activityId ? null : activityId);
};
const getActivityTypeClass = (type) => {
// Only apply color styling to clear activity categories
switch (type) {
case 'Föreläsning': return styles.lecture;
case 'Lektion': return styles.lesson;
case 'Handledning': return styles.guidance;
case 'Redovisning': return styles.presentation;
case 'Laboration': return styles.laboration;
case 'Tentamen': return styles.exam;
case 'Projektarbete': return styles.project;
// Leave unclear/mixed categories without color styling
case 'Introduktion':
case 'Info':
default:
return ''; // No color styling
}
};
const formatDate = (dateString) => {
const date = new Date(dateString);
const today = new Date();
const isToday = date.toDateString() === today.toDateString();
const options = {
weekday: 'short',
month: 'short',
day: 'numeric'
};
return {
formatted: date.toLocaleDateString('sv-SE', options),
isToday
};
};
const formatTitle = (title, type) => {
// Format titles to be more meaningful while avoiding redundancy
// For lectures, show topic instead of number
if (type === 'Föreläsning') {
const lectureTopics = {
'Föreläsning 1': 'Introduktion & UML',
'Föreläsning 2': 'Syntetisk databasdesign',
'Föreläsning 3': 'SQL I - Grundläggande',
'Föreläsning 4': 'SQL II - Avancerat',
'Föreläsning 5': 'Relationsalgebra',
'Föreläsning 6': 'Normalisering',
'Föreläsning 7': 'Databashanteringssystem',
'Föreläsning 8': 'noSQL-ansatser',
'Föreläsning 9': 'Embedded SQL',
'Föreläsning 10': 'Exempeltentamen'
};
return lectureTopics[title] || title.replace('Föreläsning ', '');
}
// For lessons, keep group info but make it clearer
if (type === 'Lektion' && title.includes('grp')) {
return title.replace('Lektion ', '').replace('grp', 'Grupp');
}
// For guidance sessions, just show number
if (type === 'Handledning') {
return title.replace('Handledning ', '');
}
// For presentations, keep group info
if (type === 'Redovisning' && title.includes('grp')) {
return title.replace('Redovisning ', '').replace('grp', 'Grupp');
}
// For other activity types, remove the prefix
const typeMap = {
'Introduktion': 'Introduktion ',
'Info': 'Info om ',
'Laboration': 'Laboration',
'Tentamen': 'Tentamen',
'Projektarbete': 'Projektarbete'
};
const prefix = typeMap[type];
if (prefix && title.startsWith(prefix)) {
return title.substring(prefix.length);
}
return title;
};
const ActivityCard = ({ activity, isExam = false }) => {
const { formatted: formattedDate, isToday } = formatDate(activity.date);
const isExpanded = expandedActivity === activity.id;
return (
<div
className={`${styles.activityCard} ${getActivityTypeClass(activity.type)} ${isToday ? styles.today : ''} ${activity.important ? styles.important : ''} ${activity.cancelled ? styles.cancelled : ''}`}
onClick={() => toggleActivity(activity.id)}
>
<div className={styles.activityHeader}>
<div className={styles.activityMeta}>
<div className={styles.activityDate}>
{formattedDate}
{isToday && <span className={styles.todayBadge}>Idag</span>}
</div>
<div className={styles.activityTime}>{activity.time}</div>
</div>
<div className={styles.activityMain}>
<h3 className={`${styles.activityTitle} ${getActivityTypeClass(activity.type)}`}>{activity.title}</h3>
{activity.location && (
<div className={styles.activityLocation}>📍 {activity.location}</div>
)}
</div>
<div className={styles.expandIcon}>
{isExpanded ? '' : '+'}
</div>
</div>
{isExpanded && (
<div className={styles.activityDetails}>
<p className={styles.activityDescription}>{activity.description}</p>
{activity.teacher && (
<div className={styles.activityTeacher}>
<strong>Lärare:</strong> {activity.teacher}
</div>
)}
</div>
)}
</div>
);
};
return (
<div className={styles.pageContainer}>
<div className={styles.header}>
<h1 className={styles.courseTitle}>Databasmetodik</h1>
<p className={styles.courseInfo}>DB HT2024 7,5 hp</p>
</div>
<div className={styles.content}>
{/* Upcoming Exams */}
<section className={styles.section}>
<h2 className={styles.sectionTitle}>📅 Examinationer</h2>
<div className={styles.activitiesList}>
{examData.map((exam) => (
<ActivityCard key={exam.id} activity={exam} isExam={true} />
))}
</div>
</section>
{/* Schedule by weeks */}
{scheduleData.map((weekData) => (
<section key={weekData.week} className={styles.section}>
<h2 className={styles.sectionTitle}>
Vecka {weekData.week}
{currentWeek === weekData.week && <span className={styles.currentWeekBadge}>Aktuell</span>}
</h2>
<div className={styles.activitiesList}>
{weekData.activities.map((activity) => (
<ActivityCard key={activity.id} activity={activity} />
))}
</div>
</section>
))}
{/* Course Info */}
<section className={styles.section}>
<h2 className={styles.sectionTitle}> Kursinformation</h2>
<div className={styles.courseInfoCard}>
<p><strong>Kursansvarig:</strong> Ann Maria Dorotea Bergholtz</p>
<p><strong>Omfattning:</strong> 7,5 högskolepoäng</p>
<p><strong>Tentamen:</strong> 4 hp</p>
<p><strong>Projektarbete:</strong> 3,5 hp</p>
</div>
</section>
</div>
</div>
);
}

View File

@@ -0,0 +1,320 @@
.pageContainer {
min-height: 100vh;
background-color: #fafafa;
padding: 1rem;
max-width: 100%;
}
.header {
margin-bottom: 2rem;
text-align: center;
padding: 1.5rem 1rem;
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.courseTitle {
font-size: 1.75rem;
font-weight: 700;
color: #1f2937;
margin: 0 0 0.5rem 0;
font-family: 'The Sans', system-ui, sans-serif;
}
.courseInfo {
color: #6b7280;
font-size: 0.95rem;
margin: 0;
font-weight: 500;
}
.content {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.section {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.sectionTitle {
font-size: 1.1rem;
font-weight: 600;
color: #374151;
margin: 0;
padding: 1rem 1.25rem;
background: #f9fafb;
border-bottom: 1px solid #e5e7eb;
display: flex;
align-items: center;
gap: 0.5rem;
}
.currentWeekBadge {
background: #10b981;
color: white;
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
border-radius: 6px;
font-weight: 500;
margin-left: 0.5rem;
}
.activitiesList {
display: flex;
flex-direction: column;
}
.activityCard {
padding: 1rem 1.25rem;
border-bottom: 1px solid #f3f4f6;
cursor: pointer;
transition: background-color 0.15s ease;
position: relative;
}
.activityCard:hover {
background-color: #f8fafc;
}
.activityCard:last-child {
border-bottom: none;
}
.activityCard.today {
background: linear-gradient(135deg, #fef3c7, #fde68a);
border-left: 4px solid #f59e0b;
}
.activityCard.important {
border-left: 4px solid #ef4444;
background: linear-gradient(135deg, #fef2f2, #fee2e2);
}
.activityCard.cancelled {
border-left: 4px solid #6b7280;
background: linear-gradient(135deg, #f9fafb, #f3f4f6);
opacity: 0.7;
}
.activityCard.cancelled .activityTitle {
text-decoration: line-through;
color: #6b7280;
}
.activityCard.cancelled .activityTitle {
background: #e5e7eb !important;
color: #6b7280 !important;
}
.activityHeader {
display: flex;
align-items: flex-start;
gap: 1rem;
width: 100%;
}
.activityMeta {
min-width: 80px;
flex-shrink: 0;
}
.activityDate {
font-size: 0.875rem;
font-weight: 600;
color: #374151;
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.25rem;
}
.todayBadge {
background: #059669;
color: white;
font-size: 0.7rem;
padding: 0.15rem 0.4rem;
border-radius: 4px;
font-weight: 500;
}
.activityTime {
font-size: 0.8rem;
color: #6b7280;
font-weight: 500;
}
.activityMain {
flex: 1;
min-width: 0;
}
.activityTitle {
font-size: 1rem;
font-weight: 600;
color: #111827;
margin: 0 0 0.25rem 0;
line-height: 1.3;
padding: 0.3rem 0.8rem;
border-radius: 6px;
width: fit-content;
font-size: 0.9rem;
}
.activityLocation {
font-size: 0.85rem;
color: #6b7280;
margin: 0.25rem 0 0 0;
}
.expandIcon {
font-size: 1.2rem;
color: #9ca3af;
font-weight: 600;
flex-shrink: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.activityDetails {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid #e5e7eb;
margin-left: 92px;
}
.activityDescription {
font-size: 0.9rem;
color: #4b5563;
line-height: 1.5;
margin: 0 0 0.75rem 0;
}
.activityTeacher {
font-size: 0.85rem;
color: #6b7280;
margin: 0;
}
.courseInfoCard {
padding: 1.25rem;
}
.courseInfoCard p {
margin: 0 0 0.75rem 0;
font-size: 0.9rem;
color: #4b5563;
}
.courseInfoCard p:last-child {
margin-bottom: 0;
}
/* Activity type colors for titles */
.lecture .activityTitle {
background: #dbeafe;
color: #1d4ed8;
}
.lesson .activityTitle {
background: #dcfce7;
color: #166534;
}
.guidance .activityTitle {
background: #fef3c7;
color: #b45309;
}
.presentation .activityTitle {
background: #f3e8ff;
color: #7c3aed;
}
.introduction .activityTitle {
background: #e0f2fe;
color: #0369a1;
}
.exam .activityTitle {
background: #fee2e2;
color: #dc2626;
}
.project .activityTitle {
background: #f0fdf4;
color: #15803d;
}
.info .activityTitle {
background: #fef3c7;
color: #b45309;
}
.laboration .activityTitle {
background: #ecfdf5;
color: #047857;
}
.default .activityTitle {
background: #f1f5f9;
color: #475569;
}
/* Responsive design */
@media (max-width: 640px) {
.pageContainer {
padding: 0.75rem;
}
.activityHeader {
gap: 0.75rem;
}
.activityDetails {
margin-left: 0;
margin-top: 0.75rem;
padding-top: 0.75rem;
}
.activityMeta {
min-width: 70px;
}
.courseTitle {
font-size: 1.5rem;
}
.header {
padding: 1.25rem 1rem;
}
}
@media (min-width: 768px) {
.pageContainer {
max-width: 768px;
margin: 0 auto;
padding: 2rem;
}
.content {
gap: 2rem;
}
.header {
padding: 2rem;
}
.courseTitle {
font-size: 2rem;
}
}