Skip to content

Commit

Permalink
[BOOKINGSG-6090][JZ|FY] Apply PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Tan Jing Zhi committed Sep 27, 2024
1 parent 83687fc commit 1d7b2de
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 84 deletions.
52 changes: 22 additions & 30 deletions src/date-navigator/date-navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import { DateNavigatorProps } from "./types";

export const DateNavigator = ({
selectedDate,
...optionalProps
minDate,
maxDate,
isLoading,
onLeftArrowClick,
onRightArrowClick,
...otherProps
}: DateNavigatorProps) => {
// =============================================================================
// CONST, STATE, REF
Expand All @@ -30,52 +35,41 @@ export const DateNavigator = ({
: DateHelper.toDayjs(selectedDate).format("dddd");

// =============================================================================
// EVENT HANDLERS
// HELPER FUNCTIONS
// =============================================================================
const isLeftArrowDisabled = () => {
if (!optionalProps.minDate) {
if (!minDate) {
return false;
}
return (
CalendarHelper.isDisabledDay(
date,
undefined,
optionalProps.minDate
) || DateHelper.isSame(date, optionalProps.minDate)
CalendarHelper.isDisabledDay(date, undefined, minDate) ||
DateHelper.isSame(date, minDate)
);
};

const isRightArrowDisabled = () => {
if (!optionalProps.maxDate) {
if (!maxDate) {
return false;
}
return (
CalendarHelper.isDisabledDay(
date,
undefined,
undefined,
optionalProps.maxDate
) || DateHelper.isSame(date, optionalProps.maxDate)
CalendarHelper.isDisabledDay(date, undefined, undefined, maxDate) ||
DateHelper.isSame(date, maxDate)
);
};

// =============================================================================
// RENDER FUNCTIONS
// =============================================================================
return (
<Container
id="date-navigator-container-id"
className={optionalProps.className}
data-testid={optionalProps["data-testid"]}
>
{optionalProps.onLeftArrowClick && (
<Container {...otherProps}>
{onLeftArrowClick && (
<HeaderArrowButton
id="date-navigator-left-arrow-btn-id"
data-testid="date-navigator-left-arrow-btn"
disabled={optionalProps.isLoading || isLeftArrowDisabled()}
disabled={isLoading || isLeftArrowDisabled()}
focusHighlight={false}
tabIndex={-1}
onClick={() => optionalProps.onLeftArrowClick(selectedDate)}
aria-label="Previous day"
onClick={() => onLeftArrowClick(selectedDate)}
>
<ArrowLeft />
</HeaderArrowButton>
Expand All @@ -96,16 +90,14 @@ export const DateNavigator = ({
{dayText}
</StyledDayText>
</Wrapper>
{optionalProps.onRightArrowClick && (
{onRightArrowClick && (
<HeaderArrowButton
id="date-navigator-right-arrow-btn-id"
data-testid="date-navigator-right-arrow-btn"
disabled={optionalProps.isLoading || isRightArrowDisabled()}
disabled={isLoading || isRightArrowDisabled()}
focusHighlight={false}
tabIndex={-1}
onClick={() =>
optionalProps.onRightArrowClick(selectedDate)
}
aria-label="Next day"
onClick={() => onRightArrowClick(selectedDate)}
>
<ArrowRight />
</HeaderArrowButton>
Expand Down
1 change: 1 addition & 0 deletions src/date-navigator/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface DateNavigatorProps {
id?: string | undefined;
className?: string | undefined;
"data-testid"?: string | undefined;
selectedDate: string;
Expand Down
40 changes: 0 additions & 40 deletions src/util/calendar-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,6 @@ dayjs.extend(isSameOrAfter);
dayjs.extend(customParseFormat);
dayjs.extend(timezone);
export namespace CalendarHelper {
/**
* Rounds time to the nearest hour, e.g 6:30 will be clamped to 6:00
* @param time the input time in HH:mm format
* @param toNextHour to clamp to next hour instead, e.g. 6:30 will be clamped to 7:00
* @returns
*/
export const roundToNearestHour = (time: string, toNextHour?: boolean) => {
const formattedTime = dayjs(time, "HH:mm");
const roundedTime =
formattedTime.minute() === 0
? formattedTime
: toNextHour
? formattedTime.minute(0).add(1, "hour")
: formattedTime.minute(0);
return roundedTime.format("HH:mm");
};

export const generateHourlyIntervals = (
startTime: string,
endTime: string,
generatedFormat = "ha"
) => {
const format = "HH:mm";
let start = dayjs(startTime, format);
let end = dayjs(endTime, format);

if (start.isSame(end)) {
end = end.add(1, "day");
}

const intervals: string[] = [];

while (start.isBefore(end)) {
intervals.push(start.format(generatedFormat));
start = start.add(1, "hour");
}

return intervals;
};

export const generateDays = (calendarDate: Dayjs): Dayjs[][] => {
const firstDayOfTheMonth = calendarDate.startOf("month");

Expand Down
41 changes: 41 additions & 0 deletions src/util/time-helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dayjs from "dayjs";
import { StringHelper } from "./string-helper";

// =============================================================================
Expand Down Expand Up @@ -27,6 +28,46 @@ interface TimeValuesPlain {
// HELPER FUNCTIONS
// =============================================================================
export namespace TimeHelper {
/**
* Rounds time to the nearest hour, e.g 6:30 will be clamped to 6:00
* @param time the input time in HH:mm format
* @param toNextHour to clamp to next hour instead, e.g. 6:30 will be clamped to 7:00
* @returns
*/
export const roundToNearestHour = (time: string, toNextHour?: boolean) => {
const formattedTime = dayjs(time, "HH:mm");
const roundedTime =
formattedTime.minute() === 0
? formattedTime
: toNextHour
? formattedTime.minute(0).add(1, "hour")
: formattedTime.minute(0);
return roundedTime.format("HH:mm");
};

export const generateHourlyIntervals = (
startTime: string,
endTime: string,
generatedFormat = "ha"
) => {
const format = "HH:mm";
let start = dayjs(startTime, format);
let end = dayjs(endTime, format);

if (start.isSame(end)) {
end = end.add(1, "day");
}

const intervals: string[] = [];

while (start.isBefore(end)) {
intervals.push(start.format(generatedFormat));
start = start.add(1, "hour");
}

return intervals;
};

export const getTimeValues = (
format: TimeFormat,
value?: string
Expand Down
29 changes: 15 additions & 14 deletions tests/date-navigator/date-navigator.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ describe("DateNavigator", () => {
jest.useRealTimers();
});

it("should render a simple date displaying the selectedDate prop without navigation arrows", () => {
const { rerender } = render(<DateNavigator selectedDate={today} />);
it("should render current date as today", () => {
render(<DateNavigator selectedDate={today} />);
expect(screen.getByText("5 September 2024")).toBeVisible();
expect(screen.getByText("Today")).toBeVisible();
expect(
Expand All @@ -23,9 +23,11 @@ describe("DateNavigator", () => {
expect(
screen.queryByTestId("date-navigator-right-arrow-btn")
).not.toBeInTheDocument();
});

it("should render other date in full", () => {
const tomorrow = "2024-09-06";
rerender(<DateNavigator selectedDate={tomorrow} />);
render(<DateNavigator selectedDate={tomorrow} />);
expect(screen.getByText("6 September 2024")).toBeVisible();
expect(screen.getByText("Friday")).toBeVisible();
expect(
Expand All @@ -36,10 +38,6 @@ describe("DateNavigator", () => {
).not.toBeInTheDocument();
});

it("should render the new date if it changes on rerender", () => {
render(<DateNavigator selectedDate={today} />);
});

it("should render a date navigator with navigation arrows", () => {
const onRightArrowClick = jest.fn();
const onLeftArrowClick = jest.fn();
Expand Down Expand Up @@ -85,32 +83,35 @@ describe("DateNavigator", () => {
expect(rightArrowButton).toBeDisabled();
});

it("should disable the corresponding buttons when the current date is ", () => {
it("should disable the left arrow button when the current date is at minDate", () => {
const onRightArrowClick = jest.fn();
const onLeftArrowClick = jest.fn();
const minDate = "2024-08-05";
const maxDate = "2024-10-05";
const { rerender } = render(
render(
<DateNavigator
selectedDate={minDate}
onRightArrowClick={onRightArrowClick}
onLeftArrowClick={onLeftArrowClick}
minDate={minDate}
maxDate={maxDate}
/>
);
const leftArrowButton = screen.getByTestId(
"date-navigator-left-arrow-btn"
);
expect(leftArrowButton).toBeDisabled();
rerender(
});

it("should disable the right arrow button when the current date is at maxDate", () => {
const onRightArrowClick = jest.fn();
const onLeftArrowClick = jest.fn();
const maxDate = "2024-10-05";
render(
<DateNavigator
selectedDate={maxDate}
onRightArrowClick={onRightArrowClick}
onLeftArrowClick={onLeftArrowClick}
minDate={minDate}
maxDate={maxDate}
></DateNavigator>
/>
);
const rightArrowButton = screen.getByTestId(
"date-navigator-right-arrow-btn"
Expand Down

0 comments on commit 1d7b2de

Please sign in to comment.