# Project export: Mood Snap

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: A web and mobile-based app that allows users to post positive/happy thoughts on various prompts anonymously every 2 hours.
- Devpost: https://devpost.com/software/mood-app
- GitHub: https://github.com/jauntybrain/mood-app
- Team: 2 GitHub contributor(s) — Pavel Ryabov (9 commits), Mudit Arora (2 commits)

## Devpost submission (written by the team)

### Inspiration

Our inspiration for the Mood App stemmed from a genuine concern for the emotional well-being of individuals in today's fast-paced world. We noticed the lack of platforms that prioritize emotional expression and connection in a simple and engaging way. We wanted to create a space where people could freely share their thoughts and feelings, fostering a sense of community and support.

### What it does

The Mood App is a unique platform designed to encourage users to share their emotions and current moods. It's a safe and supportive space where users are prompted to post their thoughts and feelings once a day. The app features a user-friendly feed where people can comment and react to these posts, allowing for interaction and emotional support among users. It's like "BeReal" but specifically geared towards encouraging emotional expression and connection.

### How we built it

We built the Mood App for the CalHacks 10 hackathon using a combination of technologies. We employed Reflex, a Python-based React Frontend, for the web application, and utilized Convex, a real-time backend framework based on Node.js, to ensure seamless and immediate interactions. For the mobile version, we used Flutter to create an intuitive and responsive user experience. This combination of technologies enabled us to provide a multi-platform solution, reaching a wider audience and ensuring that anyone can use the Mood App regardless of their device preferences.

### Challenges we ran into

Developing the Mood App presented its own set of challenges. Integrating the frontend and backend seamlessly was a complex task. Ensuring real-time updates, user authentication, and maintaining a clean and responsive user interface on both web and mobile platforms required a significant amount of effort and problem-solving. In addition, building an engaging feed while safeguarding user privacy was a delicate balance we needed to strike. We also had to contend with the technical intricacies of deploying and maintaining our app for a hackathon setting.

### Accomplishments we're proud of

We are incredibly proud of what we've achieved with the Mood App. We successfully created a platform that encourages users to open up about their emotions and mood, fostering a sense of community and support. The combination of Python-based Reflex, Convex for real-time updates, and Flutter for a mobile app resulted in a versatile and user-friendly experience. The integration of these technologies allowed us to provide a seamless and accessible solution for our users.

### What we learned

Throughout the development process, we gained valuable insights into real-time backend frameworks, multi-platform development with Flutter, and the intricacies of creating a user-friendly and engaging feed. We also learned about the importance of prioritizing user privacy and data security while maintaining a transparent and supportive atmosphere for emotional expression.

### What's next

for Mood App Our journey doesn't end with the hackathon; we see great potential for the Mood App beyond this event. In the future, we plan to refine the app's features and user experience based on user feedback. We aim to enhance our real-time features, implement user customization, and potentially introduce sentiment analysis to provide even more valuable insights to users about their emotional well-being. Additionally, we intend to expand our user base and community, promoting the Mood App as a valuable resource for emotional expression and support. We're also exploring possibilities for partnerships and collaborations that can help us grow and improve the app even further. The Mood App's journey is just beginning, and we're excited about the potential it holds for making emotional well-being a top priority for people everywhere.

## README (from the GitHub repository)

# mood-app

## Detected evidence (automated analysis)

Indexed codebase: 32 recognized source files, 34 KB.
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (42 of 42)

```
.gitignore
backend/.gitignore
backend/convex/_generated/api.d.ts
backend/convex/_generated/api.js
backend/convex/_generated/dataModel.d.ts
backend/convex/_generated/server.d.ts
backend/convex/_generated/server.js
backend/convex/.DS_Store
backend/convex/actions.ts
backend/convex/auth.config.js
backend/convex/crons.ts
backend/convex/http.ts
backend/convex/posts.ts
backend/convex/schema.ts
backend/convex/tasks.ts
backend/package.json
backend/tsconfig.json
frontend/__init__.py
frontend/.idea/.gitignore
frontend/.idea/discord.xml
frontend/.idea/inspectionProfiles/profiles_settings.xml
frontend/.idea/inspectionProfiles/Project_Default.xml
frontend/.idea/misc.xml
frontend/.idea/modules.xml
frontend/.idea/mood-app-main.iml
frontend/mood_app/__init__.py
frontend/mood_app/.DS_Store
frontend/mood_app/components/__init__.py
frontend/mood_app/components/sidebar.py
frontend/mood_app/mood_app.py
frontend/mood_app/pages/__init__.py
frontend/mood_app/pages/dashboard.py
frontend/mood_app/pages/index.py
frontend/mood_app/pages/settings.py
frontend/mood_app/state.py
frontend/mood_app/styles.py
frontend/mood_app/templates/__init__.py
frontend/mood_app/templates/template.py
frontend/requirements.txt
frontend/rxconfig.py
LICENSE
README.md
```

