import streamlit as st import firebase_admin from firebase_admin import credentials, auth, db import pandas as pd import plotly.express as px # 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.rerun() # Use st.rerun() instead of 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 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 with "All" option transaction_types = sorted(df['transactionType'].unique()) transaction_types.insert(0, "All") # Add "All" option at the beginning selected_types = st.sidebar.multiselect("Transaction Types", transaction_types, default=transaction_types[1:]) # Filter DataFrame to only include selected months filtered_by_month_df = df[df['month'].isin(selected_months)] # Date filter based on the filtered DataFrame filtered_by_month_df['transactionDate'] = pd.to_datetime(filtered_by_month_df['transactionDate']) # Ensure transactionDate is in datetime format dates = filtered_by_month_df['transactionDate'].dt.date.unique() # Get unique dates from filtered data selected_dates = st.sidebar.multiselect("Select Dates", options=dates, default=dates) # Final data filtering based on selected months, types, and dates if "All" in selected_types: filtered_df = filtered_by_month_df[ filtered_by_month_df['transactionDate'].dt.date.isin(selected_dates) ] else: filtered_df = filtered_by_month_df[ (filtered_by_month_df['transactionType'].isin(selected_types)) & (filtered_by_month_df['transactionDate'].dt.date.isin(selected_dates)) ] # 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()