import streamlit as st import pandas as pd import numpy as np import os # Configure the page to be mobile-friendly st.set_page_config(layout="centered", page_title="Halal Restaurant Data Viewer") # URLs for the logos MAIN_LOGO_URL = "https://islamictrusthk.org/assets/images/top-logo.png" SIDEBAR_LOGO_URL = "https://bot.islamictrusthk.org/assets/content_files/20240606095159123011.png" # Inject custom CSS for better mobile compatibility st.markdown( """ """, unsafe_allow_html=True, ) # Directory to save uploaded files UPLOAD_DIR = "uploaded_files" os.makedirs(UPLOAD_DIR, exist_ok=True) # Function to load data @st.cache_data def load_data(file_path): df = pd.read_excel(file_path) df.fillna("Not Available", inplace=True) return df # Function to convert dataframe to CSV def convert_df_to_csv(df): return df.to_csv(index=False).encode('utf-8') # Function to format date def format_date_column(df, column): df[column] = pd.to_datetime(df[column], errors='coerce').dt.date return df # Function to verify required columns exist def verify_columns(df, required_columns): missing_columns = [col for col in required_columns if col not in df.columns] return missing_columns # Function to display data in tiles def display_tiles(df, cols): for i, (_, row) in enumerate(df.iterrows()): col = cols[i % len(cols)] with col: st.markdown(f"**Company Name:** {row['Company Name']}") st.markdown(f"**Region:** {row['Region']}") st.markdown(f"**Factory Type:** {row['Factory Type']}") st.markdown(f"**Expiry Date:** {row['Expiry Date']}") st.markdown(f"**Contact:** {row['Contact']}") st.markdown(f"**Phone:** {row['Phone']}") st.markdown(f"**E-mail:** {row['E-mail']}") st.markdown("---") # Initialize session state if 'df' not in st.session_state: st.session_state.df = None if 'authenticated' not in st.session_state: st.session_state.authenticated = False if 'login_attempt' not in st.session_state: st.session_state.login_attempt = False # List of valid usernames and passwords user_credentials = { 'ubaid': 'Password@123', 'bot': 'Trust@123' } # Authentication function def authenticate(username, password): if username in user_credentials and user_credentials[username] == password: return True return False # Authentication block if not st.session_state.authenticated: st.title("Login") username = st.text_input("Username") password = st.text_input("Password", type="password") login_button = st.button("Login") if login_button: if authenticate(username, password): st.session_state.authenticated = True st.session_state.login_attempt = False # Reset the login attempt flag else: st.session_state.login_attempt = True st.error("Invalid username or password") if st.session_state.login_attempt: st.warning("Please try again.") else: st.write("User authenticated successfully") st.image(MAIN_LOGO_URL, use_column_width=True) st.title("HK Halal Restaurants Viewer") # File upload logic with st.sidebar: st.image(SIDEBAR_LOGO_URL, use_column_width=True) st.title("File Management") # File uploader uploaded_file = st.file_uploader("Choose an Excel file", type="xlsx") if uploaded_file: try: # Save the uploaded file file_path = os.path.join(UPLOAD_DIR, uploaded_file.name) with open(file_path, "wb") as f: f.write(uploaded_file.getbuffer()) st.success(f"File '{uploaded_file.name}' uploaded successfully.") df = load_data(file_path) st.session_state.df = df except Exception as e: st.error(f"An error occurred: {e}") # Manage existing files st.subheader("Manage Existing Files") existing_files = [f for f in os.listdir(UPLOAD_DIR) if f.endswith(".xlsx")] if existing_files: selected_file = st.selectbox("Select a file to view or delete", existing_files) if st.button("Delete Selected File"): os.remove(os.path.join(UPLOAD_DIR, selected_file)) st.success(f"File '{selected_file}' deleted successfully.") st.session_state.df = None # Reset the dataframe in session state if st.button("Load Selected File") or st.session_state.df is None: try: file_path = os.path.join(UPLOAD_DIR, selected_file) df = load_data(file_path) st.session_state.df = df except Exception as e: st.error(f"An error occurred: {e}") else: st.info("No files available.") # Display and filter the loaded dataframe if available if st.session_state.df is not None: df = st.session_state.df # Define required columns required_columns = [ 'Issued Date', 'Expiry Date', 'Cert. No', 'Company Name', 'Address', 'Region', 'Factory Type', 'Contact', 'Phone', 'E-mail', 'Status', 'Member Since' ] # Verify required columns missing_columns = verify_columns(df, required_columns) if missing_columns: st.error(f"The following required columns are missing from the uploaded file: {', '.join(missing_columns)}") else: # Format the date columns to remove time df = format_date_column(df, 'Issued Date') df = format_date_column(df, 'Expiry Date') # Display the dataframe st.subheader("Loaded Data") st.dataframe(df) # Filter functionality st.subheader("Filters") # Use columns for a more responsive layout col1, col2, col3, col4 = st.columns(4) with col1: # Filter by Company Name company_name_filter = st.text_input("Company Name contains") with col2: # Filter by Region region_filter = st.multiselect("Region", df['Region'].drop_duplicates()) with col3: # Filter by Factory Type factory_type_filter = st.multiselect("Factory Type", df['Factory Type'].drop_duplicates()) with col4: # Filter by Expiry Date expiry_date_filter = st.date_input("Expiry Date", []) # Apply filters filtered_df = df.copy() if company_name_filter: filtered_df = filtered_df[filtered_df['Company Name'].str.contains(company_name_filter, case=False, na=False)] if region_filter: filtered_df = filtered_df[filtered_df['Region'].isin(region_filter)] if factory_type_filter: filtered_df = filtered_df[filtered_df['Factory Type'].isin(factory_type_filter)] if expiry_date_filter: if len(expiry_date_filter) == 1: filtered_df = filtered_df[filtered_df['Expiry Date'] == expiry_date_filter[0]] elif len(expiry_date_filter) == 2: start_date, end_date = expiry_date_filter filtered_df = filtered_df[(filtered_df['Expiry Date'] >= start_date) & (filtered_df['Expiry Date'] <= end_date)] # Display the filtered dataframe in a tile format st.subheader("Filtered Data") if not filtered_df.empty: num_cols = 3 # Number of columns for the tile layout cols = st.columns(num_cols) display_tiles(filtered_df, cols) # Download button for filtered data csv = convert_df_to_csv(filtered_df) st.download_button( label="Download filtered data as CSV", data=csv, file_name='filtered_data.csv', mime='text/csv', ) else: st.info("No data matches the filter criteria.")