booking-flow-finalized-design kindaaaa #7

Merged
jare2473 merged 20 commits from booking-flow-finalized-design into main 2025-09-30 10:50:54 +02:00
8 changed files with 171 additions and 25 deletions
Showing only changes of commit 1ab912cbf2 - Show all commits

View File

@@ -8,11 +8,11 @@
animation: slideDown 0.2s ease-out;
width: 100%;
flex-basis: 100%;
max-width: none;
position: relative;
z-index: 1;
}
/* Arrow pointing to left card */
.arrowLeft::before {
content: '';

View File

@@ -1,11 +1,18 @@
import React from 'react';
import styles from './PageHeader.module.css';
const PageHeader = ({ title, subtitle }) => {
const PageHeader = ({ title, subtitle, imageUrl }) => {
return (
<div className={styles.header}>
<h1 className={styles.pageHeading}>{title}</h1>
{subtitle && <div className={styles.subtitle}>{subtitle}</div>}
{imageUrl && (
<div className={styles.imageContainer}>
<img className={styles.image} src={imageUrl} alt={title} />
</div>
)}
<div className={styles.textContent}>
<h1 className={styles.pageHeading}>{title}</h1>
{subtitle && <div className={styles.subtitle}>{subtitle}</div>}
</div>
</div>
);
};

View File

@@ -2,6 +2,25 @@
margin-bottom: var(--spacing-2xl);
padding-bottom: var(--spacing-xl);
border-bottom: 1px solid var(--border-light);
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
}
.imageContainer {
flex-shrink: 0;
}
.image {
width: 100%;
aspect-ratio: 7 / 3;
object-fit: cover;
}
.textContent {
flex: 1;
padding: 1rem;
}
.pageHeading {

View File

@@ -118,11 +118,30 @@ export function TimeCardContainer({ addBooking }) {
return (
<div key={columnIndex} className={styles.column}>
{pairs.map((pair, pairIndex) => (
<div key={pairIndex} className={styles.pairRow}>
{pair.map(slotIndex => renderTimeCard(slotIndex))}
</div>
))}
{pairs.map((pair, pairIndex) => {
const elements = [];
// Render the pair
elements.push(
<div key={pairIndex} className={styles.pairRow}>
{pair.map(slotIndex => renderTimeCard(slotIndex))}
</div>
);
// Check if we need to show inline form after this pair
const selectedPairStart = Math.floor(booking.selectedStartIndex / 2) * 2;
const pairStart = pair[0];
const shouldShowForm = (useInlineForm || useInlineModal || useInlineModalExtended || useInlineModalExtendedNoLabels) &&
booking.selectedStartIndex !== null &&
pairStart === selectedPairStart;
if (shouldShowForm) {
const isLeftCard = booking.selectedStartIndex === selectedPairStart;
elements.push(renderInlineForm(pairIndex, isLeftCard));
}
return elements;
}).flat()}
</div>
);
} else if (width < 769) {
@@ -134,29 +153,122 @@ export function TimeCardContainer({ addBooking }) {
return (
<div key={columnIndex} className={styles.column}>
{pairs.map((pair, pairIndex) => (
<div key={pairIndex}>
<div className={styles.pairRow}>
{pair.map(slotIndex => renderTimeCard(slotIndex))}
{pairs.map((pair, pairIndex) => {
const elements = [];
// Render the pair
elements.push(
<div key={pairIndex}>
<div className={styles.pairRow}>
{pair.map(slotIndex => renderTimeCard(slotIndex))}
</div>
{/* Add spacing after every 4th pair */}
{(pairIndex + 1) % 4 === 0 && pairIndex < pairs.length - 1 && (
<div className={styles.groupSpacer}></div>
)}
</div>
{/* Add spacing after every 4th pair */}
{(pairIndex + 1) % 4 === 0 && pairIndex < pairs.length - 1 && (
<div className={styles.groupSpacer}></div>
)}
</div>
))}
);
// Check if we need to show inline form after this pair
const selectedPairStart = Math.floor(booking.selectedStartIndex / 2) * 2;
const pairStart = pair[0];
const shouldShowForm = (useInlineForm || useInlineModal || useInlineModalExtended || useInlineModalExtendedNoLabels) &&
booking.selectedStartIndex !== null &&
pairStart === selectedPairStart;
if (shouldShowForm) {
const isLeftCard = booking.selectedStartIndex === selectedPairStart;
elements.push(renderInlineForm(pairIndex, isLeftCard));
}
return elements;
}).flat()}
</div>
);
} else {
// For large screens: render normally
// For large screens: render normally with original logic
return (
<div key={columnIndex} className={styles.column}>
{column.map(slotIndex => renderTimeCard(slotIndex))}
{column.map(slotIndex => {
const elements = [];
elements.push(renderTimeCard(slotIndex));
// Add inline booking form after the pair that contains the selected time card
// Cards are laid out in pairs: (0,1), (2,3), (4,5), etc.
if ((useInlineForm || useInlineModal || useInlineModalExtended || useInlineModalExtendedNoLabels) && booking.selectedStartIndex !== null) {
const selectedPairStart = Math.floor(booking.selectedStartIndex / 2) * 2;
const selectedPairEnd = selectedPairStart + 1;
// Show form after the second card of the pair that contains the selected card
if (slotIndex === selectedPairEnd && (booking.selectedStartIndex === selectedPairStart || booking.selectedStartIndex === selectedPairEnd)) {
const isLeftCard = booking.selectedStartIndex === selectedPairStart;
elements.push(renderInlineForm(slotIndex, isLeftCard));
}
}
return elements;
}).flat()}
</div>
);
}
};
const renderInlineForm = (key, isLeftCard) => {
if (useInlineForm) {
return (
<InlineBookingForm
key={`form-${key}`}
startTimeIndex={booking.selectedStartIndex}
hoursAvailable={booking.selectedEndIndex - booking.selectedStartIndex}
onClose={() => booking.resetTimeSelections()}
arrowPointsLeft={isLeftCard}
/>
);
} else if (useInlineModal) {
return (
<InlineModalBookingForm
key={`form-${key}`}
startTimeIndex={booking.selectedStartIndex}
hoursAvailable={booking.selectedEndIndex - booking.selectedStartIndex}
endTimeIndex={booking.selectedEndIndex}
setEndTimeIndex={booking.setSelectedEndIndex}
onClose={() => booking.resetTimeSelections()}
onNavigateToDetails={handleNavigateToDetails}
arrowPointsLeft={isLeftCard}
/>
);
} else if (useInlineModalExtended) {
return (
<InlineModalExtendedBookingForm
key={`form-${key}-${booking.selectedStartIndex}`}
startTimeIndex={booking.selectedStartIndex}
hoursAvailable={booking.selectedEndIndex - booking.selectedStartIndex}
endTimeIndex={booking.selectedEndIndex}
setEndTimeIndex={booking.setSelectedEndIndex}
onClose={() => booking.resetTimeSelections()}
onNavigateToDetails={handleNavigateToDetails}
addBooking={addBooking}
arrowPointsLeft={isLeftCard}
/>
);
} else if (useInlineModalExtendedNoLabels) {
return (
<InlineModalExtendedBookingFormNoLabels
key={`form-${key}`}
startTimeIndex={booking.selectedStartIndex}
hoursAvailable={booking.selectedEndIndex - booking.selectedStartIndex}
endTimeIndex={booking.selectedEndIndex}
setEndTimeIndex={booking.setSelectedEndIndex}
onClose={() => booking.resetTimeSelections()}
onNavigateToDetails={handleNavigateToDetails}
arrowPointsLeft={isLeftCard}
/>
);
}
return null;
};
const renderTimeCard = (slotIndex) => {
let maxConsecutive = 0;
let roomId = "";

View File

@@ -54,7 +54,7 @@
.column {
min-width: 300px;
width: fit-content;
width: 350px;
display: flex;
flex-direction: column;
gap: 0.5rem;

View File

@@ -60,8 +60,9 @@ export function NewBooking({ addBooking }) {
return (
<BookingProvider value={booking}>
<PageHeader title="Litet grupprum" subtitle="Plats för 5 personer" imageUrl="./grupprum.jpg" />
<PageContainer>
<PageHeader title="Litet grupprum" subtitle="Plats för 5 personer" />
{/* <img src="./grupprum.jpg" alt="Litet grupprum" className={styles.roomImage} /> */}
<div className={styles.formContainer}>
<main style={{ flex: 1 }}>

View File

@@ -5,6 +5,14 @@
min-height: 100vh;
}
.roomImage {
width: 100%;
height: auto;
margin-bottom: 1rem;
object-fit: cover;
aspect-ratio: 7/3;
}
.formContainer {
/*padding: 1rem;*/
min-height: 100%;
@@ -26,7 +34,6 @@
}
.bookingTimesContainer {
margin-top: 2rem;
border-radius: 0.3rem;
outline: 1px solid var(--border-light);
display: flex;

View File

@@ -13,7 +13,7 @@
border: 1px solid var(--border-light);
position: sticky;
width: 100%;
top: 1rem;
top: 0;
z-index: 10;
display: flex;
flex-direction: row;