### Dependencies

- backend/package.json: @types/node@^20.8.9, convex@^1.5.1, dotenv@^16.3.1, typescript@^5.2.2
- frontend/requirements.txt: reflex@==0.3.1

### Recent commits (newest first)

- cleanup
- Add files via upload
- cleanup backend
- update gitignore
- cleanup
- cleanup
- add: gitignore
- re-organize backend and frontend
- add: changes
- commit
- Initial commit

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

### frontend/requirements.txt

```

reflex==0.3.1

```

### backend/package.json

```
{
  "name": "mood-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "npm-run-all dev:init --parallel dev:server dev:client",
    "build": "tsc && vite build",
    "dev:server": "convex dev",
    "dev:client": "vite --open",
    "dev:init": "convex dev --run init --until-success"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module",
  "dependencies": {
    "@types/node": "^20.8.9",
    "convex": "^1.5.1",
    "dotenv": "^16.3.1",
    "typescript": "^5.2.2"
  }
}

```

### backend/convex/_generated/server.js

```javascript
/* eslint-disable */
/**
 * Generated utilities for implementing server-side Convex query and mutation functions.
 *
 * THIS CODE IS AUTOMATICALLY GENERATED.
 *
 * Generated by convex@1.5.1.
 * To regenerate, run `npx convex dev`.
 * @module
 */

import {
  actionGeneric,
  httpActionGeneric,
  queryGeneric,
  mutationGeneric,
  internalActionGeneric,
  internalMutationGeneric,
  internalQueryGeneric,
} from "convex/server";

/**
 * Define a query in this Convex app's public API.
 *
 * This function will be allowed to read your Convex database and will be accessible from the client.
 *
 * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
 * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
 */
export const query = queryGeneric;

/**
 * Define a query that is only accessible from other Convex functions (but not from the client).
 *
 * This function will be allowed to read from your Convex database. It will not be accessible from the client.
 *
 * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
 * @returns The wrapped query. Include this as an `export` to name it and make it accessible.
 */
export const internalQuery = internalQueryGeneric;

/**
 * Define a mutation in this Convex app's public API.
 *
 * This function will be allowed to modify your Convex database and will be accessible from the client.
 *
 * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
 * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
 */
export const mutation = mutationGeneric;

/**
 * Define a mutation that is only accessible from other Convex functions (but not from the client).
 *
 * This function will be allowed to modify your Convex database. It will not be accessible from the client.
 *
 * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
 * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
 */
export const internalMutation = internalMutationGeneric;

/**
 * Define an action in this Convex app's public API.
 *
 * An action is a function which can execute any JavaScript code, including non-deterministic
 * code and code with side-effects, like calling third-party services.
 * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
 * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
 *
 * @param func - The action. It receives an {@link ActionCtx} as its first argument.
 * @returns The wrapped action. Include this as an `export` to name it and make it accessible.
 */
export const action = actionGeneric;

/**
 * Define an action that is only accessible from other Convex functions (but not from the client).
 *
 * @param func - The function. It receives an {@link ActionCtx} as its first argument.
 * @returns The wrapped function. Include this as an `export` to name it and make it accessible.
 */
export const internalAction = internalActionGeneric;

/**
 * Define a Convex HTTP action.
 *
 * @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object
 * as its second.
 * @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`.
 */
export const httpAction = httpActionGeneric;

```

### frontend/mood_app/pages/index.py

```python
"""The home page of the app."""

from mood_app import styles
from mood_app.templates import template

import reflex as rx
from ..state import State
import random 
import time 

from convex import ConvexClient, ConvexError

client = ConvexClient("https://elegant-fox-172.convex.cloud")

