Login Form Issue – Dashboard Loads After First Click, But Login Form Still Visible

Hey everyone,

I’m facing an issue with my login form. Here’s what’s happening:

  1. I created a login form and the authentication seems to work fine.
  2. After successfully logging in, the dashboard page loads.
  3. However, the login form still remains visible on the page after login.
  4. If I click the login button again, the page behaves as expected – the login form disappears, and the dashboard shows up properly.

I’m not sure where the issue is. I’ve checked the logic and event handling, but I can’t figure out why the login form doesn’t hide immediately after a successful login.

Has anyone experienced this issue or have suggestions on how to fix it?

Thanks in advance for your help!

there is my code main file code `import streamlit as st
from login import Login
from dashboard import Dashboard
import database

def main():
# Initialize the session state for page tracking if not already set
if ‘page’ not in st.session_state:
st.session_state.page = ‘login’ # Set default page to ‘login’

# Check if the user is logged in
if 'user' in st.session_state and st.session_state.user:
    # User is logged in, show the dashboard
    if st.session_state.page == 'dashboard':
        db = database.Database()  # Initialize the database
        Dashboard(db)  # Show dashboard with the database connection
    else:
        # If we are not on the dashboard page, redirect to dashboard
        st.session_state.page = 'dashboard'
        db = database.Database()
        Dashboard(db)
else:
    # User is not logged in, show the login page
    if st.session_state.page == 'login':
        Login()  # Show login page
    else:
        # If we are not on the login page, redirect to login
        st.session_state.page = 'login'
        Login()  # Show login page

if name == “main”:
main()
login codeimport bcrypt
import streamlit as st
from datetime import datetime, timedelta
import pymysql
from streamlit_cookies_controller import CookieController
from dashboard import Dashboard
import database

Initialize the cookie controller

controller = CookieController()

class Login:
def init(self):
self.db = database.Database() # Instantiate the Database class
self.db.connect() # Connect to the database
self.controller = controller
self.handle_login_flow() # Manage login flow

def hash_password(self, password):
    """Hash the password using bcrypt"""
    salt = bcrypt.gensalt()  # Generate salt
    hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed_password.decode('utf-8')  # Store it as a string

def authenticate_user(self, email, password):
    """Authenticate user based on email and password"""
    query = "SELECT id, name, email, password FROM users WHERE email = %s"
    user = self.db.fetch_data(query, (email,))

    if user:
        hashed_password = user[0][3]  # Stored hashed password
        if bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8')):
            return user[0]  # Return the user data if the password matches
    return None  # Return None if no user is found or password doesn't match

def create_session(self, user, email):
    """Create a session for the user"""
    session_token = str(hash(email + str(datetime.now())))
    st.session_state.user = user  # Store user info in session state
    st.session_state.session_token = session_token  # Store session token in session state
    st.session_state.login_time = datetime.now()  # Store login time
    st.session_state.expiration_time = datetime.now() + timedelta(hours=6)  # Session expiration (6 hours)
    st.session_state.is_logged_in = True  # Set the user as logged in

    # Store session token and user info in cookies
    self.controller.set("session_token", session_token,
                        expires=datetime.now() + timedelta(hours=6))  # Set session_token cookie
    self.controller.set("user", str(user), expires=datetime.now() + timedelta(hours=6))  # Set user cookie

    return session_token  # Return session token for tracking

def check_login(self):
    """Check if the user is already logged in by verifying session token"""
    session_token = self.controller.get("session_token")  # Get session token from cookies

    # Check if session token is found and not expired
    if session_token:
        # Check if session_token matches the one in session_state and if the session is not expired
        if 'session_token' in st.session_state and 'user' in st.session_state:
            if st.session_state.session_token == session_token and \
                    st.session_state.expiration_time > datetime.now():  # Check if session is expired
                st.session_state.is_logged_in = True
                return True  # User is logged in and the session is valid
    st.session_state.is_logged_in = False
    return False  # Return False if session is not found or expired

def handle_login_flow(self):
    """Handle login flow: if logged in, show the dashboard, else show the login form"""
    if 'page' not in st.session_state:
        st.session_state.page = 'login'  # Default page is login

    # Check if user is already logged in, if so show dashboard
    if self.check_login():
        st.session_state.page = 'dashboard'  # Set the page to 'dashboard'
        self.display_dashboard()  # If already logged in, show the dashboard
    else:
        self.display_login_page()  # Show the login page if not logged in

def display_dashboard(self):
    """Display the dashboard content after successful login"""
    st.session_state.page = 'dashboard'  # Set the page to 'dashboard'
    Dashboard(self.db)  # Assuming you have a Dashboard class to handle the page view

def display_login_page(self):
    """Display login page and handle login logic"""
    # Add custom styles to override Streamlit's internal styles
    st.markdown(""" 
        <style>
        .st-emotion-cache-13ln4jf {
            width: 70% !important;
            max-width: none !important;
            padding: 6rem 3rem 10rem !important;
        }
        .indent {
            text-indent: 30px;  /* Adds indentation to content */
        }
        .logo-header {
            display: flex;
            align-items: flex-end;
            justify-content: flex-end;
            gap: 20px;
            text-align: center;
        }
        .logo-header h1 {
            color: #772782;
            font-size: 48px;
            margin: 0;  /* Removes default margin from h1 */
        }
        .logo-header img {
            width: 50px; /* Adjust logo size */
            height: auto;
        }
        </style>
    """, unsafe_allow_html=True)

    # Create a full-width layout for the page
    col1, col2 = st.columns([3, 1.5])  # Adjusted column ratio to make the login form wider

    with col1:
        # Create the HTML layout with logo and header on the same row
        # st.markdown("""
        #     <div style="display: flex; align-items: center; justify-content: flex-start; gap: 20px;">
        #         <img src="data:image/png;base64,{}" width="250" height="auto" alt="Logo">
        #         <h1 style="color: #772782; font-size: 28px; margin: 0;">Welcome to Purple Finance</h1>
        #     </div>
        # """.format(self.get_logo_base64()), unsafe_allow_html=True)

        # Indented content below the logo and header
        st.markdown(""" 
            <p class="indent" style='font-size: 20px; text-align: justify; padding: 30px;'>  
            
            </p>
        """, unsafe_allow_html=True)

    with col2:
        # Add a decorative box around the login form to make it stand out
        st.markdown("<div style='background-color: #f1f1f1; padding: 0px; border-radius: 15px;'>",
                    unsafe_allow_html=True)

        placeholder = st.empty()
        with placeholder.form("login"):
            # Stylish header for login form
            st.markdown("<h2 style='text-align: center; color: #772782;'>Login</h2>", unsafe_allow_html=True)

            # Input fields with placeholders for user experience
            email = st.text_input("Email", key='email_input', placeholder="Enter your email address", max_chars=50)
            password = st.text_input('Password', type='password', key='password_input',
                                     placeholder="Enter your password", max_chars=50)

            # Add hover effect to the submit button
            submit_button = st.form_submit_button(label="Login", use_container_width=True)

            # Adding a hover effect for the login button
            st.markdown(""" 
                <style>
                .stButton>button {
                    background-color: #772782;
                    color: white;
                    border-radius: 8px;
                    height: 45px;
                    font-size: 18px;
                    width: 100%;
                }
                .stButton>button:hover {
                    background-color: #5d2268;
                    transition: background-color 0.3s ease;
                }
                </style>
            """, unsafe_allow_html=True)

            # Handling user authentication logic
            if submit_button:  # Check if the submit button was pressed
                if email and password:
                    user = self.authenticate_user(email, password)

                    if user:
                        # Authenticate user
                        self.create_session(user, email)
                        st.success('Login Successful!')
                        self.display_dashboard()  # Display dashboard after login
                    else:
                        st.error("Invalid email or password")
                else:
                    st.error('Please enter both email and password.')

        st.markdown("</div>", unsafe_allow_html=True)  # Close the div tag

def get_logo_base64(self):
    """Returns the base64 encoded version of the logo image"""
    import base64
    with open("Purple-Finance-Arrow-logo.png", "rb") as logo_file:
        return base64.b64encode(logo_file.read()).decode('utf-8')

dashboard codeimport streamlit as st
from datetime import datetime
from user import User
from role import Role
from role_Permission import RolePermission
from Report_Management import Report
from report import ReportManager
class Dashboard:
def init(self, db):
“”“Initialize with a database connection.”“”
self.db = db
self.db.connect()
self.user = User(self.db)
self.role = Role(self.db)
self.report = Report(self.db)
self.report_manager = ReportManager(self.db)
self.role_permission = RolePermission(self.db)
self.show_dashboard()

def add_sidebar_blur(self):
    """Apply the blur effect only to the sidebar background."""
    st.markdown("""
        <style>
            /* Apply blur effect to the sidebar background */
            .css-1v3fvcr {  /* This class targets the entire sidebar container */
                backdrop-filter: blur(10px);  /* Apply the blur effect */
                background-color: rgba(255, 255, 255, 0.6);  /* Optional: Semi-transparent background */
            }

            /* Ensure the sidebar content (text, widgets) is not blurred */
            .css-1v3fvcr .stSidebar {
                z-index: 10;
                position: relative;
                color: black;
            }

            /* Optional: Add padding or styling to make the sidebar look cleaner */
            .css-1v3fvcr .stSidebar .stText {
                padding: 10px;
            }

            /* Ensure proper margins and layout */
            .stSidebar {
                margin-top: 100px;  /* Adjust for fixed header */
            }

            /* Sidebar links (widgets) should stay visible */
            .stSidebar .stRadio {
                padding: 15px;
            }

            /* Adjust for mobile responsiveness */
            @media (max-width: 800px) {
                .css-1v3fvcr {
                    backdrop-filter: none;  /* Disable blur on small screens */
                    background-color: transparent;  /* Make the sidebar background fully transparent */
                }
            }
        </style>
    """, unsafe_allow_html=True)

def display_user_details(self, current_module):
    """Display the logged-in user's details and current module at the header."""
    if 'user' in st.session_state:
        user = st.session_state.user  # Fetch the user from session state
        user_id, name, email, _ = user  # Extract user details (id, name, email)
        login_time = st.session_state.get('login_time', None)
        st.markdown(
            """
            <style>
            .st-emotion-cache-12fmjuu {
                display: none !important;
            }
            </style>
            """,
            unsafe_allow_html=True
        )
        st.markdown(
            """
            <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
            """,
            unsafe_allow_html=True
        )

        # Custom header with purple background and user details
        st.markdown(
            f"""
            <style>
            .header {{
                background-color: #800080;
                color: white;
                padding: 20px;
                text-align: center;
                width: 100%;
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                z-index: 1000;
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
                display: flex;
                justify-content: space-between;
                align-items: center;
            }}
            .header p {{
                margin: 0;
                padding: 0px;
                font-size: 14px;
            }}
            .content {{
                margin-top: 180px; /* Ensure content starts below the fixed header */
            }}
            </style>
            <div class="header">
                <h3> {current_module}</h3>
                <p><strong>Name:</strong> {name} | <strong>Email:</strong> {email} | <strong>Login Time:</strong> {login_time}</p>
            </div>
            """,
            unsafe_allow_html=True
        )
    else:
        st.warning("No user logged in.")

def show_dashboard(self):
    """Show the dashboard page if the user is logged in"""

    # Check if the user is logged in
    st.empty()
    if 'user' not in st.session_state or st.session_state.user is None:
        st.warning("You are not logged in. Redirecting to login page.")
        st.rerun()  # Redirect to login page if not logged in

    # Add login time to session state when user logs in (if not already present)
    if 'login_time' not in st.session_state:
        st.session_state['login_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    # Apply the sidebar blur effect
    self.add_sidebar_blur()

    # Sidebar navigation with a unique key for the radio element
    punique_key = f"page_selection_radio_{st.session_state.get('user_id', '8988')}"
    unique_key = f"page_selection_radio_{st.session_state.get('user_id', 'default')}"

    # Fetch reports from the database
    reports = self.db.execute_query('SELECT reports.report_name, reports.id FROM reports', None, 'dist')

    # Get the list of report names for the selectbox
    report_names = [report['report_name'] for report in reports]

    # Let the user select a report from the dropdown
    selected_report_name = st.sidebar.selectbox("Select a Report", report_names, key="report_select")

    # Find the corresponding report ID for the selected report
    selected_report_id = None
    for report in reports:
        if report['report_name'] == selected_report_name:
            selected_report_id = report['id']
            break

    # Print the selected report ID (for testing)
    if selected_report_id is not None:
        self.handle_report_selection(selected_report_id)  # Call function to handle the report ID
    # Call function to handle the report ID

    # Sidebar navigation options
    st.sidebar.title("Navigation")
    page = st.sidebar.radio("User Management", (
        "Role Management", "Report Management", "User Management", "Role and Permission"),
                            key=unique_key)

    # Display user details and the current module at the top before any content
    self.display_user_details(page)

    # Sidebar layout customizations
    st.markdown(
        """
        <style>
        .stSidebar {{
            margin-top: 100px;
        }}
        .stContent {{
            margin-left: 250px;
            margin-top: 180px;
        }}
        </style>
        """,
        unsafe_allow_html=True
    )

    user = st.session_state.user  # Fetch the user from session state
    user_id, name, email, _ = user
    permission = self.db.execute_query("""SELECT 
    u.name as name,
    rp.permission_type as type,
    rp.module_name as module,
    rep.report_name as reportsName,
    rp.add as `add`,
    rp.edit as `edit`,
    rp.delete as `delete`,
    rp.read as `read`
    FROM 
    users u
    JOIN 
    roles r ON u.role_id = r.id
    LEFT JOIN role_permission rp on rp.role_id=r.id
    LEFT JOIN reports rep on rep.id=rp.report_id
    WHERE 
    u.id = 2
    AND rp.permission_type='Module';""")

    try:
        # Conditional logic based on the selected page and permissions
        if page == "Role Management" and permission[permission['module'] == 'role']['read'].iloc[0]:
            current_module = "Role Management"
            self.role.list_roles()
        elif page == "Report Management" and permission[permission['module'] == 'report']['read'].iloc[0]:
            current_module = "Report Management"
            self.report.list_reports()
        elif page == "User Management" and permission[permission['module'] == 'user']['add'].iloc[0]:
            current_module = "User Management"
            self.user.list_users()
        elif page == "Role and Permission" and \
                permission[permission['module'] == 'role & permissions']['read'].iloc[0]:
            current_module = "Role and Permission"
            self.role_permission.list_permissions()
    except Exception as e:
        st.error(f"Error loading the page: {str(e)}")

def handle_report_selection(self, report_id):
    """Directly call ReportManager to show random data based on report ID."""


    # Directly call the show_random_data method from ReportManager and pass the report_id
    self.report_manager.show_random_data(report_id)
def logout(self):
    """Logout the user by clearing session data"""
    st.session_state.clear()  # Clear all session data
    st.write("You have been logged out.")
    st.rerun()  # Rerun the app to reset the session state

If this is run as the main script, instantiate the dashboard (assuming db is already defined)

db = YourDatabaseClass() # Replace with your actual database connection object

Dashboard(db) # Initialize the dashboard with a database connection

`

Use st.rerun() at the step you expect the form to be hidden.
I faced the same issue while building SiddhantSadangi/st_login_form: Create secure authentication forms for your Streamlit apps - in one-line of code!

thanks by the way after just posting here i figured out that keyword :laughing: :laughing:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.