# Project export: mendwell

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: Manage your health, one scan at a time.
- Devpost: https://devpost.com/software/mendwell
- GitHub: https://github.com/shirlsli/treehacks2024
- Demo: https://www.figma.com/file/pZ2YsUuyzX8RUujJalM3fM/TreeHacks-2024?type=design&node-id=2%3A6&mode=design&t=cVb0M5kASSwxPJ4N-1
- Team: 3 GitHub contributor(s) — Shirley Li (3 commits), Janani Pandurangan (2 commits), jananipands (1 commits)

## Devpost submission (written by the team)

### Inspiration

Vaishnavi came up with the idea of creating a food nutrition app that would scan ingredient lists on product labels and return a summary of whether or not the user can eat that product based on their diet restrictions. Shirley added onto this idea by proposing the medical element of the app: checking whether or not that product contains ingredients that may negatively interact with their medication. Shirley came up with that idea due to her experience with taking antibiotics once. She had forgotten to ask the pharmacist if she could drink coffee while taking the antibiotic. We also wanted to target senior citizens as a demographic for app, going off our experiences with our grandparents and their difficulty in remembering food-drug interactions for their medication. We created a user friendly and intuitive app, keeping the target market in mind.

### What it does

mendwell allows users to enter their medications upon account creation, which can later be modified in the user's dashboard. According to the user's medications, mendwell can indicate whether a food item is safe or unsafe to consume on the basis of food-drug interactions. For instance, if a user is prescribed atorvastatin for their elevated blood pressure, they would need to avoid certain food items, such as grapefruit, to ensure the efficacy of the medication and prevent side effects. If a user is unsure of whether a food item may conflict with their medication, all they would have to do is scan the food label or item with your camera, and mendwell will analyze whether the item is safe to eat or not. Once the analysis is done, mendwell will provide a comprehensive summary of the food-drug interactions by showing a list of the ingredients and medications that conflict. It will also provide more information about the medication upon the user’s request.

### How we built it

We built mendwell using React Native, Tesseract OCR, Node.js, and the native libraries for iOS. In addition to these technologies, we used Figma for creating detailed workflows in the planning process of our application.

### Challenges we ran into

We ran into so many challenges while building this application. One of our biggest challenges was figuring out React Native and the iOS build process. Since we are beginners to native applications and have a stronger base in web applications, configuring React Native to build the application on our phones was the hardest part. In addition, we learned that one of the APIs we planned to use for food-drug interaction is not a public API, even though it seemed like one. We did not have enough time to contact the API provider for the key, thus we needed to pivot quickly. Another challenge we faced was configuring the Tesseract OCR for our React Native application. Tesseract OCR does have wrapper code for JavaScript and after thorough research, we had seen that it worked for others using React Native. However, we severely underestimated how much our lack of React Native knowledge will interfere with the Tesseract OCR, and unfortunately, we were not able to set it up in time.

### Accomplishments we're proud of

Despite not having a fully working project, we hit many great milestones throughout the project. Not only were we able to complete all of the screens for our UI, but we were also able to get the built-in camera working for our application, which is a great accomplishment based on how much time we’ve spent to make it work. Overall, we are very proud of our idea and the effort we’ve put through the last 36 hours, and we believe that our application has full potential to scale!

### What we learned

Throughout this project, we faced a lot of challenges and as a result, we learned how to pivot quickly to avoid wasting time. For example, when we learned that the DrugBank API we were planning to use did not provide public API key, we pivoted quickly to generating mock data using ChatGPT in order to simulate various food-drug interactions for specific medications. Had we spent more time trying to figure out this issue, we would have not been able to finish building our UI screens and our Tesseract OCR connection. Another important thing that we learned is to always check whether the open-source applications we are using are up-to-date. We faced a lot of compatibility issues in the Expo client in our React Native app as well the tamagui React-Native framework. If we used containerization to deal with the discrepancies in our tools’ versions, the building process may have been a little easier for us.

### What's next

We plan to build and release our application for the Android and iOS App Store. Once that is done, we are hoping to build a startup focusing on this application and potentially partner with hospitals to not only gather the user’s medication information, but also to have them outsource their patients to mendwell. In addition, we would like to integrate mendwell with existing nutrition and allergy applications, such as fig, which will help us build a customer base that we can eventually launch to market with.

## README (from the GitHub repository)

# hackpack-react-native

### Overview

In this hackpack we will go over the basics of React Native and Expo to build a simple mobile application. React Native is a framework that allows you to build native mobile applications using JavaScript and React. Expo is a toolchain built around React Native that allows you to easily build, run, and deploy React Native applications. Expo also provides a number of APIs that allow you to access native device functionality such as the camera, accelerometer, and location.

