From 39f6088e4780adee6bc6c363040747bcd36189c8 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Thu, 18 Jul 2024 20:50:52 +0200 Subject: [PATCH 1/9] retrieve pushtokens to send to --- .../screens/Office/BookingDetails.tsx | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx index d892d978..679f689d 100644 --- a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx +++ b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx @@ -57,7 +57,7 @@ const BookingDetails = () => { let userinfo = await SecureStore.getItemAsync('UserData'); // if (result !== undefined) { let jsoninfo = JSON.parse(userinfo); - console.log("data",jsoninfo?.data.details.name); + console.log("data", jsoninfo?.data.details.name); setCreatorEmail(jsoninfo?.data?.email); let result: string = await SecureStore.getItemAsync('BookingInfo'); console.log("CurrentRoom:", jsoninfo?.data?.email); @@ -114,19 +114,38 @@ const BookingDetails = () => { const data = await response.json(); console.log(data); if (response.ok) { - sendPushNotification(['ExponentPushToken[5cpRYINQu42bhcKM5b7Vsb]','ExponentPushToken[ARLofOIiMGuJjE2EQTWQWq]'], "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`); - setCurrentStep(2); - setLoading(false); - toast.show({ - placement: 'top', - render: ({ id }) => { - return ( - - {data.message} - - ); - }, - }); + try { + const response = await fetch(`${apiUrl}api/get-push-tokens?emails=${attendees}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'Authorization': `${authToken}` + }, + body: JSON.stringify(body), + credentials: "include" + }); + const data = await response.json(); + console.log(data); + if (data.data) { + sendPushNotification(data.data, "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`); + } + setCurrentStep(2); + setLoading(false); + toast.show({ + placement: 'top', + render: ({ id }) => { + return ( + + {data.message} + + ); + }, + }); + } catch (error) { + console.error('Error:', error); + } + } else { console.log(data); setLoading(false); From 3dd8b02e23b076cecf2a054e25c2bdeebfcd4656 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Thu, 18 Jul 2024 23:50:10 +0200 Subject: [PATCH 2/9] notification sending complete --- .../screens/Login/SplashScreen.tsx | 2 +- .../screens/Office/BookingDetails.tsx | 21 ++++++++++++------- .../screens/Settings/NotifTester.tsx | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx b/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx index 1c5dce6c..9024fd01 100644 --- a/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx +++ b/frontend/occupi-mobile4/screens/Login/SplashScreen.tsx @@ -93,7 +93,7 @@ export default function SplashScreen() { useEffect(() => { const timer = setTimeout(() => { setSelectedIndex(1); // Assuming Onboarding1 is at index 1 - router.replace('/login'); // Navigate to Onboarding1 screen + router.replace('/notifications'); // Navigate to Onboarding1 screen }, 5000); // 8 seconds return () => clearTimeout(timer); // Clean up timer on component unmount diff --git a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx index 679f689d..324ca5f5 100644 --- a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx +++ b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx @@ -42,6 +42,7 @@ const BookingDetails = () => { const [startTime, setStartTime] = useState(''); const [endTime, setEndTime] = useState(''); const isDark = colorScheme === "dark"; + const [pushTokens, setPushTokens] = useState([]); // console.log(creatorEmail + roomId + floorNo); // console.log(bookingInfo?); // console.log(startTime); @@ -113,24 +114,27 @@ const BookingDetails = () => { }); const data = await response.json(); console.log(data); + console.log(attendees); if (response.ok) { try { - const response = await fetch(`${apiUrl}api/get-push-tokens?emails=${attendees}`, { + const response = await fetch(`${apiUrl}/api/get-push-tokens?emails=${attendees.slice(1)}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'Authorization': `${authToken}` }, - body: JSON.stringify(body), credentials: "include" }); const data = await response.json(); - console.log(data); + console.log("PUSHH TOKENSS",data); if (data.data) { - sendPushNotification(data.data, "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`); + let tokens = data.data.map((item) => item.expoPushToken); + setPushTokens(tokens); + console.log(tokens); + sendPushNotification(tokens, "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`); } - setCurrentStep(2); + // setCurrentStep(2); setLoading(false); toast.show({ placement: 'top', @@ -143,9 +147,9 @@ const BookingDetails = () => { }, }); } catch (error) { + setLoading(false); console.error('Error:', error); } - } else { console.log(data); setLoading(false); @@ -161,6 +165,7 @@ const BookingDetails = () => { }); } } catch (error) { + setLoading(false); console.error('Error:', error); // setResponse('An error occurred'); } @@ -256,6 +261,8 @@ const BookingDetails = () => { const handleBiometricAuth = async () => { const hasHardware = await LocalAuthentication.hasHardwareAsync(); const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + const biometricType = await LocalAuthentication.supportedAuthenticationTypesAsync(); + console.log('Supported biometric types:', biometricType); if (!hasHardware || !isEnrolled) { Alert.alert( @@ -527,7 +534,7 @@ const BookingDetails = () => { {attendees.map((email, idx) => ( - {idx + 1}. {email} + {idx + 1}. {email} ))} diff --git a/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx b/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx index 1270242d..b24143e1 100644 --- a/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx +++ b/frontend/occupi-mobile4/screens/Settings/NotifTester.tsx @@ -20,7 +20,7 @@ async function sendPushNotification(expoPushToken: string) { trigger: { seconds: 10 }, - to: "ExponentPushToken[ARLofOIiMGuJjE2EQTWQWq]", + to: expoPushToken, sound: 'default', title: 'Original Title', body: 'And here is the body!', From 03e5cfd3d88ceb6e203a0ccd43805b5d8e97ffa3 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Fri, 19 Jul 2024 01:36:51 +0200 Subject: [PATCH 3/9] retieval of notifications --- .../screens/Notifications/Notifications.tsx | 99 +++++++++++++++++-- 1 file changed, 91 insertions(+), 8 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index 3866c73a..c4ee061f 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -1,29 +1,112 @@ +import { useState, useEffect } from 'react'; import Navbar from '../../components/NavBar'; import { Text, View, - Image, - Card, Toast, useToast, ToastTitle, - Button, - ButtonText, + Divider, + ScrollView } from '@gluestack-ui/themed'; +import * as SecureStore from 'expo-secure-store'; import { StatusBar, useColorScheme, Dimensions } from 'react-native'; import { Entypo } from '@expo/vector-icons'; +import { Skeleton } from 'moti/skeleton'; const Notifications = () => { const colorScheme = useColorScheme(); + const toast = useToast(); + const [notifications, setNotifications] = useState(); + const [loading, setLoading] = useState(true); + + const apiUrl = process.env.EXPO_PUBLIC_DEVELOP_API_URL; + + useEffect(() => { + const getNotifications = async () => { + let userEmail = await SecureStore.getItemAsync('Email'); + let authToken = await SecureStore.getItemAsync('Token'); + const baseUrl = 'https://dev.occupi.tech/api/get-notifications'; + const params = new URLSearchParams(); + params.append('filter', '{"emails":["kamogelomoeketse@gmail.com"]}'); + + const url = `${baseUrl}?${params.toString()}`; + + try { + const response = await fetch(baseUrl, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'Authorization': `${authToken}` + }, + credentials: "include" + }); + const data = await response.json(); + console.log(`Response Data: ${JSON.stringify(data.data)}`); + // console.log(data); + if (response.ok) { + setNotifications(data.data || []); // Ensure data is an array + // console.log(data); + setLoading(false); + } else { + console.log(data); + setLoading(false); + toast.show({ + placement: 'top', + render: ({ id }) => { + return ( + + {data.error.message} + + ); + }, + }); + } + } catch (error) { + console.error('Error:', error); + toast.show({ + placement: 'top', + render: ({ id }) => { + return ( + + Network Error: {error.message} + + ); + }, + }); + } + }; + getNotifications(); + }, [apiUrl, toast]) + return ( + Notifications - - - + + + - + {loading === true ? ( + + {Array.from({ length: 8 }, (_, index) => ( + + + + ))} + + ) : ( + + {notifications.map((notification, idx) => ( + {notification.message} + ))} + + + + )} + ) From ca769d0b3aa7b1a416e779c2fdfd22ee1e39f462 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Fri, 19 Jul 2024 17:40:52 +0200 Subject: [PATCH 4/9] axios for the notifications --- .../screens/Notifications/Notifications.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index c4ee061f..ca547c63 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -13,6 +13,7 @@ import * as SecureStore from 'expo-secure-store'; import { StatusBar, useColorScheme, Dimensions } from 'react-native'; import { Entypo } from '@expo/vector-icons'; import { Skeleton } from 'moti/skeleton'; +import axios from 'axios'; const Notifications = () => { const colorScheme = useColorScheme(); @@ -26,28 +27,31 @@ const Notifications = () => { const getNotifications = async () => { let userEmail = await SecureStore.getItemAsync('Email'); let authToken = await SecureStore.getItemAsync('Token'); - const baseUrl = 'https://dev.occupi.tech/api/get-notifications'; + // const baseUrl = 'https://dev.occupi.tech/api/get-notifications'; const params = new URLSearchParams(); params.append('filter', '{"emails":["kamogelomoeketse@gmail.com"]}'); - const url = `${baseUrl}?${params.toString()}`; + // const url = `${baseUrl}?${params.toString()}`; try { - const response = await fetch(baseUrl, { - method: 'GET', + const response = await axios.get('https://dev.occupi.tech/api/get-notifications', { + params: { + filter: { + emails: [{userEmail}] + } + }, headers: { - Accept: 'application/json', + 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': `${authToken}` }, - credentials: "include" + withCredentials: true }); - const data = await response.json(); + const data = response.data; console.log(`Response Data: ${JSON.stringify(data.data)}`); // console.log(data); - if (response.ok) { + if (response.status === 200) { setNotifications(data.data || []); // Ensure data is an array - // console.log(data); setLoading(false); } else { console.log(data); From a8bbc0f6e0f5a14b96c51cd6eba142a650452c40 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Fri, 19 Jul 2024 18:30:32 +0200 Subject: [PATCH 5/9] added date --- .../screens/Notifications/Notifications.tsx | 34 +++++++++++-------- .../screens/Office/BookingDetails.tsx | 2 +- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index ca547c63..2a93364a 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -36,9 +36,10 @@ const Notifications = () => { try { const response = await axios.get('https://dev.occupi.tech/api/get-notifications', { params: { - filter: { - emails: [{userEmail}] - } + filter: { + emails: [{ userEmail }] + }, + order_desc: "send_time" }, headers: { 'Accept': 'application/json', @@ -48,7 +49,7 @@ const Notifications = () => { withCredentials: true }); const data = response.data; - console.log(`Response Data: ${JSON.stringify(data.data)}`); + // console.log(`Response Data: ${JSON.stringify(data.data)}`); // console.log(data); if (response.status === 200) { setNotifications(data.data || []); // Ensure data is an array @@ -87,30 +88,33 @@ const Notifications = () => { return ( - + Notifications {loading === true ? ( - + <> {Array.from({ length: 8 }, (_, index) => ( - - - - ))} - + + + + ))} + ) : ( {notifications.map((notification, idx) => ( - {notification.message} + + {new Date(notification.send_time) < new Date() && ( + + {notification.message} · {new Date(notification.send_time).toLocaleString()} + + )} + ))} - - )} - ) diff --git a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx index 324ca5f5..7f53a877 100644 --- a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx +++ b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx @@ -134,7 +134,7 @@ const BookingDetails = () => { console.log(tokens); sendPushNotification(tokens, "New Booking", `${jsoninfo?.data.details.name} has invited you to a booking.`); } - // setCurrentStep(2); + setCurrentStep(2); setLoading(false); toast.show({ placement: 'top', From 969034d6739fdc4a1c5ca9ab6f5280b44b0c8e96 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Fri, 19 Jul 2024 18:37:59 +0200 Subject: [PATCH 6/9] added icons oms --- .../screens/Notifications/Notifications.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index 2a93364a..443de6e5 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -11,7 +11,7 @@ import { } from '@gluestack-ui/themed'; import * as SecureStore from 'expo-secure-store'; import { StatusBar, useColorScheme, Dimensions } from 'react-native'; -import { Entypo } from '@expo/vector-icons'; +import { Entypo, FontAwesome6 } from '@expo/vector-icons'; import { Skeleton } from 'moti/skeleton'; import axios from 'axios'; @@ -96,7 +96,7 @@ const Notifications = () => { {loading === true ? ( <> - {Array.from({ length: 8 }, (_, index) => ( + {Array.from({ length: 8 }, (_, index) => ( @@ -107,9 +107,12 @@ const Notifications = () => { {notifications.map((notification, idx) => ( {new Date(notification.send_time) < new Date() && ( - - {notification.message} · {new Date(notification.send_time).toLocaleString()} - + + + + {notification.message} · {new Date(notification.send_time).toLocaleString()} + + )} ))} From 32a38c9ac6db052ae15af7142988bf516c224eee Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Sat, 20 Jul 2024 01:12:49 +0200 Subject: [PATCH 7/9] format date string --- .../screens/Notifications/Notifications.tsx | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index 443de6e5..d0760f67 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -20,9 +20,43 @@ const Notifications = () => { const toast = useToast(); const [notifications, setNotifications] = useState(); const [loading, setLoading] = useState(true); + const todayNotifications = []; + const yesterdayNotifications = []; + const olderNotifications = []; const apiUrl = process.env.EXPO_PUBLIC_DEVELOP_API_URL; + const formatNotificationDate = (sendTime) => { + const now = new Date(); + const notificationDate = new Date(sendTime); + + const differenceInHours = Math.floor((now - notificationDate) / (1000 * 60 * 60)); + const differenceInDays = Math.floor(differenceInHours / 24); + + if (differenceInDays === 0) { + return differenceInHours < 1 ? 'less than an hour ago' : `${differenceInHours} hours ago`; + } else if (differenceInDays === 1) { + return 'yesterday'; + } else { + return notificationDate.toLocaleDateString(); + } + }; + + if (notifications) { + notifications.forEach(notification => { + const formattedDate = formatNotificationDate(notification.send_time); + + if (formattedDate.includes('hours ago')) { + todayNotifications.push(notification); + } else if (formattedDate === 'yesterday') { + yesterdayNotifications.push(notification); + } else { + olderNotifications.push(notification); + } + }); + } + + useEffect(() => { const getNotifications = async () => { let userEmail = await SecureStore.getItemAsync('Email'); @@ -53,6 +87,7 @@ const Notifications = () => { // console.log(data); if (response.status === 200) { setNotifications(data.data || []); // Ensure data is an array + setLoading(false); } else { console.log(data); @@ -85,6 +120,19 @@ const Notifications = () => { getNotifications(); }, [apiUrl, toast]) + const renderNotifications = (notificationList) => ( + notificationList.map((notification, idx) => ( + + + + + {notification.message} · {formatNotificationDate(notification.send_time)} + + + + )) + ); + return ( @@ -104,18 +152,16 @@ const Notifications = () => { ) : ( - {notifications.map((notification, idx) => ( - - {new Date(notification.send_time) < new Date() && ( - - - - {notification.message} · {new Date(notification.send_time).toLocaleString()} - - - )} - - ))} + + Recent + {renderNotifications(todayNotifications)} + + Yesterday + {renderNotifications(yesterdayNotifications)} + + Older + {renderNotifications(olderNotifications)} + )} From 3c8e1c6d65122276c18a99ea4c90b810d3f88640 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Sat, 20 Jul 2024 12:37:46 +0200 Subject: [PATCH 8/9] format notifications to fit on screen --- .../screens/Notifications/Notifications.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index d0760f67..f865fb79 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -11,7 +11,7 @@ import { } from '@gluestack-ui/themed'; import * as SecureStore from 'expo-secure-store'; import { StatusBar, useColorScheme, Dimensions } from 'react-native'; -import { Entypo, FontAwesome6 } from '@expo/vector-icons'; +import { AntDesign, Entypo, FontAwesome6 } from '@expo/vector-icons'; import { Skeleton } from 'moti/skeleton'; import axios from 'axios'; @@ -84,10 +84,9 @@ const Notifications = () => { }); const data = response.data; // console.log(`Response Data: ${JSON.stringify(data.data)}`); - // console.log(data); + console.log(data); if (response.status === 200) { setNotifications(data.data || []); // Ensure data is an array - setLoading(false); } else { console.log(data); @@ -123,9 +122,9 @@ const Notifications = () => { const renderNotifications = (notificationList) => ( notificationList.map((notification, idx) => ( - - - + + + {notification.message} · {formatNotificationDate(notification.send_time)} @@ -153,7 +152,7 @@ const Notifications = () => { ) : ( - Recent + Recent {renderNotifications(todayNotifications)} Yesterday From aa2939aa4216f5e8336d0ed4089a96b3f7665f12 Mon Sep 17 00:00:00 2001 From: Kamogelo Moeketse Date: Mon, 22 Jul 2024 23:40:40 +0200 Subject: [PATCH 9/9] format the date/time correctly --- .../screens/Notifications/Notifications.tsx | 10 ++++------ .../occupi-mobile4/screens/Office/BookingDetails.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx index f865fb79..b663551c 100644 --- a/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx +++ b/frontend/occupi-mobile4/screens/Notifications/Notifications.tsx @@ -28,12 +28,15 @@ const Notifications = () => { const formatNotificationDate = (sendTime) => { const now = new Date(); + // console.log(now); const notificationDate = new Date(sendTime); + console.log(notificationDate); const differenceInHours = Math.floor((now - notificationDate) / (1000 * 60 * 60)); const differenceInDays = Math.floor(differenceInHours / 24); if (differenceInDays === 0) { + console.log(differenceInDays); return differenceInHours < 1 ? 'less than an hour ago' : `${differenceInHours} hours ago`; } else if (differenceInDays === 1) { return 'yesterday'; @@ -46,7 +49,7 @@ const Notifications = () => { notifications.forEach(notification => { const formattedDate = formatNotificationDate(notification.send_time); - if (formattedDate.includes('hours ago')) { + if (formattedDate.includes('hours ago') || formattedDate.includes('hour ago')) { todayNotifications.push(notification); } else if (formattedDate === 'yesterday') { yesterdayNotifications.push(notification); @@ -61,11 +64,6 @@ const Notifications = () => { const getNotifications = async () => { let userEmail = await SecureStore.getItemAsync('Email'); let authToken = await SecureStore.getItemAsync('Token'); - // const baseUrl = 'https://dev.occupi.tech/api/get-notifications'; - const params = new URLSearchParams(); - params.append('filter', '{"emails":["kamogelomoeketse@gmail.com"]}'); - - // const url = `${baseUrl}?${params.toString()}`; try { const response = await axios.get('https://dev.occupi.tech/api/get-notifications', { diff --git a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx index 7f53a877..047f3727 100644 --- a/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx +++ b/frontend/occupi-mobile4/screens/Office/BookingDetails.tsx @@ -107,7 +107,8 @@ const BookingDetails = () => { headers: { Accept: 'application/json', 'Content-Type': 'application/json', - 'Authorization': `${authToken}` + 'Authorization': `${authToken}`, + 'X-Timezone': 'Africa/Johannesburg' }, body: JSON.stringify(body), credentials: "include" @@ -122,7 +123,8 @@ const BookingDetails = () => { headers: { Accept: 'application/json', 'Content-Type': 'application/json', - 'Authorization': `${authToken}` + 'Authorization': `${authToken}`, + 'X-Timezone': 'Africa/Johannesburg' }, credentials: "include" });