iBankAHR / app.py
ronylu's picture
Update app.py
39518cb verified
Raw
History Blame Contribute Delete
16.3 kB
import streamlit as st
import json
import datetime
import random
import pandas as pd
import plotly.express as px
import hashlib
import time
import os
# Page configuration
st.set_page_config(
page_title="iBank AHR - Banking Redefined",
page_icon="🏦",
layout="wide",
initial_sidebar_state="collapsed"
)
# Custom CSS
st.markdown("""
<style>
.main-header {
font-size: 2.5rem;
color: #E31837;
font-weight: bold;
margin-bottom: 1rem;
}
.account-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
padding: 20px;
color: white;
margin: 10px 0;
}
.quick-action {
text-align: center;
padding: 15px;
border-radius: 10px;
background-color: #f8f9fa;
border: 1px solid #dee2e6;
margin: 5px;
}
.positive {
color: #28a745;
font-weight: 600;
}
.negative {
color: #dc3545;
font-weight: 600;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if 'authenticated' not in st.session_state:
st.session_state.authenticated = False
if 'current_user' not in st.session_state:
st.session_state.current_user = None
if 'users' not in st.session_state:
st.session_state.users = {}
if 'accounts' not in st.session_state:
st.session_state.accounts = {}
if 'transactions' not in st.session_state:
st.session_state.transactions = {}
if 'page' not in st.session_state:
st.session_state.page = "dashboard"
# Initialize default data if empty
def init_default_data():
if not st.session_state.users:
st.session_state.users = {
"demo": {
"password": "5f4dcc3b5aa765d61d8327deb882cf99", # "password"
"name": "Alex Johnson",
"email": "alex.johnson@email.com",
"phone": "+1 (416) 555-0123",
"accounts": ["001-2345678", "002-3456789"]
}
}
if not st.session_state.accounts:
st.session_state.accounts = {
"001-2345678": {
"type": "Chequing",
"balance": 12543.67,
"currency": "CAD",
"nickname": "Everyday Expenses",
"transactions": ["TXN001", "TXN002", "TXN003"]
},
"002-3456789": {
"type": "Savings",
"balance": 45678.90,
"currency": "CAD",
"nickname": "Rainy Day Fund",
"transactions": ["TXN004", "TXN005"]
}
}
if not st.session_state.transactions:
st.session_state.transactions = {
"TXN001": {"id": "TXN001", "date": "2024-01-15", "description": "Grocery Store", "amount": -156.78, "account": "001-2345678"},
"TXN002": {"id": "TXN002", "date": "2024-01-14", "description": "Salary Deposit", "amount": 3500.00, "account": "001-2345678"},
"TXN003": {"id": "TXN003", "date": "2024-01-13", "description": "Online Shopping", "amount": -89.99, "account": "001-2345678"},
"TXN004": {"id": "TXN004", "date": "2024-01-12", "description": "Interest Earned", "amount": 45.67, "account": "002-3456789"},
"TXN005": {"id": "TXN005", "date": "2024-01-10", "description": "Transfer", "amount": 500.00, "account": "002-3456789"},
}
init_default_data()
# Utility functions
def hash_password(password):
return hashlib.md5(password.encode()).hexdigest()
def login(username, password):
if username in st.session_state.users and st.session_state.users[username]["password"] == hash_password(password):
st.session_state.authenticated = True
st.session_state.current_user = username
st.session_state.page = "dashboard"
return True
return False
def register(username, password, name, email):
if username in st.session_state.users:
return False, "Username already exists"
st.session_state.users[username] = {
"password": hash_password(password),
"name": name,
"email": email,
"phone": "",
"accounts": [f"001-{random.randint(1000000, 9999999)}"]
}
account_num = st.session_state.users[username]["accounts"][0]
st.session_state.accounts[account_num] = {
"type": "Chequing",
"balance": 1000.00,
"currency": "CAD",
"nickname": "Primary Account",
"transactions": []
}
return True, "Registration successful"
# Page rendering functions
def show_login():
st.markdown('<h1 class="main-header">🏦 iBank AHR</h1>', unsafe_allow_html=True)
st.markdown("**Banking Redefined β€’ Secure β€’ Fast β€’ Reliable**")
tab1, tab2 = st.tabs(["Login", "Register"])
with tab1:
st.subheader("Login to iBank AHR")
login_user = st.text_input("Username")
login_pass = st.text_input("Password", type="password")
if st.button("Login", type="primary", use_container_width=True):
if login(login_user, login_pass):
st.success("Login successful!")
time.sleep(1)
st.rerun()
else:
st.error("Invalid username or password")
st.info("**Demo:** Username: `demo` | Password: `password`")
with tab2:
st.subheader("Create New Account")
reg_user = st.text_input("Choose Username")
reg_pass = st.text_input("Choose Password", type="password")
reg_name = st.text_input("Full Name")
reg_email = st.text_input("Email")
if st.button("Register", type="secondary", use_container_width=True):
success, message = register(reg_user, reg_pass, reg_name, reg_email)
if success:
st.success(message)
time.sleep(1)
st.rerun()
else:
st.error(message)
st.markdown("---")
st.caption("πŸ”’ 256-bit Encryption β€’ 🏦 CDIC Insured β€’ πŸ‡¨πŸ‡¦ Proudly Canadian")
def show_dashboard():
user_data = st.session_state.users[st.session_state.current_user]
accounts_data = st.session_state.accounts
# Sidebar
with st.sidebar:
st.markdown(f"### Welcome, {user_data['name'].split()[0]}!")
st.caption("Member since 2023")
# Navigation
if st.button("πŸ“Š Dashboard", use_container_width=True):
st.session_state.page = "dashboard"
st.rerun()
if st.button("πŸ’° Accounts", use_container_width=True):
st.session_state.page = "accounts"
st.rerun()
if st.button("πŸ’Έ Transfer", use_container_width=True):
st.session_state.page = "transfer"
st.rerun()
if st.button("πŸ“… Pay Bills", use_container_width=True):
st.session_state.page = "bills"
st.rerun()
if st.button("πŸ“ˆ Investments", use_container_width=True):
st.session_state.page = "investments"
st.rerun()
if st.button("πŸ’³ Cards", use_container_width=True):
st.session_state.page = "cards"
st.rerun()
st.markdown("---")
if st.button("πŸšͺ Logout", use_container_width=True):
st.session_state.authenticated = False
st.session_state.current_user = None
st.session_state.page = "dashboard"
st.rerun()
# Main content
st.markdown("## πŸ“Š Dashboard Overview")
# Total balance
total_balance = sum(accounts_data[acc]["balance"] for acc in user_data["accounts"])
col1, col2, col3 = st.columns(3)
col1.metric("Total Balance", f"${total_balance:,.2f}", "+2.3%")
col2.metric("Monthly Income", "$3,850.00", "$350")
col3.metric("Monthly Expenses", "$2,145.67", "-$125")
st.markdown("---")
# Accounts
st.subheader("Your Accounts")
cols = st.columns(len(user_data["accounts"]))
for idx, acc_num in enumerate(user_data["accounts"]):
acc = accounts_data[acc_num]
with cols[idx]:
st.markdown(f"""
<div class="account-card">
<h3>{acc['nickname']}</h3>
<p style="font-size: 1.8rem;"><strong>${acc['balance']:,.2f} {acc['currency']}</strong></p>
<p>{acc_num} β€’ {acc['type']}</p>
</div>
""", unsafe_allow_html=True)
# Recent transactions
st.markdown("---")
st.subheader("Recent Transactions")
for acc_num in user_data["accounts"]:
for tx_id in accounts_data[acc_num].get("transactions", []):
if tx_id in st.session_state.transactions:
tx = st.session_state.transactions[tx_id]
amount_class = "positive" if tx["amount"] > 0 else "negative"
amount_sign = "+" if tx["amount"] > 0 else ""
col1, col2 = st.columns([3, 1])
col1.write(f"**{tx['description']}**")
col1.caption(f"{tx['date']} β€’ Account: {acc_num}")
col2.markdown(f"<span class='{amount_class}'>${amount_sign}{tx['amount']:,.2f}</span>",
unsafe_allow_html=True)
st.divider()
def show_accounts():
st.title("πŸ’° Accounts")
user_data = st.session_state.users[st.session_state.current_user]
for acc_num in user_data["accounts"]:
acc = st.session_state.accounts[acc_num]
with st.expander(f"{acc['nickname']} - ${acc['balance']:,.2f} {acc['currency']}", expanded=True):
col1, col2 = st.columns(2)
col1.metric("Account Number", acc_num)
col2.metric("Account Type", acc['type'])
col1.metric("Interest Rate", f"{acc.get('interest_rate', 0.5)}%")
col2.metric("Available Balance", f"${acc['balance']:,.2f}")
if st.button("Back to Dashboard"):
st.session_state.page = "dashboard"
st.rerun()
def show_transfer():
st.title("πŸ’Έ Transfer Funds")
user_data = st.session_state.users[st.session_state.current_user]
with st.form("transfer_form"):
col1, col2 = st.columns(2)
with col1:
from_acc = st.selectbox(
"From Account",
user_data["accounts"],
format_func=lambda x: f"{st.session_state.accounts[x]['nickname']} (${st.session_state.accounts[x]['balance']:,.2f})"
)
amount = st.number_input("Amount ($)", min_value=0.01, value=50.00)
with col2:
to_acc = st.selectbox(
"To Account",
[acc for acc in user_data["accounts"] if acc != from_acc]
)
memo = st.text_input("Memo", "Transfer")
if st.form_submit_button("Transfer Now", type="primary"):
if amount <= st.session_state.accounts[from_acc]["balance"]:
# Update balances
st.session_state.accounts[from_acc]["balance"] -= amount
st.session_state.accounts[to_acc]["balance"] += amount
# Create transaction records
tx_id_out = f"TXN{random.randint(100000, 999999)}"
tx_id_in = f"TXN{random.randint(100000, 999999)}"
st.session_state.transactions[tx_id_out] = {
"id": tx_id_out,
"date": datetime.datetime.now().strftime("%Y-%m-%d"),
"description": f"Transfer to {st.session_state.accounts[to_acc]['nickname']}",
"amount": -amount,
"account": from_acc
}
st.session_state.transactions[tx_id_in] = {
"id": tx_id_in,
"date": datetime.datetime.now().strftime("%Y-%m-%d"),
"description": f"Transfer from {st.session_state.accounts[from_acc]['nickname']}",
"amount": amount,
"account": to_acc
}
st.session_state.accounts[from_acc]["transactions"].append(tx_id_out)
st.session_state.accounts[to_acc]["transactions"].append(tx_id_in)
st.success(f"βœ… Transfer of ${amount:,.2f} completed!")
st.balloons()
else:
st.error("Insufficient funds!")
if st.button("Back to Dashboard"):
st.session_state.page = "dashboard"
st.rerun()
def show_bills():
st.title("πŸ“… Pay Bills")
billers = {
"Hydro One": 125.67,
"Bell Canada": 89.99,
"Toronto Water": 45.50,
"Property Tax": 320.00,
"Credit Card": 450.00
}
selected_biller = st.selectbox("Select Biller", list(billers.keys()))
col1, col2 = st.columns(2)
col1.metric("Biller", selected_biller)
col2.metric("Amount Due", f"${billers[selected_biller]:,.2f}")
if st.button("Pay Now", type="primary", use_container_width=True):
st.success(f"βœ… Payment of ${billers[selected_biller]:,.2f} to {selected_biller} scheduled!")
st.markdown("---")
st.subheader("Upcoming Bills")
for biller, amount in billers.items():
col1, col2, col3 = st.columns([2, 1, 1])
col1.write(f"**{biller}**")
col2.write(f"${amount:,.2f}")
col3.button("Pay", key=f"pay_{biller}")
if st.button("Back to Dashboard"):
st.session_state.page = "dashboard"
st.rerun()
def show_investments():
st.title("πŸ“ˆ Investments")
investments = {
"RRSP": {"value": 24500.00, "change": "+3.2%"},
"TFSA": {"value": 18750.00, "change": "+1.8%"},
"Stocks": {"value": 32500.00, "change": "-0.5%"},
"Mutual Funds": {"value": 15600.00, "change": "+2.1%"}
}
total_value = sum(inv["value"] for inv in investments.values())
st.metric("Total Portfolio Value", f"${total_value:,.2f}", "+1.65%")
st.markdown("---")
for name, data in investments.items():
col1, col2, col3 = st.columns([2, 1, 1])
col1.write(f"**{name}**")
col2.write(f"${data['value']:,.2f}")
col3.write(data['change'])
st.markdown("---")
st.subheader("Quick Actions")
col1, col2 = st.columns(2)
col1.button("Buy", use_container_width=True)
col2.button("Sell", use_container_width=True)
if st.button("Back to Dashboard"):
st.session_state.page = "dashboard"
st.rerun()
def show_cards():
st.title("πŸ’³ Card Management")
cards = [
{"type": "Visa Platinum", "number": "**** 4832", "balance": 1250.00, "status": "Active"},
{"type": "Mastercard Gold", "number": "**** 5917", "balance": 500.00, "status": "Active"},
{"type": "Debit Card", "number": "**** 3268", "balance": "N/A", "status": "Active"}
]
for card in cards:
with st.expander(f"{card['type']} ({card['number']}) - {card['status']}"):
col1, col2, col3 = st.columns(3)
col1.metric("Type", card['type'])
col2.metric("Status", card['status'])
col3.metric("Balance", f"${card['balance']}" if isinstance(card['balance'], (int, float)) else card['balance'])
col1, col2 = st.columns(2)
col1.button("Lock Card", key=f"lock_{card['number']}")
col2.button("Report Lost", key=f"lost_{card['number']}")
if st.button("Back to Dashboard"):
st.session_state.page = "dashboard"
st.rerun()
# Main app router
def main():
if not st.session_state.authenticated:
show_login()
else:
if st.session_state.page == "dashboard":
show_dashboard()
elif st.session_state.page == "accounts":
show_accounts()
elif st.session_state.page == "transfer":
show_transfer()
elif st.session_state.page == "bills":
show_bills()
elif st.session_state.page == "investments":
show_investments()
elif st.session_state.page == "cards":
show_cards()
if __name__ == "__main__":
main()