improving-week-36 #1

Merged
jare2473 merged 41 commits from improving-week-36 into main 2025-09-04 10:49:05 +02:00
6 changed files with 186 additions and 78 deletions
Showing only changes of commit fa6e741fb4 - Show all commits

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { Routes, Route, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { CalendarDate } from '@internationalized/date';
import Layout from './Layout';
import { RoomBooking } from './pages/RoomBooking';
import { NewBooking } from './pages/NewBooking';
@@ -10,7 +11,60 @@ import FullScreenLoader from './components/FullScreenLoader';
const AppRoutes = () => {
const location = useLocation();
const [loading, setLoading] = useState(false);
const [bookings, setBookings] = useState([]);
const [bookings, setBookings] = useState([
{
id: 1,
date: new CalendarDate(2025, 9, 3),
startTime: 4,
endTime: 6,
room: 'G5:7',
title: 'Team standup',
participants: [
{ id: 2, name: 'Filip Norgren', username: 'fino2341', email: 'filip.norgren@dsv.su.se' },
{ id: 3, name: 'Hedvig Engelmark', username: 'heen9876', email: 'hedvig.engelmark@dsv.su.se' },
{ id: 4, name: 'Elin Rudling', username: 'elru4521', email: 'elin.rudling@dsv.su.se' }
]
},
{
id: 2,
date: new CalendarDate(2025, 9, 5),
startTime: 8,
endTime: 12,
room: 'G5:12',
title: 'Project planning workshop',
participants: [
{ id: 5, name: 'Victor Magnusson', username: 'vima8734', email: 'victor.magnusson@dsv.su.se' },
{ id: 6, name: 'Ellen Britschgi', username: 'elbr5623', email: 'ellen.britschgi@dsv.su.se' },
{ id: 7, name: 'Anna Andersson', username: 'anan3457', email: 'anna.andersson@dsv.su.se' },
{ id: 8, name: 'Erik Larsson', username: 'erla7892', email: 'erik.larsson@dsv.su.se' },
{ id: 9, name: 'Sofia Karlsson', username: 'soka1245', email: 'sofia.karlsson@dsv.su.se' },
{ id: 10, name: 'Magnus Nilsson', username: 'mani6789', email: 'magnus.nilsson@dsv.su.se' }
]
},
{
id: 3,
date: new CalendarDate(2025, 9, 4),
startTime: 2,
endTime: 3,
room: 'G5:3',
title: '1:1 with supervisor',
participants: [
{ id: 251, name: 'Arjohn Emilsson', username: 'arem1532', email: 'arjohn.emilsson@dsv.su.se' }
]
},
{
id: 4,
date: new CalendarDate(2025, 9, 6),
startTime: 6,
endTime: 8,
room: 'G5:15',
title: 'Study group session',
participants: [
{ id: 11, name: 'Emma Johansson', username: 'emjo4512', email: 'emma.johansson@dsv.su.se' },
{ id: 12, name: 'Oskar Pettersson', username: 'ospe3698', email: 'oskar.pettersson@dsv.su.se' }
]
}
]);
function addBooking(newBooking) {
setBookings([...bookings, newBooking]);

View File

@@ -1,31 +0,0 @@
import React from 'react';
import styles from './Booking.module.css';
import { convertDateObjectToString } from '../helpers';
function Booking({ booking, handleEditBooking }) {
function getTimeFromIndex(timeIndex) {
const totalHalfHoursFromStart = timeIndex;
const totalMinutes = 8 * 60 + totalHalfHoursFromStart * 30; // 8:00 as base
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
return `${hours}:${minutes === 0 ? '00' : '30'}`;
}
return (
<div className={styles.container} onClick={() => handleEditBooking(booking)}>
<div className={styles.left}>
<p className={styles.date}>{convertDateObjectToString(booking.date)}</p>
<p>{booking.title}</p>
</div>
<div className={styles.right}>
<p className={styles.room}>{booking.room}</p>
<p className={styles.time}>{getTimeFromIndex(booking.startTime)} - {getTimeFromIndex(booking.endTime)}</p>
</div>
</div>
);
}
export default Booking;

View File

@@ -1,44 +0,0 @@
.container {
display: flex;
justify-content: space-between;
border: 1px solid #E5E5E5;
padding: 0.7rem;
width: 100%;
border-radius: 0.5rem;
}
.left {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.right {
display: flex;
flex-direction: column;
align-items: end;
}
.container p {
margin: 0;
}
.container:hover {
cursor: pointer;
}
.date {
text-transform: uppercase;
font-size: 0.8rem;
}
.room {
font-weight: 600;
font-size: 0.8rem;
color: #5d5d5d;
}
.time {
font-size: 1.2rem;
}

View File

@@ -0,0 +1,53 @@
import React from 'react';
import styles from './BookingCard.module.css';
import { convertDateObjectToString } from '../helpers';
function BookingCard({ booking, onClick }) {
function getTimeFromIndex(timeIndex) {
const totalHalfHoursFromStart = timeIndex;
const totalMinutes = 8 * 60 + totalHalfHoursFromStart * 30; // 8:00 as base
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
return `${hours}:${minutes === 0 ? '00' : '30'}`;
}
function formatParticipants(participants) {
if (!participants || participants.length === 0) return null;
if (participants.length === 1) {
return participants[0].name;
} else if (participants.length === 2) {
return `${participants[0].name} and ${participants[1].name}`;
} else {
const remaining = participants.length - 2;
return `${participants[0].name}, ${participants[1].name} and ${remaining} more`;
}
}
return (
<div className={styles.card} onClick={onClick}>
<div className={styles.header}>
<div className={styles.dateContainer}>
<span className={styles.date}>{convertDateObjectToString(booking.date)}</span>
</div>
<div>
<div className={styles.time}>
{getTimeFromIndex(booking.startTime)} - {getTimeFromIndex(booking.endTime)}
</div>
<span className={styles.room}>{booking.room}</span>
</div>
</div>
<div className={styles.body}>
<h3 className={styles.title}>{booking.title}</h3>
{booking.participants && booking.participants.length > 0 && (
<p className={styles.participants}>{formatParticipants(booking.participants)}</p>
)}
</div>
</div>
);
}
export default BookingCard;

View File

@@ -0,0 +1,76 @@
.card {
border: 1px solid #E5E5E5;
padding: 1rem;
width: 100%;
border-radius: 0.75rem;
background: #fff;
transition: all 0.2s ease;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.card:hover {
cursor: pointer;
border-color: #007AFF;
box-shadow: 0 4px 12px rgba(0, 122, 255, 0.15);
transform: translateY(-1px);
}
.header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 0.75rem;
}
.dateContainer {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.date {
text-transform: uppercase;
font-size: 0.75rem;
font-weight: 600;
color: #666;
letter-spacing: 0.5px;
}
.room {
font-weight: 600;
font-size: 0.875rem;
color: #666;
}
.time {
font-size: 1.125rem;
font-weight: 600;
color: #333;
}
.body {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.title {
margin: 0;
font-size: 1rem;
font-weight: 600;
color: #333;
line-height: 1.3;
}
.participants {
margin: 0;
font-size: 0.875rem;
color: #666;
display: flex;
align-items: center;
}
.participants::before {
content: "👥";
margin-right: 0.5rem;
}

View File

@@ -1,6 +1,6 @@
import React from 'react';
import styles from './BookingsList.module.css';
import Booking from './Booking';
import BookingCard from './BookingCard';
function BookingsList({ bookings, handleEditBooking }) {
@@ -11,7 +11,7 @@ function BookingsList({ bookings, handleEditBooking }) {
{bookings.length > 0 ? (
<>
{bookings.map((booking, index) => (
<Booking key={index} booking={booking} handleEditBooking={handleEditBooking} />
<BookingCard key={index} booking={booking} onClick={() => handleEditBooking(booking)} />
))}
</>
) : (