From 21419cb58a95a9cc768b48bff3922a4574025bbd Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Thu, 1 Feb 2024 15:55:56 -0500 Subject: [PATCH 1/5] feat: userContext stuff idk man --- client/App.tsx | 59 ++++-------------------- client/contexts/userContext.tsx | 42 +++++++++++++++++ client/navigation/AppStack.tsx | 26 +++++++++++ client/navigation/BottomTabNavigator.tsx | 23 +++++++++ client/navigation/Router.tsx | 14 ++++++ client/screens/Login.tsx | 12 ++--- client/screens/Medication.tsx | 8 ++++ client/types/user.ts | 4 ++ 8 files changed, 129 insertions(+), 59 deletions(-) create mode 100644 client/contexts/userContext.tsx create mode 100644 client/navigation/AppStack.tsx create mode 100644 client/navigation/BottomTabNavigator.tsx create mode 100644 client/navigation/Router.tsx create mode 100644 client/types/user.ts diff --git a/client/App.tsx b/client/App.tsx index 947b824..f965ef0 100644 --- a/client/App.tsx +++ b/client/App.tsx @@ -1,57 +1,14 @@ import * as React from 'react'; -import { Text } from 'react-native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { NavigationContainer, NavigationProp } from '@react-navigation/native'; -import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import LoginPage from './screens/Login'; -import MedList from './screens/Medication'; -import Home from './assets/home.svg'; -import DocPickerButton from './components/DocPickerButton'; +import { SafeAreaView } from 'react-native-safe-area-context'; +import Router from './navigation/Router'; +import UserContext from './contexts/userContext'; -export type ScreenNames = ['BottomNav', 'Landing', 'TEMP-FileUpload', 'Login']; -export type RootStackParamList = Record; -export type StackNavigation = NavigationProp; - -const Stack = createNativeStackNavigator(); -const Tab = createBottomTabNavigator(); - -// TODO: figure out a way to do this better, I didnt enjoy this way of doing it in SaluTemp there HAS to be a better way export default function App() { return ( - - - - - - - - ); -} - -function Tabs() { - return ( - - , - tabBarLabel: () => Landing - }} - component={MedList} - /> - + + + + + ); } diff --git a/client/contexts/userContext.tsx b/client/contexts/userContext.tsx new file mode 100644 index 0000000..37386a6 --- /dev/null +++ b/client/contexts/userContext.tsx @@ -0,0 +1,42 @@ +import React, { createContext, useContext, useEffect, useState } from 'react'; +import { getAuth, onAuthStateChanged } from 'firebase/auth'; +import { User } from '../types/user'; + +type UserContextData = { + user: User; +}; + +const UserContext = createContext({} as UserContextData); + +export default function UserProvider({ children }: { children: any }) { + const [user, setUser] = useState({} as User); + const auth = getAuth(); + + useEffect(() => { + onAuthStateChanged(auth, (user) => { + const signedInUser: User = { + userID: user?.uid ?? '', + userEmail: user?.email ?? '' + }; + setUser(signedInUser); + }); + }, []); + + const UserStore: UserContextData = { + user: user + }; + + return ( + {children} + ); +} + +export const useUser = (): UserContextData => { + const context = useContext(UserContext); + + if (!context) { + throw new Error('useUser must be used within a UserProvider'); + } + + return context; +}; diff --git a/client/navigation/AppStack.tsx b/client/navigation/AppStack.tsx new file mode 100644 index 0000000..482573f --- /dev/null +++ b/client/navigation/AppStack.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { NavigationProp } from '@react-navigation/native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import LoginPage from '../screens/Login'; +import BottomTabNavigator from './BottomTabNavigator'; +import { RootStackParamList } from './Router'; + +export type StackNavigation = NavigationProp; +const Stack = createNativeStackNavigator(); + +export default function AppStack() { + return ( + + + + + ); +} diff --git a/client/navigation/BottomTabNavigator.tsx b/client/navigation/BottomTabNavigator.tsx new file mode 100644 index 0000000..c0f7d57 --- /dev/null +++ b/client/navigation/BottomTabNavigator.tsx @@ -0,0 +1,23 @@ +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import React from 'react'; +import MedList from '../screens/Medication'; +import { Text } from 'react-native'; +import Home from '../assets/home.svg'; + +const Tab = createBottomTabNavigator(); + +export default function BottomTabNavigator() { + return ( + + , + tabBarLabel: () => Landing + }} + component={MedList} + /> + + ); +} diff --git a/client/navigation/Router.tsx b/client/navigation/Router.tsx new file mode 100644 index 0000000..8c2ce41 --- /dev/null +++ b/client/navigation/Router.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { NavigationContainer } from '@react-navigation/native'; +import AppStack from './AppStack'; + +export type ScreenNames = ['BottomNav', 'Landing', 'Login']; +export type RootStackParamList = Record; + +export default function Router() { + return ( + + + + ); +} diff --git a/client/screens/Login.tsx b/client/screens/Login.tsx index 622f17f..fb76ceb 100644 --- a/client/screens/Login.tsx +++ b/client/screens/Login.tsx @@ -1,19 +1,15 @@ import React, { useState } from 'react'; -import { View, TextInput, Button, Alert, StyleSheet } from 'react-native'; +import { View, TextInput, Button, Alert } from 'react-native'; import { logIn } from '../services/auth/login'; import { signUp } from '../services/auth/signup'; -import { - useNavigation, - StackActions, - useRoute -} from '@react-navigation/native'; +import { useNavigation } from '@react-navigation/native'; +import { StackNavigation } from '../navigation/AppStack'; const LoginPage: React.FC = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - const navigation = useNavigation(); - const route = useRoute(); + const navigation = useNavigation(); const handleLogin = async () => { if (!email || !password) { diff --git a/client/screens/Medication.tsx b/client/screens/Medication.tsx index d412928..a612866 100644 --- a/client/screens/Medication.tsx +++ b/client/screens/Medication.tsx @@ -2,9 +2,11 @@ import * as React from 'react'; import { View, Text } from 'react-native'; import { getAllMedications } from '../services/medication'; import { Medication } from '../types/medication'; +import { useUser } from '../contexts/userContext'; export default function MedList() { const [medications, setMedications] = React.useState(); + const { user } = useUser(); React.useEffect(() => { getAllMedications().then((med) => setMedications(med)); }, []); @@ -17,6 +19,12 @@ export default function MedList() { {`Name: ${med.medication_name} id: ${med.medication_id}`} ))} + {user && ( + + The user id is: {user.userID} + The user email is: {user.userEmail} + + )} ); } diff --git a/client/types/user.ts b/client/types/user.ts new file mode 100644 index 0000000..a6f6a18 --- /dev/null +++ b/client/types/user.ts @@ -0,0 +1,4 @@ +export interface User { + userID: string; + userEmail: string; +} From b566ef5a7305fcc8f31a6a353878591171e2e952 Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Thu, 1 Feb 2024 18:52:18 -0500 Subject: [PATCH 2/5] refactor: general all around fixes (removing unused imports, fixing navigation errors --- client/components/Card.tsx | 4 ++-- client/components/PopupModal.tsx | 1 + client/navigation/AppStack.tsx | 23 ++++++++++++----------- client/navigation/BottomTabNavigator.tsx | 10 +++++----- client/navigation/Router.tsx | 8 +++----- client/screens/Login.tsx | 4 ++-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/client/components/Card.tsx b/client/components/Card.tsx index 167ba6c..a3b8e9c 100644 --- a/client/components/Card.tsx +++ b/client/components/Card.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { StyleSheet, View, GestureResponderEvent, Text } from 'react-native'; +import { StyleSheet } from 'react-native'; import { Card } from 'react-native-paper'; -import { useNavigation } from '@react-navigation/native'; +import { Medication } from '../types/medication'; interface ClickableCardProps { med: Medication[]; diff --git a/client/components/PopupModal.tsx b/client/components/PopupModal.tsx index aab5978..1446023 100644 --- a/client/components/PopupModal.tsx +++ b/client/components/PopupModal.tsx @@ -6,6 +6,7 @@ import { Button, Provider as PaperProvider } from 'react-native-paper'; +import { Medication } from '../types/medication'; interface PopupModalProps { med: Medication[]; diff --git a/client/navigation/AppStack.tsx b/client/navigation/AppStack.tsx index 482573f..11d05b6 100644 --- a/client/navigation/AppStack.tsx +++ b/client/navigation/AppStack.tsx @@ -2,25 +2,26 @@ import React from 'react'; import { NavigationProp } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import LoginPage from '../screens/Login'; -import BottomTabNavigator from './BottomTabNavigator'; -import { RootStackParamList } from './Router'; +import AppStackBottomTabNavigator from './BottomTabNavigator'; -export type StackNavigation = NavigationProp; -const Stack = createNativeStackNavigator(); +export type AppScreenNames = ['BottomNavScreens', 'Landing', 'Login']; +type AppStackParamList = Record; +export type StackNavigation = NavigationProp; +const AppStack = createNativeStackNavigator(); -export default function AppStack() { +export default function AppNavigation() { return ( - - + - - + ); } diff --git a/client/navigation/BottomTabNavigator.tsx b/client/navigation/BottomTabNavigator.tsx index c0f7d57..3e7dd99 100644 --- a/client/navigation/BottomTabNavigator.tsx +++ b/client/navigation/BottomTabNavigator.tsx @@ -4,12 +4,12 @@ import MedList from '../screens/Medication'; import { Text } from 'react-native'; import Home from '../assets/home.svg'; -const Tab = createBottomTabNavigator(); +const AppStackBottomTab = createBottomTabNavigator(); -export default function BottomTabNavigator() { +export default function AppStackBottomTabNavigator() { return ( - - + - + ); } diff --git a/client/navigation/Router.tsx b/client/navigation/Router.tsx index 8c2ce41..0b1d5a0 100644 --- a/client/navigation/Router.tsx +++ b/client/navigation/Router.tsx @@ -1,14 +1,12 @@ import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; -import AppStack from './AppStack'; - -export type ScreenNames = ['BottomNav', 'Landing', 'Login']; -export type RootStackParamList = Record; +import AppNavigation from './AppStack'; export default function Router() { + // TODO: If we ever introduce onboarding questionairs and stuff, it can probably be another stack on this page () return ( - + ); } diff --git a/client/screens/Login.tsx b/client/screens/Login.tsx index fb76ceb..36c3753 100644 --- a/client/screens/Login.tsx +++ b/client/screens/Login.tsx @@ -22,7 +22,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Login Success', 'Welcome back!'); // console.log('result: ', result); - navigation.navigate('BottomNav'); + navigation.navigate('Landing'); } }; @@ -37,7 +37,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Signup Success', 'Welcome to the app!'); // console.log('result: ', result); - navigation.navigate('BottomNav'); + navigation.navigate('Landing'); } }; From cefb51ef2725f7736b29c886fef43d7c8ea56f70 Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Thu, 1 Feb 2024 19:50:00 -0500 Subject: [PATCH 3/5] refactor: all over the place with this commit, but added swagger docs for file upload --- backend/docs/docs.go | 43 ++++++++++++++++++- backend/docs/swagger.json | 43 ++++++++++++++++++- backend/docs/swagger.yaml | 27 ++++++++++++ backend/schema/files/routes.go | 7 ++- client/contexts/userContext.tsx | 3 ++ .../{AppStack.tsx => AppNavigation.tsx} | 3 +- client/navigation/Router.tsx | 3 +- client/screens/Login.tsx | 4 +- client/tailwind.config.js | 7 ++- 9 files changed, 130 insertions(+), 10 deletions(-) rename client/navigation/{AppStack.tsx => AppNavigation.tsx} (92%) diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 1c29687..d976f43 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -22,9 +22,24 @@ const docTemplate = `{ "file" ], "summary": "Upload a file", + "parameters": [ + { + "type": "file", + "description": "Body with file zip", + "name": "file_data", + "in": "formData", + "required": true + } + ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/models.File" + } + }, + "400": { + "description": "Bad Request" } } } @@ -51,6 +66,32 @@ const docTemplate = `{ } }, "definitions": { + "models.File": { + "type": "object", + "properties": { + "file_id": { + "type": "integer" + }, + "file_name": { + "type": "string" + }, + "file_size": { + "type": "integer" + }, + "group_id": { + "type": "integer" + }, + "task_id": { + "type": "integer" + }, + "upload_by": { + "type": "integer" + }, + "upload_date": { + "type": "string" + } + } + }, "models.Medication": { "type": "object", "properties": { diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 1ac678d..c924157 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -15,9 +15,24 @@ "file" ], "summary": "Upload a file", + "parameters": [ + { + "type": "file", + "description": "Body with file zip", + "name": "file_data", + "in": "formData", + "required": true + } + ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/models.File" + } + }, + "400": { + "description": "Bad Request" } } } @@ -44,6 +59,32 @@ } }, "definitions": { + "models.File": { + "type": "object", + "properties": { + "file_id": { + "type": "integer" + }, + "file_name": { + "type": "string" + }, + "file_size": { + "type": "integer" + }, + "group_id": { + "type": "integer" + }, + "task_id": { + "type": "integer" + }, + "upload_by": { + "type": "integer" + }, + "upload_date": { + "type": "string" + } + } + }, "models.Medication": { "type": "object", "properties": { diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 0f4976b..25aaeba 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,5 +1,22 @@ basePath: / definitions: + models.File: + properties: + file_id: + type: integer + file_name: + type: string + file_size: + type: integer + group_id: + type: integer + task_id: + type: integer + upload_by: + type: integer + upload_date: + type: string + type: object models.Medication: properties: medication_id: @@ -16,9 +33,19 @@ paths: /files/upload: post: description: Upload a file to database and S3 bucket + parameters: + - description: Body with file zip + in: formData + name: file_data + required: true + type: file responses: "200": description: OK + schema: + $ref: '#/definitions/models.File' + "400": + description: Bad Request summary: Upload a file tags: - file diff --git a/backend/schema/files/routes.go b/backend/schema/files/routes.go index bfae7aa..f32a874 100644 --- a/backend/schema/files/routes.go +++ b/backend/schema/files/routes.go @@ -28,10 +28,13 @@ func GetFileGroup(v1 *gin.RouterGroup, c *PgModel) *gin.RouterGroup { // @summary Upload a file // @description Upload a file to database and S3 bucket // @tags file -// @success 200 +// @param file_data formData file true "Body with file zip" +// +// @success 200 {object} models.File +// @failure 400 // @router /files/upload [post] func (pg *PgModel) UploadFileRoute(c *gin.Context) { - // TODO: Ensure Swagger Knows about there bad request returns!!! + // TODO: Ensure Swagger Knows about the bad request returns!!! var file models.File if err := c.Bind(&file); err != nil { diff --git a/client/contexts/userContext.tsx b/client/contexts/userContext.tsx index 37386a6..9cac113 100644 --- a/client/contexts/userContext.tsx +++ b/client/contexts/userContext.tsx @@ -8,6 +8,9 @@ type UserContextData = { const UserContext = createContext({} as UserContextData); +// TODO: Add Group ID, and User Role to this. +// TODO: Should maybe be a group prop and not inside user. +// TODO: make name more generic export default function UserProvider({ children }: { children: any }) { const [user, setUser] = useState({} as User); const auth = getAuth(); diff --git a/client/navigation/AppStack.tsx b/client/navigation/AppNavigation.tsx similarity index 92% rename from client/navigation/AppStack.tsx rename to client/navigation/AppNavigation.tsx index 11d05b6..7ca830b 100644 --- a/client/navigation/AppStack.tsx +++ b/client/navigation/AppNavigation.tsx @@ -6,7 +6,8 @@ import AppStackBottomTabNavigator from './BottomTabNavigator'; export type AppScreenNames = ['BottomNavScreens', 'Landing', 'Login']; type AppStackParamList = Record; -export type StackNavigation = NavigationProp; + +export type AppStackNavigation = NavigationProp; const AppStack = createNativeStackNavigator(); export default function AppNavigation() { diff --git a/client/navigation/Router.tsx b/client/navigation/Router.tsx index 0b1d5a0..a1c1257 100644 --- a/client/navigation/Router.tsx +++ b/client/navigation/Router.tsx @@ -1,9 +1,8 @@ import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; -import AppNavigation from './AppStack'; +import AppNavigation from './AppNavigation'; export default function Router() { - // TODO: If we ever introduce onboarding questionairs and stuff, it can probably be another stack on this page () return ( diff --git a/client/screens/Login.tsx b/client/screens/Login.tsx index 36c3753..4e4a9b1 100644 --- a/client/screens/Login.tsx +++ b/client/screens/Login.tsx @@ -3,13 +3,13 @@ import { View, TextInput, Button, Alert } from 'react-native'; import { logIn } from '../services/auth/login'; import { signUp } from '../services/auth/signup'; import { useNavigation } from '@react-navigation/native'; -import { StackNavigation } from '../navigation/AppStack'; +import { AppStackNavigation } from '../navigation/AppNavigation'; const LoginPage: React.FC = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - const navigation = useNavigation(); + const navigation = useNavigation(); const handleLogin = async () => { if (!email || !password) { diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 0e7790f..2a6c6f1 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -1,6 +1,11 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ['./App.{js,jsx,ts,tsx}', './screens/**/*.{js,jsx,ts,tsx}'], + content: [ + './App.{js,jsx,ts,tsx}', + './screens/**/*.{js,jsx,ts,tsx}', + './components/**/*.{js,jsx,ts,tsx}', + './navigation/**/*.{js,jsx,ts,tsx}' + ], theme: { extend: {} }, From 640851d7700f5e0724b64d4853377b8c6ff3ffb5 Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Sat, 3 Feb 2024 15:27:09 -0500 Subject: [PATCH 4/5] refactor: make context more general --- client/App.tsx | 6 +-- client/contexts/CareWalletContext.tsx | 53 +++++++++++++++++++++++++++ client/contexts/types.ts | 9 +++++ client/contexts/userContext.tsx | 45 ----------------------- client/screens/Login.tsx | 4 +- client/screens/Medication.tsx | 12 +++--- client/types/user.ts | 4 -- 7 files changed, 74 insertions(+), 59 deletions(-) create mode 100644 client/contexts/CareWalletContext.tsx create mode 100644 client/contexts/types.ts delete mode 100644 client/contexts/userContext.tsx delete mode 100644 client/types/user.ts diff --git a/client/App.tsx b/client/App.tsx index f965ef0..c9231a3 100644 --- a/client/App.tsx +++ b/client/App.tsx @@ -1,14 +1,14 @@ import * as React from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import Router from './navigation/Router'; -import UserContext from './contexts/userContext'; +import CareWalletProvider from './contexts/CareWalletContext'; export default function App() { return ( - + - + ); } diff --git a/client/contexts/CareWalletContext.tsx b/client/contexts/CareWalletContext.tsx new file mode 100644 index 0000000..55347ca --- /dev/null +++ b/client/contexts/CareWalletContext.tsx @@ -0,0 +1,53 @@ +import React, { createContext, useContext, useEffect, useState } from 'react'; +import { getAuth, onAuthStateChanged } from 'firebase/auth'; +import { Group, User } from './types'; + +type CareWalletContextData = { + user: User; + group: Group; +}; + +const CareWalletContext = createContext({} as CareWalletContextData); + +export default function CareWalletProvider({ children }: { children: any }) { + const [user, setUser] = useState({} as User); + const [group, setGroup] = useState({} as Group); + const auth = getAuth(); + + useEffect(() => { + onAuthStateChanged(auth, (user) => { + const signedInUser: User = { + userID: user?.uid ?? '', + userEmail: user?.email ?? '' + }; + setUser(signedInUser); + }); + setGroup({ + groupID: 'TEMP - REPLACE WITH ACTUAL', + role: 'TEMP - REPLACE WITH ACTUAL' + }); + }, []); + + const CareWalletContextStore: CareWalletContextData = { + user: user, + group: group + }; + + return ( + + {children} + + ); +} + +export const useCareWalletContext = (): CareWalletContextData => { + const context = useContext(CareWalletContext); + + if (!context) { + throw new Error( + 'useCareWalletContext must be used within a CareWalletContextProvider' + ); + } + + return context; +}; diff --git a/client/contexts/types.ts b/client/contexts/types.ts new file mode 100644 index 0000000..82969df --- /dev/null +++ b/client/contexts/types.ts @@ -0,0 +1,9 @@ +export interface User { + userID: string; + userEmail: string; +} + +export interface Group { + groupID: string; + role: string; // TODO: update to enum +} diff --git a/client/contexts/userContext.tsx b/client/contexts/userContext.tsx deleted file mode 100644 index 9cac113..0000000 --- a/client/contexts/userContext.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { createContext, useContext, useEffect, useState } from 'react'; -import { getAuth, onAuthStateChanged } from 'firebase/auth'; -import { User } from '../types/user'; - -type UserContextData = { - user: User; -}; - -const UserContext = createContext({} as UserContextData); - -// TODO: Add Group ID, and User Role to this. -// TODO: Should maybe be a group prop and not inside user. -// TODO: make name more generic -export default function UserProvider({ children }: { children: any }) { - const [user, setUser] = useState({} as User); - const auth = getAuth(); - - useEffect(() => { - onAuthStateChanged(auth, (user) => { - const signedInUser: User = { - userID: user?.uid ?? '', - userEmail: user?.email ?? '' - }; - setUser(signedInUser); - }); - }, []); - - const UserStore: UserContextData = { - user: user - }; - - return ( - {children} - ); -} - -export const useUser = (): UserContextData => { - const context = useContext(UserContext); - - if (!context) { - throw new Error('useUser must be used within a UserProvider'); - } - - return context; -}; diff --git a/client/screens/Login.tsx b/client/screens/Login.tsx index 4e4a9b1..ffa1c8f 100644 --- a/client/screens/Login.tsx +++ b/client/screens/Login.tsx @@ -22,7 +22,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Login Success', 'Welcome back!'); // console.log('result: ', result); - navigation.navigate('Landing'); + navigation.navigate('BottomNavScreens'); } }; @@ -37,7 +37,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Signup Success', 'Welcome to the app!'); // console.log('result: ', result); - navigation.navigate('Landing'); + navigation.navigate('BottomNavScreens'); } }; diff --git a/client/screens/Medication.tsx b/client/screens/Medication.tsx index a612866..b08717b 100644 --- a/client/screens/Medication.tsx +++ b/client/screens/Medication.tsx @@ -2,11 +2,11 @@ import * as React from 'react'; import { View, Text } from 'react-native'; import { getAllMedications } from '../services/medication'; import { Medication } from '../types/medication'; -import { useUser } from '../contexts/userContext'; +import { useCareWalletContext } from '../contexts/CareWalletContext'; export default function MedList() { const [medications, setMedications] = React.useState(); - const { user } = useUser(); + const { user, group } = useCareWalletContext(); React.useEffect(() => { getAllMedications().then((med) => setMedications(med)); }, []); @@ -19,11 +19,13 @@ export default function MedList() { {`Name: ${med.medication_name} id: ${med.medication_id}`} ))} - {user && ( - + {user && group && ( + The user id is: {user.userID} The user email is: {user.userEmail} - + The group id is: {group.groupID} + The group role is: {group.role} + )} ); diff --git a/client/types/user.ts b/client/types/user.ts deleted file mode 100644 index a6f6a18..0000000 --- a/client/types/user.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface User { - userID: string; - userEmail: string; -} From f3ee13c1b055ceb7b1deb3f4c9449eda63c6d586 Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Sun, 4 Feb 2024 16:34:44 -0500 Subject: [PATCH 5/5] refactor: utilize card and popup in the medlist fe Found solution to RNP components not utilizing tailwind styling, some changes to the components to make them more generic to allow it to be used in multiple places with different content --- client/App.tsx | 5 +- client/babel.config.js | 2 +- client/components/Card.tsx | 63 ++++------------ client/components/PopupModal.tsx | 73 +++++++------------ client/navigation/AppNavigation.tsx | 6 +- ...tor.tsx => AppStackBottomTabNavigator.tsx} | 0 client/screens/Login.tsx | 4 +- client/screens/Medication.tsx | 33 +++++++-- 8 files changed, 75 insertions(+), 111 deletions(-) rename client/navigation/{BottomTabNavigator.tsx => AppStackBottomTabNavigator.tsx} (100%) diff --git a/client/App.tsx b/client/App.tsx index c9231a3..23205c7 100644 --- a/client/App.tsx +++ b/client/App.tsx @@ -2,12 +2,15 @@ import * as React from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import Router from './navigation/Router'; import CareWalletProvider from './contexts/CareWalletContext'; +import { PaperProvider } from 'react-native-paper'; export default function App() { return ( - + + + ); diff --git a/client/babel.config.js b/client/babel.config.js index e3a823c..6fa972e 100644 --- a/client/babel.config.js +++ b/client/babel.config.js @@ -2,6 +2,6 @@ module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], - plugins: ['nativewind/babel'] + plugins: ['react-native-paper/babel', 'nativewind/babel'] }; }; diff --git a/client/components/Card.tsx b/client/components/Card.tsx index a3b8e9c..527f00d 100644 --- a/client/components/Card.tsx +++ b/client/components/Card.tsx @@ -1,62 +1,27 @@ +import { styled } from 'nativewind'; import React from 'react'; -import { StyleSheet } from 'react-native'; import { Card } from 'react-native-paper'; -import { Medication } from '../types/medication'; interface ClickableCardProps { - med: Medication[]; + title: string; onPress: () => void; - children: JSX.Element[] | JSX.Element; - cardStyle?: object; - navigateTo?: string; + children?: JSX.Element[] | JSX.Element; } -const ClickableCard: React.FC = ({ - med, +const StyledModal = styled(Card.Title, { + props: { + titleStyle: true + } +}); + +export const ClickableCard: React.FC = ({ + title, onPress, - children, - cardStyle, - navigateTo + children }) => { - // const navigation = useNavigation(); - - const handlePress = () => { - if (navigateTo) { - console.log('trying to navigate!'); - // navigation.navigate(navigateTo as never); - } else { - onPress(); - } - }; - - const styles = StyleSheet.create({ - card: { - margin: 10, - width: 200, - borderRadius: 8, - borderWidth: 1, - borderColor: 'gray', - backgroundColor: 'lightblue', - shadowColor: '#000', - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.3, - shadowRadius: 3, - elevation: 5 - }, - title: { - fontSize: 18, - marginBottom: 8, - fontWeight: 'bold' - }, - content: { - fontSize: 16, - color: 'gray' - } - }); - return ( - - + + {children} ); diff --git a/client/components/PopupModal.tsx b/client/components/PopupModal.tsx index 1446023..97f96df 100644 --- a/client/components/PopupModal.tsx +++ b/client/components/PopupModal.tsx @@ -1,57 +1,34 @@ +import { styled } from 'nativewind'; import React from 'react'; -import { - Modal, - Portal, - Text, - Button, - Provider as PaperProvider -} from 'react-native-paper'; -import { Medication } from '../types/medication'; +import { Modal, Portal } from 'react-native-paper'; interface PopupModalProps { - med: Medication[]; - onPress: () => void; - buttonStyle?: object; - modalStyle?: object; - modalContent?: React.ReactNode; + isVisible: boolean; + setVisible: (val: boolean) => void; + children?: JSX.Element[] | JSX.Element; } -const PopupModal: React.FC = ({ - med, - onPress, - buttonStyle, - modalStyle, - modalContent -}) => { - const [visible, setVisible] = React.useState(false); - - const showModal = () => setVisible(true); - const hideModal = () => setVisible(false); - const containerStyle = { - backgroundColor: 'white', - padding: 20, - ...modalStyle - }; +// rnp requires contentcontainerstyle to style the component, this will integrate native-wind into that +const StyledModal = styled(Modal, { + props: { + contentContainerStyle: true + } +}); +export default function PopupModal({ + children, + isVisible, + setVisible +}: PopupModalProps) { return ( - - - - {modalContent || Default Modal Content} - - - - + {children} + + ); -}; - -export default PopupModal; +} diff --git a/client/navigation/AppNavigation.tsx b/client/navigation/AppNavigation.tsx index 7ca830b..fe7531f 100644 --- a/client/navigation/AppNavigation.tsx +++ b/client/navigation/AppNavigation.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { NavigationProp } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import LoginPage from '../screens/Login'; -import AppStackBottomTabNavigator from './BottomTabNavigator'; +import AppStackBottomTabNavigator from './AppStackBottomTabNavigator'; -export type AppScreenNames = ['BottomNavScreens', 'Landing', 'Login']; +export type AppScreenNames = ['MainNavScreens', 'Landing', 'Login']; type AppStackParamList = Record; export type AppStackNavigation = NavigationProp; @@ -19,7 +19,7 @@ export default function AppNavigation() { component={LoginPage} /> diff --git a/client/navigation/BottomTabNavigator.tsx b/client/navigation/AppStackBottomTabNavigator.tsx similarity index 100% rename from client/navigation/BottomTabNavigator.tsx rename to client/navigation/AppStackBottomTabNavigator.tsx diff --git a/client/screens/Login.tsx b/client/screens/Login.tsx index ffa1c8f..71d8cf5 100644 --- a/client/screens/Login.tsx +++ b/client/screens/Login.tsx @@ -22,7 +22,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Login Success', 'Welcome back!'); // console.log('result: ', result); - navigation.navigate('BottomNavScreens'); + navigation.navigate('MainNavScreens'); } }; @@ -37,7 +37,7 @@ const LoginPage: React.FC = () => { } else { Alert.alert('Signup Success', 'Welcome to the app!'); // console.log('result: ', result); - navigation.navigate('BottomNavScreens'); + navigation.navigate('MainNavScreens'); } }; diff --git a/client/screens/Medication.tsx b/client/screens/Medication.tsx index b08717b..0ddfbc0 100644 --- a/client/screens/Medication.tsx +++ b/client/screens/Medication.tsx @@ -1,24 +1,43 @@ import * as React from 'react'; -import { View, Text } from 'react-native'; +import { View, Text, ScrollView } from 'react-native'; import { getAllMedications } from '../services/medication'; import { Medication } from '../types/medication'; import { useCareWalletContext } from '../contexts/CareWalletContext'; +import ClickableCard from '../components/Card'; +import PopupModal from '../components/PopupModal'; export default function MedList() { const [medications, setMedications] = React.useState(); + const [selectedMed, setSelectedMed] = React.useState(); const { user, group } = useCareWalletContext(); + const [visible, setVisible] = React.useState(false); React.useEffect(() => { getAllMedications().then((med) => setMedications(med)); }, []); return ( - {medications && - medications.map((med, index) => ( - - {`Name: ${med.medication_name} id: ${med.medication_id}`} - - ))} + + + {selectedMed?.medication_name} + + ID: {selectedMed?.medication_id} + + + {medications && + medications.map((med, index) => ( + { + setSelectedMed(med); + setVisible(true); + }} + > + ID: {med.medication_id} + + ))} + {user && group && ( The user id is: {user.userID}