# Project export: Disaster Resource Allocation

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 11.0
- Tagline: Our platform uses XRP to enable near-instant cross-border donations, solving the days-long delay in overseas transfers during disasters, ensuring fast and reliable relief support when it’s needed most
- Devpost: https://devpost.com/software/disaster-resource-allocation
- GitHub: https://github.com/nkim33937/disasterResAlloc
- Team: 2 GitHub contributor(s) — Jason (18 commits), nkim33937 (8 commits)

## Devpost submission (written by the team)

### Inspiration

The need for fast, reliable financial aid during natural disasters or wars inspired us to build a platform that eliminates the delay of traditional overseas transfers, using XRP for instant donations.

### What it does

Our platform allows users to donate to relief organizations across the globe using XRP, ensuring near-instantaneous cross-border transfers, and overcoming the usual delays in emergency financial support.

### How we built it

We developed the platform using Reflex for the frontend, integrating XRP wallets for transactions. The backend leverages Python for managing organization data and real-time donation history tracking.

### Challenges we ran into

The biggest challenge was ensuring the seamless integration of XRP transactions while maintaining a user-friendly interface and handling real-time updates of donation data for transparency.

### Accomplishments we're proud of

We are proud of implementing a solution that provides real-time donation tracking and eliminates days of waiting for transfers to process during crucial disaster relief situations.

### What we learned

We learned the importance of efficient financial infrastructure in crisis management and how decentralized solutions like XRP can significantly reduce bottlenecks in donation systems.

### What's next

Next, we plan to expand the platform’s capabilities by adding multi-currency support and working on deeper integration with AI-driven analytics to optimize fund allocation for disaster relief.

## README (from the GitHub repository)

# Welcome to Reflex!

This is the base Reflex template - installed when you run `reflex init`.

If you want to use a different template, pass the `--template` flag to `reflex init`.
For example, if you want a more basic starting point, you can run:

```bash
reflex init --template blank
```

## About this Template

This template has the following directory structure:

```bash
├── README.md
├── assets
├── rxconfig.py
└── {your_app}
    ├── __init__.py
    ├── components
    │   ├── __init__.py
    │   ├── navbar.py
    │   └── sidebar.py
    ├── pages
    │   ├── __init__.py
    │   ├── about.py
    │   ├── index.py
    │   ├── profile.py
    │   ├── settings.py
    │   └── table.py
    ├── styles.py
    ├── templates
    │   ├── __init__.py
    │   └── template.py
    └── {your_app}.py
```

