# Project export: Mental Map

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: Cal Hacks 10.0
- Tagline: Mental Map: Your essential mental health diary. Connect with our chatbot, journal your emotions, and discover the path to a happier version of yourself with greater emotional self-understanding.
- Devpost: https://devpost.com/software/mentalmaps
- GitHub: https://github.com/apai25/mental-map
- Video: https://www.youtube.com/embed/hN_nLD8chOc?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — Kushal Kodnad (17 commits), RaghavPu (14 commits), Rushil Desai (6 commits)

## Devpost submission (written by the team)

### Inspiration

Being a student at university today is no easy task; as our contemporary world advances, it becomes increasingly competitive in many domains, especially those revolving around technology. Many times, it is easy to lose ourselves in such a competitive and academically-minded world—Mental Map strives to solve that. By enabling its users to track their mental health in methodical ways and interact with a sympathetic chatbot, Mental Maps reminds us that there’s more to life than academics and stress; it’s okay to have a little bit of fun at times, too. Recognizing the prevalence of mental health challenges and the reluctance many face in seeking help, Mental Map was created as a tech-savvy solution to promote self-reflection, emotional awareness, and a sense of companionship, contributing to a more mentally healthy society. By providing a digital friend that encourages users to engage with their emotions and life events, Mental Map aims to reduce the stigma surrounding mental health and offer a user-friendly platform for individuals to enhance their emotional well-being.

### What it does

Mental Map is all about helping users navigate their emotional journeys in a modern and user-friendly way. This app serves as a digital diary with an AI chatbot that checks in on your feelings and experiences. The AI chatbot periodically initiates spontaneous conversations with users throughout the day, encouraging them to discuss their current emotional state and ongoing life events if they haven't engaged with it recently. Each interaction is subject to sentiment analysis, enabling the app to extract the user's prevailing mood over the course of a week. At the end of each week, the application compiles a comprehensive report and generalized summary, offering users a detailed overview of their week, with a particular focus on the dominant emotions experienced during that time. It analyzes your emotions, generates weekly summaries, and helps you gain a better understanding of your mental well-being—all in an effort to foster self-awareness and promote better mental health.

### How we built it

The app's codebase can be divided into two main components: the frontend and the server. Server The server utilizes a variety of tech stacks and APIs from CalHacks's sponsors to deliver an efficient set of HTTP endpoints that can respond to the frontend application in real-time. We use Hume API for text-based sentiment analysis, enabling Mental Map to gauge the user's emotional responses to the chat interface each day. We use the sentiments from each diary entry to carefully and precisely create a weekly summary at the end of the week that both encourages the user to dwell on their highlights, and provides a more positive outlook on the lower points of their week. To enhance the user experience, we leveraged the BERT Hugging Face model to convert user responses into high-dimensional vector embeddings, facilitating similarity checks between responses, which were efficiently stored using the Milvus vector database. The vector database enabled us to store information of high-dimensionality without great overhead during retrieval and entry creation. For a more general data management system, we chose to utilize CockroachDB's robust serverless data cluster platform. We stored our sentiment classifications, user diary entries, and other pieces of relevant information in two different tables on CockroachDB. Frontend For the frontend, we utilized React Native's powerful UI interface to build an iOS application that is both aesthetic and efficient in terms of runtime. We seamlessly linked our frontend to our Flask REST server using "axios", a popular React library for sending HTTP requests. We controlled the navigation of our application with database navigation routers, which securely store user sessions.

### Challenges we ran into

During the app development process, we encountered several hurdles. Initially, our intention was to have the chatbot pose spontaneous questions to the user at various intervals during the day. Yet, we found this approach somewhat trivial from our core objective of fostering user-initiated self-expression on their own merit. Furthermore, the logistical feasibility of implementing random question prompts throughout the day within our time constraints appeared quite impossible. We also ran into a good amount of troubles getting CockroachDB set up. None of us had experience with such a serverless database before, and we were proud of how we were able to overcome this learning curve by carefully reading CockroachDB's comprehensive API.

### Accomplishments we're proud of

We are very proud of the app we managed to put together in somewhat of a rather tight timeframe. We got the entire frontend up and running with the magic of React Native and hooked it up to our backend routes, which connect to CockroachDB. What we are really proud of is how well our sentiment analysis feature works--it can accurately pinpoint the emotion tied to any input text, making our app functional and enabling us to delve into data analysis from various angles, all neatly integrated into the app.

### What we learned

