improving-week-36 #1
@@ -6,15 +6,39 @@ import { useBookingContext } from '../context/BookingContext';
|
||||
|
||||
export function BookingDatePicker() {
|
||||
const booking = useBookingContext();
|
||||
const minDate = today(getLocalTimeZone());
|
||||
const maxDate = getFutureDate(14);
|
||||
|
||||
const handlePreviousDay = () => {
|
||||
const previousDay = booking.selectedDate.subtract({ days: 1 });
|
||||
if (previousDay.compare(minDate) >= 0) {
|
||||
booking.handleDateChange(previousDay);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextDay = () => {
|
||||
const nextDay = booking.selectedDate.add({ days: 1 });
|
||||
if (nextDay.compare(maxDate) <= 0) {
|
||||
booking.handleDateChange(nextDay);
|
||||
}
|
||||
};
|
||||
|
||||
const canNavigatePrevious = booking.selectedDate.compare(minDate) > 0;
|
||||
const canNavigateNext = booking.selectedDate.compare(maxDate) < 0;
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<DatePicker
|
||||
value={booking.selectedDate}
|
||||
onChange={(date) => booking.handleDateChange(date)}
|
||||
firstDayOfWeek="mon"
|
||||
minValue={today(getLocalTimeZone())}
|
||||
maxValue={getFutureDate(14)}
|
||||
minValue={minDate}
|
||||
maxValue={maxDate}
|
||||
isDateUnavailable={isDateUnavailable}
|
||||
onPreviousClick={handlePreviousDay}
|
||||
onNextClick={handleNextDay}
|
||||
canNavigatePrevious={canNavigatePrevious}
|
||||
canNavigateNext={canNavigateNext}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -11,21 +11,27 @@ export function getTimeFromIndex(timeIndex) {
|
||||
}
|
||||
|
||||
export function convertDateObjectToString( date ) {
|
||||
|
||||
const days = ["Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"];
|
||||
const dayIndex = getDayOfWeek(date, "en-US");
|
||||
|
||||
const dayOfWeek = (dayIndex >= 1 && dayIndex <= 7) ? days[dayIndex - 1] : "Ogiltig dag";
|
||||
|
||||
const months = [
|
||||
"Januari", "Februari", "Mars", "April", "Maj", "Juni",
|
||||
"Juli", "Augusti", "September", "Oktober", "November", "December"
|
||||
];
|
||||
|
||||
const monthIndex = date.month;
|
||||
const monthName = (monthIndex >= 1 && monthIndex <= 12) ? months[monthIndex - 1] : "Ogiltig månad";
|
||||
|
||||
|
||||
return `${dayOfWeek} ${date.day} ${monthName} ${date.year}`;
|
||||
return "";
|
||||
|
||||
// Always use long format for now
|
||||
const isSmallScreen = false;
|
||||
|
||||
if (isSmallScreen) {
|
||||
const days = ["Mån", "Tis", "Ons", "Tor", "Fre", "Lör", "Sön"];
|
||||
const months = ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
|
||||
|
||||
const dayOfWeek = (dayIndex >= 0 && dayIndex < 7) ? days[dayIndex === 0 ? 6 : dayIndex - 1] : "Ogiltig dag";
|
||||
const monthName = (monthIndex >= 1 && monthIndex <= 12) ? months[monthIndex - 1] : "Ogiltig månad";
|
||||
|
||||
return `${dayOfWeek} ${date.day} ${monthName}`;
|
||||
} else {
|
||||
const days = ["Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"];
|
||||
const months = ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"];
|
||||
|
||||
const dayOfWeek = (dayIndex >= 0 && dayIndex < 7) ? days[dayIndex === 0 ? 6 : dayIndex - 1] : "Ogiltig dag";
|
||||
const monthName = (monthIndex >= 1 && monthIndex <= 12) ? months[monthIndex - 1] : "Ogiltig månad";
|
||||
|
||||
return `${dayOfWeek} ${date.day} ${monthName} ${date.year}`;
|
||||
}
|
||||
}
|
||||
18
my-app/src/icons/CalendarIcon.jsx
Normal file
18
my-app/src/icons/CalendarIcon.jsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function CalendarIcon({ color = '#666', size = 16 }) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" stroke={color} strokeWidth="2" fill="none"/>
|
||||
<line x1="16" y1="2" x2="16" y2="6" stroke={color} strokeWidth="2"/>
|
||||
<line x1="8" y1="2" x2="8" y2="6" stroke={color} strokeWidth="2"/>
|
||||
<line x1="3" y1="10" x2="21" y2="10" stroke={color} strokeWidth="2"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -43,12 +43,11 @@
|
||||
}
|
||||
|
||||
.chevron-button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.3;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.chevron-button:focus-visible {
|
||||
outline: 2px solid var(--focus-ring-color);
|
||||
outline: 2px solid #2563EB;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@@ -79,6 +78,55 @@
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-button {
|
||||
min-width: 220px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: space-between !important;
|
||||
gap: 0.75rem !important;
|
||||
cursor: pointer !important;
|
||||
background: white !important;
|
||||
border: 1px solid #E5E7EB !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 12px 16px !important;
|
||||
font-weight: 500 !important;
|
||||
color: #374151 !important;
|
||||
transition: all 0.2s ease !important;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.calendar-button {
|
||||
min-width: 200px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-button:hover {
|
||||
border-color: #D1D5DB !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
.calendar-button[data-pressed] {
|
||||
background: #F9FAFB !important;
|
||||
border-color: #9CA3AF !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-offset: 2px !important;
|
||||
border-color: #2563EB !important;
|
||||
}
|
||||
|
||||
.calendar-date {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.react-aria-DateInput {
|
||||
padding: 4px 2.5rem 4px 8px;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import './DatePicker.css';
|
||||
import { convertDateObjectToString } from '../../helpers';
|
||||
import ChevronLeft from '../../icons/ChevronLeft';
|
||||
import ChevronRight from '../../icons/ChevronRight';
|
||||
import CalendarIcon from '../../icons/CalendarIcon';
|
||||
|
||||
export interface DatePickerProps<T extends DateValue>
|
||||
extends AriaDatePickerProps<T> {
|
||||
@@ -70,18 +71,21 @@ export function DatePicker<T extends DateValue>(
|
||||
disabled={!canNavigatePrevious}
|
||||
>
|
||||
<ChevronLeft
|
||||
color={chevronColor}
|
||||
color={!canNavigatePrevious ? "#666" : "#111"}
|
||||
disabled={!canNavigatePrevious}
|
||||
/>
|
||||
</button>
|
||||
<Button>{convertDateObjectToString(props.value)}</Button>
|
||||
<Button className="calendar-button">
|
||||
<span className="calendar-date">{convertDateObjectToString(props.value)}</span>
|
||||
<CalendarIcon color={chevronColor} size={16} />
|
||||
</Button>
|
||||
<button
|
||||
className="chevron-button"
|
||||
onClick={() => onNextClick ? onNextClick() : console.log('ChevronRight clicked')}
|
||||
disabled={!canNavigateNext}
|
||||
>
|
||||
<ChevronRight
|
||||
color={chevronColor}
|
||||
color={!canNavigateNext ? "#666" : "#111"}
|
||||
disabled={!canNavigateNext}
|
||||
/>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user