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 80 additions and 9 deletions
Showing only changes of commit 87bac4194a - Show all commits

View File

@@ -12,7 +12,8 @@ export function BookingModal({
endTimeIndex,
setEndTimeIndex,
className,
onClose
onClose,
isOpen = true
}) {
const booking = useBookingContext();
const { getCurrentUser } = useSettingsContext();
@@ -88,7 +89,13 @@ export function BookingModal({
return (
<Modal isDismissable onOpenChange={(isOpen) => !isOpen && onClose && onClose()} className={className} style={{borderRadius: '0.4rem', overflow: 'hidden'}}>
<Modal
isOpen={isOpen}
isDismissable
onOpenChange={(open) => !open && onClose && onClose()}
className={className}
style={{borderRadius: '0.4rem', overflow: 'hidden'}}
>
<Dialog style={{overflow: 'hidden'}}>
<form>
<Heading slot="title">{booking.title == "" ? "Jacobs bokning" : booking.title}</Heading>

View File

@@ -98,7 +98,7 @@
}
.modalContainer {
background-color: transparent;
background-color: white;
width: 85%;
max-width: 400px;
overflow: hidden;
@@ -113,6 +113,11 @@
/* Ensure modal appears above header and handles overflow */
:global(.react-aria-ModalOverlay) {
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important;
z-index: 1100 !important;
overflow-y: auto !important;
display: flex !important;
@@ -120,7 +125,7 @@
justify-content: center !important;
padding: 2rem 1rem !important;
box-sizing: border-box !important;
background: rgba(0, 0, 0, 0.25) !important;
background: rgba(0, 0, 0, 0.5) !important;
backdrop-filter: blur(12px) saturate(150%) !important;
-webkit-backdrop-filter: blur(12px) saturate(150%) !important;
}
@@ -129,7 +134,9 @@
max-height: calc(100vh - 4rem) !important;
max-width: 90vw !important;
overflow-y: auto !important;
background: rgba(255, 255, 255, 0.85) !important;
background: white !important;
border-radius: 0.5rem !important;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
}
/* New time display styles */

View File

@@ -1,13 +1,20 @@
import React from 'react';
import TimeCard from './TimeCard';
import { InlineBookingForm } from './InlineBookingForm';
import { BookingModal } from './BookingModal';
import styles from './TimeCardContainer.module.css';
import modalStyles from './BookingModal.module.css';
import { useBookingContext } from '../context/BookingContext';
import { useSettingsContext } from '../context/SettingsContext';
const SLOT_GROUPING_SIZE = 8;
export function TimeCardContainer() {
const booking = useBookingContext();
const { settings } = useSettingsContext();
// Check if we should use inline form
const useInlineForm = settings.bookingFormType === 'inline';
const slotCount = 24; // 12 hours * 2 slots per hour (8:00 to 20:00)
const slotIndices = Array.from({ length: slotCount }, (_, i) => i);
@@ -116,8 +123,9 @@ export function TimeCardContainer() {
);
// Add inline booking form after the pair that contains the selected time card
// Only show inline form if useInlineForm is true
// Cards are laid out in pairs: (0,1), (2,3), (4,5), etc.
if (booking.selectedStartIndex !== null) {
if (useInlineForm && booking.selectedStartIndex !== null) {
const selectedPairStart = Math.floor(booking.selectedStartIndex / 2) * 2;
const selectedPairEnd = selectedPairStart + 1;
@@ -142,6 +150,19 @@ export function TimeCardContainer() {
)
})}
</div>
{/* Show modal when a time slot is selected and not using inline form */}
{!useInlineForm && booking.selectedStartIndex !== null && (
<BookingModal
startTimeIndex={booking.selectedStartIndex}
hoursAvailable={booking.selectedEndIndex - booking.selectedStartIndex}
endTimeIndex={booking.selectedEndIndex}
setEndTimeIndex={booking.setSelectedEndIndex}
className={modalStyles.modalContainer}
onClose={() => booking.resetTimeSelections()}
isOpen={true}
/>
)}
</div>
);
}

View File

@@ -31,6 +31,7 @@ export const SettingsProvider = ({ children }) => {
showDevelopmentBanner: false,
showBookingConfirmationBanner: false,
showBookingDeleteBanner: false,
bookingFormType: 'inline', // 'modal' or 'inline'
// Then override with saved values
...parsed,
// Convert date strings back to DateValue objects
@@ -64,6 +65,8 @@ export const SettingsProvider = ({ children }) => {
showBookingConfirmationBanner: false,
// Booking delete banner toggle
showBookingDeleteBanner: false,
// Booking form type
bookingFormType: 'inline', // 'modal' or 'inline'
};
});
@@ -104,6 +107,10 @@ export const SettingsProvider = ({ children }) => {
earliestTimeSlot: 0,
latestTimeSlot: 23,
currentUserName: USER.name,
showDevelopmentBanner: false,
showBookingConfirmationBanner: false,
showBookingDeleteBanner: false,
bookingFormType: 'inline',
});
localStorage.removeItem('calendarSettings');
};

View File

@@ -128,6 +128,27 @@ export function BookingSettings() {
</span>
</div>
</div>
<div className={styles.setting}>
<label htmlFor="bookingFormType">
<strong>Booking Form Type</strong>
<span className={styles.description}>
Choose between modal popup or inline form for creating bookings
</span>
</label>
<select
id="bookingFormType"
value={settings.bookingFormType}
onChange={(e) => updateSettings({ bookingFormType: e.target.value })}
className={styles.select}
>
<option value="inline">Inline Form (New)</option>
<option value="modal">Modal Popup (Classic)</option>
</select>
<div className={styles.currentStatus}>
Current: <strong>{settings.bookingFormType === 'inline' ? 'Inline Form' : 'Modal Popup'}</strong>
</div>
</div>
</div>
<div className={styles.section}>

View File

@@ -11,10 +11,13 @@ import { BookingProvider } from '../context/BookingContext';
import { useSettingsContext } from '../context/SettingsContext';
export function NewBooking({ addBooking }) {
const { getEffectiveToday } = useSettingsContext();
const { getEffectiveToday, settings } = useSettingsContext();
const booking = useBookingState(addBooking, getEffectiveToday());
const [showFilters, setShowFilters] = useState(false);
// Check if we should use inline form (hide title and participants from main form)
const useInlineForm = settings.bookingFormType === 'inline';
// Check if any filters are active
const hasActiveFilters = booking.selectedRoom !== "allRooms" || booking.selectedBookingLength > 0;
@@ -57,8 +60,13 @@ export function NewBooking({ addBooking }) {
<h2>Boka litet grupprum</h2>
<div className={styles.formContainer}>
<main style={{ flex: 1 }}>
<BookingTitleField />
<ParticipantsSelector />
{/* Only show title and participants fields in modal mode */}
{!useInlineForm && (
<>
<BookingTitleField />
<ParticipantsSelector />
</>
)}
<div className={styles.bookingTimesContainer}>
<BookingDatePicker />