Throughout this project, we have learned a lot about the tools that we leveraged. For starters, we learned how to use the CockroachDB SQL database management system. Additionally, we learned how to use the Hume API to generate sentiment analysis scores for each of 53 emotions for every input text, which we condensed into the 10 most popular sentiments. Lastly, we learned how to seamlessly connect the React Native frontend to the backend database components. We enjoyed interacting with the APIs of several of CalHacks's sponsors this year. We were excited to learn something new, and were glad with the way were able to integrate a lot of the functionality with the goals and constraints of our application.

### What's next

for Mentalmaps One of the next steps for Mental Map is to further incorporate our Milvus vector embeddings within the pipeline of our application, enabling us to make full use of the high-dimensionality capabilities that the database comes with. We would like to expand our application such that it allows users to connect with one another; once "friends," users will be able to see similar diary entries from their friends, enabling connection and fostering closer relationships to bolster mental health. Another potential next step is to utilize the vector embeddings and sentiment data to recommend relevant resources, articles, or activities to users based on their emotional state and experiences. Additionally, we could provide users with personalized insights and tips based on their emotional responses and activities. This could include self-care suggestions, stress-relief techniques, or mindfulness exercises.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 24 recognized source files, 91 KB.
- Flask (technology) — detected in the code
- Hugging Face (technology) — detected in the code
- JavaScript (language) — detected in the code
- OpenAI (technology) — detected in the code
- PostgreSQL (technology) — detected in the code
- Python (language) — detected in the code
- PyTorch (technology) — detected in the code
- React (technology) — detected in the code

## Codebase structure (from repository index)

### Files (30 of 30)

```
.gitignore
backend/app.py
backend/requirements.txt
backend/utils/chatbot.py
backend/utils/date_manipulation.py
backend/utils/embedding.py
backend/utils/milvus.py
backend/utils/populate_db_script.py
backend/utils/sentiment_classification.py
examples.py
frontend/.gitignore
frontend/.watchmanconfig
frontend/App.js
frontend/app.json
frontend/babel.config.js
frontend/hooks/usePrevious.js
frontend/index.js
frontend/MainScreen.js
frontend/package.json
frontend/screens/chat/ChatScreen.js
frontend/screens/journal/CalendarView.js
frontend/screens/journal/DayView.js
frontend/screens/journal/Emotion.js
frontend/screens/journal/EntryView.js
frontend/screens/journal/IosFonts.js
frontend/screens/journal/JournalScreen.js
frontend/screens/journal/MoodView.js
frontend/screens/login/CreateAccountScreen.js
frontend/screens/login/LoginScreen.js
frontend/screens/login/LoginStackScreen.js
```

### Dependencies

- backend/requirements.txt: aiohttp@==3.8.6, aiosignal@==1.3.1, asgiref@==3.7.2, async-timeout@==4.0.3, asyncio@==3.4.3, attrs@==23.1.0, blinker@==1.6.3, certifi@==2023.7.22, charset-normalizer@==3.3.1, click@==8.1.7, filelock@==3.13.0, Flask@==3.0.0, Flask-Cors@==4.0.0, frozenlist@==1.4.0, fsspec@==2023.10.0, http-client@==0.1.22, huggingface-hub@==0.17.3, hume@==0.4.1, idna@==3.4, itsdangerous@==2.1.2, Jinja2@==3.1.2, MarkupSafe@==2.1.3, mpmath@==1.3.0, multidict@==6.0.4, networkx@==3.2.1, numpy@==1.26.1, openai@==0.28.1, packaging@==23.2, psycopg@==3.1.12, psycopg-binary@==3.1.12, pycurl@==7.45.2, PyYAML@==6.0.1, regex@==2023.10.3, requests@==2.31.0, safetensors@==0.4.0, six@==1.16.0, sympy@==1.12, tokenizers@==0.14.1, torch@==2.1.0, tqdm@==4.66.1, transformers@==4.34.1, typing_extensions@==4.8.0, urllib3@==2.0.7, websockets@==10.4, Werkzeug@==3.0.1, yarl@==1.9.2
- frontend/package.json: @babel/core@^7.20.0, @flyerhq/react-native-chat-ui@^1.4.3, @flyerhq/react-native-keyboard-accessory-view@^2.4.0, @flyerhq/react-native-link-preview@^1.6.0, @react-navigation/bottom-tabs@^6.5.11, @react-navigation/material-bottom-tabs@^6.2.19, @react-navigation/material-top-tabs@^6.6.5, @react-navigation/native@^6.1.9, @react-navigation/native-stack@^6.9.16, @reduxjs/toolkit@^1.9.7, axios@^1.6.0, expo@~49.0.15, expo-status-bar@~1.6.0, react@18.2.0, react-native@0.72.6, react-native-calendars@^1.1301.0, react-native-circular-progress@^1.3.9, react-native-paper@^5.11.1, react-native-safe-area-context@4.6.3, react-native-screens@~3.22.0, react-native-svg@^13.14.0, react-native-uuid@^2.0.1, react-navigation@^5.0.0, react-redux@^8.1.3, redux@^4.2.1