### Setup

1. Install Node.js and npm
   - Node.js is a JavaScript runtime that allows you to run JavaScript outside of the browser. npm is a package manager for JavaScript that allows you to easily install and manage JavaScript libraries.
   - You can download Node.js and npm [here](https://nodejs.org/en/download/).
   - To check if you have Node.js and npm installed, run the following commands in your terminal:
     ```
     node -v
     npm -v
     ```
   - For this hackpack, we will be using Node.js version 16.19.1 and npm version 9.6.7.

<br/>

2. Install Expo CLI
   - Expo CLI is a command line tool that allows you to easily build, run, and deploy React Native applications.
   - To install Expo CLI, run the following command in your terminal:
     ```
     npm install -g expo-cli
     ```
   - To install Expo SDK, which is a collection of libraries that provide access to native device functionality, run the following command in your terminal (we'll be using version 48 for this hackpack)
     ```
       npm install expo@48 -g
     ```

Note: You may find that newer packages may have less support across the community libraries and may not be compatible with the latest version of Node.js. If you run into any issues, try using an older version.

### Creating a New Project

1. To create a new project, run the following command in your terminal:

   ```
   npx create-expo-app my-app
   ```

   This will create a new directory called my-project with all the files you need to get started.

2. To run the application, run the following command in your terminal:
   ```
   cd my-app
   npm start
   ```
   With Expo, you can directly run your application on your phone. To do so, download the Expo app on your phone. Once you have the Expo app, you can scan the QR code that appears in your terminal. Alternatively, you can press 'a' in your terminal to run the application in an Android emulator ([instructions](https://docs.expo.dev/workflow/android-studio-emulator/)) or 'i' to run the application in an iOS simulator ([instructions](https://docs.expo.dev/workflow/ios-simulator/)).

Notes: There will be several additional files in the my-project directory that tell Expo how to build and run your application. You can ignore these files for now.

### Hello World

1. Open the App.js file in your text editor of choice. You should see the following code:

```jsx
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style='auto' />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

2. Replace the Text component with the following:
   ```
   <Text>Hello World!</Text>
   ```
3. You should see the text "Hello World!" appear in the Expo app on your phone or emulator through live reloading.

![](/hackpack-assets/hello_world.png)

### Styling

It's a little bland right now. Let's add some styling to make it look a little nicer.

1. First, let's take a look at the following code:

```jsx
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

The styles object contains a number of properties that describe how a component should be styled. Each property contains a number of key-value pairs. The key is the name of the style property aka the class, and the value is the value of the style property. For example, the backgroundColor property sets the background color of the component. The value of the backgroundColor property is '#fff', which is a hex code that represents white. Notice how these properties are camelCased versions of CSS properties.

2. Let's change the background color of the container to blue. Change the backgroundColor property to '#0000ff'. You should see the background color of the container change to blue.

Notes: Flexbox is a layout system that allows you to easily position elements in a container. The flex property specifies how much space an element should take up relative to other elements in the container. The alignItems property specifies how to align elements along the cross axis. The justifyContent property specifies how to align elements along the main axis. Here is a [guide](https://reactnative.dev/docs/flexbox) that goes over the basics of flexbox.

### Components

1. Now let's create a component in a new `components/` folder named `button.component.jsx`. These are like lego blocks that you can use to build your application. Let's create a button component.

```jsx
import { TouchableOpacity, Text } from 'react-native';

const Button = () => {
  return (
    <TouchableOpacity onPress={() => console.log('Button Pressed!')}>
      <Text>Click Me!</Text>
    </TouchableOpacity>
  );
};

export default Button;
```

2. Export the Button component from App.js and import it into App.js. You should see the button appear in the Expo app on your phone or emulator.

```jsx
export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello world!</Text>
      <Button />
      <StatusBar style='auto' />
    </View>
  );
}
```

3. Although, the button works, we can't customize it as there are no properties that we can pass into the component. Let's some props, namely title, onPress, and style. This will allow us to dynamically change the title, onPress function, and style of the button.

```jsx
const Button = (props) => {
  return (
    <TouchableOpacity
      onPress={props.onPress}
      style={props.style}>
      <Text>{props.title}</Text>
    </TouchableOpacity>
  );
};
```

4. Now, we can customize the button in App.js.

```jsx
export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello world!</Text>
      <Button
        title='Click Me!'
        onPress={() => console.log('Button Pressed!')}
        style={styles.button}
      />
      <StatusBar style='auto' />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  button: {
    backgroundColor: '#ccc',
    padding: 10,
    borderRadius: 15,
    margin: 10,
  },
});
```

5. Now, let's make a counter that tracks the number of times the button is pressed. First, let's create a state variable, count, using the useState hook and display that in the text component. The useState hook takes in an initial value and returns a state variable and a function to update the state variable. We can use the state variable to keep track of the count and the function to update the count. Whenever, a state is updated, the component is re-rendered, meaning that the component is rendered again with the updated state.

```jsx
// Add this import
import { useState } from 'react';

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.container}>
      <Text>{count} clicks</Text>
      <Button
        title='Click Me!'
        onPress={() => {
          setCount(count + 1);
          console.log('Button Pressed!');
        }}
        style={styles.button}
      />
      <StatusBar style='auto' />
    </View>
  );
}
```

![](

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 18 recognized source files, 41 KB.
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (24 of 24)

```
.DS_Store
my-app/.gitignore
my-app/App.js
my-app/app.json
my-app/babel.config.js
my-app/components/box.component.jsx
my-app/components/button.component.jsx
my-app/components/list-item.component.jsx
my-app/components/logo.component.jsx
my-app/components/post.component.jsx
my-app/components/searchbar.component.jsx
my-app/database/food-drug-interaction.json
my-app/package.json
my-app/screens/camera.screen.jsx
my-app/screens/dashboard.screen.jsx
my-app/screens/details.screen.jsx
my-app/screens/home.screen.jsx
my-app/screens/intro.screen.jsx
my-app/screens/launch.screen.jsx
my-app/screens/signup.screen.jsx
my-app/screens/welcome.screen.jsx
my-app/tamagui.config.ts
my-app/tsconfig.json
README.md
```

### Dependencies

- my-app/package.json: @babel/core@^7.20.0, @expo-google-fonts/sora@^0.2.3, @expo/webpack-config@^19.0.0, @react-navigation/native@^6.1.7, @react-navigation/native-stack@^6.9.12, @tamagui/config@^1.89.30, @tamagui/core@^1.89.29, @tamagui/lucide-icons@^1.89.30, @types/react@~18.2.14, expo@^49.0.23, expo-camera@~13.4.4, expo-status-bar@~1.4.4, react@18.2.0, react-dom@18.2.0, react-native@0.71.8, react-native-chip@^3.1.0, react-native-paper@^5.12.3, react-native-svg@13.9.0, react-native-svg-transformer@^1.3.0, react-native-web@~0.19.6, tamagui@^1.89.29, typescript@^5.1.3

### Recent commits (newest first)

- Merge pull request #4 from shirlsli/shirley1
- Working summary
- Working summary
- My updated code
- Merge pull request #3 from shirlsli/shirley1
- Janani's camera changes
- Merge pull request #2 from shirlsli/shirley1
- Janani's camera changes
- Finished making JSON database and started implementing
- All my updates lol
- Most recent version rn
- Updated Intro + Launch Screens
- Added Signup and Welcome pages
- Merge branch 'main' of https://github.com/shirlsli/treehacks2024
- tamagui
- Merge pull request #1 from shirlsli/janani
- finished Launch Screen and Logo Component
- Integrated Tamagui
- Hopefully have all dependencies
- Update navigation.gif

## Key source files (fetched from GitHub, selected and truncated for size)

### my-app/package.json

```
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@expo-google-fonts/sora": "^0.2.3",
    "@expo/webpack-config": "^19.0.0",
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.12",
    "@tamagui/config": "^1.89.30",
    "@tamagui/core": "^1.89.29",
    "@tamagui/lucide-icons": "^1.89.30",
    "@types/react": "~18.2.14",
    "expo": "^49.0.23",
    "expo-camera": "~13.4.4",
    "expo-status-bar": "~1.4.4",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.71.8",
    "react-native-chip": "^3.1.0",
    "react-native-paper": "^5.12.3",
    "react-native-svg": "13.9.0",
    "react-native-web": "~0.19.6",
    "tamagui": "^1.89.29",
    "typescript": "^5.1.3"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "react-native-svg-transformer": "^1.3.0"
  },
  "private": true
}

```

### my-app/App.js

```javascript
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import SignupScreen from "./screens/signup.screen";
import DetailsScreen from "./screens/details.screen";
import '@tamagui/core/reset.css';
import { TamaguiProvider } from 'tamagui';
import tamaguiConfig from './tamagui.config';
import WelcomeScreen from "./screens/welcome.screen";
import HomeScreen from "./screens/home.screen";
import DashboardScreen from "./screens/dashboard.screen";
import CameraScreen from "./screens/camera.screen";


const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <TamaguiProvider config={tamaguiConfig}>
      <NavigationContainer>
        <Stack.Navigator
        screenOptions={{
          headerShown: false // Hide the navigation bar
        }}>
          {/* <Stack.Screen
            name="Camera"
            component={CameraScreen}
          /> */}
          <Stack.Screen
            name="Signup"
            component={SignupScreen}
          />
          <Stack.Screen
            name="Welcome"
            component={WelcomeScreen}
          />
          <Stack.Screen
            name="Home"
            component={HomeScreen}
          />
          <Stack.Screen
            name="DashboardScreen"
            component={DashboardScreen}
          />
          <Stack.Screen
            name="Camera"
            component={CameraScreen}
          />
        </Stack.Navigator>
      </NavigationContainer>
    </TamaguiProvider>
  );
}


```

### my-app/babel.config.js

```javascript
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
  };
};

```

### my-app/tamagui.config.ts

```typescript
import { config } from '@tamagui/config/v3'

import { createTamagui } from 'tamagui'
const tamaguiConfig = createTamagui(config)
// this makes typescript properly type everything based on the config

type Conf = typeof tamaguiConfig

declare module 'tamagui' {

  interface TamaguiCustomConfig extends Conf {}

}
export default tamaguiConfig
// depending on if you chose tamagui, @tamagui/core, or @tamagui/web
// be sure the import and declare module lines both use that same name
```

### my-app/components/list-item.component.jsx

```javascript
import { View, Text, StyleSheet } from 'react-native';

const ListItem = ({ title }) => {
  return (
    <View style={styles.container}>
      <Text>{title}</Text>
    </View>
  );
};

export default ListItem;

const styles = StyleSheet.create({
  // Styles
});
```

### my-app/components/button.component.jsx

```javascript
import { TouchableOpacity, Text } from 'react-native';

const Button = (props) => {
  return (
    <TouchableOpacity
      onPress={props.onPress}
      style={props.style}>
      <Text>{props.title}</Text>
    </TouchableOpacity>
  );
};

export default Button;

```

### my-app/components/post.component.jsx

```javascript
import { View, Text, StyleSheet } from 'react-native';

const Post = ({ title, body }) => {
  return (
    <View style={styles.container}>
      <Text>{title}</Text>
      <Text>{body}</Text>
    </View>
  );
};

export default Post;

const styles = StyleSheet.create({
  // Styles
});

```

### my-app/screens/details.screen.jsx

```javascript
import { View, Text, StyleSheet } from 'react-native';
import Button from '../components/button.component';

const DetailsScreen = ({ navigation }) => {
  return (
    <View style={styles.container}>
      <Text>Details Screen</Text>
      <Button
        title='Go back'
        onPress={() => navigation.goBack()}
        style={styles.button}
      />
    </View>
  );
};

export default DetailsScreen;

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    height: '100%',
  },
  button: {
    backgroundColor: '#ccc',
    padding: 10,
    borderRadius: 15,
    margin: 10,
  },
});
```

### my-app/screens/launch.screen.jsx

```javascript
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';
import Logo from '../components/logo.component';

import {
    useFonts,
    Sora_400Regular,
    Sora_500Medium,
    Sora_600SemiBold,
    Sora_700Bold,
} from '@expo-google-fonts/sora';

const LaunchScreen = ({ navigation }) => {
    let [fontsLoaded] = useFonts({
        Sora_400Regular,
        Sora_500Medium,
        Sora_600SemiBold,
        Sora_700Bold,
    });
  
  return (
    <View style={styles.container}>
        <Logo fontFamily={'Sora_500Medium'} fontSize={32} imageSize={30} color={true}/>
    </View>
  );
};

export default LaunchScreen;

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#FBF6F1',
    alignItems: 'center',
    justifyContent: 'center',
    height: '100%',
  },
});
```

### my-app/components/searchbar.component.jsx

```javascript
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Image } from 'react-native';
import { Button, Text, Input } from "tamagui";

import {
    useFonts,
    Sora_400Regular,
    Sora_500Medium,
    Sora_600SemiBold,
    Sora_700Bold,
} from '@expo-google-fonts/sora';

const SearchBar = ({user}) => {
  let [fontsLoaded] = useFonts({
    Sora_400Regular,
    Sora_500Medium,
    Sora_600SemiBold,
    Sora_700Bold,
  });

  const [input, setInput] = useState("");
  return (
    <View style={styles.container}>
        <Input
          size="$3"
          style={styles.inputBox}
          borderWidth={2}
          value={input}
          onChangeText={(text) => setInput(text)}
        />
    </View>
  );
}

export default SearchBar;

const styles = StyleSheet.create({
    inputBox: {
        width: "272px",
        height: "29px",
        backgroundColor: "#FBF6F1",
        boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)",
        borderRadius: "7px",
        marginBottom: 50,
      },
});
```

[8 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]