From a35bd5e612ced626627bd3a88475d95c2e2500a0 Mon Sep 17 00:00:00 2001 From: Jonathan Loh <36648707+jloh02@users.noreply.github.com> Date: Sat, 20 Apr 2024 16:15:22 +0800 Subject: [PATCH] Fix sorting order on table by using start date time as keys (#39) * Sort by event start date time * Fix time sorting --- .../booking-admin-table.tsx | 25 +++++++++---- .../booking-base-table/booking-base-table.tsx | 6 ++-- .../booking-user-table/booking-user-table.tsx | 35 +++++++++++-------- frontend/src/constants/index.ts | 7 ++-- frontend/src/utils/transform-utils.ts | 10 +++++- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/booking-admin-table/booking-admin-table.tsx b/frontend/src/components/booking-admin-table/booking-admin-table.tsx index b5bce4c..35b7a73 100644 --- a/frontend/src/components/booking-admin-table/booking-admin-table.tsx +++ b/frontend/src/components/booking-admin-table/booking-admin-table.tsx @@ -8,10 +8,13 @@ import { CREATED_AT_STRING, DATE_FORMAT, EMAIL, - EVENT_DATE, + EVENT_DATE_STRING, EVENT_TIME_RANGE, ID, NAME, + START_DATE_TIME, + START_DATE_TIME_STRING, + START_TIME_MINS, STATUS, TITLE, VENUE, @@ -24,7 +27,11 @@ import { selectAllBookings, selectBookingsLoadingState, } from "../../redux/slices/bookings-slice"; -import { displayDateTime, displayTimeRange } from "../../utils/transform-utils"; +import { + dateTimeToTimeMins, + displayDateTime, + displayTimeRange, +} from "../../utils/transform-utils"; import BookingBaseTable, { BookingViewProps } from "../booking-base-table"; import PlaceholderWrapper from "../placeholder-wrapper"; import SearchBar from "../search-bar"; @@ -40,7 +47,6 @@ const BOOKING_ADMIN_TABLE_STATE_OPTIONS: TableStateOptions = { ID, BOOKER_NAME, BOOKER_EMAIL, - EVENT_DATE, EVENT_TIME_RANGE, VENUE_NAME, CREATED_AT_STRING, @@ -56,7 +62,12 @@ function BookingAdminTable() { () => allBookings.map((booking) => ({ ...booking, - [EVENT_DATE]: displayDateTime(booking.startDateTime, DATE_FORMAT), + [START_TIME_MINS]: dateTimeToTimeMins(booking.startDateTime), + [START_DATE_TIME_STRING]: displayDateTime(booking.startDateTime), + [EVENT_DATE_STRING]: displayDateTime( + booking.startDateTime, + DATE_FORMAT, + ), [EVENT_TIME_RANGE]: displayTimeRange( booking.startDateTime, booking.endDateTime, @@ -143,15 +154,15 @@ function BookingAdminTable() { sortable /> - key={EVENT_DATE} - dataKey={EVENT_DATE} + key={START_DATE_TIME} + dataKey={EVENT_DATE_STRING} title="Date" width={100} resizable sortable /> - key={EVENT_TIME_RANGE} + key={START_TIME_MINS} dataKey={EVENT_TIME_RANGE} title="Time" width={150} diff --git a/frontend/src/components/booking-base-table/booking-base-table.tsx b/frontend/src/components/booking-base-table/booking-base-table.tsx index a3ab959..5efd466 100644 --- a/frontend/src/components/booking-base-table/booking-base-table.tsx +++ b/frontend/src/components/booking-base-table/booking-base-table.tsx @@ -5,9 +5,10 @@ import { Segment } from "semantic-ui-react"; import { ACTION, CREATED_AT_STRING, - EVENT_DATE, EVENT_TIME_RANGE, ID, + START_DATE_TIME_STRING, + START_TIME_MINS, STATUS, } from "../../constants"; import { useGetSingleBooking } from "../../custom-hooks/api/bookings-api"; @@ -20,7 +21,8 @@ import Table, { TableProps } from "../table"; import styles from "./booking-base-table.module.scss"; export type BookingViewProps = BookingData & { - [EVENT_DATE]: string; + [START_TIME_MINS]: number; + [START_DATE_TIME_STRING]: string; [EVENT_TIME_RANGE]: string; [CREATED_AT_STRING]: string; booking?: BookingData; diff --git a/frontend/src/components/booking-user-table/booking-user-table.tsx b/frontend/src/components/booking-user-table/booking-user-table.tsx index 9685e3f..1d90341 100644 --- a/frontend/src/components/booking-user-table/booking-user-table.tsx +++ b/frontend/src/components/booking-user-table/booking-user-table.tsx @@ -7,10 +7,14 @@ import { CREATED_AT, CREATED_AT_STRING, DATE_FORMAT, - EVENT_DATE, + END_DATE_TIME_STRING, + EVENT_DATE_STRING, EVENT_TIME_RANGE, ID, NAME, + START_DATE_TIME, + START_DATE_TIME_STRING, + START_TIME_MINS, STATUS, TITLE, VENUE, @@ -24,7 +28,11 @@ import { selectBookingsLoadingState, } from "../../redux/slices/bookings-slice"; import { selectCurrentUserDisplayInfo } from "../../redux/slices/current-user-slice"; -import { displayDateTime, displayTimeRange } from "../../utils/transform-utils"; +import { + dateTimeToTimeMins, + displayDateTime, + displayTimeRange, +} from "../../utils/transform-utils"; import BookingBaseTable, { BookingViewProps } from "../booking-base-table"; import PlaceholderWrapper from "../placeholder-wrapper"; import SearchBar from "../search-bar"; @@ -32,14 +40,7 @@ import SearchBar from "../search-bar"; const VENUE_NAME = `${VENUE}.${NAME}`; const BOOKING_ADMIN_TABLE_STATE_OPTIONS: TableStateOptions = { - searchKeys: [ - ID, - VENUE_NAME, - EVENT_DATE, - EVENT_TIME_RANGE, - CREATED_AT_STRING, - STATUS, - ], + searchKeys: [ID, VENUE_NAME, EVENT_TIME_RANGE, CREATED_AT_STRING, STATUS], }; function BookingUserTable() { @@ -54,7 +55,13 @@ function BookingUserTable() { () => userBookings.map((booking) => ({ ...booking, - [EVENT_DATE]: displayDateTime(booking.startDateTime, DATE_FORMAT), + [START_TIME_MINS]: dateTimeToTimeMins(booking.startDateTime), + [START_DATE_TIME_STRING]: displayDateTime(booking.startDateTime), + [END_DATE_TIME_STRING]: displayDateTime(booking.endDateTime), + [EVENT_DATE_STRING]: displayDateTime( + booking.startDateTime, + DATE_FORMAT, + ), [EVENT_TIME_RANGE]: displayTimeRange( booking.startDateTime, booking.endDateTime, @@ -120,15 +127,15 @@ function BookingUserTable() { sortable /> - key={EVENT_DATE} - dataKey={EVENT_DATE} + key={START_DATE_TIME} + dataKey={EVENT_DATE_STRING} title="Date" width={150} resizable sortable /> - key={EVENT_TIME_RANGE} + key={START_TIME_MINS} dataKey={EVENT_TIME_RANGE} title="Time" width={190} diff --git a/frontend/src/constants/index.ts b/frontend/src/constants/index.ts index 03d5976..330969d 100644 --- a/frontend/src/constants/index.ts +++ b/frontend/src/constants/index.ts @@ -23,9 +23,8 @@ export const EMAIL_REGEX = export const EMAILS = "emails"; export const END_DATE_TIME = "endDateTime"; export const EVENT = "event"; -export const EVENT_DATE = "eventDate"; // added export const EVENT_ID = "eventId"; -export const EVENT_TIME_RANGE = "eventTimeRange"; // added +export const EVENT_TIME_RANGE = "eventTimeRange"; export const LABEL = "label"; export const RESPONSE = "response"; export const TYPE = "type"; @@ -55,6 +54,7 @@ export const SIGN_UP_COUNT = "signUpCount"; export const SIGN_UP_STATUS = "signUpStatus"; export const SIGN_UPS = "signUps"; export const START_DATE_TIME = "startDateTime"; +export const START_TIME_MINS = "startTime"; // Start time of event in minutes from midnight export const STATUS = "status"; export const SUBSCRIBED_CATEGORIES = "subscribedCategories"; export const TITLE = "title"; @@ -67,6 +67,9 @@ export const VENUE_ID = "venueId"; export const VENUE_NAME = "venueName"; export const START = "start"; export const END = "end"; +export const START_DATE_TIME_STRING = "startDateTimeString"; +export const END_DATE_TIME_STRING = "endDateTimeString"; +export const EVENT_DATE_STRING = "eventDateString"; export const PROFILE_IMAGE = "profileImage"; export const DEFAULT_ARRAY = []; export const FULL_DETAILS = "fullDetails"; diff --git a/frontend/src/utils/transform-utils.ts b/frontend/src/utils/transform-utils.ts index d124d6a..7a6ea3a 100644 --- a/frontend/src/utils/transform-utils.ts +++ b/frontend/src/utils/transform-utils.ts @@ -1,5 +1,5 @@ import arraySort from "array-sort"; -import { format, isSameDay } from "date-fns"; +import { format, getHours, getMinutes, isSameDay } from "date-fns"; import { StringifiableRecord } from "query-string"; import { DATE_FORMAT, DATE_TIME_FORMAT, TIME_FORMAT } from "../constants"; @@ -95,6 +95,14 @@ export function displayDateTimeRange( : `${displayDateTime(startDateTime)} - ${displayDateTime(endDateTime)}`; } +export function dateTimeToTimeMins(inputDateTime: string | number | Date) { + const dateTime = + typeof inputDateTime === "string" + ? parseInt(inputDateTime, 10) + : inputDateTime; + return getHours(dateTime) * 60 + getMinutes(dateTime); +} + export function changeKeyCase( caseChanger: (input: string) => string, object?: StringifiableRecord,