### Recent commits (newest first)

- Final Version 1
- optimized embeddings.py
- updated requirements.txt
- Merge branch 'main' of github.com:apai25/mental-map
- milvus implemented
- updated get_daily_summary prompt
- restructuring
- Merge branch 'main' of https://github.com/apai25/mental-map
- test db population script
- examples for app summaries
- Update Zilliz Integration
- Finish Zilliz Milvus API Integration
- Finish Zilliz Milvus API Integration
- Calendar Done
- removed unused prints
- v3 backend
- v3
- Frontend v2
- working endpoints, all modified
- scaled and sorted get_sentiments dictionary

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

### backend/requirements.txt

```
aiohttp==3.8.6
aiosignal==1.3.1
asgiref==3.7.2
async-timeout==4.0.3
asyncio==3.4.3
attrs==23.1.0
blinker==1.6.3
certifi==2023.7.22
charset-normalizer==3.3.1
click==8.1.7
filelock==3.13.0
Flask==3.0.0
Flask-Cors==4.0.0
frozenlist==1.4.0
fsspec==2023.10.0
http-client==0.1.22
huggingface-hub==0.17.3
hume==0.4.1
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
mpmath==1.3.0
multidict==6.0.4
networkx==3.2.1
numpy==1.26.1
openai==0.28.1
packaging==23.2
psycopg==3.1.12
psycopg-binary==3.1.12
pycurl==7.45.2
PyYAML==6.0.1
regex==2023.10.3
requests==2.31.0
safetensors==0.4.0
six==1.16.0
sympy==1.12
tokenizers==0.14.1
torch==2.1.0
tqdm==4.66.1
transformers==4.34.1
typing_extensions==4.8.0
urllib3==2.0.7
websockets==10.4
Werkzeug==3.0.1
yarl==1.9.2

```

### frontend/package.json

```
{
  "name": "frontend",
  "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": {
    "@flyerhq/react-native-chat-ui": "^1.4.3",
    "@flyerhq/react-native-keyboard-accessory-view": "^2.4.0",
    "@flyerhq/react-native-link-preview": "^1.6.0",
    "@react-navigation/bottom-tabs": "^6.5.11",
    "@react-navigation/material-bottom-tabs": "^6.2.19",
    "@react-navigation/material-top-tabs": "^6.6.5",
    "@react-navigation/native": "^6.1.9",
    "@react-navigation/native-stack": "^6.9.16",
    "@reduxjs/toolkit": "^1.9.7",
    "axios": "^1.6.0",
    "expo": "~49.0.15",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.6",
    "react-native-calendars": "^1.1301.0",
    "react-native-circular-progress": "^1.3.9",
    "react-native-paper": "^5.11.1",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0",
    "react-native-svg": "^13.14.0",
    "react-native-uuid": "^2.0.1",
    "react-navigation": "^5.0.0",
    "react-redux": "^8.1.3",
    "redux": "^4.2.1"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

```

### frontend/App.js

```javascript
// In App.js in a new project

import * as React from 'react';
import { SafeAreaProvider } from "react-native-safe-area-context"
import MainScreen from './MainScreen';

// const Stack = createNativeStackNavigator();

function App() {
  return (
    <SafeAreaProvider>
      <MainScreen />
    </SafeAreaProvider>
  );
}

export default App;
```

### frontend/index.js

```javascript
import React from "react"
import { AppRegistry } from "react-native"
import App from "./App"
import { name as appName } from './app.json'
import { Provider } from "react-redux"
import configureStore from "./store"

const store = configureStore();

// As of React 18
const ProviderWrapper = () => 
  <Provider store={store}>
    <App />
  </Provider>

AppRegistry.registerComponent(appName, () => ProviderWrapper)
```

### backend/app.py

