|
import streamlit as st |
|
import pandas as pd |
|
import requests |
|
from datetime import datetime |
|
import pytz |
|
|
|
|
|
SHEETDB_API_URL_TIMECARD = "https://sheetdb.io/api/v1/jsh4nri7t8rko" |
|
|
|
|
|
PASSWORD = "ma_12345" |
|
|
|
|
|
METADATA = { |
|
"Employee Names": [ |
|
"Ubaid Bashir", "Shoaib Ahmad", "Rumaan Hassan Alamgeer", |
|
"Sana Sanaullah", "Aafreen Mushtaq", "Andleeb Gul" |
|
], |
|
"Project Names": [ |
|
"ICCL", "Reston", "BAC","Stormwater", "NISA Engineering", |
|
"Paramount", "Preng", "Misc.", "Marketing" |
|
], |
|
"Project Codes": [ |
|
"US 001", "US 003", "US 004", "US 005", "US 006", 'US 008',"IND 001", "IND 007" |
|
] |
|
} |
|
|
|
|
|
def load_data(): |
|
response = requests.get(SHEETDB_API_URL_TIMECARD) |
|
if response.status_code == 200: |
|
return pd.DataFrame(response.json()) |
|
else: |
|
return pd.DataFrame(columns=["Employee Name", "Project Name", "Project Code", "Date", "Hours", "Notes"]) |
|
|
|
|
|
def save_data(employee_name, project_name, project_code, hours, notes): |
|
|
|
|
|
|
|
ist = pytz.timezone('Asia/Kolkata') |
|
ist_now = datetime.now(ist) |
|
|
|
|
|
formatted_date = ist_now.date().isoformat() |
|
|
|
|
|
new_entry = { |
|
"Employee Name": employee_name, |
|
"Project Name": project_name, |
|
"Project Code": project_code, |
|
"Date": formatted_date, |
|
"Hours": hours, |
|
"Notes": notes |
|
} |
|
response = requests.post(SHEETDB_API_URL_TIMECARD, json=new_entry) |
|
if response.status_code == 201: |
|
st.success("Entry added successfully!") |
|
else: |
|
st.error("Failed to add entry. Please try again.") |
|
|
|
|
|
st.markdown( |
|
""" |
|
<style> |
|
/* General Styling */ |
|
body { |
|
background-color: #000000; |
|
color: #00FF00; |
|
font-family: 'Courier New', monospace; |
|
} |
|
h1, h2, h3, h4, h5, h6 { |
|
color: #00FF00; |
|
font-family: 'Courier New', monospace; |
|
} |
|
.stButton button { |
|
background-color: #00FF00; |
|
color: #000000; |
|
border: 2px solid #00FF00; |
|
border-radius: 5px; |
|
font-family: 'Courier New', monospace; |
|
font-weight: bold; |
|
} |
|
.stButton button:hover { |
|
background-color: #000000; |
|
color: #00FF00; |
|
border: 2px solid #00FF00; |
|
} |
|
.stTextInput input, .stSelectbox select, .stDateInput input, .stNumberInput input, .stTextArea textarea { |
|
background-color: #000000; |
|
color: #00FF00; |
|
border: 2px solid #00FF00; |
|
font-family: 'Courier New', monospace; |
|
} |
|
.stDataFrame { |
|
background-color: #000000; |
|
color: #00FF00; |
|
border: 2px solid #00FF00; |
|
} |
|
.stSidebar { |
|
background-color: #000000; |
|
color: #00FF00; |
|
border-right: 2px solid #00FF00; |
|
} |
|
.stMarkdown { |
|
color: #00FF00; |
|
} |
|
/* Reduced Neon Glow Effect */ |
|
.neon-text { |
|
color: #00FF00; |
|
text-shadow: 0 0 3px #00FF00, 0 0 5px #00FF00; |
|
} |
|
.neon-border { |
|
border: 2px solid #00FF00; |
|
box-shadow: 0 0 3px #00FF00, 0 0 5px #00FF00; |
|
} |
|
</style> |
|
""", |
|
unsafe_allow_html=True |
|
) |
|
|
|
|
|
if "authenticated" not in st.session_state: |
|
st.session_state.authenticated = False |
|
|
|
if not st.session_state.authenticated: |
|
st.markdown("<h1 class='neon-text' style='text-align: center;'>Munshi Associates Dashboard</h1>", unsafe_allow_html=True) |
|
st.markdown("<p class='neon-text'>Please enter the password to access the application.</p>", unsafe_allow_html=True) |
|
password = st.text_input("Password", type="password") |
|
|
|
if st.button("Login"): |
|
if password == PASSWORD: |
|
st.session_state.authenticated = True |
|
st.success("Login successful!") |
|
else: |
|
st.error("Incorrect password. Please try again.") |
|
else: |
|
|
|
st.sidebar.image("ma_logo.png") |
|
st.sidebar.markdown("<h1 class='neon-text'>Munshi Associates Dashboard</h1>", unsafe_allow_html=True) |
|
st.sidebar.markdown("<p class='neon-text'>Employee Timecard Management System</p>", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown("<h1 class='neon-text'>Employee Time Card Management</h1>", unsafe_allow_html=True) |
|
st.markdown("<p class='neon-text'>Welcome to the <strong>Munshi Associates Time Card Management System</strong></p>", unsafe_allow_html=True) |
|
|
|
|
|
employee_names = METADATA["Employee Names"] |
|
project_names = METADATA["Project Names"] |
|
project_codes = METADATA["Project Codes"] |
|
|
|
|
|
st.markdown("<h3 class='neon-text'>Add Timecard Entry</h3>", unsafe_allow_html=True) |
|
with st.form("timecard_form"): |
|
st.markdown("<p class='neon-text'>Fill out the form below to add a new entry.</p>", unsafe_allow_html=True) |
|
col1, col2 = st.columns(2) |
|
with col1: |
|
employee_name = st.selectbox("Select Employee Name", employee_names) |
|
project_name = st.selectbox("Select Project Name", project_names) |
|
project_code = st.selectbox("Select Project Code", project_codes) |
|
with col2: |
|
hours = st.number_input("Hours Worked", min_value=0.0, step=0.5) |
|
notes = st.text_area("Notes", placeholder="Add any relevant notes here...") |
|
|
|
submitted = st.form_submit_button("Add Entry") |
|
if submitted: |
|
save_data(employee_name, project_name, project_code, hours, notes) |
|
|
|
|
|
st.markdown("<h3 class='neon-text'>Existing Time Card Data</h3>", unsafe_allow_html=True) |
|
data = load_data() |
|
st.dataframe(data, use_container_width=True) |
|
|
|
|
|
st.markdown("<h3 class='neon-text'>Download Time Card Data</h3>", unsafe_allow_html=True) |
|
st.download_button( |
|
label="Download CSV", |
|
data=data.to_csv(index=False), |
|
file_name="timecard_data.csv", |
|
mime="text/csv" |
|
) |