import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import easyocr
import cv2
import datetime
import os
import speech_recognition as sr
from PIL import Image
from groq import Groq
from dotenv import load_dotenv
import json
import os
RECEIPT_FOLDER = "receipts"
os.makedirs(RECEIPT_FOLDER, exist_ok=True)
DATA_FILE = "data.json"
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r") as f:
return json.load(f)
else:
return {"receipts": [], "budgets": {}}
def save_data():
with open(DATA_FILE, "w") as f:
json.dump(data, f, indent=4)
# β
This loads your existing data or creates a new one
data = load_data()
# Load environment variables
load_dotenv()
# Initialize Groq client
client = Groq(api_key=os.getenv("smartspender"))
# App Configuration
st.set_page_config(page_title="SmartSpender πΈ", layout="wide")
# Display App Logo (Centered)
st.markdown("
", unsafe_allow_html=True)
st.image("logo.png.png", width=150)
st.markdown("
", unsafe_allow_html=True)
st.markdown("""
""", unsafe_allow_html=True)
# Session State Defaults
if "expenses" not in st.session_state:
st.session_state.expenses = []
if "budget" not in st.session_state:
st.session_state.budget = 50000
if "total_spent" not in st.session_state:
st.session_state.total_spent = 0
if "reminders" not in st.session_state:
st.session_state.reminders = []
# Navigation Panel
menu = st.sidebar.radio("πΈ Navigation", [
"π Dashboard",
"π₯ Expense Entry",
"π― Budget",
"π° Savings",
"π¨ Budget Alerts",
"π Goals",
"π± Currency Converter",
"π Upload Receipt",
"π Reminders",
"π₯ Guac AI Chatbot"
], key="navigation_menu")
# Dashboard
if menu == "π Dashboard":
st.title("π SmartSpender Dashboard")
st.metric("πΈ Total Spent", f"Rs. {st.session_state.total_spent:,.2f}")
st.metric("π― Budget", f"Rs. {st.session_state.budget:,.2f}")
auto_savings = st.session_state.budget - st.session_state.total_spent
st.metric("π° Savings", f"Rs. {auto_savings:,.2f}")
# Pie chart
labels = ['Spent', 'Remaining']
values = [st.session_state.total_spent, auto_savings]
fig, ax = plt.subplots()
ax.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)
ax.axis('equal')
st.pyplot(fig)
# Expense Entry (Voice + Manual)
if menu == "π₯ Expense Entry":
st.title("π₯ Expense Entry")
method = st.radio("Choose input method:", ["Manual", "Voice"])
if method == "Manual":
category = st.text_input("Category")
amount = st.number_input("Amount (Rs.)", min_value=0.0, step=100.0)
if st.button("Add Expense"):
st.session_state.expenses.append((category, amount))
st.session_state.total_spent += amount
st.success(f"Added Rs. {amount} to {category}!")
else:
st.info("Click below and speak your expense like 'Grocery 500'")
if st.button("ποΈ Record Expense"):
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source)
try:
text = r.recognize_google(audio)
st.write(f"You said: {text}")
parts = text.split()
category = parts[0]
amount = float(parts[1])
st.session_state.expenses.append((category, amount))
st.session_state.total_spent += amount
st.success(f"Added Rs. {amount} to {category}!")
except Exception as e:
st.error(f"Error: {str(e)}")
# Budget Setting
if menu == "π― Budget":
st.title("π― Set Your Monthly Budget")
st.session_state.budget = st.number_input(
"Monthly Budget (Rs.)",
min_value=0.0,
step=100.0,
value=float(st.session_state.budget)
)
st.success(f"Your monthly budget is set to Rs. {st.session_state.budget:,.2f}")
# Savings Section
if menu == "π° Savings":
st.title("π° Your Savings")
auto_savings = st.session_state.budget - st.session_state.total_spent
manual_savings = st.number_input("Enter additional manual savings (optional)", min_value=0.0, step=100.0)
total_savings = auto_savings + manual_savings
st.success(f"πΈ Total Savings: Rs. {total_savings:,.2f}")
# Budget Alerts
if menu == "π¨ Budget Alerts":
st.title("π¨ Budget Alerts")
spent_ratio = st.session_state.total_spent / st.session_state.budget
if spent_ratio >= 0.8:
st.error("Youβve spent over 80% of your budget! Slow down π’")
else:
st.success("Youβre within your budget π")
# Goals with Medals
if menu == "π Goals":
st.title("π Savings Goals")
goal = st.number_input("Set a savings goal:", min_value=0.0, step=100.0)
current_savings = st.session_state.budget - st.session_state.total_spent
if current_savings >= goal:
if current_savings >= goal * 3:
st.balloons()
st.success("ποΈ GOLD Medal Earned!")
elif current_savings >= goal * 2:
st.success("π₯ SILVER Medal Earned!")
else:
st.success("π₯ BRONZE Medal Earned!")
else:
st.info("Keep going! You're on your way to a medal β¨")
# Currency Converter
if menu == "π± Currency Converter":
st.title("π± Currency Converter")
amount = st.number_input("Amount (Rs.)", min_value=0.0)
currency = st.selectbox("Convert to:", ["USD", "EUR", "SAR", "AED"])
rates = {"USD": 0.0036, "EUR": 0.0033, "SAR": 0.0135, "AED": 0.0132}
converted = amount * rates[currency]
st.success(f"{amount} PKR = {converted:.2f} {currency}")
# Upload Receipt
if menu == "π Upload Receipt":
st.header("π§Ύ Upload & View Receipts")
uploaded_receipt = st.file_uploader("Upload your receipt", type=["png", "jpg", "jpeg"])
if uploaded_receipt is not None:
if not os.path.exists(RECEIPT_FOLDER):
os.makedirs(RECEIPT_FOLDER)
filename = f"{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}_{uploaded_receipt.name}"
filepath = os.path.join(RECEIPT_FOLDER, filename)
img = Image.open(uploaded_receipt)
img.save(filepath)
data["receipts"].append({"image": filepath, "date": str(datetime.date.today())})
def save_data(data):
with open("data.json", "w") as f:
json.dump(data, f, indent=4)
save_data(data)
st.success("Receipt uploaded and saved!")
st.subheader("Saved Receipts")
if data["receipts"]:
cols = st.columns(3)
for idx, r in enumerate(data["receipts"]):
if os.path.exists(r["image"]):
with cols[idx % 3]:
st.image(r["image"], width=200)
st.caption(f"{r['date']}")
else:
st.info("No receipts uploaded yet.")
# Reminders
if menu == "π Reminders":
st.title("π Bill/Subscription Reminders")
reminder = st.text_input("Add Reminder")
if st.button("Add Reminder"):
st.session_state.reminders.append(reminder)
if st.session_state.reminders:
st.markdown("### π Your Reminders:")
for r in st.session_state.reminders:
st.write(f"π {r}")
# Guac AI Chatbot
if menu == "π₯ Guac AI Chatbot":
st.title("π₯ Guac AI Chatbot")
user_prompt = st.chat_input("Ask me anything about budgeting π¬")
if user_prompt:
try:
response = client.chat.completions.create(
model="llama3-70b-8192",
messages=[
{"role": "system", "content": "You are Guac AIπ₯, a smart, cute, fun financial assistant."},
{"role": "user", "content": user_prompt}
]
)
st.chat_message("Guac AIπ₯").write(response.choices[0].message.content)
except Exception as e:
st.error(f"Chatbot error: {str(e)}")
# Footer
st.markdown("""
---
π‘ One-stop app for budgeting, saving & tracking
π Reminders for bills & subscriptions
π Auto detects overspending & trends
π Savings goals with reward badges
π· Upload & store receipts in one place
π Built-in currency converter
π₯ Guac AI for smart finance tips
""")