```python
from flask import Flask, request, jsonify
from utils.sentiment_classification import get_sentiments
from utils.chatbot import get_chatbot_response, get_weekly_summary, get_daily_summary
from utils.date_manipulation import get_first_day_of_week
from utils.embedding import generate_primary_embedding
from flask_cors import CORS
import os
import psycopg
from datetime import datetime

app = Flask(__name__)
CORS(app)
conn = psycopg.connect("postgresql://apai25:ZqZMx32nohbDmTaTwOqGZQ@mental-map-3658.g95.cockroachlabs.cloud:26257/defaultdb?sslmode=require")
EMOTIONS = ['Anger', 'Anxiety', 'Disappointment', 'Excitement', 'Fear', 'Joy', 'Love', 'Pain', 'Sadness', 'Tiredness']

@app.route('/get-chat-response', methods=['POST'])
def get_chat_response():
    data = request.json
    context = data['context']
    try:
        chatbot_response = get_chatbot_response(context)
    except KeyError:
        return 'Malformed input.', 400

    return jsonify({'chat_response': chatbot_response}), 200

@app.route('/login', methods=['POST'])
def login():
    data = request.json

    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (user_id, email, user_password) FROM user_information WHERE email = %s",
            (data['email'],)
        )
        user_information = cursor.fetchone()

    if user_information is None:
        return 'Email or password is incorrect.', 401

    if data['password'] != user_information[0][2]:
        return 'Email or password is incorrect.', 401

    return jsonify({'user_id': user_information[0][0]}), 200

@app.route('/register', methods=['POST'])
def register():
    data = request.json

    if 'email' not in data or 'password' not in data:
        return 'Malformed input.', 400

    with conn.cursor() as cursor:
        cursor.execute("SELECT user_id FROM user_information WHERE email = %s", (data['email'],))
        existing_user = cursor.fetchone()

    if existing_user:
        return "User already registered.", 400

    with conn.cursor() as cursor:
        cursor.execute(
            "INSERT INTO user_information (email, user_password) VALUES (%s, %s)",
            (data['email'], data['password'])
        )
    conn.commit()

    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (user_id, email, user_password) FROM user_information WHERE email = %s",
            (data['email'],)
        )
        user_information = cursor.fetchone()
    
    return jsonify({'user_id': user_information[0][0]}), 200

@app.route('/store-entry', methods=['POST'])
async def store_entry():
    data = request.json
    if 'context' not in data:
        return 'Malformed input.', 400
    
    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (user_id) FROM user_information WHERE user_id = %s",
            (data['user_id'],)
        )
        user_information = cursor.fetchone()

    if user_information is None:
        return 'User does not exist.', 400

    entry_text = get_daily_summary(data['context'])
    sentiments = await get_sentiments(entry_text)

    current_date = datetime.now()
    formatted_date = current_date.strftime("%Y-%m-%d")

    with conn.cursor() as cursor:
        cursor.execute(
            "UPSERT INTO diary_entries (entry_id, user_id, entry_date, entry_text, anger, anxiety, disappointment, excitement, fear, joy, love, pain, sadness, tiredness) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
            (data['entry_id'], data['user_id'], formatted_date, entry_text, sentiments['Anger'], sentiments['Anxiety'], sentiments['Disappointment'], sentiments['Excitement'], sentiments['Fear'], sentiments['Joy'], sentiments['Love'], sentiments['Pain'], sentiments['Sadness'], sentiments['Tiredness'])
        )

    conn.commit()
    generate_primary_embedding(entry_text)
    return 'Entry stored.', 200

@app.route('/get-entries', methods=['POST'])
def get_entries():
    data = request.json
    user_id = data['user_id']
    formatted_date = data['date']

    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (user_id) FROM user_information WHERE user_id = %s",
            (user_id,)
        )
        entries = cursor.fetchone()
    
    if entries is None:
        return 'User does not exist.', 400

    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT * FROM diary_entries WHERE user_id = %s AND entry_date = %s",
            (user_id, formatted_date)
        )
        entries = cursor.fetchall()
    
    entry_information = []
    for entry in entries:
        emotion_vals = [(EMOTIONS[i], entry[i + 4]) for i in range(len(EMOTIONS))]
        emotion_vals.sort(key=lambda x: x[1], reverse=True)
        emotion_vals = emotion_vals[:3]
        
        sum_vals = sum([val[1] for val in emotion_vals])
        emotion_vals = [(val[0], val[1] * (100 / sum_vals)) for val in emotion_vals]
        
        entry_information.append({
            'entry_id': entry[0],
            'user_id': entry[1],
            'entry_date': entry[2],
            'entry_text': entry[3],
            'sentiments': emotion_vals,
        })

    return jsonify(entry_information), 200

@app.route('/get-weekly-summary', methods=['POST'])
async def get_weekly_entry_summary():
    data = request.json
    user_id = data['user_id']

    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (user_id) FROM user_information WHERE user_id = %s",
            (user_id,)
        )
        entries = cursor.fetchone()
    
    if entries is None:
        return 'User does not exist.', 400
    
    monday_date = get_first_day_of_week()
    with conn.cursor() as cursor:
        cursor.execute(
            "SELECT (entry_text) FROM diary_entries WHERE user_id = %s AND entry_date >= %s",
            (user_id, monday_date)
        )
        entries = cursor.fetchall()
    
    if not len(entries):
        return jsonify({'weekly_summary': 'No entries so far!', 'sentiments': [('Have a', 
[truncated — 1426 more characters]
```