# def add_item(self, form_data: dict[str, str]):
#     """Add a new item to the todo list.r
#
#     Args:
#         form_data: The data from the form.
#     """
#     # Add the new item to the list.
#     new_item = form_data.pop("new_item")
#     if not new_item:
#         self.invalid_item = True
#         return
#
#     self.items.append(new_item)
#     # set the invalid status to False.
#     self.invalid_item = False
#     # Clear the value of the input.
#     return rx.set_value("new_item", "")

class ChatState(State):

    show: bool = False

    def change(self):
        self.show = not (self.show)

    @rx.var
    def is_error(self) -> bool:
        return len(self.answer) <= 0

    answer = ""
    done = False

   #should_redirect: bool = False 

    alert: bool = False
    has_clicked = False

    def process_data(self):
        # call convex here answer
        # save to database
        if self.has_clicked:
            self.show = True
            return

        self.has_clicked = True
        try:
            client.mutation("posts:add", {"content":self.answer})
        except ConvexError as err:
            print(err.data)
        #return rx.redirect("/dashboard")
    
    def show_alert(self):
        self.alert = True
        yield
        import time
        time.sleep(5)
        self.alert = False

def action_bar() -> rx.Component:
    return rx.hstack(
        rx.form_control(
            rx.input(
                placeholder="Tell me your thoughts",
                on_blur=ChatState.set_answer,
                text_align="center",
                style=styles.answer_style,
            ),
            rx.cond(
                ChatState.is_error,
                rx.form_error_message("You need to write something before posting."),
                rx.form_helper_text("Enter your response"),
            ),
            is_invalid=ChatState.is_error,
            is_required=True,
        ),
        rx.cond(
            ChatState.is_error,
            rx.button("Post", disabled=True, style=styles.button_style, text_align="center"),
            rx.button("Post", on_click=ChatState.process_data, style=styles.button_style, text_align="center"),

        ),
        width="100%"
    )

# Define a list of prompts
prompts = [
    "What's on your mind?",
    "What is your comfort food",
    "Tell us ways to brighten your day",
    "Tell us about your day in one word",
    "Share a funny childhood memory",
    "What's your go-to karaoke song",
    "Tell me about a memorable adventure",
    "Share a quirky hobby that brings you joy",
    "Tell us the most cringe joke you ever made",
    "Best way to take care of your mental health"
]

@template(route="/",title="Prompt")

def index() -> rx.component:
    random_prompt = random.choice(prompts)
    return rx.center(
        rx.vstack(
            rx.heading("Mood Snap", font_size="3em"),
            rx.divider(),
            rx.box(
                random_prompt,
                style=styles.question_style,
                text_align="center",
                width="100%",
            ),
            action_bar(),
            rx.cond(
                ChatState.show,
                rx.box(
    rx.alert_dialog(
        rx.alert_dialog_overlay(
            rx.alert_dialog_content(
                rx.alert_dialog_header("We would love to hear about your thoughts but..."),
                rx.alert_dialog_body(
                    "You have already posted, please come back again in some time"
                ),
                rx.alert_dialog_footer(
                    rx.button(
                        "OK",
                        on_click=ChatState.change,
                    )
                ),
            )
        ),
        is_open=ChatState.show,
    ),
)
            ),
        ),
        width="100%",
        height="100vh",
        background="radial-gradient(circle at 22% 11%,rgba(62, 180, 137,.20),hsla(0,0%,100%,0) 19%),radial-gradient(circle at 82% 25%,rgba(33,150,243,.18),hsla(0,0%,100%,0) 35%),radial-gradient(circle at 25% 61%,rgba(250, 128, 114, .28),hsla(0,0%,100%,0) 55%)",
    )



```

### frontend/__init__.py

```python
"""Base template for Reflex."""

```

### frontend/rxconfig.py

```python
import reflex as rx

config = rx.Config(
    app_name="mood_app",
)
```

### frontend/mood_app/__init__.py

```python
"""Base template for Reflex."""

```

### backend/convex/tasks.ts

```typescript
import { query } from "./_generated/server";

export const get = query({
  handler: async ({ db }) => {
    return await db.query('posts').collect();
  },
});
```

### frontend/mood_app/state.py

```python
"""Base state for the app."""

import reflex as rx


class State(rx.State):
    """Base state for the app.

    The base state is used to store general vars used throughout the app.
    """

    pass

```

### frontend/.idea/misc.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (mood-app-main)" project-jdk-type="Python SDK" />
</project>
```

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