course-schedule #2
@ -2,14 +2,17 @@ import React from 'react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import AppRoutes from './AppRoutes'; // move the routing and loading logic here
|
||||
import { SettingsProvider } from './context/SettingsContext';
|
||||
import { ThemeProvider } from './context/ThemeContext';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<SettingsProvider>
|
||||
<Router basename={import.meta.env.BASE_URL}>
|
||||
<AppRoutes />
|
||||
</Router>
|
||||
</SettingsProvider>
|
||||
<ThemeProvider>
|
||||
<SettingsProvider>
|
||||
<Router basename={import.meta.env.BASE_URL}>
|
||||
<AppRoutes />
|
||||
</Router>
|
||||
</SettingsProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ 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 { CourseScheduleView } from './pages/CourseScheduleView';
|
||||
import { TestSession } from './pages/TestSession';
|
||||
import FullScreenLoader from './components/FullScreenLoader';
|
||||
|
||||
@ -105,7 +107,7 @@ const AppRoutes = () => {
|
||||
return (
|
||||
<>
|
||||
{/* Pass loading as isVisible to FullScreenLoader */}
|
||||
{/*<FullScreenLoader isVisible={loading} />*/}
|
||||
{<FullScreenLoader isVisible={loading} />}
|
||||
|
||||
|
||||
<Routes>
|
||||
@ -115,6 +117,8 @@ 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="course-schedule/:courseId" element={<CourseScheduleView />} />
|
||||
<Route path="booking-settings" element={<BookingSettings />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
.card {
|
||||
border: 1px solid #E5E5E5;
|
||||
padding: 1.25rem;
|
||||
border: var(--border-width-thin) solid var(--border-light);
|
||||
padding: var(--card-padding);
|
||||
width: 100%;
|
||||
border-radius: 0.5rem;
|
||||
background: #fff;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
border-radius: var(--border-radius-md);
|
||||
background: var(--bg-primary);
|
||||
transition: var(--transition-medium);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
cursor: pointer;
|
||||
border-color: #007AFF;
|
||||
box-shadow: 0 4px 16px rgba(0, 122, 255, 0.12);
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: var(--shadow-xl);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@ -28,55 +28,55 @@
|
||||
|
||||
.date {
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: #999;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--text-muted);
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.titleRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
gap: var(--spacing-md);
|
||||
margin-bottom: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
font-size: var(--font-size-3xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--text-primary);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.room {
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
padding: 0.375rem 0.75rem;
|
||||
border-radius: 1rem;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-base);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-lg);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.room-green {
|
||||
background: #D4EDDA;
|
||||
color: #155724;
|
||||
background: var(--room-green-bg);
|
||||
color: var(--room-green-text);
|
||||
}
|
||||
|
||||
.room-red {
|
||||
background: #F8D7DA;
|
||||
color: #721C24;
|
||||
background: var(--room-red-bg);
|
||||
color: var(--room-red-text);
|
||||
}
|
||||
|
||||
.room-blue {
|
||||
background: #D1ECF1;
|
||||
color: #0C5460;
|
||||
background: var(--room-blue-bg);
|
||||
color: var(--room-blue-text);
|
||||
}
|
||||
|
||||
.room-yellow {
|
||||
background: #FFF3CD;
|
||||
color: #856404;
|
||||
background: var(--room-yellow-bg);
|
||||
color: var(--room-yellow-text);
|
||||
}
|
||||
|
||||
.timeSection {
|
||||
@ -91,28 +91,28 @@
|
||||
|
||||
.startTime {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
font-weight: var(--font-weight-normal);
|
||||
color: var(--text-primary);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.endTime {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
color: #acacac;
|
||||
font-weight: var(--font-weight-normal);
|
||||
color: var(--text-tertiary);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.participants {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
color: #999;
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Expanded card styles */
|
||||
.expanded {
|
||||
border-color: #007AFF;
|
||||
box-shadow: 0 4px 16px rgba(0, 122, 255, 0.12);
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: var(--shadow-xl);
|
||||
}
|
||||
|
||||
.expanded:hover {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
.dialog {
|
||||
overflow: hidden;
|
||||
background: rgba(255, 255, 255, 0.95) !important;
|
||||
background: var(--modal-dialog-bg) !important;
|
||||
padding: 0;
|
||||
border-radius: 0.4rem;
|
||||
}
|
||||
@ -32,7 +32,7 @@
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
color: var(--text-primary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0.25rem;
|
||||
color: #6b7280;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
@ -54,12 +54,12 @@
|
||||
}
|
||||
|
||||
.closeButton:hover {
|
||||
background-color: #f3f4f6;
|
||||
color: #374151;
|
||||
background-color: var(--modal-close-hover-bg);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.closeButton:focus {
|
||||
outline: 2px solid #2563eb;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
.sectionWithTitle label {
|
||||
font-size: 0.8rem;
|
||||
color: #717171;
|
||||
color: var(--text-tertiary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.25rem;
|
||||
text-transform: uppercase;
|
||||
@ -85,16 +85,16 @@
|
||||
.sectionWithTitle p {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
color: #1f2937;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.timeDisplay {
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--modal-display-bg);
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e9ecef;
|
||||
border: 1px solid var(--modal-display-border);
|
||||
width: fit-content;
|
||||
margin-left: 0;
|
||||
}
|
||||
@ -114,7 +114,7 @@
|
||||
|
||||
.startTime label, .endTime label {
|
||||
font-size: 0.75rem;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.25rem;
|
||||
text-transform: uppercase;
|
||||
@ -124,20 +124,20 @@
|
||||
.timeValue {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #212529;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.timeSeparator {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
margin: 0 0.5rem;
|
||||
padding-top: 1.3rem;
|
||||
}
|
||||
|
||||
.roomText {
|
||||
font-weight: 600 !important;
|
||||
color: #059669 !important;
|
||||
color: var(--modal-save-bg) !important;
|
||||
}
|
||||
|
||||
.modalFooter {
|
||||
@ -152,74 +152,74 @@
|
||||
|
||||
.cancelButton {
|
||||
flex: 2;
|
||||
background-color: white;
|
||||
background-color: var(--modal-cancel-bg);
|
||||
height: 4rem;
|
||||
color: #374151;
|
||||
color: var(--modal-cancel-text);
|
||||
font-weight: 600;
|
||||
border: 2px solid #d1d5db;
|
||||
border: 2px solid var(--modal-cancel-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cancelButton:hover {
|
||||
background-color: #f9fafb;
|
||||
border-color: #9ca3af;
|
||||
background-color: var(--modal-cancel-hover-bg);
|
||||
border-color: var(--modal-cancel-hover-border);
|
||||
}
|
||||
|
||||
.cancelButton:active {
|
||||
background-color: #e5e7eb;
|
||||
background-color: var(--modal-cancel-active-bg);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.saveButton {
|
||||
flex: 3;
|
||||
background-color: #059669;
|
||||
color: white;
|
||||
background-color: var(--modal-save-bg);
|
||||
color: var(--modal-save-text);
|
||||
height: 4rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
border: 2px solid #047857;
|
||||
border: 2px solid var(--modal-save-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.saveButton:hover {
|
||||
background-color: #047857;
|
||||
box-shadow: 0 4px 8px rgba(5, 150, 105, 0.3);
|
||||
background-color: var(--modal-save-hover-bg);
|
||||
box-shadow: var(--modal-save-hover-shadow);
|
||||
}
|
||||
|
||||
.saveButton:active {
|
||||
background-color: #065f46;
|
||||
background-color: var(--modal-save-active-bg);
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 2px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-active-shadow);
|
||||
}
|
||||
|
||||
.saveButton[data-focused],
|
||||
.cancelButton[data-focused] {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.disabledButton {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #adb5bd !important;
|
||||
border: 2px dashed #dee2e6 !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
color: var(--button-disabled-text) !important;
|
||||
border: 2px dashed var(--button-disabled-border) !important;
|
||||
opacity: 0.6 !important;
|
||||
box-shadow: none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.disabledButton:hover {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.disabledButton:active {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
.elementHeading {
|
||||
margin: 0;
|
||||
color: #8E8E8E;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 0.8rem;
|
||||
font-style: normal;
|
||||
font-weight: 520;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
.modalFooter {
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
color: blue;
|
||||
color: var(--color-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
@ -21,58 +21,58 @@
|
||||
|
||||
.cancelButton {
|
||||
flex: 2;
|
||||
background-color: white;
|
||||
background-color: var(--modal-cancel-bg);
|
||||
height: 4rem;
|
||||
color: #374151;
|
||||
color: var(--modal-cancel-text);
|
||||
font-weight: 600;
|
||||
border: 2px solid #d1d5db;
|
||||
border: 2px solid var(--modal-cancel-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.cancelButton:hover {
|
||||
background-color: #f9fafb;
|
||||
border-color: #9ca3af;
|
||||
background-color: var(--modal-cancel-hover-bg);
|
||||
border-color: var(--modal-cancel-hover-border);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.saveButton {
|
||||
flex: 3;
|
||||
background-color: #059669;
|
||||
color: white;
|
||||
background-color: var(--modal-save-bg);
|
||||
color: var(--modal-save-text);
|
||||
height: 4rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
border: 2px solid #047857;
|
||||
border: 2px solid var(--modal-save-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-shadow);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.saveButton:hover {
|
||||
background-color: #047857;
|
||||
box-shadow: 0 4px 8px rgba(5, 150, 105, 0.3);
|
||||
background-color: var(--modal-save-hover-bg);
|
||||
box-shadow: var(--modal-save-hover-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.saveButton:active {
|
||||
background-color: #065f46;
|
||||
background-color: var(--modal-save-active-bg);
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 2px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-active-shadow);
|
||||
}
|
||||
|
||||
.saveButton[data-focused],
|
||||
.cancelButton[data-focused] {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.cancelButton:active {
|
||||
background-color: #e5e7eb;
|
||||
background-color: var(--modal-cancel-active-bg);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
|
||||
.sectionWithTitle label {
|
||||
font-size: 0.8rem;
|
||||
color: #717171;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.sectionWithTitle p {
|
||||
@ -98,15 +98,12 @@
|
||||
}
|
||||
|
||||
.modalContainer {
|
||||
background-color: white;
|
||||
background-color: var(--modal-bg);
|
||||
width: 85%;
|
||||
max-width: 400px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18) !important;
|
||||
box-shadow: 0 32px 64px rgba(0, 0, 0, 0.12),
|
||||
0 16px 32px rgba(0, 0, 0, 0.08),
|
||||
0 8px 16px rgba(0, 0, 0, 0.04),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.15) !important;
|
||||
border: 1px solid var(--modal-border) !important;
|
||||
box-shadow: var(--modal-shadow) !important;
|
||||
backdrop-filter: blur(20px) saturate(140%) !important;
|
||||
-webkit-backdrop-filter: blur(20px) saturate(140%) !important;
|
||||
}
|
||||
@ -134,18 +131,18 @@
|
||||
max-height: calc(100vh - 4rem) !important;
|
||||
max-width: 90vw !important;
|
||||
overflow-y: auto !important;
|
||||
background: white !important;
|
||||
background: var(--modal-bg) !important;
|
||||
border-radius: 0.5rem !important;
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
|
||||
box-shadow: var(--modal-shadow) !important;
|
||||
}
|
||||
|
||||
/* New time display styles */
|
||||
.timeDisplay {
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--modal-display-bg);
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e9ecef;
|
||||
border: 1px solid var(--modal-display-border);
|
||||
min-width: 196px;
|
||||
width: fit-content;
|
||||
}
|
||||
@ -165,7 +162,7 @@
|
||||
|
||||
.startTime label, .endTime label {
|
||||
font-size: 0.75rem;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.25rem;
|
||||
text-transform: uppercase;
|
||||
@ -175,11 +172,11 @@
|
||||
.timeValue {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #212529;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.timeValue.placeholder {
|
||||
color: #adb5bd;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
font-size: 1rem;
|
||||
}
|
||||
@ -187,23 +184,23 @@
|
||||
.timeSeparator {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
margin: 0 0.5rem;
|
||||
padding-top: 1.3rem;
|
||||
}
|
||||
|
||||
/* Disabled button styles */
|
||||
.disabledButton {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #adb5bd !important;
|
||||
border: 2px dashed #dee2e6 !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
color: var(--button-disabled-text) !important;
|
||||
border: 2px dashed var(--button-disabled-border) !important;
|
||||
opacity: 0.6 !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.disabledButton:hover {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
transform: none !important;
|
||||
box-shadow: none;
|
||||
cursor: default;
|
||||
@ -211,6 +208,6 @@
|
||||
}
|
||||
|
||||
.disabledButton:active {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
transform: none !important;
|
||||
}
|
||||
@ -1,10 +1,11 @@
|
||||
.textInput {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #D2D9E0;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 0.5rem;
|
||||
font-size: 16px;
|
||||
background-color: #FAFBFC;
|
||||
background-color: var(--input-bg);
|
||||
color: var(--input-text);
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
@ -12,12 +13,12 @@
|
||||
}
|
||||
|
||||
.textInput::placeholder {
|
||||
color: #adadad;
|
||||
color: var(--input-placeholder);
|
||||
}
|
||||
|
||||
.elementHeading {
|
||||
margin: 0;
|
||||
color: #8E8E8E;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 0.8rem;
|
||||
font-style: normal;
|
||||
font-weight: 520;
|
||||
@ -29,7 +30,7 @@
|
||||
/* Compact styles */
|
||||
.compactElementHeading {
|
||||
font-size: 0.75rem;
|
||||
color: #717171;
|
||||
color: var(--text-tertiary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.4rem;
|
||||
margin-top: 0;
|
||||
@ -40,10 +41,11 @@
|
||||
.compactTextInput {
|
||||
width: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 0.375rem;
|
||||
font-size: 16px;
|
||||
background-color: white;
|
||||
background-color: var(--input-bg);
|
||||
color: var(--input-text);
|
||||
font-family: inherit;
|
||||
transition: border-color 0.2s ease;
|
||||
box-sizing: border-box;
|
||||
@ -51,7 +53,7 @@
|
||||
}
|
||||
|
||||
.compactTextInput:focus {
|
||||
outline: 2px solid #007AFF;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
border-color: #007AFF;
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
.bookingsListContainer {
|
||||
/*border-top: 1px solid gray;*/
|
||||
padding-bottom: 2rem;
|
||||
padding-bottom: var(--spacing-3xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@ -8,45 +7,45 @@
|
||||
.bookingsContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.message {
|
||||
font-style: italic;
|
||||
color: #838383;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.heading {
|
||||
margin: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.showMoreButton {
|
||||
background: #ffffff;
|
||||
background: var(--button-secondary-bg);
|
||||
border: none;
|
||||
border-radius: 0.75rem;
|
||||
padding: 1rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: rgb(0, 0, 0);
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: var(--spacing-lg);
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--button-secondary-text);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
margin-top: 1rem;
|
||||
transition: var(--transition-medium);
|
||||
margin-top: var(--spacing-lg);
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
box-shadow: 0 2px 8px rgba(143, 143, 143, 0.2);
|
||||
box-shadow: var(--button-secondary-shadow);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
gap: var(--spacing-sm);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.showMoreButton:hover {
|
||||
background: #f2f6ff;
|
||||
background: var(--button-secondary-hover-bg);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(192, 192, 192, 0.3);
|
||||
box-shadow: var(--button-secondary-hover-shadow);
|
||||
}
|
||||
|
||||
.showMoreButton:active {
|
||||
|
||||
@ -10,10 +10,10 @@
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
padding: 0.5rem 2.5rem 0.5rem 1rem; /* More room on right for chevron */
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 0.375rem;
|
||||
background-color: white;
|
||||
color: #333;
|
||||
background-color: var(--input-bg);
|
||||
color: var(--input-text);
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
width: 100%;
|
||||
@ -27,7 +27,7 @@
|
||||
top: 50%;
|
||||
right: 1rem;
|
||||
transform: translateY(-50%);
|
||||
color: #888;
|
||||
color: var(--dropdown-chevron-color);
|
||||
font-size: 0.8rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import styles from './Header.module.css'; // Import the CSS Module
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ThemeToggle } from './ThemeToggle';
|
||||
|
||||
const Header = () => {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
@ -23,14 +24,18 @@ const Header = () => {
|
||||
</Link>
|
||||
Studentportalen
|
||||
</div>
|
||||
<div className={styles.menuIcon} onClick={toggleMenu}>
|
||||
{/* Simple menu icon, you can replace it with an icon from a library */}
|
||||
☰
|
||||
<div className={styles.right}>
|
||||
<ThemeToggle />
|
||||
<div className={styles.menuIcon} onClick={toggleMenu}>
|
||||
{/* Simple menu icon, you can replace it with an icon from a library */}
|
||||
☰
|
||||
</div>
|
||||
</div>
|
||||
{menuOpen && (
|
||||
<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>
|
||||
)}
|
||||
|
||||
@ -2,45 +2,68 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
background-color: #f8f8f8;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: fixed; /* Make the header sticky */
|
||||
top: 0; /* Stick to the top */
|
||||
width: 100%; /* Full width */
|
||||
z-index: 1000; /* Ensure it stays on top of other content */
|
||||
padding: var(--spacing-sm) var(--spacing-xl);
|
||||
background-color: var(--bg-secondary);
|
||||
box-shadow: var(--shadow-md);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: var(--z-header);
|
||||
}
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-lg);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 40px; /* Adjust the height as needed */
|
||||
transition: filter 0.2s ease;
|
||||
}
|
||||
|
||||
.menuIcon {
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: var(--text-primary);
|
||||
padding: var(--spacing-xs);
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: var(--transition-fast);
|
||||
}
|
||||
|
||||
.menuIcon:hover {
|
||||
background-color: var(--bg-muted);
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: 60px; /* Position below the header */
|
||||
right: 20px;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
top: var(--header-height);
|
||||
right: var(--spacing-xl);
|
||||
background-color: var(--bg-primary);
|
||||
box-shadow: var(--shadow-lg);
|
||||
padding: var(--spacing-sm);
|
||||
border-radius: var(--border-radius-md);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.menu a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
padding: 5px 10px;
|
||||
color: var(--text-primary);
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
background-color: #f0f0f0;
|
||||
background-color: var(--bg-muted);
|
||||
}
|
||||
|
||||
/* Responsive design for larger screens */
|
||||
@ -70,5 +93,10 @@ body {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
color: #002E5F;
|
||||
color: var(--header-brand-color);
|
||||
}
|
||||
|
||||
/* Dark mode logo filter */
|
||||
:global([data-theme="dark"]) .logo img {
|
||||
filter: brightness(0) saturate(100%) invert(1);
|
||||
}
|
||||
@ -1,18 +1,18 @@
|
||||
/* Base banner styles */
|
||||
.banner {
|
||||
border-radius: 0.75rem;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: var(--spacing-lg) var(--spacing-xl);
|
||||
margin-bottom: var(--spacing-2xl);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.bannerContent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.icon {
|
||||
@ -22,114 +22,114 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
font-size: 1rem;
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-size: var(--font-size-xl);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.titleRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-size: var(--font-size-2xl);
|
||||
}
|
||||
|
||||
.details {
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.bookingTitle {
|
||||
font-weight: 400;
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #6C757D;
|
||||
color: var(--notification-close-button);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 300;
|
||||
font-weight: var(--font-weight-light);
|
||||
cursor: pointer;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 0.375rem;
|
||||
transition: all 0.2s ease;
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: var(--transition-medium);
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.closeButton:hover {
|
||||
background: rgba(108, 117, 125, 0.1);
|
||||
color: #495057;
|
||||
background: var(--notification-close-button-bg-hover);
|
||||
color: var(--notification-close-button-hover);
|
||||
}
|
||||
|
||||
/* Success variant styles */
|
||||
.success {
|
||||
background: #E8F5E8;
|
||||
border: 1px solid #4CAF50;
|
||||
background: var(--notification-success-bg);
|
||||
border: var(--border-width-thin) solid var(--notification-success-border);
|
||||
}
|
||||
|
||||
.successIcon {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
background: var(--notification-success-icon-bg);
|
||||
color: var(--notification-success-icon-text);
|
||||
}
|
||||
|
||||
.successTitle {
|
||||
color: #2E7D32;
|
||||
color: var(--notification-success-title);
|
||||
}
|
||||
|
||||
.successDetails {
|
||||
color: #388E3C;
|
||||
color: var(--notification-success-details);
|
||||
}
|
||||
|
||||
/* Delete variant styles */
|
||||
.delete {
|
||||
background: #FFF4F4;
|
||||
border: 1px solid #F87171;
|
||||
background: var(--notification-error-bg);
|
||||
border: var(--border-width-thin) solid var(--notification-error-border);
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
background: #EF4444;
|
||||
color: white;
|
||||
background: var(--notification-error-icon-bg);
|
||||
color: var(--notification-error-icon-text);
|
||||
}
|
||||
|
||||
.deleteTitle {
|
||||
color: #DC2626;
|
||||
color: var(--notification-error-title);
|
||||
}
|
||||
|
||||
.deleteDetails {
|
||||
color: #EF4444;
|
||||
color: var(--notification-error-details);
|
||||
}
|
||||
|
||||
/* Development variant styles */
|
||||
.development {
|
||||
background: #FFF8E1;
|
||||
border: 1px solid #FFB74D;
|
||||
background: var(--notification-warning-bg);
|
||||
border: var(--border-width-thin) solid var(--notification-warning-border);
|
||||
}
|
||||
|
||||
.developmentIcon {
|
||||
font-size: 1.5rem;
|
||||
color: #FF9800;
|
||||
color: var(--notification-warning-icon);
|
||||
}
|
||||
|
||||
/* Test label styles */
|
||||
.testLabel {
|
||||
background: #FF9800;
|
||||
color: white;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
background: var(--notification-warning-icon);
|
||||
color: var(--color-white);
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-bold);
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: var(--border-radius-sm);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
@ -143,15 +143,15 @@
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: #333;
|
||||
color: white;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.375rem;
|
||||
font-size: 0.875rem;
|
||||
margin-top: var(--spacing-sm);
|
||||
background: var(--tooltip-bg);
|
||||
color: var(--tooltip-text);
|
||||
padding: var(--spacing-md) var(--spacing-lg);
|
||||
border-radius: var(--border-radius-md);
|
||||
font-size: var(--font-size-base);
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
z-index: 10;
|
||||
box-shadow: var(--shadow-xl);
|
||||
z-index: var(--z-dropdown);
|
||||
animation: fadeIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@ -159,10 +159,10 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
right: 1rem;
|
||||
right: var(--spacing-lg);
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #333;
|
||||
border-bottom: 6px solid var(--tooltip-bg);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
.elementHeading {
|
||||
margin: 0;
|
||||
color: #8E8E8E;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 0.8rem;
|
||||
font-style: normal;
|
||||
font-weight: 520;
|
||||
@ -24,15 +24,15 @@
|
||||
.participantChip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #F0F8FF;
|
||||
border: 1px solid #D1E7FF;
|
||||
background-color: var(--chip-bg);
|
||||
border: 1px solid var(--chip-border);
|
||||
border-radius: 1.25rem;
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
color: #2563EB;
|
||||
color: var(--chip-text);
|
||||
gap: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: var(--chip-shadow);
|
||||
}
|
||||
|
||||
|
||||
@ -48,38 +48,38 @@
|
||||
}
|
||||
|
||||
.clickableChip:hover {
|
||||
background-color: #E0F2FE;
|
||||
border-color: #BAE6FD;
|
||||
background-color: var(--chip-hover-bg);
|
||||
border-color: var(--chip-hover-border);
|
||||
}
|
||||
|
||||
.clickableChip:focus {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.clickableChip:active {
|
||||
background-color: #BFDBFE;
|
||||
background-color: var(--chip-active-bg);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
|
||||
.removeIcon {
|
||||
color: #2563EB;
|
||||
color: var(--chip-text);
|
||||
font-size: 0.875rem;
|
||||
font-weight: bold;
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.defaultUserChip {
|
||||
background-color: #F3F4F6;
|
||||
border-color: #D1D5DB;
|
||||
color: #374151;
|
||||
background-color: var(--chip-default-bg);
|
||||
border-color: var(--chip-default-border);
|
||||
color: var(--chip-default-text);
|
||||
}
|
||||
|
||||
.defaultUserChip:hover {
|
||||
background-color: #F3F4F6;
|
||||
border-color: #D1D5DB;
|
||||
color: #374151;
|
||||
background-color: var(--chip-default-bg);
|
||||
border-color: var(--chip-default-border);
|
||||
color: var(--chip-default-text);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@ -93,23 +93,24 @@
|
||||
.searchInput {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #D2D9E0;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 0.5rem;
|
||||
font-size: 16px;
|
||||
background-color: #FAFBFC;
|
||||
background-color: var(--input-bg);
|
||||
color: var(--input-text);
|
||||
padding: 1rem;
|
||||
font-family: inherit;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.searchInput::placeholder {
|
||||
color: #adadad;
|
||||
color: var(--input-placeholder);
|
||||
}
|
||||
|
||||
.searchInput:focus {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: -1px;
|
||||
border-color: #2563EB;
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
@ -117,10 +118,10 @@
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
border: 1px solid #D2D9E0;
|
||||
background: var(--dropdown-bg);
|
||||
border: 1px solid var(--dropdown-border);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||
box-shadow: var(--dropdown-shadow);
|
||||
z-index: 1000;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
@ -132,12 +133,12 @@
|
||||
}
|
||||
|
||||
.section:not(:last-child) {
|
||||
border-bottom: 1px solid #F1F3F4;
|
||||
border-bottom: 1px solid var(--dropdown-divider);
|
||||
}
|
||||
|
||||
.sectionHeader {
|
||||
font-weight: 600;
|
||||
color: #5F6368;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
@ -150,8 +151,9 @@
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
border: none;
|
||||
border-bottom: 1px solid #F1F3F4;
|
||||
border-bottom: 1px solid var(--dropdown-divider);
|
||||
background: none;
|
||||
color: var(--text-primary);
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
font-family: inherit;
|
||||
@ -165,11 +167,11 @@
|
||||
}
|
||||
|
||||
.dropdownItem:hover {
|
||||
background-color: #F8F9FA;
|
||||
background-color: var(--dropdown-hover-bg);
|
||||
}
|
||||
|
||||
.dropdownItem:active {
|
||||
background-color: #E8F0FE;
|
||||
background-color: var(--dropdown-active-bg);
|
||||
}
|
||||
|
||||
.personAvatar {
|
||||
@ -190,8 +192,8 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: #2563EB;
|
||||
color: white;
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-white);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -208,7 +210,7 @@
|
||||
|
||||
.personName {
|
||||
font-weight: 500;
|
||||
color: #202124;
|
||||
color: var(--text-primary);
|
||||
font-size: 0.875rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -217,11 +219,11 @@
|
||||
|
||||
.personUsername {
|
||||
font-size: 0.75rem;
|
||||
color: #5F6368;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.addNewItem {
|
||||
color: #1A73E8;
|
||||
color: var(--color-primary);
|
||||
font-weight: 500;
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
@ -232,46 +234,46 @@
|
||||
}
|
||||
|
||||
.selectedItem {
|
||||
background-color: #F0F8FF;
|
||||
background-color: var(--dropdown-selected-bg);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.selectedItem:hover {
|
||||
background-color: #E0F2FE;
|
||||
background-color: var(--dropdown-selected-hover-bg);
|
||||
}
|
||||
|
||||
.selectedIndicator {
|
||||
color: #2563EB;
|
||||
color: var(--color-primary);
|
||||
font-weight: bold;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.focusedItem {
|
||||
background-color: #2563EB !important;
|
||||
color: white !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
color: var(--color-white) !important;
|
||||
}
|
||||
|
||||
.focusedItem .personName {
|
||||
color: white !important;
|
||||
color: var(--color-white) !important;
|
||||
}
|
||||
|
||||
.focusedItem .personUsername {
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
color: var(--color-white-transparent) !important;
|
||||
}
|
||||
|
||||
.focusedItem .selectedIndicator {
|
||||
color: white !important;
|
||||
color: var(--color-white) !important;
|
||||
}
|
||||
|
||||
.focusedItem .avatarInitials {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
background-color: var(--color-white-transparent-low);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.noResults {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: #5F6368;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
font-style: italic;
|
||||
}
|
||||
@ -283,7 +285,7 @@
|
||||
|
||||
.compactElementHeading {
|
||||
font-size: 0.75rem;
|
||||
color: #717171;
|
||||
color: var(--text-tertiary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.4rem;
|
||||
margin-top: 0;
|
||||
@ -294,17 +296,18 @@
|
||||
.compactSearchInput {
|
||||
width: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 0.375rem;
|
||||
font-size: 16px;
|
||||
background-color: white;
|
||||
background-color: var(--input-bg);
|
||||
color: var(--input-text);
|
||||
font-family: inherit;
|
||||
transition: border-color 0.2s ease;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.compactSearchInput:focus {
|
||||
outline: 2px solid #007AFF;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
border-color: #007AFF;
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
.elementHeading {
|
||||
margin: 0;
|
||||
color: #8E8E8E;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 0.8rem;
|
||||
font-style: normal;
|
||||
font-weight: 520;
|
||||
|
||||
25
my-app/src/components/ThemeToggle.jsx
Normal file
25
my-app/src/components/ThemeToggle.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { useTheme } from '../context/ThemeContext';
|
||||
import styles from './ThemeToggle.module.css';
|
||||
|
||||
export const ThemeToggle = () => {
|
||||
const { isDarkMode, toggleTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<button
|
||||
className={styles.toggleButton}
|
||||
onClick={toggleTheme}
|
||||
aria-label={`Switch to ${isDarkMode ? 'light' : 'dark'} mode`}
|
||||
title={`Switch to ${isDarkMode ? 'light' : 'dark'} mode`}
|
||||
>
|
||||
<div className={styles.toggleContainer}>
|
||||
<div className={`${styles.toggle} ${isDarkMode ? styles.dark : styles.light}`}>
|
||||
<div className={styles.toggleHandle}></div>
|
||||
</div>
|
||||
<span className={styles.toggleLabel}>
|
||||
{isDarkMode ? '🌙' : '☀️'}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
107
my-app/src/components/ThemeToggle.module.css
Normal file
107
my-app/src/components/ThemeToggle.module.css
Normal file
@ -0,0 +1,107 @@
|
||||
.toggleButton {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: var(--spacing-xs);
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: var(--transition-fast);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.toggleButton:hover {
|
||||
background-color: var(--bg-muted);
|
||||
}
|
||||
|
||||
.toggleContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.toggle {
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
position: relative;
|
||||
transition: var(--transition-medium);
|
||||
border: 1px solid var(--border-medium);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.toggle.light {
|
||||
background: linear-gradient(to bottom, #ffffff, #f0f0f0);
|
||||
}
|
||||
|
||||
.toggle.dark {
|
||||
background: linear-gradient(to bottom, #4a4a4a, #2a2a2a);
|
||||
}
|
||||
|
||||
.toggleHandle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(to bottom, #ffffff, #e0e0e0);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transition: var(--transition-medium);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.toggle.light .toggleHandle {
|
||||
left: 2px;
|
||||
background: linear-gradient(to bottom, #ffd700, #ffed4a);
|
||||
border-color: rgba(255, 165, 0, 0.3);
|
||||
}
|
||||
|
||||
.toggle.dark .toggleHandle {
|
||||
left: calc(100% - 20px);
|
||||
background: linear-gradient(to bottom, #e6e6e6, #cccccc);
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.toggleLabel {
|
||||
font-size: var(--font-size-lg);
|
||||
line-height: 1;
|
||||
user-select: none;
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* iPhone-style pressed state */
|
||||
.toggleButton:active .toggle {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.toggleButton:active .toggleHandle {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.toggleContainer {
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.toggle {
|
||||
width: 40px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.toggleHandle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.toggle.dark .toggleHandle {
|
||||
left: calc(100% - 18px);
|
||||
}
|
||||
|
||||
.toggleLabel {
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
}
|
||||
@ -3,14 +3,15 @@
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #CECECE;
|
||||
border: 1px solid var(--timecard-border);
|
||||
min-width: 90px;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 6px;
|
||||
background-color: #F8FBFC;
|
||||
background-color: var(--timecard-bg);
|
||||
color: var(--timecard-text);
|
||||
width: 135px;
|
||||
height: 20px;
|
||||
transition: all 0.15s ease;
|
||||
@ -18,36 +19,36 @@
|
||||
|
||||
@media (hover: hover) {
|
||||
.container:hover {
|
||||
background-color: #E5E5E5;
|
||||
background-color: var(--timecard-hover-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.container:active,
|
||||
.container[data-pressed] {
|
||||
background-color: #D1D5DB;
|
||||
background-color: var(--timecard-active-bg);
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: var(--timecard-active-shadow);
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.container[data-focus-visible] {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: #2563EB !important;
|
||||
color: white !important;
|
||||
border-color: #1d4ed8 !important;
|
||||
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.3);
|
||||
background-color: var(--color-primary) !important;
|
||||
color: var(--color-white) !important;
|
||||
border-color: var(--color-primary-dark) !important;
|
||||
box-shadow: var(--timecard-selected-shadow);
|
||||
}
|
||||
|
||||
.selected .upToText {
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
color: var(--color-white-transparent) !important;
|
||||
}
|
||||
|
||||
.selected .hoursText {
|
||||
color: white !important;
|
||||
color: var(--color-white) !important;
|
||||
}
|
||||
|
||||
.container p {
|
||||
@ -62,13 +63,13 @@
|
||||
|
||||
.upToText {
|
||||
font-weight: 300;
|
||||
color: #919191;
|
||||
color: var(--timecard-muted-text);
|
||||
font-size: 0.9rem
|
||||
}
|
||||
|
||||
.hoursText {
|
||||
font-weight: 500;
|
||||
color:#686765;
|
||||
color: var(--timecard-secondary-text);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@ -78,9 +79,9 @@
|
||||
}
|
||||
|
||||
.unavailableSlot {
|
||||
background-color: #E5E5E5;
|
||||
color: #B1B1B1;
|
||||
border: 1px solid #CECECE;
|
||||
background-color: var(--timecard-unavailable-bg);
|
||||
color: var(--timecard-unavailable-text);
|
||||
border: 1px solid var(--timecard-unavailable-border);
|
||||
height: 50px;
|
||||
width: 165px;
|
||||
}
|
||||
@ -88,7 +89,7 @@
|
||||
.modalFooter {
|
||||
height: fit-content;
|
||||
width: 100%;
|
||||
color: blue;
|
||||
color: var(--color-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
@ -100,52 +101,52 @@
|
||||
|
||||
.cancelButton {
|
||||
flex: 2;
|
||||
background-color: white;
|
||||
background-color: var(--modal-cancel-bg);
|
||||
height: 4rem;
|
||||
color: #374151;
|
||||
color: var(--modal-cancel-text);
|
||||
font-weight: 600;
|
||||
border: 2px solid #d1d5db;
|
||||
border: 2px solid var(--modal-cancel-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.cancelButton:hover {
|
||||
background-color: #f9fafb;
|
||||
border-color: #9ca3af;
|
||||
background-color: var(--modal-cancel-hover-bg);
|
||||
border-color: var(--modal-cancel-hover-border);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.saveButton {
|
||||
flex: 3;
|
||||
background-color: #059669;
|
||||
color: white;
|
||||
background-color: var(--modal-save-bg);
|
||||
color: var(--modal-save-text);
|
||||
height: 4rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
border: 2px solid #047857;
|
||||
border: 2px solid var(--modal-save-border);
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-shadow);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.saveButton:hover {
|
||||
background-color: #047857;
|
||||
box-shadow: 0 4px 8px rgba(5, 150, 105, 0.3);
|
||||
background-color: var(--modal-save-hover-bg);
|
||||
box-shadow: var(--modal-save-hover-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.saveButton:active {
|
||||
background-color: #065f46;
|
||||
background-color: var(--modal-save-active-bg);
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 2px rgba(5, 150, 105, 0.2);
|
||||
box-shadow: var(--modal-save-active-shadow);
|
||||
}
|
||||
|
||||
.cancelButton:active {
|
||||
background-color: #e5e7eb;
|
||||
background-color: var(--modal-cancel-active-bg);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
@ -163,7 +164,7 @@
|
||||
|
||||
.sectionWithTitle label {
|
||||
font-size: 0.8rem;
|
||||
color: #717171;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.sectionWithTitle p {
|
||||
@ -171,7 +172,7 @@
|
||||
}
|
||||
|
||||
.modalContainer {
|
||||
background-color: white;
|
||||
background-color: var(--modal-bg);
|
||||
width: 85%;
|
||||
max-width: 400px;
|
||||
}
|
||||
@ -180,9 +181,9 @@
|
||||
.timeDisplay {
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
background-color: var(--modal-display-bg);
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e9ecef;
|
||||
border: 1px solid var(--modal-display-border);
|
||||
}
|
||||
|
||||
.timeRange {
|
||||
@ -200,7 +201,7 @@
|
||||
|
||||
.startTime label, .endTime label {
|
||||
font-size: 0.75rem;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.25rem;
|
||||
text-transform: uppercase;
|
||||
@ -210,11 +211,11 @@
|
||||
.timeValue {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #212529;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.timeValue.placeholder {
|
||||
color: #adb5bd;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
font-size: 1rem;
|
||||
}
|
||||
@ -222,28 +223,28 @@
|
||||
.timeSeparator {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 300;
|
||||
color: #6c757d;
|
||||
color: var(--text-secondary);
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
/* Disabled button styles */
|
||||
.disabledButton {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #adb5bd !important;
|
||||
border: 2px dashed #dee2e6 !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
color: var(--button-disabled-text) !important;
|
||||
border: 2px dashed var(--button-disabled-border) !important;
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.6 !important;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.disabledButton:hover {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
cursor: not-allowed !important;
|
||||
transform: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.disabledButton:active {
|
||||
background-color: #f8f9fa !important;
|
||||
background-color: var(--button-disabled-bg) !important;
|
||||
transform: none !important;
|
||||
}
|
||||
74
my-app/src/context/ThemeContext.jsx
Normal file
74
my-app/src/context/ThemeContext.jsx
Normal file
@ -0,0 +1,74 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
|
||||
const ThemeContext = createContext();
|
||||
|
||||
export const useTheme = () => {
|
||||
const context = useContext(ThemeContext);
|
||||
if (!context) {
|
||||
throw new Error('useTheme must be used within a ThemeProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export const ThemeProvider = ({ children }) => {
|
||||
const [isDarkMode, setIsDarkMode] = useState(() => {
|
||||
// Check localStorage for saved preference
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme) {
|
||||
return savedTheme === 'dark';
|
||||
}
|
||||
|
||||
// Check system preference if no saved preference
|
||||
if (window.matchMedia) {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
// Default to light mode
|
||||
return false;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Apply theme to document element
|
||||
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
|
||||
}, [isDarkMode]);
|
||||
|
||||
// Listen for system theme changes
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
const handleChange = (e) => {
|
||||
// Only update if user hasn't manually set a preference
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (!savedTheme) {
|
||||
setIsDarkMode(e.matches);
|
||||
}
|
||||
};
|
||||
|
||||
mediaQuery.addEventListener('change', handleChange);
|
||||
return () => mediaQuery.removeEventListener('change', handleChange);
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
setIsDarkMode(prev => !prev);
|
||||
};
|
||||
|
||||
const setTheme = (theme) => {
|
||||
setIsDarkMode(theme === 'dark');
|
||||
};
|
||||
|
||||
const value = {
|
||||
isDarkMode,
|
||||
theme: isDarkMode ? 'dark' : 'light',
|
||||
toggleTheme,
|
||||
setTheme
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={value}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
631
my-app/src/data/courseScheduleData.js
Normal file
631
my-app/src/data/courseScheduleData.js
Normal file
@ -0,0 +1,631 @@
|
||||
export 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'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export 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 const courseInfo = {
|
||||
title: 'Databasmetodik',
|
||||
code: 'DB HT2024',
|
||||
credits: '7,5 hp',
|
||||
coordinator: 'Ann Maria Dorotea Bergholtz',
|
||||
examCredits: '4 hp',
|
||||
projectCredits: '3,5 hp'
|
||||
};
|
||||
24
my-app/src/data/coursesData.js
Normal file
24
my-app/src/data/coursesData.js
Normal file
@ -0,0 +1,24 @@
|
||||
export const coursesData = [
|
||||
{
|
||||
id: 'db-ht2024',
|
||||
title: 'Databasmetodik',
|
||||
code: 'DB HT2024',
|
||||
credits: '7,5 hp',
|
||||
coordinator: 'Ann Maria Dorotea Bergholtz',
|
||||
period: 'HT 2024',
|
||||
description: 'Kursen behandlar konceptuell modellering, databasdesign, SQL, relationsalgebra och normalisering.',
|
||||
color: '#1d4ed8',
|
||||
dataModule: () => import('./courseScheduleData')
|
||||
},
|
||||
{
|
||||
id: 'proto2-vt2025',
|
||||
title: 'Prototyper inom interaktionsdesign II',
|
||||
code: 'PROTO2 VT2025',
|
||||
credits: '7,5 hp',
|
||||
coordinator: 'Ola Knutsson, Johan Stymne',
|
||||
period: 'VT 2025',
|
||||
description: 'Kursen behandlar designsprintar, prototypning i fysiska och digitala material, användarflöden och testning av prototyper.',
|
||||
color: '#059669',
|
||||
dataModule: () => import('./proto2ScheduleData')
|
||||
}
|
||||
];
|
||||
526
my-app/src/data/proto2ScheduleData.js
Normal file
526
my-app/src/data/proto2ScheduleData.js
Normal file
@ -0,0 +1,526 @@
|
||||
export const scheduleData = [
|
||||
// Week 13
|
||||
{
|
||||
week: 13,
|
||||
activities: [
|
||||
{
|
||||
id: 1,
|
||||
date: '2025-03-24',
|
||||
time: '08:00-09:00',
|
||||
location: 'L70',
|
||||
type: 'Föreläsning',
|
||||
title: 'Föreläsning 1',
|
||||
description: 'Kursintroduktion and Introduktion till Designsprint Fas 1: Map. Det är obligatoriskt att deltaga i designsprinten. Eget arbete i designteamet 09:00-11:00',
|
||||
teacher: 'Lon Hansson, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '2025-03-24',
|
||||
time: '11:00-11:45',
|
||||
location: 'L70',
|
||||
type: 'Seminarium',
|
||||
title: 'Seminarium 1',
|
||||
description: 'Designsprint Fas 1: Map, Debriefing',
|
||||
teacher: 'Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: '2025-03-24',
|
||||
time: '13:00-15:00',
|
||||
location: 'L70',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 1',
|
||||
description: 'Designsprint Fas 2: Sketch & Decide, Introduktion',
|
||||
teacher: 'Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: '2025-03-24',
|
||||
time: '15:00-15:45',
|
||||
location: 'L70',
|
||||
type: 'Seminarium',
|
||||
title: 'Seminarium 2',
|
||||
description: 'Designsprint Fas 2: Sketch & Decide, Debriefing',
|
||||
teacher: 'Lon Hansson, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
date: '2025-03-25',
|
||||
time: '08:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 2 grp 1',
|
||||
description: 'Designsprint Fas 3: Prototype in physical design material, Introduktion. Designsprint-grupp 1-7',
|
||||
teacher: 'Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
date: '2025-03-25',
|
||||
time: '13:00-16:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 2 grp 2',
|
||||
description: 'Designsprint Fas 3: Prototype in physical design material, Introduktion. Designsprint-grupp 8-14',
|
||||
teacher: 'Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
date: '2025-03-27',
|
||||
time: '08:00-08:45',
|
||||
location: 'D3, D4',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 3',
|
||||
description: 'Designsprint Fas 4:Prototype in digital design material, Wireframing, Introduktion. Uppstart av dagen. Eget arbete i designteamet 08:20-11:00',
|
||||
teacher: 'Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
date: '2025-03-27',
|
||||
time: '11:00-11:45',
|
||||
location: 'D3, D4',
|
||||
type: 'Seminarium',
|
||||
title: 'Seminarium 3',
|
||||
description: 'Designsprint Fas 4: Prototype in digital design material, Wireframing, Debriefing. D3: Designsprint-grupp 1-7, D4: Designsprint-grupp 8-14',
|
||||
teacher: 'Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
date: '2025-03-27',
|
||||
time: '13:00-16:45',
|
||||
location: 'L50',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 4 grp 1',
|
||||
description: 'Designsprint Fas 5: Test: Introduktion, Tester, Debriefing. Designsprint-grupp 1-7',
|
||||
teacher: 'Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
date: '2025-03-27',
|
||||
time: '13:00-16:45',
|
||||
location: 'L70',
|
||||
type: 'Lektion',
|
||||
title: 'Lektion 4 grp 2',
|
||||
description: 'Designsprint Fas 5: Test: Introduktion, Tester, Debriefing. Designsprint-grupp 8-14',
|
||||
teacher: 'Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
date: '2025-03-28',
|
||||
time: '13:00-15:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 1 grp 1',
|
||||
description: 'Labb 1: Arduino. Muntlig redovisning på plats. Designsprint-grupp 1-5',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 14
|
||||
{
|
||||
week: 14,
|
||||
activities: [
|
||||
{
|
||||
id: 12,
|
||||
date: '2025-03-31',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 1 grp 2',
|
||||
description: 'Labb 1: Arduino. Muntlig redovisning på plats. Designsprint-grupp 6-10',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
date: '2025-03-31',
|
||||
time: '13:00-15:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 1 grp 3',
|
||||
description: 'Labb 1: Arduino. Muntlig redovisning på plats. Designsprint-grupp 11-14',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
date: '2025-04-01',
|
||||
time: '10:00-12:45',
|
||||
location: 'L70',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 1',
|
||||
description: 'UI och Interaktionsprogrammering, del 1. Designsprint-grupp 1-14. Vi kommer att sluta ca kl. 12',
|
||||
teacher: 'Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
date: '2025-04-02',
|
||||
time: '08:00-11:45',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 2 grp 1',
|
||||
description: 'Labb 2: Gränssnittsdesign och prototypning med SwiftUI i XCode. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 1-5',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Mika Haverås, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
date: '2025-04-02',
|
||||
time: '13:00-16:45',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 2 grp 2',
|
||||
description: 'Labb 2: Gränssnittsdesign och prototypning med SwiftUI i XCode. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 6-10',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Mika Haverås, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
date: '2025-04-03',
|
||||
time: '09:00-12:45',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 2 grp 3',
|
||||
description: 'Labb 2: Gränssnittsdesign och prototypning med SwiftUI i XCode. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 11-14',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Mika Haverås, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
date: '2025-04-03',
|
||||
time: '15:00-17:00',
|
||||
location: 'Lilla Hörsalen',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 2',
|
||||
description: 'UI och Interaktionsprogrammering, del 2. Designsprint-grupp 1-14',
|
||||
teacher: 'Ola Knutsson'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 15
|
||||
{
|
||||
week: 15,
|
||||
activities: [
|
||||
{
|
||||
id: 19,
|
||||
date: '2025-04-07',
|
||||
time: '08:00-11:00',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 3 grp 1',
|
||||
description: 'Labb 3: Jetpack Compose i Android Studio. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 1-5',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Lon Hansson, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
date: '2025-04-07',
|
||||
time: '12:00-15:00',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 3 grp 2',
|
||||
description: 'Labb 3: Jetpack Compose i Android Studio. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 6-10',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Kim Lindfors, Lon Hansson, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
date: '2025-04-08',
|
||||
time: '09:00-12:00',
|
||||
location: 'Studentlabb ID Höger',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 3 grp 3',
|
||||
description: 'Labb 3: Jetpack Compose i Android Studio. Muntlig redovisning på plats och filinlämning i iLearn. Designsprint-grupp 11-14',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Kim Lindfors, Lon Hansson, Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
date: '2025-04-10',
|
||||
time: '13:00-15:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 1',
|
||||
description: 'Skisser och Arduino',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne, Kim Lindfors, Mika Haverås'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 16
|
||||
{
|
||||
week: 16,
|
||||
activities: [
|
||||
{
|
||||
id: 23,
|
||||
date: '2025-04-14',
|
||||
time: '09:00-09:45',
|
||||
location: 'L50',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 3 grp 2',
|
||||
description: 'Kick-off för individuella designprojektet. Designsprint-grupp 8-14',
|
||||
teacher: 'Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
date: '2025-04-14',
|
||||
time: '10:00-10:45',
|
||||
location: 'L50',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 3 grp 1',
|
||||
description: 'Kick-off för individuella designprojektet. Designsprint-grupp 1-7',
|
||||
teacher: 'Ola Knutsson'
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
date: '2025-04-14',
|
||||
time: '13:00-16:45',
|
||||
location: 'D3, D4',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 4 grp 1',
|
||||
description: 'Labb 4: HTML, Bootstrap & JavaScript. Designsprint-grupp 1-7',
|
||||
teacher: 'Lon Hansson, Stefan Nenzén'
|
||||
},
|
||||
{
|
||||
id: 26,
|
||||
date: '2025-04-15',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 2',
|
||||
description: 'Användarflöden',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 27,
|
||||
date: '2025-04-15',
|
||||
time: '13:00-16:45',
|
||||
location: 'D3, D4',
|
||||
type: 'Laboration',
|
||||
title: 'Laboration 4 grp 2',
|
||||
description: 'Labb 4: HTML, Bootstrap & JavaScript. Designsprint-grupp 8-14',
|
||||
teacher: 'Lon Hansson, Stefan Nenzén'
|
||||
},
|
||||
{
|
||||
id: 28,
|
||||
date: '2025-04-16',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 1 grp 1',
|
||||
description: 'Interaktion, gränssnittsskisser och UI i fysiska och digitala material. Designsprint-grupp 1-7',
|
||||
teacher: 'Johan Stymne, Ola Knutsson',
|
||||
important: true
|
||||
},
|
||||
{
|
||||
id: 29,
|
||||
date: '2025-04-16',
|
||||
time: '14:00-16:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 1 grp 2',
|
||||
description: 'Interaktion, gränssnittsskisser och UI i fysiska och digitala material. Designsprint-grupp 8-14',
|
||||
teacher: 'Johan Stymne, Ola Knutsson',
|
||||
important: true
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 17
|
||||
{
|
||||
week: 17,
|
||||
activities: [
|
||||
{
|
||||
id: 30,
|
||||
date: '2025-04-23',
|
||||
time: '09:00-10:45',
|
||||
location: 'L70',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 4 grp 2',
|
||||
description: 'McElroys begrepp. Designsprint-grupp 8-14',
|
||||
teacher: 'Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 31,
|
||||
date: '2025-04-23',
|
||||
time: '13:00-14:45',
|
||||
location: 'L70',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 4 grp 1',
|
||||
description: 'McElroys begrepp. Designsprint-grupp 1-7',
|
||||
teacher: 'Johan Stymne'
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
date: '2025-04-24',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 3',
|
||||
description: 'Gestaltning, Bredd, Djup, Interaktivitet, Data',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne, Kim Lindfors, Mika Haverås'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 18
|
||||
{
|
||||
week: 18,
|
||||
activities: [
|
||||
{
|
||||
id: 33,
|
||||
date: '2025-04-29',
|
||||
time: '13:00-14:45',
|
||||
location: 'Lilla Hörsalen',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 5',
|
||||
description: 'Designsystem och värdering. Designsprint-grupp 1-14',
|
||||
teacher: 'Johan Stymne'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 19
|
||||
{
|
||||
week: 19,
|
||||
activities: [
|
||||
{
|
||||
id: 34,
|
||||
date: '2025-05-05',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 4',
|
||||
description: 'Integration av prototypens delar',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne, Kim Lindfors, Mika Haverås'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 20
|
||||
{
|
||||
week: 20,
|
||||
activities: [
|
||||
{
|
||||
id: 35,
|
||||
date: '2025-05-12',
|
||||
time: '13:00-14:45',
|
||||
location: 'L70',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 6 grp 1',
|
||||
description: 'Testning av prototyper. Designsprint-grupp 1-7',
|
||||
teacher: 'Johan Stymne, Lon Hansson'
|
||||
},
|
||||
{
|
||||
id: 36,
|
||||
date: '2025-05-12',
|
||||
time: '15:00-16:45',
|
||||
location: 'Lilla Hörsalen',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 6 grp 2',
|
||||
description: 'Testning av prototyper. Designsprint-grupp 8-14',
|
||||
teacher: 'Johan Stymne, Lon Hansson'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 21
|
||||
{
|
||||
week: 21,
|
||||
activities: [
|
||||
{
|
||||
id: 37,
|
||||
date: '2025-05-19',
|
||||
time: '09:00-11:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 5',
|
||||
description: 'Designsystem, Ändringar efter testerna',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Johan Stymne, Kim Lindfors'
|
||||
},
|
||||
{
|
||||
id: 38,
|
||||
date: '2025-05-22',
|
||||
time: '15:00-17:00',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Workshop',
|
||||
title: 'Workshop 7',
|
||||
description: 'Resttillfälle Workshop, möjlighet att hämta ut prototyper kl. 12 i ID:Fix för att förbereda dessa för testning.',
|
||||
teacher: 'Ola Knutsson'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 22
|
||||
{
|
||||
week: 22,
|
||||
activities: [
|
||||
{
|
||||
id: 39,
|
||||
date: '2025-05-28',
|
||||
time: '12:00-14:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Handledning',
|
||||
title: 'Handledning 6',
|
||||
description: 'Alla delar av projektet',
|
||||
teacher: 'António Miguel Beleza Maciel Pinheiro Braga, Jacob Reinikainen Lindström, Mika Haverås, Ola Knutsson'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Week 23
|
||||
{
|
||||
week: 23,
|
||||
activities: [
|
||||
{
|
||||
id: 40,
|
||||
date: '2025-06-02',
|
||||
time: '12:00-13:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 2 grp 1',
|
||||
description: 'Visning och demo av de individuella designprojekten',
|
||||
teacher: 'Jacob Reinikainen Lindström, Johan Stymne, Ola Knutsson',
|
||||
important: true
|
||||
},
|
||||
{
|
||||
id: 41,
|
||||
date: '2025-06-02',
|
||||
time: '14:00-15:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 2 grp 2',
|
||||
description: 'Visning och demo av de individuella designprojekten',
|
||||
teacher: 'Jacob Reinikainen Lindström, Johan Stymne, Ola Knutsson',
|
||||
important: true
|
||||
},
|
||||
{
|
||||
id: 42,
|
||||
date: '2025-06-03',
|
||||
time: '12:00-13:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 2 grp 3',
|
||||
description: 'Visning och demo av de individuella designprojekten',
|
||||
teacher: 'Johan Stymne, Mika Haverås, Ola Knutsson',
|
||||
important: true
|
||||
},
|
||||
{
|
||||
id: 43,
|
||||
date: '2025-06-03',
|
||||
time: '14:00-15:45',
|
||||
location: 'Studentlabb ID:fix',
|
||||
type: 'Redovisning',
|
||||
title: 'Redovisning 2 grp 4',
|
||||
description: 'Visning och demo av de individuella designprojekten',
|
||||
teacher: 'Johan Stymne, Mika Haverås, Ola Knutsson',
|
||||
important: true
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const examData = [
|
||||
{
|
||||
id: 'exam1',
|
||||
date: '2025-06-09',
|
||||
time: '',
|
||||
type: 'Inlämningsuppgifter',
|
||||
title: 'Inlämningsuppgifter (7,5hp)',
|
||||
location: '',
|
||||
important: true,
|
||||
isExam: true
|
||||
}
|
||||
];
|
||||
|
||||
export const courseInfo = {
|
||||
title: 'Prototyper inom interaktionsdesign II',
|
||||
code: 'PROTO2 VT2025',
|
||||
credits: '7,5 hp',
|
||||
coordinator: 'Ola Knutsson, Johan Stymne',
|
||||
examCredits: '7,5 hp',
|
||||
projectCredits: 'Inlämningsuppgifter'
|
||||
};
|
||||
@ -1,4 +1,5 @@
|
||||
@import './fonts.css';
|
||||
@import './styles/variables.css';
|
||||
|
||||
:root {
|
||||
font-family: 'The Sans', system-ui, Avenir, Helvetica, Arial, sans-serif !important;
|
||||
@ -6,8 +7,8 @@
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--bg-primary);
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
@ -17,11 +18,11 @@
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
color: var(--color-primary);
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
color: var(--color-primary-hover);
|
||||
}
|
||||
|
||||
body {
|
||||
@ -56,14 +57,14 @@ button {
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--bg-primary);
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
background-color: var(--button-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
44
my-app/src/pages/CourseSchedule.jsx
Normal file
44
my-app/src/pages/CourseSchedule.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import styles from './CourseSchedule.module.css';
|
||||
import { coursesData } from '../data/coursesData';
|
||||
|
||||
export function CourseSchedule() {
|
||||
|
||||
return (
|
||||
<div className={styles.pageContainer}>
|
||||
<div className={styles.header}>
|
||||
<h1 className={styles.courseTitle}>Kursscheman</h1>
|
||||
<p className={styles.courseInfo}>Välj en kurs för att se dess schema</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.content}>
|
||||
<div className={styles.coursesList}>
|
||||
{coursesData.map((course) => (
|
||||
<Link
|
||||
key={course.id}
|
||||
to={`/course-schedule/${course.id}`}
|
||||
className={styles.courseCard}
|
||||
>
|
||||
<div className={styles.courseCardHeader}>
|
||||
<div
|
||||
className={styles.courseColorIndicator}
|
||||
style={{ backgroundColor: course.color }}
|
||||
></div>
|
||||
<div className={styles.courseCardContent}>
|
||||
<h3 className={styles.courseCardTitle}>{course.title}</h3>
|
||||
<p className={styles.courseCardCode}>{course.code} • {course.credits}</p>
|
||||
<p className={styles.courseCardDescription}>{course.description}</p>
|
||||
<div className={styles.courseCardFooter}>
|
||||
<span className={styles.courseCardPeriod}>{course.period}</span>
|
||||
<span className={styles.courseCardCoordinator}>{course.coordinator}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
532
my-app/src/pages/CourseSchedule.module.css
Normal file
532
my-app/src/pages/CourseSchedule.module.css
Normal file
@ -0,0 +1,532 @@
|
||||
.pageContainer {
|
||||
min-height: 100vh;
|
||||
background: var(--bg-iphone-gradient);
|
||||
padding: var(--container-padding);
|
||||
max-width: var(--page-max-width);
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: var(--spacing-3xl);
|
||||
text-align: center;
|
||||
padding: var(--spacing-2xl) var(--spacing-lg);
|
||||
background: var(--bg-iphone-header);
|
||||
border: var(--border-width-thin) solid var(--border-dark);
|
||||
border-radius: var(--border-radius-xl);
|
||||
box-shadow: var(--shadow-iphone-inset), var(--shadow-iphone-outer);
|
||||
}
|
||||
|
||||
.courseTitle {
|
||||
font-size: var(--font-size-5xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--color-black);
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
font-family: var(--font-primary);
|
||||
text-shadow: var(--text-shadow-light);
|
||||
}
|
||||
|
||||
.courseInfo {
|
||||
color: var(--text-primary);
|
||||
font-size: var(--font-size-lg);
|
||||
margin: 0;
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-shadow: var(--text-shadow-light);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-2xl);
|
||||
}
|
||||
|
||||
.coursesList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.courseCard {
|
||||
display: block;
|
||||
background: var(--bg-primary);
|
||||
border-radius: var(--border-radius-2xl);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-lg);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: var(--transition-transform);
|
||||
}
|
||||
|
||||
.courseCard:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-xl);
|
||||
}
|
||||
|
||||
.courseCardHeader {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--spacing-lg);
|
||||
padding: var(--spacing-2xl);
|
||||
}
|
||||
|
||||
.courseColorIndicator {
|
||||
width: var(--color-indicator-width);
|
||||
height: var(--color-indicator-height);
|
||||
border-radius: var(--border-radius-sm);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.courseCardContent {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.courseCardTitle {
|
||||
font-size: var(--font-size-3xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-gray-800);
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
line-height: var(--line-height-normal);
|
||||
}
|
||||
|
||||
.courseCardCode {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--font-size-md);
|
||||
margin: 0 0 var(--spacing-md) 0;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.courseCardDescription {
|
||||
color: var(--color-gray-600);
|
||||
font-size: var(--font-size-md);
|
||||
line-height: var(--line-height-relaxed);
|
||||
margin: 0 0 var(--spacing-lg) 0;
|
||||
}
|
||||
|
||||
.courseCardFooter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.courseCardPeriod {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.courseCardCoordinator {
|
||||
color: var(--color-gray-400);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
/* Day grouping styles */
|
||||
.dayGroup {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.dayGroup:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.dayHeader {
|
||||
margin-bottom: 0.75rem;
|
||||
padding: 0 1.25rem;
|
||||
}
|
||||
|
||||
.dayTitle {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.dayActivitiesList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
padding: 0 1.25rem;
|
||||
}
|
||||
|
||||
.singleActivityWrapper {
|
||||
padding: 0 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Day divider styles */
|
||||
.dayDivider {
|
||||
background: var(--bg-iphone-day-divider);
|
||||
border-top: var(--border-width-thin) solid var(--border-dark);
|
||||
border-bottom: var(--border-width-thin) solid var(--border-dark);
|
||||
padding: var(--spacing-sm) var(--spacing-xl);
|
||||
margin: 0;
|
||||
position: relative;
|
||||
box-shadow: var(--shadow-iphone-day-divider);
|
||||
}
|
||||
|
||||
.dayDivider:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.dayDividerText {
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-black);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
text-shadow: var(--text-shadow-light);
|
||||
}
|
||||
|
||||
.todayIndicator {
|
||||
color: var(--color-iphone-blue);
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.section {
|
||||
background: var(--bg-primary);
|
||||
border: var(--border-width-thin) solid var(--border-dark);
|
||||
border-radius: var(--border-radius-xl);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-iphone-inset), var(--shadow-iphone-outer);
|
||||
}
|
||||
|
||||
.sectionTitle {
|
||||
font-size: var(--font-size-2xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-black);
|
||||
margin: 0;
|
||||
padding: var(--spacing-lg) var(--spacing-xl);
|
||||
background: var(--bg-iphone-section);
|
||||
border-bottom: var(--border-width-thin) solid var(--border-dark);
|
||||
text-shadow: var(--text-shadow-light);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.currentWeekBadge {
|
||||
background: linear-gradient(to bottom, var(--color-iphone-blue), var(--color-iphone-blue-dark));
|
||||
color: var(--color-white);
|
||||
font-size: var(--font-size-xs);
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
border-radius: var(--border-radius-xl);
|
||||
border: var(--border-width-thin) solid var(--color-iphone-blue-border);
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-left: var(--spacing-sm);
|
||||
text-shadow: var(--text-shadow-dark);
|
||||
box-shadow: var(--shadow-iphone-button);
|
||||
}
|
||||
|
||||
.activitiesList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.activityCard {
|
||||
padding: var(--spacing-lg) var(--spacing-xl);
|
||||
border-bottom: var(--border-width-thin) solid var(--border-divider);
|
||||
cursor: pointer;
|
||||
transition: var(--transition-fast);
|
||||
position: relative;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.activityCard:hover {
|
||||
background: var(--bg-iphone-hover);
|
||||
}
|
||||
|
||||
.activityCard:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.activityCard.today {
|
||||
background: var(--state-today-bg);
|
||||
border-left: var(--border-width-thick) solid var(--state-today-border);
|
||||
}
|
||||
|
||||
.activityCard.important {
|
||||
border-left: var(--border-width-thick) solid var(--state-important-border);
|
||||
background: var(--state-important-bg);
|
||||
}
|
||||
|
||||
.activityCard.cancelled {
|
||||
border-left: var(--border-width-thick) solid var(--state-cancelled-border);
|
||||
background: var(--state-cancelled-bg);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.activityCard.cancelled .activityTitle {
|
||||
text-decoration: line-through;
|
||||
color: var(--state-cancelled-text);
|
||||
}
|
||||
|
||||
.activityCard.cancelled .activityTitle {
|
||||
background: var(--color-gray-200) !important;
|
||||
color: var(--state-cancelled-text) !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: var(--font-size-sm);
|
||||
color: var(--text-secondary);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.activityMain {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
|
||||
.activityTitle {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-gray-900);
|
||||
margin: 0 0 var(--spacing-xs) 0;
|
||||
line-height: var(--line-height-normal);
|
||||
}
|
||||
|
||||
.activityLocation {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--text-secondary);
|
||||
margin: var(--spacing-xs) 0 0 0;
|
||||
}
|
||||
|
||||
.expandIcon {
|
||||
font-size: 1.2rem;
|
||||
color: var(--color-gray-400);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
flex-shrink: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.activityDetails {
|
||||
margin-top: var(--spacing-lg);
|
||||
padding-top: var(--spacing-lg);
|
||||
border-top: var(--border-width-thin) solid var(--color-gray-200);
|
||||
margin-left: 92px;
|
||||
}
|
||||
|
||||
.activityDescription {
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-gray-600);
|
||||
line-height: var(--line-height-loose);
|
||||
margin: 0 0 var(--spacing-md) 0;
|
||||
}
|
||||
|
||||
.activityTeacher {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.courseInfoCard {
|
||||
padding: var(--spacing-xl);
|
||||
}
|
||||
|
||||
.courseInfoCard p {
|
||||
margin: 0 0 var(--spacing-md) 0;
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-gray-600);
|
||||
}
|
||||
|
||||
.courseInfoCard p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Activity type colors for titles */
|
||||
.lecture .activityTitle {
|
||||
background: var(--activity-lecture-bg);
|
||||
color: var(--activity-lecture-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.lesson .activityTitle {
|
||||
background: var(--activity-lesson-bg);
|
||||
color: var(--activity-lesson-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.guidance .activityTitle {
|
||||
background: var(--activity-guidance-bg);
|
||||
color: var(--activity-guidance-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.presentation .activityTitle {
|
||||
background: var(--activity-presentation-bg);
|
||||
color: var(--activity-presentation-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.introduction .activityTitle {
|
||||
background: var(--activity-info-bg);
|
||||
color: var(--activity-info-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.exam .activityTitle {
|
||||
background: var(--activity-exam-bg);
|
||||
color: var(--activity-exam-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.project .activityTitle {
|
||||
background: var(--activity-project-bg);
|
||||
color: var(--activity-project-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.info .activityTitle {
|
||||
background: var(--activity-info-bg);
|
||||
color: var(--activity-info-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.laboration .activityTitle {
|
||||
background: var(--activity-laboration-bg);
|
||||
color: var(--activity-laboration-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.workshop .activityTitle {
|
||||
background: var(--activity-workshop-bg);
|
||||
color: var(--activity-workshop-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.seminar .activityTitle {
|
||||
background: var(--activity-seminar-bg);
|
||||
color: var(--activity-seminar-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
.default .activityTitle {
|
||||
background: var(--activity-default-bg);
|
||||
color: var(--activity-default-text);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-md);
|
||||
width: fit-content;
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
232
my-app/src/pages/CourseScheduleView.jsx
Normal file
232
my-app/src/pages/CourseScheduleView.jsx
Normal file
@ -0,0 +1,232 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import styles from './CourseSchedule.module.css';
|
||||
import { coursesData } from '../data/coursesData';
|
||||
|
||||
export function CourseScheduleView() {
|
||||
const { courseId } = useParams();
|
||||
const [courseData, setCourseData] = useState(null);
|
||||
const [scheduleData, setScheduleData] = useState([]);
|
||||
const [examData, setExamData] = useState([]);
|
||||
const [courseInfo, setCourseInfo] = useState({});
|
||||
const [expandedActivity, setExpandedActivity] = useState(null);
|
||||
const [currentWeek, setCurrentWeek] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const loadCourseData = async () => {
|
||||
const course = coursesData.find(c => c.id === courseId);
|
||||
if (!course) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setCourseData(course);
|
||||
|
||||
try {
|
||||
const dataModule = await course.dataModule();
|
||||
setScheduleData(dataModule.scheduleData);
|
||||
setExamData(dataModule.examData);
|
||||
setCourseInfo(dataModule.courseInfo);
|
||||
} catch (error) {
|
||||
console.error('Failed to load course data:', error);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
loadCourseData();
|
||||
|
||||
// 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);
|
||||
}, [courseId]);
|
||||
|
||||
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;
|
||||
case 'Workshop': return styles.workshop;
|
||||
case 'Seminarium': return styles.seminar;
|
||||
// Leave unclear/mixed categories without color styling
|
||||
case 'Introduktion':
|
||||
case 'Info':
|
||||
case 'Inlämningsuppgifter':
|
||||
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 ActivityCard = ({ activity, isExam = false, hideDayInfo = false }) => {
|
||||
const { formatted: formattedDate, isToday } = formatDate(activity.date);
|
||||
const isExpanded = expandedActivity === activity.id;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${styles.activityCard} ${getActivityTypeClass(activity.type)} ${!hideDayInfo && isToday ? styles.today : ''} ${activity.important ? styles.important : ''} ${activity.cancelled ? styles.cancelled : ''}`}
|
||||
onClick={() => toggleActivity(activity.id)}
|
||||
>
|
||||
<div className={styles.activityHeader}>
|
||||
<div className={styles.activityMeta}>
|
||||
{!hideDayInfo && (
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return <div className={styles.pageContainer}>Loading...</div>;
|
||||
}
|
||||
|
||||
if (!courseData) {
|
||||
return (
|
||||
<div className={styles.pageContainer}>
|
||||
<div className={styles.notFound}>
|
||||
<h1>Course not found</h1>
|
||||
<Link to="/course-schedule">← Back to courses</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.pageContainer}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.backLink}>
|
||||
<Link to="/course-schedule">← Tillbaka till kurser</Link>
|
||||
</div>
|
||||
<h1 className={styles.courseTitle}>{courseInfo.title}</h1>
|
||||
<p className={styles.courseInfo}>{courseInfo.code} • {courseInfo.credits}</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.content}>
|
||||
{/* Upcoming Exams */}
|
||||
{examData.length > 0 && (
|
||||
<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) => {
|
||||
// Group activities by date for day dividers
|
||||
const activitiesByDate = weekData.activities.reduce((acc, activity) => {
|
||||
const dateKey = activity.date;
|
||||
if (!acc[dateKey]) {
|
||||
acc[dateKey] = [];
|
||||
}
|
||||
acc[dateKey].push(activity);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Sort dates chronologically
|
||||
const sortedDates = Object.keys(activitiesByDate).sort((a, b) => new Date(a) - new Date(b));
|
||||
|
||||
return (
|
||||
<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}>
|
||||
{sortedDates.map((date, dateIndex) => {
|
||||
const { formatted: formattedDate, isToday } = formatDate(date);
|
||||
const dayActivities = activitiesByDate[date];
|
||||
|
||||
return (
|
||||
<div key={date}>
|
||||
<div className={styles.dayDivider}>
|
||||
<span className={styles.dayDividerText}>
|
||||
{formattedDate}
|
||||
{isToday && <span className={styles.todayIndicator}>• Idag</span>}
|
||||
</span>
|
||||
</div>
|
||||
{dayActivities.map((activity) => (
|
||||
<ActivityCard key={activity.id} activity={activity} hideDayInfo={true} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Course Info */}
|
||||
<section className={styles.section}>
|
||||
<h2 className={styles.sectionTitle}>ℹ️ Kursinformation</h2>
|
||||
<div className={styles.courseInfoCard}>
|
||||
<p><strong>Kursansvarig:</strong> {courseInfo.coordinator}</p>
|
||||
<p><strong>Omfattning:</strong> {courseInfo.credits}</p>
|
||||
{courseInfo.examCredits && (
|
||||
<p><strong>Tentamen:</strong> {courseInfo.examCredits}</p>
|
||||
)}
|
||||
{courseInfo.projectCredits && (
|
||||
<p><strong>Projektarbete:</strong> {courseInfo.projectCredits}</p>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
.pageContainer {
|
||||
padding: 1rem;
|
||||
background-color: white;
|
||||
padding: var(--container-padding);
|
||||
background-color: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.formContainer {
|
||||
@ -20,7 +22,7 @@
|
||||
margin-top: 2rem;
|
||||
padding: 2rem;
|
||||
border-radius: 0.3rem;
|
||||
outline: 1px solid #E7E7E7;
|
||||
outline: 1px solid var(--border-light);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@ -38,8 +40,8 @@
|
||||
padding: 0;
|
||||
z-index: 10;
|
||||
padding: 1rem;
|
||||
border-top: 1px solid rgb(214, 214, 214);
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
|
||||
border-top: 1px solid var(--border-medium);
|
||||
box-shadow: var(--modal-footer-shadow);
|
||||
}
|
||||
|
||||
.cancelButton {
|
||||
@ -56,7 +58,7 @@
|
||||
|
||||
|
||||
.inactiveButton {
|
||||
color: #D4D4D4;
|
||||
color: var(--text-disabled);
|
||||
}
|
||||
|
||||
|
||||
@ -95,9 +97,9 @@
|
||||
font-size: 1.2rem;
|
||||
padding: 1rem 4rem;
|
||||
/*border: 1px solid #D4D4D4;*/
|
||||
background-color: #2B4EF5;
|
||||
background-color: var(--color-primary);
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
color: var(--color-white);
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
@ -109,7 +111,7 @@
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: var(--button-mobile-shadow);
|
||||
cursor: pointer;
|
||||
}
|
||||
.bookingSummaryRight {
|
||||
@ -118,17 +120,17 @@
|
||||
bottom: 16px;
|
||||
left: 16px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: var(--button-mobile-shadow);
|
||||
height: fit-content;
|
||||
background-color: white;
|
||||
background-color: var(--bg-primary);
|
||||
padding: 1rem;
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.inactiveButton {
|
||||
background-color: rgb(220, 220, 220);
|
||||
color: #8f8f8f;
|
||||
background-color: var(--button-disabled-bg);
|
||||
color: var(--button-disabled-text);
|
||||
}
|
||||
|
||||
.bookingSummary p {
|
||||
@ -139,7 +141,7 @@
|
||||
|
||||
.line {
|
||||
height: 1px;
|
||||
background-color: rgb(216, 216, 216);
|
||||
background-color: var(--divider-color);
|
||||
width: 100%;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
@ -158,8 +160,8 @@
|
||||
|
||||
.filterButton {
|
||||
width: fit-content;
|
||||
background: white;
|
||||
border: 1px solid #D1D5DB;
|
||||
background: var(--filter-button-bg);
|
||||
border: 1px solid var(--filter-button-border);
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
display: flex;
|
||||
@ -169,27 +171,27 @@
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
color: var(--filter-button-text);
|
||||
}
|
||||
|
||||
.filterButton:hover {
|
||||
background: #F9FAFB;
|
||||
border-color: #9CA3AF;
|
||||
background: var(--filter-button-hover-bg);
|
||||
border-color: var(--filter-button-hover-border);
|
||||
}
|
||||
|
||||
.filterButton:active {
|
||||
background: #F3F4F6;
|
||||
background: var(--filter-button-active-bg);
|
||||
}
|
||||
|
||||
.activeFilter {
|
||||
background: #EBF8FF !important;
|
||||
border-color: #3B82F6 !important;
|
||||
color: #1E40AF !important;
|
||||
background: var(--filter-active-bg) !important;
|
||||
border-color: var(--filter-active-border) !important;
|
||||
color: var(--filter-active-text) !important;
|
||||
}
|
||||
|
||||
.activeFilter:hover {
|
||||
background: #DBEAFE !important;
|
||||
border-color: #2563EB !important;
|
||||
background: var(--filter-active-hover-bg) !important;
|
||||
border-color: var(--filter-active-hover-border) !important;
|
||||
}
|
||||
|
||||
.filterIcon {
|
||||
@ -198,7 +200,7 @@
|
||||
|
||||
.chevron {
|
||||
font-size: 0.75rem;
|
||||
color: #6B7280;
|
||||
color: var(--filter-chevron-color);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
@ -214,8 +216,8 @@
|
||||
width: fit-content;
|
||||
max-width: 600px;
|
||||
padding: 1rem;
|
||||
background: #F9FAFB;
|
||||
border: 1px solid #E5E7EB;
|
||||
background: var(--filter-content-bg);
|
||||
border: 1px solid var(--filter-content-border);
|
||||
border-radius: 0.5rem;
|
||||
animation: slideDown 0.2s ease-out;
|
||||
}
|
||||
@ -230,15 +232,15 @@
|
||||
.resetSection {
|
||||
margin-top: 1rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid #E5E7EB;
|
||||
border-top: 1px solid var(--filter-reset-divider);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.resetButton {
|
||||
background: white;
|
||||
border: 1px solid #DC2626;
|
||||
color: #DC2626;
|
||||
background: var(--reset-button-bg);
|
||||
border: 1px solid var(--reset-button-border);
|
||||
color: var(--reset-button-text);
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
@ -248,13 +250,13 @@
|
||||
}
|
||||
|
||||
.resetButton:hover {
|
||||
background: #FEF2F2;
|
||||
border-color: #B91C1C;
|
||||
color: #B91C1C;
|
||||
background: var(--reset-button-hover-bg);
|
||||
border-color: var(--reset-button-hover-border);
|
||||
color: var(--reset-button-hover-text);
|
||||
}
|
||||
|
||||
.resetButton:active {
|
||||
background: #FEE2E2;
|
||||
background: var(--reset-button-active-bg);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ export function RoomBooking({ bookings, showSuccessBanner, lastCreatedBooking, o
|
||||
<hr className={styles.sectionDivider} />
|
||||
<h2 className={styles.sectionHeading}>Ny bokning</h2>
|
||||
<Link to='/new-booking'>
|
||||
<Card imageUrl="/grupprum.jpg" header="Litet grupprum" subheader="Plats för 5 personer" />
|
||||
<Card imageUrl="./grupprum.jpg" header="Litet grupprum" subheader="Plats för 5 personer" />
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,24 +1,28 @@
|
||||
.pageContainer {
|
||||
color: rgb(51, 51, 51);
|
||||
padding: 1rem;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--bg-tertiary);
|
||||
padding: var(--container-padding);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.pageHeading {
|
||||
font-size: 2.6rem;
|
||||
font-weight: 300;
|
||||
font-family: 'The Sans', system-ui, sans-serif;
|
||||
font-size: var(--font-size-6xl);
|
||||
font-weight: var(--font-weight-light);
|
||||
font-family: var(--font-primary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.sectionHeading {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
font-size: var(--font-size-4xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin-bottom: var(--spacing-lg);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.sectionDivider {
|
||||
border: none;
|
||||
border-top: 1px solid #dedede;
|
||||
margin-bottom: 2rem;
|
||||
border-top: var(--border-width-thin) solid var(--border-medium);
|
||||
margin-bottom: var(--spacing-3xl);
|
||||
}
|
||||
|
||||
.welcomeSection {
|
||||
@ -26,10 +30,10 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #3d50a8;
|
||||
padding: 2rem 2.5rem;
|
||||
margin: 1.5rem 0 2.5rem 0;
|
||||
color: white;
|
||||
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.15);
|
||||
padding: var(--spacing-3xl) var(--spacing-4xl);
|
||||
margin: var(--spacing-2xl) 0 var(--spacing-4xl) 0;
|
||||
color: var(--color-white);
|
||||
box-shadow: var(--shadow-2xl);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -52,24 +56,24 @@
|
||||
|
||||
.welcomeTitle {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 700;
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin: 0;
|
||||
font-family: 'The Sans', system-ui, sans-serif;
|
||||
font-family: var(--font-primary);
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.welcomeSubtitle {
|
||||
font-size: 1rem;
|
||||
margin: 0.5rem 0 0 0;
|
||||
font-size: var(--font-size-xl);
|
||||
margin: var(--spacing-sm) 0 0 0;
|
||||
opacity: 0.9;
|
||||
font-weight: 400;
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
.welcomeIcon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
opacity: 0.8;
|
||||
color: white;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.welcomeIcon svg {
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
}
|
||||
|
||||
&:hover:not([data-selected]):not([data-disabled]):not([data-unavailable]) {
|
||||
background-color: #e9e9e9;
|
||||
background-color: var(--highlight-hover);
|
||||
}
|
||||
|
||||
&[data-pressed] {
|
||||
@ -71,8 +71,7 @@
|
||||
.react-aria-CalendarCell {
|
||||
&[data-unavailable] {
|
||||
text-decoration: line-through;
|
||||
color: var(--invalid-color);
|
||||
color: rgb(203, 203, 203);
|
||||
color: var(--text-color-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,23 +31,26 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s, opacity 0.2s;
|
||||
transition: background-color 0.2s, opacity 0.2s, color 0.2s;
|
||||
color: var(--chevron-button-color);
|
||||
}
|
||||
|
||||
.chevron-button:hover:not(:disabled) {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
background-color: var(--highlight-hover);
|
||||
}
|
||||
|
||||
.chevron-button:active:not(:disabled) {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
background-color: var(--highlight-pressed);
|
||||
}
|
||||
|
||||
.chevron-button:disabled {
|
||||
cursor: default;
|
||||
color: var(--chevron-button-disabled-color);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.chevron-button:focus-visible {
|
||||
outline: 2px solid #2563EB;
|
||||
outline: 2px solid var(--focus-ring-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@ -58,7 +61,7 @@
|
||||
forced-color-adjust: none;
|
||||
border-radius: 4px;
|
||||
/*border: none;*/
|
||||
border: 1px solid #D4D4D4;
|
||||
border: 1px solid var(--border-color);
|
||||
/*width: 1.429rem;*/
|
||||
/*height: 1.429rem;*/
|
||||
width: fit-content;
|
||||
@ -69,7 +72,7 @@
|
||||
&[data-pressed] {
|
||||
box-shadow: none;
|
||||
/*background: var(--highlight-background);*/
|
||||
background: #f1f1f1;
|
||||
background: var(--button-background-pressed);
|
||||
}
|
||||
|
||||
&[data-focus-visible] {
|
||||
@ -85,12 +88,12 @@
|
||||
justify-content: space-between !important;
|
||||
gap: 0.75rem !important;
|
||||
cursor: pointer !important;
|
||||
background: white !important;
|
||||
border: 1px solid #E5E7EB !important;
|
||||
background: var(--field-background) !important;
|
||||
border: 1px solid var(--border-color) !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 12px 16px !important;
|
||||
font-weight: 500 !important;
|
||||
color: #374151 !important;
|
||||
color: var(--field-text-color) !important;
|
||||
transition: all 0.2s ease !important;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) !important;
|
||||
white-space: nowrap !important;
|
||||
@ -103,21 +106,21 @@
|
||||
}
|
||||
|
||||
.calendar-button:hover {
|
||||
border-color: #D1D5DB !important;
|
||||
border-color: var(--border-color-hover) !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
.calendar-button[data-pressed] {
|
||||
background: #F9FAFB !important;
|
||||
border-color: #9CA3AF !important;
|
||||
background: var(--button-background-pressed) !important;
|
||||
border-color: var(--border-color-pressed) !important;
|
||||
transform: translateY(1px) !important;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) !important;
|
||||
}
|
||||
|
||||
.calendar-button[data-focus-visible] {
|
||||
outline: 2px solid #2563EB !important;
|
||||
outline: 2px solid var(--focus-ring-color) !important;
|
||||
outline-offset: 2px !important;
|
||||
border-color: #2563EB !important;
|
||||
border-color: var(--focus-ring-color) !important;
|
||||
}
|
||||
|
||||
.calendar-date {
|
||||
|
||||
@ -71,7 +71,6 @@ export function DatePicker<T extends DateValue>(
|
||||
disabled={!canNavigatePrevious}
|
||||
>
|
||||
<ChevronLeft
|
||||
color={!canNavigatePrevious ? "#666" : "#111"}
|
||||
disabled={!canNavigatePrevious}
|
||||
/>
|
||||
</button>
|
||||
@ -85,7 +84,6 @@ export function DatePicker<T extends DateValue>(
|
||||
disabled={!canNavigateNext}
|
||||
>
|
||||
<ChevronRight
|
||||
color={!canNavigateNext ? "#666" : "#111"}
|
||||
disabled={!canNavigateNext}
|
||||
/>
|
||||
</button>
|
||||
|
||||
@ -61,6 +61,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode support for data-theme attribute */
|
||||
[data-theme="dark"] {
|
||||
--background-color: #1d1d1d;
|
||||
--gray-50: #101010;
|
||||
--gray-100: #393939;
|
||||
--gray-200: #4f4f4f;
|
||||
--gray-300: #CECECE;
|
||||
--gray-400: #848484;
|
||||
--gray-500: #a7a7a7;
|
||||
--gray-600: #cfcfcf;
|
||||
--purple-100: #3c1e95;
|
||||
--purple-200: #522acd;
|
||||
--purple-300: #6f46ed;
|
||||
--purple-400: #8e6ef1;
|
||||
--purple-500: #b099f5;
|
||||
--purple-600: #d5c8fa;
|
||||
--red-100: #721200;
|
||||
--red-200: #9c1900;
|
||||
--red-300: #cc2000;
|
||||
--red-400: #e95034;
|
||||
--red-500: #f08c79;
|
||||
--red-600: #f7c3ba;
|
||||
--highlight-hover: rgb(255 255 255 / 0.1);
|
||||
--highlight-pressed: rgb(255 255 255 / 0.2);
|
||||
}
|
||||
|
||||
/* Semantic colors */
|
||||
:root {
|
||||
--focus-ring-color: var(--purple-400);
|
||||
|
||||
616
my-app/src/styles/variables.css
Normal file
616
my-app/src/styles/variables.css
Normal file
@ -0,0 +1,616 @@
|
||||
:root {
|
||||
/* === COLORS === */
|
||||
|
||||
/* Primary Colors */
|
||||
--color-primary: #007AFF;
|
||||
--color-primary-hover: #0056b3;
|
||||
--color-primary-light: rgba(0, 122, 255, 0.12);
|
||||
|
||||
/* iPhone/iPod Style Colors */
|
||||
--color-iphone-blue: #4d90fe;
|
||||
--color-iphone-blue-dark: #3e7ce0;
|
||||
--color-iphone-blue-border: #2d5aa0;
|
||||
|
||||
/* Grayscale */
|
||||
--color-black: #000;
|
||||
--color-gray-900: #111827;
|
||||
--color-gray-800: #1f2937;
|
||||
--color-gray-700: #374151;
|
||||
--color-gray-600: #4b5563;
|
||||
--color-gray-500: #6b7280;
|
||||
--color-gray-400: #9ca3af;
|
||||
--color-gray-300: #d1d5db;
|
||||
--color-gray-200: #e5e7eb;
|
||||
--color-gray-100: #f3f4f6;
|
||||
--color-gray-50: #f9fafb;
|
||||
--color-white: #fff;
|
||||
|
||||
/* Text Colors */
|
||||
--text-primary: #333;
|
||||
--text-secondary: #6b7280;
|
||||
--text-tertiary: #9ca3af;
|
||||
--text-muted: #999;
|
||||
|
||||
/* Background Colors */
|
||||
--bg-primary: #fff;
|
||||
--bg-secondary: #f8f8f8;
|
||||
--bg-tertiary: #fafafa;
|
||||
--bg-muted: #f0f0f0;
|
||||
|
||||
/* iPhone/iPod Style Backgrounds */
|
||||
--bg-iphone-gradient: linear-gradient(to bottom, #c5ccd4, #92a5b8);
|
||||
--bg-iphone-header: linear-gradient(to bottom, #ffffff, #e6e6e6);
|
||||
--bg-iphone-section: linear-gradient(to bottom, #f2f2f2, #d9d9d9);
|
||||
--bg-iphone-day-divider: linear-gradient(to bottom, #e6e6e6, #d9d9d9);
|
||||
--bg-iphone-hover: linear-gradient(to bottom, #e8f0ff, #d0e2ff);
|
||||
|
||||
/* Activity Type Colors */
|
||||
--activity-lecture-bg: #dbeafe;
|
||||
--activity-lecture-text: #1d4ed8;
|
||||
--activity-lesson-bg: #dcfce7;
|
||||
--activity-lesson-text: #166534;
|
||||
--activity-guidance-bg: #fef3c7;
|
||||
--activity-guidance-text: #b45309;
|
||||
--activity-presentation-bg: #f3e8ff;
|
||||
--activity-presentation-text: #7c3aed;
|
||||
--activity-exam-bg: #fee2e2;
|
||||
--activity-exam-text: #dc2626;
|
||||
--activity-project-bg: #f0fdf4;
|
||||
--activity-project-text: #15803d;
|
||||
--activity-info-bg: #fef3c7;
|
||||
--activity-info-text: #b45309;
|
||||
--activity-laboration-bg: #ecfdf5;
|
||||
--activity-laboration-text: #047857;
|
||||
--activity-workshop-bg: #fef2f2;
|
||||
--activity-workshop-text: #dc2626;
|
||||
--activity-seminar-bg: #f0f4ff;
|
||||
--activity-seminar-text: #3b82f6;
|
||||
--activity-default-bg: #f1f5f9;
|
||||
--activity-default-text: #475569;
|
||||
|
||||
/* Border Colors */
|
||||
--border-light: #E5E5E5;
|
||||
--border-medium: #dedede;
|
||||
--border-dark: #999;
|
||||
--border-divider: #d9d9d9;
|
||||
|
||||
/* === SPACING === */
|
||||
--spacing-xs: 0.25rem; /* 4px */
|
||||
--spacing-sm: 0.5rem; /* 8px */
|
||||
--spacing-md: 0.75rem; /* 12px */
|
||||
--spacing-lg: 1rem; /* 16px */
|
||||
--spacing-xl: 1.25rem; /* 20px */
|
||||
--spacing-2xl: 1.5rem; /* 24px */
|
||||
--spacing-3xl: 2rem; /* 32px */
|
||||
--spacing-4xl: 2.5rem; /* 40px */
|
||||
--spacing-5xl: 3rem; /* 48px */
|
||||
|
||||
/* === TYPOGRAPHY === */
|
||||
|
||||
/* Font Family */
|
||||
--font-primary: 'The Sans', system-ui, sans-serif;
|
||||
--font-secondary: system-ui, -apple-system, sans-serif;
|
||||
|
||||
/* Font Weights */
|
||||
--font-weight-light: 300;
|
||||
--font-weight-normal: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-semibold: 600;
|
||||
--font-weight-bold: 700;
|
||||
--font-weight-extrabold: 800;
|
||||
|
||||
/* Font Sizes */
|
||||
--font-size-xs: 0.7rem; /* 11.2px */
|
||||
--font-size-sm: 0.8rem; /* 12.8px */
|
||||
--font-size-base: 0.85rem; /* 13.6px */
|
||||
--font-size-md: 0.9rem; /* 14.4px */
|
||||
--font-size-lg: 0.95rem; /* 15.2px */
|
||||
--font-size-xl: 1rem; /* 16px */
|
||||
--font-size-2xl: 1.1rem; /* 17.6px */
|
||||
--font-size-3xl: 1.25rem; /* 20px */
|
||||
--font-size-4xl: 1.5rem; /* 24px */
|
||||
--font-size-5xl: 1.75rem; /* 28px */
|
||||
--font-size-6xl: 2.6rem; /* 41.6px */
|
||||
|
||||
/* Line Heights */
|
||||
--line-height-tight: 1.1;
|
||||
--line-height-normal: 1.3;
|
||||
--line-height-relaxed: 1.4;
|
||||
--line-height-loose: 1.5;
|
||||
|
||||
/* === BORDERS === */
|
||||
--border-radius-sm: 0.25rem; /* 4px */
|
||||
--border-radius-md: 0.5rem; /* 8px */
|
||||
--border-radius-lg: 0.75rem; /* 12px */
|
||||
--border-radius-xl: 10px; /* iPhone style */
|
||||
--border-radius-2xl: 12px; /* Modern style */
|
||||
|
||||
--border-width-thin: 1px;
|
||||
--border-width-medium: 2px;
|
||||
--border-width-thick: 4px;
|
||||
|
||||
/* === SHADOWS === */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
--shadow-lg: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
--shadow-xl: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-2xl: 0 10px 30px rgba(102, 126, 234, 0.15);
|
||||
|
||||
/* iPhone/iPod Style Shadows */
|
||||
--shadow-iphone-inset: inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
--shadow-iphone-outer: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
--shadow-iphone-button: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--shadow-iphone-day-divider: inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
|
||||
/* Text Shadows */
|
||||
--text-shadow-light: 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
--text-shadow-dark: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
|
||||
/* === TRANSITIONS === */
|
||||
--transition-fast: 0.15s ease;
|
||||
--transition-medium: 0.2s ease;
|
||||
--transition-slow: 0.3s ease;
|
||||
--transition-transform: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
/* === Z-INDEX === */
|
||||
--z-dropdown: 10;
|
||||
--z-sticky: 100;
|
||||
--z-header: 1000;
|
||||
--z-modal: 9999;
|
||||
|
||||
/* === LAYOUT === */
|
||||
--container-padding: var(--spacing-lg);
|
||||
--page-max-width: 100%;
|
||||
--header-height: 60px;
|
||||
|
||||
/* === SPECIFIC COMPONENT SIZES === */
|
||||
--card-padding: var(--spacing-xl);
|
||||
--button-padding-y: var(--spacing-sm);
|
||||
--button-padding-x: var(--spacing-lg);
|
||||
--input-padding: var(--spacing-md);
|
||||
|
||||
/* Color indicator sizes */
|
||||
--color-indicator-width: 4px;
|
||||
--color-indicator-height: 60px;
|
||||
|
||||
/* Special states */
|
||||
--state-today-bg: linear-gradient(135deg, #fef3c7, #fde68a);
|
||||
--state-today-border: #f59e0b;
|
||||
--state-important-bg: linear-gradient(135deg, #fef2f2, #fee2e2);
|
||||
--state-important-border: #ef4444;
|
||||
--state-cancelled-bg: linear-gradient(135deg, #f9fafb, #f3f4f6);
|
||||
--state-cancelled-border: #6b7280;
|
||||
--state-cancelled-text: #6b7280;
|
||||
|
||||
/* Room category colors */
|
||||
--room-green-bg: #D4EDDA;
|
||||
--room-green-text: #155724;
|
||||
--room-red-bg: #F8D7DA;
|
||||
--room-red-text: #721C24;
|
||||
--room-blue-bg: #D1ECF1;
|
||||
--room-blue-text: #0C5460;
|
||||
--room-yellow-bg: #FFF3CD;
|
||||
--room-yellow-text: #856404;
|
||||
|
||||
/* Notification colors */
|
||||
--notification-success-bg: #E8F5E8;
|
||||
--notification-success-border: #4CAF50;
|
||||
--notification-success-icon-bg: #4CAF50;
|
||||
--notification-success-icon-text: white;
|
||||
--notification-success-title: #2E7D32;
|
||||
--notification-success-details: #388E3C;
|
||||
|
||||
--notification-error-bg: #FFF4F4;
|
||||
--notification-error-border: #F87171;
|
||||
--notification-error-icon-bg: #EF4444;
|
||||
--notification-error-icon-text: white;
|
||||
--notification-error-title: #DC2626;
|
||||
--notification-error-details: #EF4444;
|
||||
|
||||
--notification-warning-bg: #FFF8E1;
|
||||
--notification-warning-border: #FFB74D;
|
||||
--notification-warning-icon: #FF9800;
|
||||
|
||||
--notification-close-button: #6C757D;
|
||||
--notification-close-button-hover: #495057;
|
||||
--notification-close-button-bg-hover: rgba(108, 117, 125, 0.1);
|
||||
|
||||
--tooltip-bg: #333;
|
||||
--tooltip-text: white;
|
||||
|
||||
/* Button colors */
|
||||
--button-bg: #f9f9f9;
|
||||
--button-secondary-bg: #ffffff;
|
||||
--button-secondary-text: #000;
|
||||
--button-secondary-hover-bg: #f2f6ff;
|
||||
--button-secondary-shadow: 0 2px 8px rgba(143, 143, 143, 0.2);
|
||||
--button-secondary-hover-shadow: 0 4px 12px rgba(192, 192, 192, 0.3);
|
||||
|
||||
/* Input colors */
|
||||
--input-bg: #FAFBFC;
|
||||
--input-text: #333;
|
||||
--input-border: #D2D9E0;
|
||||
--input-placeholder: #adadad;
|
||||
|
||||
/* Chip colors */
|
||||
--chip-bg: #F0F8FF;
|
||||
--chip-text: #2563EB;
|
||||
--chip-border: #D1E7FF;
|
||||
--chip-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--chip-hover-bg: #E0F2FE;
|
||||
--chip-hover-border: #BAE6FD;
|
||||
--chip-active-bg: #BFDBFE;
|
||||
--chip-default-bg: #F3F4F6;
|
||||
--chip-default-text: #374151;
|
||||
--chip-default-border: #D1D5DB;
|
||||
|
||||
/* Dropdown colors */
|
||||
--dropdown-bg: white;
|
||||
--dropdown-border: #D2D9E0;
|
||||
--dropdown-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||
--dropdown-divider: #F1F3F4;
|
||||
--dropdown-hover-bg: #F8F9FA;
|
||||
--dropdown-active-bg: #E8F0FE;
|
||||
--dropdown-selected-bg: #F0F8FF;
|
||||
--dropdown-selected-hover-bg: #E0F2FE;
|
||||
|
||||
/* TimeCard colors */
|
||||
--timecard-bg: #F8FBFC;
|
||||
--timecard-text: #333;
|
||||
--timecard-border: #CECECE;
|
||||
--timecard-hover-bg: #E5E5E5;
|
||||
--timecard-active-bg: #D1D5DB;
|
||||
--timecard-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
--timecard-selected-shadow: 0 2px 8px rgba(37, 99, 235, 0.3);
|
||||
--timecard-muted-text: #919191;
|
||||
--timecard-secondary-text: #686765;
|
||||
--timecard-unavailable-bg: #E5E5E5;
|
||||
--timecard-unavailable-text: #B1B1B1;
|
||||
--timecard-unavailable-border: #CECECE;
|
||||
|
||||
/* Modal colors */
|
||||
--modal-bg: white;
|
||||
--modal-display-bg: #f8f9fa;
|
||||
--modal-display-border: #e9ecef;
|
||||
--modal-cancel-bg: white;
|
||||
--modal-cancel-text: #374151;
|
||||
--modal-cancel-border: #d1d5db;
|
||||
--modal-cancel-hover-bg: #f9fafb;
|
||||
--modal-cancel-hover-border: #9ca3af;
|
||||
--modal-cancel-active-bg: #e5e7eb;
|
||||
--modal-save-bg: #059669;
|
||||
--modal-save-text: white;
|
||||
--modal-save-border: #047857;
|
||||
--modal-save-shadow: 0 2px 4px rgba(5, 150, 105, 0.2);
|
||||
--modal-save-hover-bg: #047857;
|
||||
--modal-save-hover-shadow: 0 4px 8px rgba(5, 150, 105, 0.3);
|
||||
--modal-save-active-bg: #065f46;
|
||||
--modal-save-active-shadow: 0 1px 2px rgba(5, 150, 105, 0.2);
|
||||
|
||||
/* Button disabled states */
|
||||
--button-disabled-bg: #f8f9fa;
|
||||
--button-disabled-text: #adb5bd;
|
||||
--button-disabled-border: #dee2e6;
|
||||
|
||||
/* Additional color variants */
|
||||
--color-primary-dark: #1d4ed8;
|
||||
--color-white-transparent: rgba(255, 255, 255, 0.8);
|
||||
--color-white-transparent-low: rgba(255, 255, 255, 0.2);
|
||||
|
||||
/* Header colors */
|
||||
--header-brand-color: #002E5F;
|
||||
|
||||
/* Filter colors */
|
||||
--filter-button-bg: white;
|
||||
--filter-button-text: #374151;
|
||||
--filter-button-border: #D1D5DB;
|
||||
--filter-button-hover-bg: #F9FAFB;
|
||||
--filter-button-hover-border: #9CA3AF;
|
||||
--filter-button-active-bg: #F3F4F6;
|
||||
--filter-active-bg: #EBF8FF;
|
||||
--filter-active-text: #1E40AF;
|
||||
--filter-active-border: #3B82F6;
|
||||
--filter-active-hover-bg: #DBEAFE;
|
||||
--filter-active-hover-border: #2563EB;
|
||||
--filter-chevron-color: #6B7280;
|
||||
--filter-content-bg: #F9FAFB;
|
||||
--filter-content-border: #E5E7EB;
|
||||
--filter-reset-divider: #E5E7EB;
|
||||
|
||||
/* Reset button colors */
|
||||
--reset-button-bg: white;
|
||||
--reset-button-text: #DC2626;
|
||||
--reset-button-border: #DC2626;
|
||||
--reset-button-hover-bg: #FEF2F2;
|
||||
--reset-button-hover-text: #B91C1C;
|
||||
--reset-button-hover-border: #B91C1C;
|
||||
--reset-button-active-bg: #FEE2E2;
|
||||
|
||||
/* Additional UI colors */
|
||||
--border-light: #E7E7E7;
|
||||
--border-medium: #d6d6d6;
|
||||
--text-disabled: #D4D4D4;
|
||||
--divider-color: #d8d8d8;
|
||||
--button-mobile-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
--modal-footer-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
/* Modal specific colors */
|
||||
--modal-border: rgba(255, 255, 255, 0.18);
|
||||
--modal-shadow: 0 32px 64px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.08), 0 8px 16px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||
--modal-dialog-bg: rgba(255, 255, 255, 0.95);
|
||||
--modal-close-hover-bg: #f3f4f6;
|
||||
|
||||
/* Dropdown chevron */
|
||||
--dropdown-chevron-color: #888;
|
||||
|
||||
/* Date picker chevron buttons */
|
||||
--chevron-button-color: #111;
|
||||
--chevron-button-disabled-color: #666;
|
||||
}
|
||||
|
||||
/* === DARK MODE === */
|
||||
[data-theme="dark"] {
|
||||
/* Primary Colors - keep same for consistency */
|
||||
--color-primary: #007AFF;
|
||||
--color-primary-hover: #0056b3;
|
||||
--color-primary-light: rgba(0, 122, 255, 0.2);
|
||||
|
||||
/* iPhone/iPod Style Colors - darker variants */
|
||||
--color-iphone-blue: #4d90fe;
|
||||
--color-iphone-blue-dark: #3e7ce0;
|
||||
--color-iphone-blue-border: #2d5aa0;
|
||||
|
||||
/* Grayscale - inverted for dark mode */
|
||||
--color-black: #fff;
|
||||
--color-gray-900: #f9fafb;
|
||||
--color-gray-800: #f3f4f6;
|
||||
--color-gray-700: #e5e7eb;
|
||||
--color-gray-600: #d1d5db;
|
||||
--color-gray-500: #9ca3af;
|
||||
--color-gray-400: #6b7280;
|
||||
--color-gray-300: #4b5563;
|
||||
--color-gray-200: #374151;
|
||||
--color-gray-100: #1f2937;
|
||||
--color-gray-50: #111827;
|
||||
--color-white: #1a1a1a;
|
||||
|
||||
/* Text Colors */
|
||||
--text-primary: #e5e5e5;
|
||||
--text-secondary: #b0b0b0;
|
||||
--text-tertiary: #888;
|
||||
--text-muted: #666;
|
||||
|
||||
/* Background Colors */
|
||||
--bg-primary: #1a1a1a;
|
||||
--bg-secondary: #2a2a2a;
|
||||
--bg-tertiary: #333;
|
||||
--bg-muted: #3a3a3a;
|
||||
|
||||
/* iPhone/iPod Style Backgrounds - dark variants */
|
||||
--bg-iphone-gradient: linear-gradient(to bottom, #2a2a2a, #1a1a1a);
|
||||
--bg-iphone-header: linear-gradient(to bottom, #333, #2a2a2a);
|
||||
--bg-iphone-section: linear-gradient(to bottom, #2a2a2a, #222);
|
||||
--bg-iphone-day-divider: linear-gradient(to bottom, #333, #2a2a2a);
|
||||
--bg-iphone-hover: linear-gradient(to bottom, #3a4a6a, #2a3a5a);
|
||||
|
||||
/* Activity Type Colors - darker backgrounds, brighter text */
|
||||
--activity-lecture-bg: #1e3a8a;
|
||||
--activity-lecture-text: #93c5fd;
|
||||
--activity-lesson-bg: #166534;
|
||||
--activity-lesson-text: #86efac;
|
||||
--activity-guidance-bg: #92400e;
|
||||
--activity-guidance-text: #fcd34d;
|
||||
--activity-presentation-bg: #581c87;
|
||||
--activity-presentation-text: #c4b5fd;
|
||||
--activity-exam-bg: #991b1b;
|
||||
--activity-exam-text: #fca5a5;
|
||||
--activity-project-bg: #166534;
|
||||
--activity-project-text: #86efac;
|
||||
--activity-info-bg: #92400e;
|
||||
--activity-info-text: #fcd34d;
|
||||
--activity-laboration-bg: #047857;
|
||||
--activity-laboration-text: #6ee7b7;
|
||||
--activity-workshop-bg: #991b1b;
|
||||
--activity-workshop-text: #fca5a5;
|
||||
--activity-seminar-bg: #1d4ed8;
|
||||
--activity-seminar-text: #93c5fd;
|
||||
--activity-default-bg: #374151;
|
||||
--activity-default-text: #d1d5db;
|
||||
|
||||
/* Border Colors */
|
||||
--border-light: #404040;
|
||||
--border-medium: #555;
|
||||
--border-dark: #666;
|
||||
--border-divider: #444;
|
||||
|
||||
/* Shadows - adjusted for dark mode */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4);
|
||||
--shadow-lg: 0 2px 8px rgba(0, 0, 0, 0.5);
|
||||
--shadow-xl: 0 4px 16px rgba(0, 0, 0, 0.6);
|
||||
--shadow-2xl: 0 10px 30px rgba(0, 0, 0, 0.7);
|
||||
|
||||
/* iPhone/iPod Style Shadows - adjusted */
|
||||
--shadow-iphone-inset: inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
--shadow-iphone-outer: 0 1px 3px rgba(0, 0, 0, 0.7);
|
||||
--shadow-iphone-button: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 2px rgba(0, 0, 0, 0.7);
|
||||
--shadow-iphone-day-divider: inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
|
||||
/* Text Shadows */
|
||||
--text-shadow-light: 0 1px 0 rgba(0, 0, 0, 0.5);
|
||||
--text-shadow-dark: 0 -1px 0 rgba(255, 255, 255, 0.1);
|
||||
|
||||
/* Special states - dark mode */
|
||||
--state-today-bg: linear-gradient(135deg, #92400e, #78350f);
|
||||
--state-today-border: #f59e0b;
|
||||
--state-important-bg: linear-gradient(135deg, #991b1b, #7f1d1d);
|
||||
--state-important-border: #ef4444;
|
||||
--state-cancelled-bg: linear-gradient(135deg, #374151, #1f2937);
|
||||
--state-cancelled-border: #9ca3af;
|
||||
--state-cancelled-text: #9ca3af;
|
||||
|
||||
/* Room category colors - dark mode */
|
||||
--room-green-bg: #166534;
|
||||
--room-green-text: #86efac;
|
||||
--room-red-bg: #991b1b;
|
||||
--room-red-text: #fca5a5;
|
||||
--room-blue-bg: #1e40af;
|
||||
--room-blue-text: #93c5fd;
|
||||
--room-yellow-bg: #92400e;
|
||||
--room-yellow-text: #fcd34d;
|
||||
|
||||
/* Notification colors - dark mode */
|
||||
--notification-success-bg: #164e36;
|
||||
--notification-success-border: #22c55e;
|
||||
--notification-success-icon-bg: #22c55e;
|
||||
--notification-success-icon-text: white;
|
||||
--notification-success-title: #86efac;
|
||||
--notification-success-details: #4ade80;
|
||||
|
||||
--notification-error-bg: #991b1b;
|
||||
--notification-error-border: #f87171;
|
||||
--notification-error-icon-bg: #ef4444;
|
||||
--notification-error-icon-text: white;
|
||||
--notification-error-title: #fca5a5;
|
||||
--notification-error-details: #f87171;
|
||||
|
||||
--notification-warning-bg: #92400e;
|
||||
--notification-warning-border: #f59e0b;
|
||||
--notification-warning-icon: #fbbf24;
|
||||
|
||||
--notification-close-button: #9ca3af;
|
||||
--notification-close-button-hover: #d1d5db;
|
||||
--notification-close-button-bg-hover: rgba(156, 163, 175, 0.1);
|
||||
|
||||
--tooltip-bg: #1f2937;
|
||||
--tooltip-text: #e5e7eb;
|
||||
|
||||
/* Button colors - dark mode */
|
||||
--button-bg: #374151;
|
||||
--button-secondary-bg: #374151;
|
||||
--button-secondary-text: #e5e7eb;
|
||||
--button-secondary-hover-bg: #4b5563;
|
||||
--button-secondary-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
|
||||
--button-secondary-hover-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
|
||||
|
||||
/* Input colors - dark mode */
|
||||
--input-bg: #374151;
|
||||
--input-text: #e5e7eb;
|
||||
--input-border: #4b5563;
|
||||
--input-placeholder: #9ca3af;
|
||||
|
||||
/* Chip colors - dark mode */
|
||||
--chip-bg: #1e3a8a;
|
||||
--chip-text: #93c5fd;
|
||||
--chip-border: #3b82f6;
|
||||
--chip-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--chip-hover-bg: #1e40af;
|
||||
--chip-hover-border: #60a5fa;
|
||||
--chip-active-bg: #1d4ed8;
|
||||
--chip-default-bg: #4b5563;
|
||||
--chip-default-text: #d1d5db;
|
||||
--chip-default-border: #6b7280;
|
||||
|
||||
/* Dropdown colors - dark mode */
|
||||
--dropdown-bg: #374151;
|
||||
--dropdown-border: #4b5563;
|
||||
--dropdown-shadow: 0 4px 6px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
--dropdown-divider: #4b5563;
|
||||
--dropdown-hover-bg: #4b5563;
|
||||
--dropdown-active-bg: #1e3a8a;
|
||||
--dropdown-selected-bg: #1e3a8a;
|
||||
--dropdown-selected-hover-bg: #1e40af;
|
||||
|
||||
/* TimeCard colors - dark mode */
|
||||
--timecard-bg: #374151;
|
||||
--timecard-text: #e5e7eb;
|
||||
--timecard-border: #4b5563;
|
||||
--timecard-hover-bg: #4b5563;
|
||||
--timecard-active-bg: #6b7280;
|
||||
--timecard-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--timecard-selected-shadow: 0 2px 8px rgba(59, 130, 246, 0.5);
|
||||
--timecard-muted-text: #9ca3af;
|
||||
--timecard-secondary-text: #d1d5db;
|
||||
--timecard-unavailable-bg: #4b5563;
|
||||
--timecard-unavailable-text: #6b7280;
|
||||
--timecard-unavailable-border: #6b7280;
|
||||
|
||||
/* Modal colors - dark mode */
|
||||
--modal-bg: #1f2937;
|
||||
--modal-display-bg: #374151;
|
||||
--modal-display-border: #4b5563;
|
||||
--modal-cancel-bg: #374151;
|
||||
--modal-cancel-text: #d1d5db;
|
||||
--modal-cancel-border: #4b5563;
|
||||
--modal-cancel-hover-bg: #4b5563;
|
||||
--modal-cancel-hover-border: #6b7280;
|
||||
--modal-cancel-active-bg: #6b7280;
|
||||
--modal-save-bg: #059669;
|
||||
--modal-save-text: white;
|
||||
--modal-save-border: #047857;
|
||||
--modal-save-shadow: 0 2px 4px rgba(5, 150, 105, 0.3);
|
||||
--modal-save-hover-bg: #047857;
|
||||
--modal-save-hover-shadow: 0 4px 8px rgba(5, 150, 105, 0.4);
|
||||
--modal-save-active-bg: #065f46;
|
||||
--modal-save-active-shadow: 0 1px 2px rgba(5, 150, 105, 0.3);
|
||||
|
||||
/* Button disabled states - dark mode */
|
||||
--button-disabled-bg: #374151;
|
||||
--button-disabled-text: #6b7280;
|
||||
--button-disabled-border: #4b5563;
|
||||
|
||||
/* Additional color variants - dark mode */
|
||||
--color-primary-dark: #1d4ed8;
|
||||
--color-white-transparent: rgba(255, 255, 255, 0.8);
|
||||
--color-white-transparent-low: rgba(255, 255, 255, 0.2);
|
||||
|
||||
/* Header colors - dark mode */
|
||||
--header-brand-color: #ffffff;
|
||||
|
||||
/* Filter colors - dark mode */
|
||||
--filter-button-bg: #374151;
|
||||
--filter-button-text: #d1d5db;
|
||||
--filter-button-border: #4b5563;
|
||||
--filter-button-hover-bg: #4b5563;
|
||||
--filter-button-hover-border: #6b7280;
|
||||
--filter-button-active-bg: #6b7280;
|
||||
--filter-active-bg: #1e3a8a;
|
||||
--filter-active-text: #93c5fd;
|
||||
--filter-active-border: #3b82f6;
|
||||
--filter-active-hover-bg: #1e40af;
|
||||
--filter-active-hover-border: #60a5fa;
|
||||
--filter-chevron-color: #9ca3af;
|
||||
--filter-content-bg: #374151;
|
||||
--filter-content-border: #4b5563;
|
||||
--filter-reset-divider: #4b5563;
|
||||
|
||||
/* Reset button colors - dark mode */
|
||||
--reset-button-bg: #374151;
|
||||
--reset-button-text: #f87171;
|
||||
--reset-button-border: #dc2626;
|
||||
--reset-button-hover-bg: #450a0a;
|
||||
--reset-button-hover-text: #fca5a5;
|
||||
--reset-button-hover-border: #b91c1c;
|
||||
--reset-button-active-bg: #7f1d1d;
|
||||
|
||||
/* Additional UI colors - dark mode */
|
||||
--border-light: #4b5563;
|
||||
--border-medium: #6b7280;
|
||||
--text-disabled: #6b7280;
|
||||
--divider-color: #4b5563;
|
||||
--button-mobile-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
--modal-footer-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* Modal specific colors - dark mode */
|
||||
--modal-border: rgba(75, 85, 99, 0.4);
|
||||
--modal-shadow: 0 32px 64px rgba(0, 0, 0, 0.4), 0 16px 32px rgba(0, 0, 0, 0.3), 0 8px 16px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
--modal-dialog-bg: rgba(31, 41, 55, 0.95);
|
||||
--modal-close-hover-bg: #4b5563;
|
||||
|
||||
/* Dropdown chevron - dark mode */
|
||||
--dropdown-chevron-color: #9ca3af;
|
||||
|
||||
/* Date picker chevron buttons - dark mode */
|
||||
--chevron-button-color: #e5e7eb;
|
||||
--chevron-button-disabled-color: #6b7280;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user