### examples.py

```python
ex1 = {'summary': "Today was a day of celebration! I just got an internship at Apple for summer 2024 in ML/AI. After applying online and going through a rigorous interview process, I was thrilled to hear the good news. I'll be working on a mix of computer vision and natural language processing projects, which I'm really looking forward to. I'm a bit nervous about the high expectations, but I'm reminded of the faith Apple has in my skills and potential. I'm going to give this my all.",
       'sentiments': {'Excitement': 60.33475588335631,'Joy': 23.690672813882667,'Anxiety': 15.974571302761017},
       'date': '2023-10-25'}

ex2 = {'summary': "Today has been a tough one. I found out that my girlfriend had cheated on me and it's been a huge blow to my trust. I thought we had something special, but now I feel betrayed. Thankfully, I have a friend who's been supportive and understanding, and who's given me the space to open up and talk about what happened. I'm still feeling the pain, but I'm trying to remember that I'm strong and I'll get through this.",
       'sentiments': {'Disappointment': 34.78068937076821,'Sadness': 34.766696837210866,'Pain': 30.452613792020937},
       'date': '2023-10-22'}

ex3 = {'summary': "I was feeling overwhelmed about the upcoming computer science midterm on optimizing algorithms and intractable problems. I was grateful for my friend's encouragement, and I'm doing my best to prepare by reviewing class notes, doing practice problems, and watching online tutorials. I'm trying to be mindful of taking breaks and getting rest, understanding that the process is just as important as the result. I'm breaking it down and tackling one concept at a time.",
       'sentiments': {'Anxiety': 60.09055119187781,'Tiredness': 28.412389139045164,'Fear': 11.497059669077036},
       'date': '2023-10-27'}

ex4 = {'summary': "I finally confessed my feelings to my crush and she told me she likes me back! I'm over the moon and I think I might be in love with her. Now, I'm looking forward to getting to know her better and maybe planning a nice date. I'm so grateful for the support I've received and am excited to embark on this new chapter of my life.",
       'sentiments': {'Love': 42.79288339475731,'Joy': 30.349479687422203,'Excitement': 26.857636917820493},
       'date': '2023-10-23'}

ex5 = {'summary': "My beloved cat, who had been with me for 15 years, passed away yesterday. We had so many memories together, from the day we first brought her home as a tiny ball of fur to the many adventures we had over the years. It's tough to imagine coming home without her there. Talking about it helps, though, and I'm grateful for the time we had together. I'm also thankful for the support of my friends.",
       'sentiments': {'Sadness': 45.76713114103804,'Love': 30.701021772652602,'Pain': 23.531847086309355},
       'date': '2023-10-26'}

ex6 = {'summary': "Today was a really scary day. I was trying to do a parkour move, but I lost my footing and ended up falling off a building. Thankfully, I'm at the hospital now and it looks like nothing is broken, but I'm still pretty banged up. I'm just glad to be alive, and I know now that I need to prioritize safety when it comes to pursuing my passions. My friend was understanding and reminded me to take the time to rest and recover.",
       'sentiments': {'Fear': 43.73803460319453,'Anxiety': 31.37518778363556,'Tiredness': 24.8867776131699},
       'date': '2023-10-24'}

ex7 = {'summary': "Today was a difficult day. I woke up hungover and with no recollection of what had happened the night before. I was worried that I might have done something I would regret. Thankfully, my friend was there for me and offered support. We discussed ways to figure out what had happened, like checking my phone for texts or calls. They reminded me to focus on taking care of myself first, and that this was a learning experience. I'm grateful for their understanding and support.",
       'sentiments': {'Tiredness': 42.140341844550925,'Anxiety': 30.488686630594408,'Sadness': 27.37097152485467},
       'date': '2023-10-28'}

ex8 = {'summary': "Today was a great day. I had the most romantic date at a fancy restaurant with dim lighting, soft music, and delicious food. We even had a private corner overlooking the city lights. We talked about everything - our dreams, favorite books, and even our childhood memories. My date even surprised me with a special dessert with 'Congratulations' written in chocolate - they had heard about my recent promotion! We're already planning a weekend getaway to a cozy cabin in the mountains.",
       'sentiments': {'Joy': 42.317625995351364,'Love': 32.88015333784602,'Excitement': 24.802220666802626},
       'date': '2023-10-21'}

ex9 = {'summary': "Today was a long day. My team and I worked hard all night on a cybersecurity project for the Cal Hacks 10.0 hackathon. We put together a malware detection system that we are all proud of. Despite the exhaustion, we're still pumped up and ready to make some final adjustments before the submission. We want the user interface to be perfect, so we're putting in the extra effort. I'm a bit nervous about presenting it, but I'm sure all the hard work will pay off.",
       'sentiments': {'Tiredness': 56.41072398109108,'Anxiety': 22.064660838162702,'Excitement': 21.524615180746228},
       'date': '2023-10-19'}

ex10 = {'summary': "Today was a great day. I got assigned to work on a project with IKEA through my college tech consulting club. It's focused on optimizing the online customer experience and I'll be diving into UX/UI design and data analysis. I'm so excited to learn and contribute! I'm planning to do some research on IKEA's current online platforms and customer feedback, then come up with some creative solutions with the team. My friend was a great source of encouragement and showed their support.",
       'sentiments': {'Excitement': 70.78050303882928,'Joy': 27.433368124331793,'Love': 1.7861288368389336
[truncated — 95 more characters]
```

