Spaces:
Sleeping
Sleeping
File size: 6,527 Bytes
737dc7a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | import streamlit as st
import firebase_admin
from firebase_admin import credentials, auth, db
import pandas as pd
import plotly.express as px
from datetime import datetime
# Initialize Firebase
try:
if not firebase_admin._apps:
cred = credentials.Certificate("serviceAccountKey.json")
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://transacapp-22b6e-default-rtdb.firebaseio.com/'
})
except Exception as e:
st.error(f"Error initializing Firebase: {str(e)}")
st.stop()
def login():
st.title("π Financial Dashboard Login")
with st.form("login_form"):
email = st.text_input("Email")
password = st.text_input("Password", type="password")
submit_button = st.form_submit_button("Login")
if submit_button:
try:
user = auth.get_user_by_email(email)
st.session_state['user'] = user
st.success("Logged in successfully!")
st.experimental_rerun()
except Exception as e:
st.error("Invalid credentials. Please try again.")
return submit_button
return False
def get_user_transactions(uid):
try:
transactions = []
# Get all financial messages for the user
ref = db.reference(f'financialMessages/{uid}')
financial_data = ref.get()
if financial_data:
for month, month_data in financial_data.items():
if isinstance(month_data, dict):
for trans_id, trans_data in month_data.items():
if isinstance(trans_data, dict):
trans_data['month'] = month
# Convert amount to float if it's a string
if 'amount' in trans_data:
try:
trans_data['amount'] = float(str(trans_data['amount']).replace(',', ''))
except ValueError:
trans_data['amount'] = 0.0
transactions.append(trans_data)
df = pd.DataFrame(transactions)
return df if not df.empty else pd.DataFrame(columns=[
'accountNumber', 'amount', 'personName', 'referenceNo',
'transactionDate', 'transactionType', 'month'
])
except Exception as e:
st.error(f"Error fetching transactions: {str(e)}")
return pd.DataFrame()
def main():
st.set_page_config(page_title="Financial Dashboard", page_icon="π°", layout="wide")
if 'user' not in st.session_state:
if not login():
return
st.title("π° Financial Dashboard")
# Add logout button
# Add logout button
if st.sidebar.button("Logout"):
st.session_state.pop('user', None)
st.rerun() # Updated line
# Get user data
user = st.session_state['user']
df = get_user_transactions(user.uid)
if df.empty:
st.warning("No transactions found for this account.")
return
# Date filters
st.sidebar.header("π
Filters")
months = sorted(df['month'].unique())
selected_months = st.sidebar.multiselect("Select Months", months, default=months)
# Transaction type filter
transaction_types = sorted(df['transactionType'].unique())
selected_types = st.sidebar.multiselect("Transaction Types", transaction_types, default=transaction_types)
# Filter data
filtered_df = df[
(df['month'].isin(selected_months)) &
(df['transactionType'].isin(selected_types))
]
# Dashboard layout
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Transactions", len(filtered_df))
with col2:
debited = filtered_df[filtered_df['transactionType'] == 'debited']['amount'].sum()
credited = filtered_df[filtered_df['transactionType'] == 'credited']['amount'].sum()
net_amount = credited - debited
st.metric("Net Amount", f"βΉ{net_amount:,.2f}")
with col3:
avg_amount = filtered_df['amount'].mean()
st.metric("Average Transaction", f"βΉ{avg_amount:,.2f}")
# Visualizations
st.subheader("π Transaction Analysis")
# Create two columns for charts
chart_col1, chart_col2 = st.columns(2)
with chart_col1:
# Monthly transaction summary
monthly_summary = filtered_df.groupby(['month', 'transactionType']).agg({
'amount': 'sum'
}).reset_index()
fig1 = px.bar(monthly_summary, x='month', y='amount', color='transactionType',
title='Monthly Transaction Volume by Type',
labels={'amount': 'Amount (βΉ)', 'month': 'Month'},
barmode='group')
st.plotly_chart(fig1, use_container_width=True)
with chart_col2:
# Transaction type distribution
fig2 = px.pie(filtered_df, values='amount', names='transactionType',
title='Transaction Amount Distribution by Type')
st.plotly_chart(fig2, use_container_width=True)
# Transaction Trends
fig3 = px.line(monthly_summary, x='month', y='amount', color='transactionType',
title='Transaction Trends Over Time',
labels={'amount': 'Amount (βΉ)', 'month': 'Month'})
st.plotly_chart(fig3, use_container_width=True)
# Detailed transaction table
st.subheader("π Recent Transactions")
# Format the dataframe for display
display_df = filtered_df.copy()
display_df['amount'] = display_df['amount'].apply(lambda x: f"βΉ{x:,.2f}")
display_df = display_df.sort_values('transactionDate', ascending=False)
# Display as a styled dataframe
st.dataframe(
display_df,
column_config={
"transactionDate": "Date",
"transactionType": "Type",
"amount": "Amount",
"personName": "Person",
"referenceNo": "Reference",
"accountNumber": "Account"
},
hide_index=True
)
# Add download button for CSV
if st.button("Download Transaction Data"):
csv = filtered_df.to_csv(index=False)
st.download_button(
label="Download CSV",
data=csv,
file_name="transactions.csv",
mime="text/csv"
)
if __name__ == "__main__":
main() |