See the [Project Structure docs](https://reflex.dev/docs/getting-started/project-structure/) for more information on general Reflex project structure.

### Adding Pages

In this template, the pages in your app are defined in `{your_app}/pages/`.
Each page is a function that returns a Reflex component.
For example, to edit this page you can modify `{your_app}/pages/index.py`.
See the [pages docs](https://reflex.dev/docs/pages/routes/) for more information on pages.

In this template, instead of using `rx.add_page` or the `@rx.page` decorator,
we use the `@template` decorator from `{your_app}/templates/template.py`.

To add a new page:

1. Add a new file in `{your_app}/pages/`. We recommend using one file per page, but you can also group pages in a single file.
2. Add a new function with the `@template` decorator, which takes the same arguments as `@rx.page`.
3. Import the page in your `{your_app}/pages/__init__.py` file and it will automatically be added to the app.
4. Order the pages in `{your_app}/components/sidebar.py` and `{your_app}/components/navbar.py`.


### Adding Components

In order to keep your code organized, we recommend putting components that are
used across multiple pages in the `{your_app}/components/` directory.

In this template, we have a sidebar component in `{your_app}/components/sidebar.py`.

### Adding State

As your app grows, we recommend using [substates](https://reflex.dev/docs/substates/overview/)
to organize your state.

You can either define substates in their own files, or if the state is
specific to a page, you can define it in the page file itself.


## Detected evidence (automated analysis)

Indexed codebase: 38 recognized source files, 75 KB.
- CSS (language) — detected in the code
- Python (language) — detected in the code
- SQL (language) — detected in the code

## Codebase structure (from repository index)

### Files (46 of 46)

```
.DS_Store
.gitignore
alembic.ini
alembic/addCreatedTime.sql
alembic/env.py
alembic/README
alembic/script.py.mako
alembic/versions/427ff7c411e3_.py
alembic/versions/4b13cc59af44_.py
alembic/versions/c73e833426f5_.py
assets/styles.css
disasterResAlloc/__init__.py
disasterResAlloc/backend/__init__.py
disasterResAlloc/backend/organisations.py
disasterResAlloc/backend/routes.py
disasterResAlloc/backend/table_state.py
disasterResAlloc/components/__init__.py
disasterResAlloc/components/card.py
disasterResAlloc/components/navbar.py
disasterResAlloc/components/notification.py
disasterResAlloc/components/profile_input.py
disasterResAlloc/components/sidebar.py
disasterResAlloc/components/status_badge.py
disasterResAlloc/disasterResAlloc.py
disasterResAlloc/pages/__init__.py
disasterResAlloc/pages/about.py
disasterResAlloc/pages/index.py
disasterResAlloc/pages/organisation.py
disasterResAlloc/pages/settings.py
disasterResAlloc/pages/table.py
disasterResAlloc/styles.py
disasterResAlloc/templates/__init__.py
disasterResAlloc/templates/template.py
disasterResAlloc/views/__init__.py
disasterResAlloc/views/adquisition_view.py
disasterResAlloc/views/charts.py
disasterResAlloc/views/color_picker.py
disasterResAlloc/views/radius_picker.py
disasterResAlloc/views/scaling_picker.py
disasterResAlloc/views/stats_cards.py
disasterResAlloc/views/table.py
items.csv
README.md
reflex.db
requirements.txt
rxconfig.py
```

### Dependencies

- requirements.txt: reflex@>=0.5.5

### Recent commits (newest first)

- search dropdown animation
- fixed indentations
- Merge branch 'main' of https://github.com/nkim33937/disasterResAlloc
- typing animation
- green graph
- Merge branch 'main' of github.com:nkim33937/disasterResAlloc
- test dataset donation graph
- fullscreen background
- UI for orgs
- ui fixes
- routing fix + dropdown ui
- Merge branch 'main' of https://github.com/nkim33937/disasterResAlloc
- Merge branch 'main' of https://github.com/nkim33937/disasterResAlloc
- index changes
- rtng
- added calhacks logo
- Merge branch 'main' of https://github.com/nkim33937/disasterResAlloc
- removed db from gitignore
- added db for hacking convenience
- Ignore Python bytecode files

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

### requirements.txt

```
reflex>=0.5.5
```

### disasterResAlloc/pages/index.py

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

import reflex as rx
from .. import styles
from ..templates import template
from ..views.stats_cards import stats_cards
from ..views.charts import (
    users_chart,
    revenue_chart,
    orders_chart,
    area_toggle,
    pie_chart,
    timeframe_select,
    StatsState,
    donation_history_chart,
)
from ..views.adquisition_view import adquisition
from ..components.notification import notification
from ..components.card import card
from ..backend.table_state import TableState
# from .profile import ProfileState
import datetime


def _time_data() -> rx.Component:
    return rx.hstack(
        rx.tooltip(
            rx.icon("info", size=20),
            content=f"{(datetime.datetime.now() - datetime.timedelta(days=30)).strftime('%b %d, %Y')} - {datetime.datetime.now().strftime('%b %d, %Y')}",
        ),
        rx.text("Last 30 days", size="4", weight="medium"),
        align="center",
        spacing="2",
        display=["none", "none", "flex"],
    )

def special_events_example():
    return rx.button(
        "Alert", on_click=rx.window_alert("Hello World!")
    )

def tab_content_header() -> rx.Component:
    return rx.hstack(
        _time_data(),
        area_toggle(),
        align="center",
        width="100%",
        spacing="4",
    )


@template(route="/", title="Overview", on_load=StatsState.randomize_data)
def index() -> rx.Component:
    """The overview page.

    Returns:
        The UI for the overview page.
    """
    # donation_data = [
    #     {"Date": "10-01", "Donation": 100},
    #     {"Date": "10-05", "Donation": 500},
    #     {"Date": "10-10", "Donation": 800},
    #     {"Date": "10-15", "Donation": 200},
    #     {"Date": "10-20", "Donation": 400},
    #     {"Date": "10-25", "Donation": 300},
    # ]

    return rx.vstack(
        rx.heading(f"Welcome, Organization", size="5", style={ 
                "width": "20%",    
                "animation": "typing 1.5s steps(40, end), blink-caret .75s step-end infinite",
                "animation-fill-mode": "forwards",
                "white-space": "nowrap",
                "overflow": "hidden",
                "@keyframes typing": {
                    "from": { "width": "0" },
                    "to": { "width": "23%" }
                },
                # "@keyframes blink-caret": {
                #     "from": { "border-right": ".15em solid grey" },
                #     "50%": { "border-right": "transparent" },
                #     "to": { "border-right": "none" }

                # }
                }),
        stats_cards(),
        rx.flex(
            rx.input(
                rx.input.slot(rx.icon("search"), padding_left="0"),
                placeholder="Search Relief Organisations...",
                size="3",
                width="100%",
                max_width="450px",
                radius="large",
                style=styles.ghost_input_style,
                on_change=rx.event(TableState.set_search_query),
            ),
            justify="between",
            align="center",
            width="100%",
        ),
        rx.cond(
            TableState.search_query != "",
            rx.foreach(TableState.search_results, lambda org: rx.button(
                rx.box(
                    rx.text(f"{org.name}", color=styles.text_color, hover_color=styles.accent_text_color, style={"padding":"20px", "border-radius":"12px",":hover": {"background_color": styles.gray_bg_color}}),
                    # rx.text(f"Location: {org.location}"),
                    # rx.text(f"Email: {org.email}")
                    # rx.text(f"Wallet: {org.encoded_wallet}"),
                ),
                on_click=rx.redirect(f"/organisation/{org.id}"),
                style=[styles.ghost_button_style, {
                "animation": "slide-down 0.5s ease-out",
                "@keyframes slide-down": {
                    "from": {"transform": "translateY(-20px)", "opacity": "0"},
                    "to": {"transform": "translateY(0)", "opacity": "1"},
                },
            }],
            )),
        ),
        card(
            rx.hstack(
                tab_content_header(),
                rx.segmented_control.root(
                    rx.segmented_control.item("Donation Total", value="donation"),
                    margin_bottom="1.5em",
                    default_value="donation",
                    on_change=StatsState.set_selected_tab,
                ),
                width="100%",
                justify="between",
            ),
            rx.cond(
                StatsState.selected_tab == "donation",
                donation_history_chart(),
                #("donation", donation_history_chart()),
                #("revenue", revenue_chart()),
                rx.text("Select 'Donation Total' to view the chart"),
            ),
        ),
        spacing="8",
        width="100%",
    )

```

### rxconfig.py

```python
import reflex as rx

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

### disasterResAlloc/__init__.py

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

```

### alembic/addCreatedTime.sql

```sql
-- SQLite
-- ALTER TABLE organisation ADD COLUMN updated time_updated;
SELECT * FROM organisation;
```

### assets/styles.css

```css
body {
    overflow-y: scroll;
}

.recharts-cartesian-grid-horizontal line {
	stroke-dasharray: 0;
	stroke-opacity: 0.6 !important;
	stroke: var(--gray-7);
}

.recharts-cartesian-grid-vertical line {
	stroke-opacity: 0 !important;
}

.rt-BaseTabList {
	box-shadow: none;
}

```

### disasterResAlloc/disasterResAlloc.py

```python
"""Welcome to Reflex!."""

# Import all the pages.
from .pages import *
from .pages import organisation
from . import styles
from disasterResAlloc.backend.table_state import Organisation
import reflex as rx


# Create the app. 
app = rx.App(
    style=styles.base_style,
    stylesheets=styles.base_stylesheets,
    title="Disaster Relief Payment Gateway",
    description="A dashboard for fast payments for disaster relief.",
)

```

### alembic/env.py

```python
from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
    fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline() -> None:
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )

    with context.begin_transaction():
        context.run_migrations()


def run_migrations_online() -> None:
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    connectable = engine_from_config(
        config.get_section(config.config_ini_section, {}),
        prefix="sqlalchemy.",
        poolclass=pool.NullPool,
    )

    with connectable.connect() as connection:
        context.configure(
            connection=connection, target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()

```

### disasterResAlloc/styles.py

```python
"""Styles for the app."""

import reflex as rx

border_radius = "var(--radius-2)"
border = f"1px solid {rx.color('gray', 5)}"
text_color = rx.color("gray", 11)
gray_color = rx.color("gray", 11)
gray_bg_color = rx.color("gray", 3)
accent_text_color = rx.color("accent", 10)
accent_color = rx.color("accent", 1)
accent_bg_color = rx.color("accent", 3)
hover_accent_color = {"_hover": {"color": accent_text_color}}
hover_accent_bg = {"_hover": {"background_color": accent_color}}
content_width_vw = "90vw"
sidebar_width = "32em"
sidebar_content_width = "16em"
max_width = "1480px"
color_box_size = ["2.25rem", "2.25rem", "2.5rem"]


template_page_style = {
    "padding_top": ["1em", "1em", "2em"],
    "padding_x": ["auto", "auto", "2em"],
}

template_content_style = {
    "padding": "1em",
    "margin_bottom": "2em",
    "min_height": "90vh",
}

link_style = {
    "color": accent_text_color,
    "text_decoration": "none",
    **hover_accent_color,
}

overlapping_button_style = {
    "background_color": "white",
    "border_radius": border_radius,
}

markdown_style = {
    "code": lambda text: rx.code(text, color_scheme="gray"),
    "codeblock": lambda text, **props: rx.code_block(text, **props, margin_y="1em"),
    "a": lambda text, **props: rx.link(
        text,
        **props,
        font_weight="bold",
        text_decoration="underline",
        text_decoration_color=accent_text_color,
    ),
}

notification_badge_style = {
    "width": "1.25rem",
    "height": "1.25rem",
    "display": "flex",
    "align_items": "center",
    "justify_content": "center",
    "position": "absolute",
    "right": "-0.35rem",
    "top": "-0.35rem",
}

ghost_input_style = {
    "--text-field-selection-color": "",
    "--text-field-focus-color": "transparent",
    "--text-field-border-width": "1px",
    "background_clip": "content-box",
    "background_color": "transparent",
    "box_shadow": "inset 0 0 0 var(--text-field-border-width) transparent",
    "color": "",
}

ghost_button_style = {
    "background_color": "transparent",
    "color": "",
    "border": "none",
    "cursor": "pointer",
    "padding": "100",
    ":hover": { 
        "background_color":"rgba(255, 255, 255, 0.3)",
        ""
        "color": accent_text_color,
    },
}
box_shadow_style = "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"

color_picker_style = {
    "border_radius": "max(var(--radius-3), var(--radius-full))",
    "box_shadow": box_shadow_style,
    "cursor": "pointer",
    "display": "flex",
    "align_items": "center",
    "justify_content": "center",
    "transition": "transform 0.15s ease-in-out",
    "_active": {
        "transform": "translateY(2px) scale(0.95)",
    },
}


base_stylesheets = [
    "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap",
    "styles.css",
]

base_style = {
    "font_family": "Inter",
}

```

### disasterResAlloc/templates/__init__.py

```python
from .template import ThemeState, template

```

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