### frontend/babel.config.js

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

```

### frontend/MainScreen.js

```javascript
import React, { useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import JournalScreen from './screens/journal/JournalScreen';
import ChatScreen from './screens/chat/ChatScreen';
import LoginStackScreen from './screens/login/LoginStackScreen';
import LoginScreen from './screens/login/LoginScreen';
import CreateAccountScreen from './screens/login/CreateAccountScreen';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {Connect} from 'react-redux'


export default function MainScreen() {

    const Tab = createMaterialTopTabNavigator();
    const Stack = createNativeStackNavigator();
    const insets = useSafeAreaInsets();

    const [loggedIn, setLoggedIn] = useState(false);
    const [userId, setUserId] = useState(null);

    return (
        <NavigationContainer>
            {loggedIn && userId ?
                <Tab.Navigator screenOptions={{
                    tabBarStyle: {
                        marginTop: insets.top
                    }
                }}>
                    <Tab.Screen name="Journal" component={JournalScreen} initialParams={{userId: userId}}  />
                    <Tab.Screen name="Chat" component={ChatScreen} initialParams={{userId: userId}} />
                </Tab.Navigator>
            :
                <LoginStackScreen setLoggedIn={setLoggedIn} setUserId={setUserId}/>
                /* <Stack.Navigator >
                    <Stack.Screen name="Login" component={LoginScreen} />
                    <Stack.Screen name="Create Account" component={CreateAccountScreen} />
                </Stack.Navigator> */
            }
        </NavigationContainer>
    );
}
```

### frontend/hooks/usePrevious.js

```javascript
import * as React from "react"

export const usePrevious = value => {
  const ref = React.useRef()

  React.useEffect(() => {
    ref.current = value
  }, [value])

  return ref.current
}

```

### backend/utils/date_manipulation.py

```python
from datetime import datetime, timedelta

def get_first_day_of_week():
    # Get the current date
    today = datetime.now()

    # Calculate the difference in days between the current day of the week (0=Monday, 6=Sunday) and Monday (0)
    days_to_monday = today.weekday()

    # Subtract the difference to get the date of the first day of the week (Monday)
    first_day_of_week = today - timedelta(days=days_to_monday)

    # Format the date in "YYYY-MM-DD" format
    formatted_date = first_day_of_week.strftime("%Y-%m-%d")

    return formatted_date
```

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