new-modal #4

Merged
jare2473 merged 18 commits from new-modal into main 2025-09-10 10:01:30 +02:00
4 changed files with 256 additions and 40 deletions
Showing only changes of commit 49e7337ea1 - Show all commits

View File

@@ -47,4 +47,30 @@ export function convertDateObjectToString( date ) {
}
return 'Ogiltigt datum';
}
}
export function formatBookingDate(date) {
console.log('formatBookingDate called with:', date);
if (!date || !date.day || !date.month || !date.year) {
console.log('Date validation failed:', { date, day: date?.day, month: date?.month, year: date?.year });
return 'Ogiltigt datum';
}
const months = ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"];
const monthIndex = date.month;
console.log('Month index:', monthIndex);
const monthName = months[monthIndex - 1]; // month is 1-based, array is 0-based
console.log('Month name:', monthName);
if (!monthName) {
console.log('Month name not found, falling back');
// If month is out of range, fall back to simple format
return `${date.day}/${date.month}/${date.year}`;
}
const result = `${date.day} ${monthName} ${date.year}`;
console.log('Final result:', result);
return result;
}

View File

@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import styles from './BookingDetails.module.css';
import { BookingTitleField } from '../components/forms/BookingTitleField';
@@ -7,13 +7,14 @@ import { useBookingContext } from '../context/BookingContext';
import { BookingProvider } from '../context/BookingContext';
import { useSettingsContext } from '../context/SettingsContext';
import { useBookingState } from '../hooks/useBookingState';
import { convertDateObjectToString, getTimeFromIndex } from '../helpers';
import { convertDateObjectToString, formatBookingDate, getTimeFromIndex } from '../helpers';
export function BookingDetails({ addBooking }) {
const navigate = useNavigate();
const location = useLocation();
const { getEffectiveToday } = useSettingsContext();
const booking = useBookingState(addBooking, getEffectiveToday());
const [isAccordionOpen, setIsAccordionOpen] = useState(false);
useEffect(() => {
window.scrollTo(0, 0);
@@ -45,37 +46,76 @@ export function BookingDetails({ addBooking }) {
booking.handleSave();
};
const toggleAccordion = () => {
setIsAccordionOpen(!isAccordionOpen);
};
return (
<BookingProvider value={booking}>
<div className={styles.pageContainer}>
<div className={styles.header}>
<h2 className={styles.pageTitle}>Ny bokning</h2>
<div className={styles.dateTimeSection}>
<div className={styles.dateContainer}>
<span className={styles.date}>{booking.selectedDate ? formatBookingDate(booking.selectedDate) : 'Välj datum'}</span>
</div>
<div className={styles.timeContainer}>
<span className={styles.time}>{getTimeFromIndex(booking.selectedStartIndex)} - {getTimeFromIndex(booking.selectedEndIndex)}</span>
</div>
</div>
</div>
<div className={styles.mainSection}>
<button
className={styles.backButton}
onClick={handleBack}
>
Tillbaka
className={styles.backButton}
onClick={handleBack}
>
Tillbaka
</button>
<h2>Bokningsuppgifter</h2>
</div>
<div className={styles.timeInfo}>
<p className={styles.dateTime}>
{convertDateObjectToString(booking.selectedDate)} · {getTimeFromIndex(booking.selectedStartIndex)} - {getTimeFromIndex(booking.selectedEndIndex)}
</p>
</div>
<div className={styles.roomVisualization}>
<div className={styles.roomArea}></div>
<div className={`${styles.roomInfo} ${isAccordionOpen ? styles.expanded : ''}`} onClick={toggleAccordion}>
<div className={styles.roomHeader}>
<span>Lokal: {booking.assignedRoom || 'G5:12'}</span>
<span className={`${styles.dropdown} ${isAccordionOpen ? styles.rotated : ''}`}>
{isAccordionOpen ? '▲' : '▼'}
</span>
</div>
{isAccordionOpen && (
<div className={styles.roomDetails}>
<div className={styles.roomDetailItem}>
<span className={styles.roomDetailLabel}>5 platser</span>
</div>
<div className={styles.roomDetailItem}>
<span className={styles.roomDetailLabel}>Plats:</span>
<span className={styles.roomDetailValue}>Röda avdelningen</span>
</div>
<div className={styles.roomDetailItem}>
<span className={styles.roomDetailLabel}>Utrustning:</span>
<span className={styles.roomDetailValue}>Whiteboard, TV, Tangentbord, Mus.</span>
</div>
<div className={styles.roomDetailItem}>
<span className={styles.roomDetailLabel}> Status:</span>
<span className={styles.roomDetailValue}>HDMI-kabel glappar.</span>
</div>
</div>
)}
</div>
</div>
<div className={styles.formContainer}>
<BookingTitleField />
<ParticipantsSelector />
</div>
<div className={styles.formContainer}>
<BookingTitleField />
<ParticipantsSelector />
</div>
<div className={styles.footer}>
<button
className={styles.saveButton}
onClick={handleSave}
>
Boka
</button>
<div className={styles.footer}>
<button
className={styles.saveButton}
onClick={handleSave}
>
Boka
</button>
</div>
</div>
</div>
</BookingProvider>

View File

@@ -1,6 +1,5 @@
.pageContainer {
margin: 0 auto;
padding: 1rem;
min-height: calc(100vh - 4rem); /* Adjust for header/footer height */
display: flex;
flex-direction: column;
@@ -11,7 +10,16 @@
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 2rem;
padding: 0 1rem;
border-bottom: 1px solid var(--border-light);
background-color: var(--bg-primary);
position: sticky;
top: 4rem;
z-index: 999;
}
.mainSection {
padding: 1rem;
}
.backButton {
@@ -23,32 +31,135 @@
padding: 0.5rem;
border-radius: 0.25rem;
transition: background-color 0.2s ease;
width: fit-content;
margin-bottom: 2rem;
}
.backButton:hover {
background-color: var(--bg-secondary);
}
.header h2 {
margin: 0;
font-size: 1.5rem;
.pageTitle {
font-size: 1rem;
font-weight: 600;
color: var(--text-primary);
text-transform: uppercase;
}
.timeInfo {
background: var(--bg-secondary);
padding: 1rem;
border-radius: 0.5rem;
.bookingInfo {
margin-bottom: 2rem;
}
.dateTime {
margin: 0;
font-size: 1.1rem;
font-weight: 500;
.dateTimeSection {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1rem;
}
.dateContainer,
.timeContainer {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.date, .time {
font-size: 0.9rem;
font-weight: 300;
color: var(--text-primary);
}
.roomVisualization {
margin-bottom: 2rem;
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.roomArea {
height: 200px;
background-image: url('./grupprum.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
position: relative;
}
.roomInfo {
background: #1976d2;
color: white;
padding: 1rem;
font-weight: 500;
font-size: 1.1rem;
cursor: pointer;
transition: all 0.3s ease;
}
.roomHeader {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.dropdown {
font-size: 0.8rem;
opacity: 0.8;
transition: transform 0.3s ease;
}
.dropdown.rotated {
transform: rotate(180deg);
}
.roomDetails {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
flex-direction: column;
gap: 0.75rem;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.roomDetailItem {
display: flex;
gap: 0.5rem;
align-items: flex-start;
}
.roomDetailItem:first-child {
font-size: 1.2rem;
font-weight: 600;
}
.roomDetailItem:first-child .roomDetailLabel {
color: white;
}
.roomDetailLabel {
color: rgba(255, 255, 255, 0.9);
font-weight: 500;
min-width: fit-content;
}
.roomDetailValue {
color: white;
flex: 1;
}
.formContainer {
display: flex;
flex-direction: column;
@@ -56,11 +167,9 @@
}
.footer {
margin-top: 2rem;
margin-top: auto;
padding-top: 2rem;
border-top: 1px solid var(--border-light);
width: 100%;
padding: 1rem;
}
.saveButton {

View File

@@ -354,6 +354,47 @@
--loader-text-color: #333;
--loader-border: rgba(0, 0, 0, 0.1);
--loader-shadow: 0 20px 40px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.06);
/* === STOCKHOLM UNIVERSITY BRAND COLORS === */
/* Primary university color */
--su-university-blue: #002F5F;
--su-university-blue-80: #33587F;
/* Secondary colors - Sky/Himmel */
--su-sky: #ACDEE6;
--su-sky-70: #C4E8ED;
--su-sky-35: #E3F4F7;
--su-sky-20: #EEF9FA;
/* Secondary colors - Water/Vatten */
--su-water: #9BB2CE;
--su-water-70: #B8C9DC;
--su-water-35: #DCE4EE;
--su-water-20: #EBF0F5;
/* Secondary colors - Fire/Eld */
--su-fire: #EB7125;
--su-fire-70: #F19B66;
--su-fire-35: #F8CDB3;
--su-fire-20: #FBE2D3;
/* Secondary colors - Olive/Oliv */
--su-olive: #A3A86B;
--su-olive-70: #BEC297;
--su-olive-35: #DFE1CB;
--su-olive-20: #EDEEE1;
/* Base colors */
--su-dark-gray: #4B4B4B;
--su-white: #FFFFFF;
--su-medium-gray: #BABABA;
--su-light-gray: #DADADA;
/* Utility colors - limited use */
--su-green: #499943;
--su-red: #B00020;
--su-red-10: #F7E5E8;
}
/* === DARK MODE === */