From 068c243fa888bc0f6ee1b4dda9520b92d289c23d Mon Sep 17 00:00:00 2001 From: chasevill <98123650+rhit-villencr@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:58:51 -0500 Subject: [PATCH] Putting all API calls into one file for readability, testability, and comprehension --- app/accountSetting.tsx | 2 +- app/addCalendarEvents.tsx | 4 ++-- app/addFinanceEvents.tsx | 4 ++-- app/addHealthEvents.tsx | 4 ++-- app/addMeals.tsx | 8 +++---- app/genericAddViewEventPage.tsx | 15 +++++-------- app/genericMainPage.tsx | 16 ++++---------- app/index.tsx | 13 ++++++----- app/mainCalendarEvents.tsx | 18 ++++------------ app/notes.tsx | 37 +++++++++++++++++--------------- app/viewCalendarEvents.tsx | 4 ++-- app/viewFinanceEvents.tsx | 4 ++-- app/viewHealthEvents.tsx | 4 ++-- app/viewMealEvents.tsx | 6 +++--- backend/omniplanner.db | Bin 118784 -> 118784 bytes components/apiCall.tsx | 21 ++++++++++++++++++ {app => components}/log.tsx | 0 constants/constants.tsx | 10 ++++----- 18 files changed, 84 insertions(+), 86 deletions(-) create mode 100644 components/apiCall.tsx rename {app => components}/log.tsx (100%) diff --git a/app/accountSetting.tsx b/app/accountSetting.tsx index 424dafe..f68a365 100644 --- a/app/accountSetting.tsx +++ b/app/accountSetting.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native'; -import { cLog } from './log'; +import { cLog } from '../components/log'; import { useFocusEffect } from '@react-navigation/native'; import AsyncStorage from '@react-native-async-storage/async-storage'; diff --git a/app/addCalendarEvents.tsx b/app/addCalendarEvents.tsx index 93e9ea8..f21aa8f 100644 --- a/app/addCalendarEvents.tsx +++ b/app/addCalendarEvents.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { calendarFields, IPAddr } from '@/constants/constants'; +import { calendarFields } from '@/constants/constants'; import GenericAddViewPageForm from './genericAddViewEventPage'; export default function AddCalendarEvents() { @@ -18,7 +18,7 @@ export default function AddCalendarEvents() { initialData={calendarInitialData} fields={calendarFields} mainPage="mainCalendarEvents" - updateEndpoint={`${IPAddr}/add_calendar_event`} + updateEndpoint={`/add_calendar_event`} method="POST" /> ); diff --git a/app/addFinanceEvents.tsx b/app/addFinanceEvents.tsx index e348556..f62ca01 100644 --- a/app/addFinanceEvents.tsx +++ b/app/addFinanceEvents.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { financeFields, IPAddr } from '@/constants/constants'; +import { financeFields } from '@/constants/constants'; import GenericAddViewPageForm from './genericAddViewEventPage'; export default function AddFinanceEvents() { @@ -18,7 +18,7 @@ export default function AddFinanceEvents() { initialData={financeInitialData} fields={financeFields} mainPage='mainFinanceTracker' - updateEndpoint={`${IPAddr}/add_finance_events`} + updateEndpoint={`/add_finance_events`} method="POST" /> ); diff --git a/app/addHealthEvents.tsx b/app/addHealthEvents.tsx index c56847c..f8bd924 100644 --- a/app/addHealthEvents.tsx +++ b/app/addHealthEvents.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { healthFields, IPAddr } from '@/constants/constants'; +import { healthFields } from '@/constants/constants'; import GenericAddViewPageForm from './genericAddViewEventPage'; export default function AddHealthEvents() { @@ -17,7 +17,7 @@ export default function AddHealthEvents() { initialData={healthInitialData} fields={healthFields} mainPage='mainHealthTracker' - updateEndpoint={`${IPAddr}/add_health_events`} + updateEndpoint={`/add_health_events`} method="POST" /> ); diff --git a/app/addMeals.tsx b/app/addMeals.tsx index 4a6b414..682be34 100644 --- a/app/addMeals.tsx +++ b/app/addMeals.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { mealFields, IPAddr } from '@/constants/constants'; +import { mealFields } from '@/constants/constants'; import GenericAddViewPageForm from './genericAddViewEventPage'; export default function AddMeals() { @@ -16,8 +16,8 @@ export default function AddMeals() { initialData={mealInitialData} fields={mealFields} mainPage="mainMealTracker" - updateEndpoint={`${IPAddr}/add_meal_events`} - fetchEndpoint={`${IPAddr}/get_ingredients`} + updateEndpoint={`/add_meal_events`} + fetchEndpoint={`/get_ingredients`} keyValue={{'key':"id", "value":"ingredientName"}} method="POST" /> @@ -32,4 +32,4 @@ export default function AddMeals() { // console.error('Error adding new ingredient:', error); // } // }; - + diff --git a/app/genericAddViewEventPage.tsx b/app/genericAddViewEventPage.tsx index 961c485..8147042 100644 --- a/app/genericAddViewEventPage.tsx +++ b/app/genericAddViewEventPage.tsx @@ -1,9 +1,8 @@ import React, { useCallback, useState } from 'react'; -import axios from 'axios'; import DateTimePicker from '@react-native-community/datetimepicker'; import { View, Text, TextInput, ScrollView, TouchableOpacity } from 'react-native'; import { Dropdown } from 'react-native-element-dropdown'; -import { cLog } from './log'; +import { cLog } from '../components/log'; import { styles } from '@/assets/styles/styles'; import { GenericEventPageProps, RootStackParamList } from '@/components/Types'; import { StackNavigationProp } from '@react-navigation/stack'; @@ -11,6 +10,7 @@ import { useNavigation, useFocusEffect, RouteProp, useRoute } from '@react-navig import MultiSelect from 'react-native-multiple-select'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { verifyToken } from '@/constants/constants'; +import { call } from '../components/apiCall'; const GenericAddViewPageForm: React.FC = ({ title, initialData = {}, fields, mainPage, updateEndpoint, fetchEndpoint, keyValue, method }) => { const [showDatePicker, setShowDatePicker] = useState(false); @@ -46,13 +46,8 @@ const GenericAddViewPageForm: React.FC = ({ title, initia cLog(formattedData); try { cLog('Saving event to:' + updateEndpoint); - if (method === 'PUT') { - const response = await axios.put(updateEndpoint, formattedData); - cLog('Event updated successfully:' + response.data); - } else { - const response = await axios.post(updateEndpoint, formattedData); - cLog('Event saved successfully:' + response.data); - } + const response = await call(updateEndpoint, method, undefined, formattedData) + cLog('Event updated successfully:' + response.data); } catch (error) { console.error('Error saving event:', error); } @@ -87,7 +82,7 @@ const GenericAddViewPageForm: React.FC = ({ title, initia if (!fetchEndpoint) return; try { const userId = await AsyncStorage.getItem('userId'); - const response = await axios.get(`${fetchEndpoint}/${userId}`); + const response = await call(`${fetchEndpoint}/${userId}`, 'GET'); const formattedData = response.data.map((item: { [x: string]: any; id: any; name: any; }) => ({ value: keyValue ? item[keyValue.key] : item.id, label: keyValue ? item[keyValue.value] : item.name, diff --git a/app/genericMainPage.tsx b/app/genericMainPage.tsx index b585710..1ec42fb 100644 --- a/app/genericMainPage.tsx +++ b/app/genericMainPage.tsx @@ -7,10 +7,10 @@ import { Ionicons } from "@expo/vector-icons"; import { EventProps, GoogleCalendarProps, NavigationProps, RootStackParamList, Task } from '@/components/Types'; import { useFocusEffect, useNavigation } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; -import { cLog } from './log'; -import { formatTime, getPageFromEventType, getPageName, IPAddr, verifyToken } from '@/constants/constants'; -import axios from 'axios'; +import { cLog } from '../components/log'; +import { formatTime, getPageFromEventType, getPageName, verifyToken } from '@/constants/constants'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { call } from '../components/apiCall'; interface FormProps extends EventProps, GoogleCalendarProps, NavigationProps { title: string; @@ -77,22 +77,14 @@ const GenericMainPageForm: React.FC = ({ const fetchEvents = async () => { try { const userId = await AsyncStorage.getItem('userId'); - const hit = `${IPAddr}${hitAddress}${userId}`; - cLog(`Fetching events from: ${hit}`); - const response = await axios.get(hit); + const response = await call(`${hitAddress}${userId}`, 'GET'); if (response.status === 200 && response.data) { const { events, googleCalendarLinked } = response.data; - cLog(`response.data:`); - cLog(response.data); - cLog(`events:`); - cLog(events); - if (googleCalendar) { setIsGoogleCalendarLinked(googleCalendarLinked); } - const eventsArray = Array.isArray(events) ? events : response.data; cLog(`eventsArray:`); cLog(eventsArray); diff --git a/app/index.tsx b/app/index.tsx index 9093faa..1b22db2 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -1,13 +1,12 @@ import React, { useState, useCallback, useRef } from 'react'; -import { IPAddr } from '@/constants/constants'; import { RootStackParamList, UserInfo } from '@/components/Types'; -import axios from 'axios'; import { styles } from '@/assets/styles/styles'; import { useFocusEffect, useNavigation } from '@react-navigation/native'; -import { cLog } from './log'; +import { cLog } from '../components/log'; import AsyncStorage from "@react-native-async-storage/async-storage"; import { StackNavigationProp } from '@react-navigation/stack'; import { TextInput, View, Text, TouchableOpacity } from 'react-native'; +import { call } from '../components/apiCall'; export default function TaskScreen() { type Prop = StackNavigationProp; @@ -40,7 +39,7 @@ export default function TaskScreen() { const performLoginRequest = async (url: string, data: object) => { try { - const response = await axios.put(url, data); + const response = await call(url, 'PUT', undefined, data); cLog('Login response:', response.data); await handleLoginResponse(response.data); } catch (error) { @@ -51,16 +50,16 @@ export default function TaskScreen() { const checkLogin = async () => { const [storedToken, storedUserName] = await AsyncStorage.multiGet(['token', 'userName']); if (storedToken[1] && storedUserName[1]) { - await performLoginRequest(`${IPAddr}/checkLogin`, { userName: storedUserName[1], token: storedToken[1] }); + await performLoginRequest(`/checkLogin`, { userName: storedUserName[1], token: storedToken[1] }); } else { - console.log('No valid token or username found'); + cLog('No valid token or username found'); } }; const handleLogin = async () => { cLog("Attempting to log in..."); const { userName, password } = credentials; - performLoginRequest(`${IPAddr}/login`, { userName, password }) + performLoginRequest(`/login`, { userName, password }) } const parseUserInfo = (data: string): UserInfo => { diff --git a/app/mainCalendarEvents.tsx b/app/mainCalendarEvents.tsx index d9637fc..d71200b 100644 --- a/app/mainCalendarEvents.tsx +++ b/app/mainCalendarEvents.tsx @@ -3,9 +3,8 @@ import GenericMainPageForm from './genericMainPage'; import { Alert } from 'react-native'; import * as WebBrowser from 'expo-web-browser'; import * as Linking from 'expo-linking'; -import axios from 'axios'; -import { IPAddr } from '@/constants/constants'; -import { cLog } from './log' +import { cLog } from '../components/log' +import { call } from '../components/apiCall'; const CLIENT_ID = process.env.EXPO_PUBLIC_CLIENT_ID || ''; const CLIENT_SECRET = process.env.EXPO_PUBLIC_CLIENT_SECRET || ''; @@ -52,11 +51,7 @@ export default function CalendarTracker() { params.append('client_secret', CLIENT_SECRET); params.append('redirect_uri', REDIRECT_URI); params.append('grant_type', 'authorization_code'); - const response = await axios.post(TOKEN_URI, params, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - }); + const response = await call(TOKEN_URI, 'POST', 'application/x-www-form-urlencoded', params); if (response.data.access_token) { cLog("Received access token:" + response.data.access_token); linkGoogleCalendar(1, response.data.access_token); @@ -73,12 +68,7 @@ export default function CalendarTracker() { const linkGoogleCalendar = async (userId: any, token: any) => { cLog("Linking Google Calendar for user and fetching events..."); try { - const hit = `${IPAddr}/link_calendar`; - cLog("Linking Google Calendar with hit:" + hit); - const response = await axios.post(hit, { - userId: userId, - accessToken: token, - }); + const response = await call(`/link_calendar`, 'POST', undefined, { userId, accessToken: token }); if (response.status === 200 && response.data.includes("successfully")) { cLog('Google Calendar linked successfully:' + response.data); Alert.alert('Google Calendar linked successfully!'); diff --git a/app/notes.tsx b/app/notes.tsx index 862e463..3e4632b 100644 --- a/app/notes.tsx +++ b/app/notes.tsx @@ -1,11 +1,10 @@ import React, { useCallback, useState } from 'react'; import { View, Text, TextInput, TouchableOpacity } from 'react-native'; -import { cLog } from './log'; -import { IPAddr } from '@/constants/constants'; +import { cLog } from '../components/log'; import { styles } from '@/assets/styles/styles'; -import axios from 'axios'; import { useFocusEffect } from '@react-navigation/native'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { call } from '../components/apiCall'; export default function Notes() { const initialData = { userId: 1, text: "" }; @@ -20,10 +19,8 @@ export default function Notes() { event_date: currentDate, event_time: currentTime, }; - const hit = IPAddr + '/add_note'; - const response = await axios.put(hit, updatedFormData); - - console.log('Note saved successfully: ' + response.data); + const response = await call('/add_note', 'PUT', undefined, updatedFormData); + cLog('Note saved successfully: ' + response.data); } catch (error) { console.error('Error saving note:', error); } @@ -34,16 +31,22 @@ export default function Notes() { }; const fetchNote = async () => { - const hit = IPAddr + '/get_note/' + (await AsyncStorage.getItem('userId')); - cLog('Fetching note from:' + hit); - axios.get(hit) - .then(response => { - const events = response.data.map((event: { text: any; }) => ({ - text: `${event.text}`, - })); - setFormData({ ...formData, text: events[0]?.text || "" }); - }) - .catch(error => console.error('Error fetching events:', error)); + try { + const userId = await AsyncStorage.getItem('userId'); + if (!userId) throw new Error('User ID not found'); + + const hit = '/get_note/' + userId; + cLog('Fetching note from: ' + hit); + + const response = await call(hit, 'GET'); + const events = response.data.map((event: { text: any; }) => ({ + text: `${event.text}`, + })); + + setFormData({ ...formData, text: events[0]?.text || "" }); + } catch (error) { + console.error('Error fetching note:', error); + } }; useFocusEffect( diff --git a/app/viewCalendarEvents.tsx b/app/viewCalendarEvents.tsx index 9ed7b63..1168c6f 100644 --- a/app/viewCalendarEvents.tsx +++ b/app/viewCalendarEvents.tsx @@ -1,13 +1,13 @@ import React from 'react'; import GenericAddViewEventForm from './genericAddViewEventPage'; -import { IPAddr, calendarFields } from '@/constants/constants'; +import { calendarFields } from '@/constants/constants'; export default function ViewCalendarEvents() { return ( diff --git a/app/viewFinanceEvents.tsx b/app/viewFinanceEvents.tsx index db77ae5..a7752e8 100644 --- a/app/viewFinanceEvents.tsx +++ b/app/viewFinanceEvents.tsx @@ -1,13 +1,13 @@ import React from 'react'; import GenericAddViewEventForm from './genericAddViewEventPage'; -import { IPAddr, financeFields } from '@/constants/constants'; +import { financeFields } from '@/constants/constants'; export default function ViewFinanceEvents() { return ( diff --git a/app/viewHealthEvents.tsx b/app/viewHealthEvents.tsx index 6588016..79185ad 100644 --- a/app/viewHealthEvents.tsx +++ b/app/viewHealthEvents.tsx @@ -1,13 +1,13 @@ import React from 'react'; import GenericAddViewEventForm from './genericAddViewEventPage'; -import { IPAddr, healthFields } from '@/constants/constants'; +import { healthFields } from '@/constants/constants'; export default function ViewHealthEvents() { return ( diff --git a/app/viewMealEvents.tsx b/app/viewMealEvents.tsx index 0ecaef1..e954a44 100644 --- a/app/viewMealEvents.tsx +++ b/app/viewMealEvents.tsx @@ -1,14 +1,14 @@ import React from 'react'; import GenericAddViewEventForm from './genericAddViewEventPage'; -import { IPAddr, mealFields } from '@/constants/constants'; +import { mealFields } from '@/constants/constants'; export default function ViewMealEvents() { return ( s_6ea(Kq_H^-{v(F4sj^TYx6Sjva*PB z@N@EV3NtWHN!Gj2z$)tTA~!WL$Iwj2baVgAf--J*UcO@tLcC{Kc%Mz@5@1wd;yp9n zK!8zix`O~C%l0?{#ynna@y--Z238hcPJT{dggGEH4BJ9LGLB%G$vbVnO#dm%sKjih zW42vJj!~Jf-rps#!au~Z*fTfGB-z>1%r_*t%CE}N*w-c0)Yrp6FR`F3JHpM|GQ`5M zywI?)xWFUCKPoh{)Wx}?AgbJ{(7-j(%`7`5ASuTw+}NTdwJN+Y-7&}9C(k!O%fzcB zEZZm8D<{yvr!36N$TuQCJ>8`u%cHzWgqfFtfq{cz`#v2;k7ky;4E%Sub8TR}%rB|X hEX>BB%gM?Tl95@g07NCJ#U%1Er$?Puf?005YzW+DIp delta 350 zcmZozz}~QceS#Dd)9;BgPC#;F!jgVwEzbVQ>=QyKCrt30Trh!U^STKKI23tVSwuPb zIb}J887Hs%VAH_Le{Moz^E|Y zK!8zix`O~C+x9pC#yno#3?l{xCL;z`7I~m)5TjV$rv7mB@Gx#OYzyH8$~bcJgKRn6 zxn}xzSw*yG_vtWtG_yQp;D5NC oYXjqDe#wl);#8StVKxR;PF9wXjLc#MASy{MF4_KVKO>g_0GKIl!T> => { + const fullUrl = `${IPAddr}${endpoint}`; + cLog('Full URL:', fullUrl); + + try { + const response = await axios({ + url: fullUrl, + method: method, + data: data, + headers: headers ? { 'Content-Type': headers } : {}, + }); + return response; + } catch (error) { + console.error('API call error:', error); + throw error; + } +}; diff --git a/app/log.tsx b/components/log.tsx similarity index 100% rename from app/log.tsx rename to components/log.tsx diff --git a/constants/constants.tsx b/constants/constants.tsx index ae25338..a006e47 100644 --- a/constants/constants.tsx +++ b/constants/constants.tsx @@ -1,12 +1,12 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; -import axios from "axios"; -import { cLog } from '@/app/log'; +import { cLog } from '@/components/log'; import { RootStackParamList } from "@/components/Types"; import { StackNavigationProp } from "@react-navigation/stack"; import { Field } from "@/components/Types"; +import { call } from '@/components/apiCall'; // export const IPAddr = "http://34.204.83.156:8080" // For AWS -export const IPAddr = "http://137.112.198.165:8080" // For local testing on lapto +export const IPAddr = "http://137.112.196.132:8080" // For local testing on lapto export const repeatingData = [ { label: 'Daily', value: 1 }, @@ -74,18 +74,16 @@ export const getPageFromEventType = (eventType: any) => { } export const verifyToken = async (navigation: StackNavigationProp) => { - const hit = IPAddr + '/checkLogin'; const storedUserName = await AsyncStorage.getItem('userName'); const storedToken = await AsyncStorage.getItem('token'); const storedUserId = await AsyncStorage.getItem('userId'); - const response = await axios.put(hit, { userName: storedUserName, token: storedToken, userId: storedUserId }); + const response = await call('/checkLogin', 'PUT', undefined, { userName: storedUserName, token: storedToken, userId: storedUserId }); if (!response.data) { cLog('Token verification failed'); await AsyncStorage.clear(); navigation.navigate('index'); return false; } - cLog('Verify response:', response.data); return true; }