diff --git a/src/helpers/converters.ts b/src/helpers/converters.ts index 734a1dd..668e4be 100644 --- a/src/helpers/converters.ts +++ b/src/helpers/converters.ts @@ -138,3 +138,46 @@ export const convertJsonStringToBase64Download = (json: string): string => { const b64Encoded = Buffer.from(json).toString("base64"); return `data:application/json;base64,${b64Encoded}`; }; + +export const convertReduxTripItem = (tripItem: TripItem): TripItem => { + const formattedTripItem: TripItem = { ...tripItem }; + + Object.keys(tripItem) + .filter((k: string): k is keyof TripItem => + tripItemTimestampKeys.includes(k as keyof TripItem) + ) + .forEach((k) => { + // value is either unset, an ISO date string, or a Firestore Timestamp object + if ( + !formattedTripItem[k] || + !dayjs(formattedTripItem[k] as string).isValid() + ) { + return; + } + console.log("converting", formattedTripItem); + // @ts-ignore this works stfu typescript + formattedTripItem[k] = forceDateInUserTimezone( + formattedTripItem[k] as string + ).format(); + }); + + return { + ...tripItem, + startsAt: forceDateInUserTimezone(tripItem.startsAt).format(), + }; +}; + +/** + * Conversion for trips from redux datastore + * @param trip The raw trip + */ +export const convertReduxTrip = (trip: Trip): Trip => { + return { + ...trip, + startsAt: forceDateInUserTimezone(trip.startsAt!).format(), + endsAt: trip.endsAt && forceDateInUserTimezone(trip.endsAt).format(), + createdAtUtc: forceDateInUserTimezone(trip.createdAtUtc).format(), + updatedAtUtc: forceDateInUserTimezone(trip.updatedAtUtc).format(), + items: (trip.items ?? []).map(convertReduxTripItem), + }; +}; diff --git a/src/store/features/trips/index.tsx b/src/store/features/trips/index.tsx index 2ae8312..c0d1dd2 100644 --- a/src/store/features/trips/index.tsx +++ b/src/store/features/trips/index.tsx @@ -22,6 +22,7 @@ import TripDetails from "../../../types/TripDetails"; import Trip from "../../../types/Trip"; import { convertJsonStringToBase64Download, + convertReduxTrip, convertTripDocument, convertTripItemDocuments, } from "../../../helpers/converters"; @@ -40,6 +41,7 @@ export const useAddTrip: TripHooks["useAddTrip"] = () => { return useCallback( async (data) => { if (activeProvider === "redux") { + // @TODO: data.startsAt is a dayjs non-serializable object which is a no-no for passing dispatch( providerRedux.actions.addTrip(data) as PayloadAction ); @@ -279,6 +281,8 @@ export const useGetTripById: TripHooks["useGetTripById"] = (tripId) => { useEffect(() => { if (activeProvider === "redux") { + // why is firestore here? because logged out people can view public + // trips :) // firestore trip IDs are a completely different format to local trips // so we can safely assume if no trip is returned and a firebase object // is that the user is a) not logged in and b) trying to view a public trip. @@ -288,7 +292,7 @@ export const useGetTripById: TripHooks["useGetTripById"] = (tripId) => { ...firestoreTripValue, items: firestoreItemValues ?? [], } - : (trip as Trip), + : convertReduxTrip(trip as Trip), // @TODO: set this to true if firebase loading ONLY if there's no trip loading: false, }); diff --git a/src/store/features/trips/redux.ts b/src/store/features/trips/redux.ts index 984eb72..8d4e816 100644 --- a/src/store/features/trips/redux.ts +++ b/src/store/features/trips/redux.ts @@ -60,8 +60,8 @@ const tripSlice = createSlice({ id: payload.id, title: payload.title, location: payload.location, - startsAt: payload.startsAt, - endsAt: payload.endsAt, + startsAt: dayjs(payload.startsAt).utc(true).format(), + endsAt: payload.endsAt && dayjs(payload.endsAt).utc(true).format(), createdAtUtc: dayjs.utc().format(), updatedAtUtc: dayjs.utc().format(), image: payload.image, @@ -82,8 +82,8 @@ const tripSlice = createSlice({ // be set otherwise on cloud storage trips userId: undefined, public: false, - startsAt: dayjs(payload.startsAt).format("YYYY-MM-DD"), - endsAt: payload.endsAt && dayjs(payload.endsAt).format("YYYY-MM-DD"), + startsAt: dayjs(payload.startsAt).utc(true).format(), + endsAt: payload.endsAt && dayjs(payload.endsAt).utc(true).format(), updatedAtUtc: dayjs.utc().format(), }; @@ -112,8 +112,10 @@ const tripSlice = createSlice({ title: filteredPayload?.title?.length ? filteredPayload.title : getTripItemTypeLabel(filteredPayload.type), - startsAt: filteredPayload.startsAt, - endsAt: filteredPayload.endsAt, + startsAt: dayjs(filteredPayload.startsAt).utc(true).format(), + endsAt: + filteredPayload.endsAt && + dayjs(filteredPayload.endsAt).utc(true).format(), }; const items: TripItem[] = [...(trip?.items || []), newTripItem]; @@ -149,8 +151,8 @@ const tripSlice = createSlice({ const newDataFormatted: TripItem = { ...newData, id: newData.id!, - startsAt: newData.startsAt, - endsAt: newData.endsAt, + startsAt: dayjs(newData.startsAt).utc(true).format(), + endsAt: newData.endsAt && dayjs(newData.endsAt).utc(true).format(), }; const items: TripItem[] = [...allOtherItems, newDataFormatted];