1- import streamlit as st
2- import requests
3- from datetime import datetime
41import json
2+ from datetime import datetime
3+
4+ import requests
5+ import streamlit as st
56from streamlit_cookies_manager import EncryptedCookieManager
67
78# Configure the page
89st .set_page_config (
910 page_title = "Splitwiser" ,
1011 page_icon = "💰" ,
1112 layout = "wide" ,
12- initial_sidebar_state = "expanded"
13+ initial_sidebar_state = "expanded" ,
1314)
1415
1516# Initialize session state variables
2425API_URL = "https://splitwiser-production.up.railway.app"
2526
2627cookies = EncryptedCookieManager (
27- prefix = "splitwiser_" ,
28- password = "your_super_secret_key" #note for prod: store this in a env file.
28+ prefix = "splitwiser_" ,
29+ # note for prod: store this in a env file.
30+ password = "your_super_secret_key" ,
2931)
3032if not cookies .ready ():
3133 st .stop ()
3234
35+
3336def login (email , password ):
3437 """Login user and store access token in session state"""
3538 try :
3639 response = requests .post (
37- f"{ API_URL } /auth/login/email" ,
38- json = {"email" : email , "password" : password }
40+ f"{ API_URL } /auth/login/email" , json = {"email" : email , "password" : password }
3941 )
4042 if response .status_code == 200 :
4143 data = response .json ()
4244 st .session_state .access_token = data .get ("access_token" )
4345 # Update user_id from the response format
4446 user_data = data .get ("user" , {})
45- st .session_state .user_id = user_data .get ("_id" ) # Changed from user_id to _id
46- st .session_state .username = user_data .get ("name" ) # Changed from username to name
47-
47+ st .session_state .user_id = user_data .get (
48+ "_id"
49+ ) # Changed from user_id to _id
50+ st .session_state .username = user_data .get (
51+ "name"
52+ ) # Changed from username to name
53+
4854 cookies ["access_token" ] = data .get ("access_token" )
4955 cookies ["user_id" ] = user_data .get ("_id" )
5056 cookies ["username" ] = user_data .get ("name" )
5157 cookies .save ()
52-
58+
5359 return True , "Login successful!"
5460 else :
55- return False , f"Login failed: { response .json ().get ('detail' , 'Unknown error' )} "
61+ return (
62+ False ,
63+ f"Login failed: { response .json ().get ('detail' , 'Unknown error' )} " ,
64+ )
5665 except Exception as e :
5766 return False , f"Error: { str (e )} "
5867
68+
5969def signup (username , email , password ):
6070 """Register a new user"""
6171 try :
6272 response = requests .post (
6373 f"{ API_URL } /auth/signup/email" ,
64- json = {"name" : username , "email" : email , "password" : password }
74+ json = {"name" : username , "email" : email , "password" : password },
6575 )
6676 if response .status_code == 200 :
6777 return True , "Registration successful! Please login."
6878 else :
69- return False , f"Registration failed: { response .json ().get ('detail' , 'Unknown error' )} "
79+ return (
80+ False ,
81+ f"Registration failed: { response .json ().get ('detail' , 'Unknown error' )} " ,
82+ )
7083 except Exception as e :
7184 return False , f"Error: { str (e )} "
7285
86+
7387def logout ():
7488 """Clear session state and log out user"""
7589 # Clear session state keys by deleting them
@@ -79,14 +93,15 @@ def logout():
7993 del st .session_state [key ]
8094 cookies [key ] = ""
8195 cookies .save ()
82-
96+
8397 st .rerun ()
8498
99+
85100def check_cookies ():
86101 access_token = cookies .get ("access_token" )
87102 user_id = cookies .get ("user_id" )
88103 username = cookies .get ("username" )
89-
104+
90105 if access_token == "" or not access_token :
91106 st .session_state .access_token = None
92107 st .session_state .user_id = None
@@ -96,41 +111,43 @@ def check_cookies():
96111 st .session_state .user_id = user_id
97112 st .session_state .username = username
98113 return True
99-
100-
114+
115+
101116# Main app
102117def main ():
103118 # Sidebar for app navigation
104119 cookie_check = False
105120 with st .sidebar :
106121 st .title ("Splitwiser 💰" )
107-
108- if cookie_check := check_cookies ():
122+
123+ if cookie_check := check_cookies ():
109124 st .success (f"Logged in as { st .session_state .username } " )
110125 if st .button ("Logout" , key = "logout_btn" ):
111126 logout ()
112-
127+
113128 # Main content
114129 if not cookie_check :
115130 display_auth_page ()
116131 else :
117132 display_main_app ()
118133
134+
119135def display_auth_page ():
120136 """Display login/signup interface"""
121137 st .title ("Welcome to Splitwiser" )
122138 st .write ("Track and split expenses with friends and groups" )
123-
139+
124140 # Create tabs for login and signup
125141 login_tab , signup_tab = st .tabs (["Login" , "Sign Up" ])
126-
142+
127143 # Login tab
128144 with login_tab :
129145 with st .form ("login_form" , clear_on_submit = False ):
130146 email = st .text_input ("Email" , key = "login_email" )
131- password = st .text_input ("Password" , type = "password" , key = "login_password" )
147+ password = st .text_input (
148+ "Password" , type = "password" , key = "login_password" )
132149 submit_button = st .form_submit_button ("Login" )
133-
150+
134151 if submit_button :
135152 if email and password :
136153 success , message = login (email , password )
@@ -141,16 +158,19 @@ def display_auth_page():
141158 st .error (message )
142159 else :
143160 st .warning ("Please fill in all fields" )
144-
161+
145162 # Sign up tab
146163 with signup_tab :
147164 with st .form ("signup_form" , clear_on_submit = True ):
148165 username = st .text_input ("Username" , key = "signup_username" )
149166 email = st .text_input ("Email" , key = "signup_email" )
150- password = st .text_input ("Password" , type = "password" , key = "signup_password" )
151- confirm_password = st .text_input ("Confirm Password" , type = "password" , key = "signup_confirm_password" )
167+ password = st .text_input (
168+ "Password" , type = "password" , key = "signup_password" )
169+ confirm_password = st .text_input (
170+ "Confirm Password" , type = "password" , key = "signup_confirm_password"
171+ )
152172 submit_button = st .form_submit_button ("Sign Up" )
153-
173+
154174 if submit_button :
155175 if username and email and password and confirm_password :
156176 if password != confirm_password :
@@ -164,72 +184,82 @@ def display_auth_page():
164184 else :
165185 st .warning ("Please fill in all fields" )
166186
187+
167188def display_main_app ():
168189 """Display the main application after login"""
169190 st .title ("Splitwiser Dashboard" )
170-
191+
171192 # Welcome message and quick stats
172193 st .write (f"Welcome back, { st .session_state .username } ! 👋" )
173-
194+
174195 # Quick actions section
175196 st .header ("Quick Actions" )
176197 col1 , col2 , col3 = st .columns (3 )
177-
198+
178199 with col1 :
179200 if st .button ("📱 View Groups" , use_container_width = True ):
180201 st .switch_page ("pages/Groups.py" )
181-
202+
182203 with col2 :
183204 if st .button ("👥 Manage Friends" , use_container_width = True ):
184205 st .switch_page ("pages/Friends.py" )
185-
206+
186207 with col3 :
187208 if st .button ("📊 View Analytics" , use_container_width = True ):
188209 st .info ("Analytics page coming soon!" )
189-
210+
190211 # Recent activity section
191212 st .header ("Recent Activity" )
192-
213+
193214 # Show recent groups and expenses summary
194215 try :
195216 headers = {"Authorization" : f"Bearer { st .session_state .access_token } " }
196217 response = requests .get (f"{ API_URL } /groups" , headers = headers )
197-
218+
198219 if response .status_code == 200 :
199220 data = response .json ()
200- groups = data .get (' groups' , [])
201-
221+ groups = data .get (" groups" , [])
222+
202223 if groups :
203224 st .subheader ("Your Groups" )
204225 for group in groups [:3 ]: # Show only first 3 groups
205226 with st .container ():
206227 col1 , col2 = st .columns ([3 , 1 ])
207228 with col1 :
208- st .write (f"**{ group .get ('name' , 'Unnamed Group' )} **" )
209- st .caption (f"Group Code: { group .get ('joinCode' , 'N/A' )} " )
229+ st .write (
230+ f"**{ group .get ('name' , 'Unnamed Group' )} **" )
231+ st .caption (
232+ f"Group Code: { group .get ('joinCode' , 'N/A' )} " )
210233 with col2 :
211- if st .button ("View" , key = f"view_group_home_{ group .get ('_id' )} " ):
234+ if st .button (
235+ "View" , key = f"view_group_home_{ group .get ('_id' )} "
236+ ):
212237 st .switch_page ("pages/Groups.py" )
213-
238+
214239 if len (groups ) > 3 :
215240 st .caption (f"And { len (groups ) - 3 } more groups..." )
216241 else :
217- st .info ("You haven't joined any groups yet. Create or join a group to get started!" )
242+ st .info (
243+ "You haven't joined any groups yet. Create or join a group to get started!"
244+ )
218245 if st .button ("Get Started - Create a Group" ):
219246 st .switch_page ("pages/Groups.py" )
220247 else :
221248 st .error ("Failed to fetch your recent activity." )
222249 except Exception as e :
223250 st .error (f"Error loading dashboard: { str (e )} " )
224-
251+
225252 # Quick tips section
226253 with st .expander ("💡 Tips for Getting Started" ):
227- st .markdown ("""
254+ st .markdown (
255+ """
228256 - **Create a Group**: Start by creating a group for your household, trips, or shared activities
229257 - **Invite Friends**: Share the group code with friends to start splitting expenses
230258 - **Add Expenses**: Record expenses and automatically split them among group members
231259 - **Track Balances**: See who owes what and settle up easily
232- """ )
260+ """
261+ )
262+
233263
234264# Legacy group functionality (moved to Groups page)
235265def legacy_groups_section ():
0 commit comments