Update app.py
Browse files
app.py
CHANGED
|
@@ -4,8 +4,6 @@ from firebase_admin import credentials, firestore, auth
|
|
| 4 |
import pandas as pd
|
| 5 |
import plotly.express as px
|
| 6 |
from datetime import datetime
|
| 7 |
-
import hashlib
|
| 8 |
-
from fpdf import FPDF
|
| 9 |
|
| 10 |
# Initialize Firebase
|
| 11 |
if not firebase_admin._apps:
|
|
@@ -34,34 +32,6 @@ def authenticate_user(email, password):
|
|
| 34 |
except Exception:
|
| 35 |
return False
|
| 36 |
|
| 37 |
-
# Function to generate PDF with tabular format
|
| 38 |
-
def generate_pdf(df):
|
| 39 |
-
pdf = FPDF()
|
| 40 |
-
pdf.set_auto_page_break(auto=True, margin=15)
|
| 41 |
-
pdf.add_page()
|
| 42 |
-
pdf.set_font("Arial", size=12)
|
| 43 |
-
pdf.cell(200, 10, "Task Status Report", ln=True, align='C')
|
| 44 |
-
pdf.ln(10)
|
| 45 |
-
|
| 46 |
-
pdf.set_font("Arial", style='B', size=10)
|
| 47 |
-
col_widths = [50, 40, 50, 30, 30]
|
| 48 |
-
headers = ["Task", "Type", "Project", "Status", "Date"]
|
| 49 |
-
for i in range(len(headers)):
|
| 50 |
-
pdf.cell(col_widths[i], 10, headers[i], border=1, align='C')
|
| 51 |
-
pdf.ln()
|
| 52 |
-
pdf.set_font("Arial", size=10)
|
| 53 |
-
|
| 54 |
-
for _, row in df.iterrows():
|
| 55 |
-
pdf.cell(col_widths[0], 10, row['task'], border=1)
|
| 56 |
-
pdf.cell(col_widths[1], 10, row['type'], border=1)
|
| 57 |
-
pdf.cell(col_widths[2], 10, row['project'], border=1)
|
| 58 |
-
pdf.cell(col_widths[3], 10, row['status'], border=1)
|
| 59 |
-
pdf.cell(col_widths[4], 10, row['date'], border=1)
|
| 60 |
-
pdf.ln()
|
| 61 |
-
|
| 62 |
-
# Return PDF as bytes (critical fix)
|
| 63 |
-
return pdf.output(dest="S").encode("latin1")
|
| 64 |
-
|
| 65 |
# UI Layout
|
| 66 |
st.set_page_config(page_title="Construction To-Do List", layout="wide")
|
| 67 |
|
|
@@ -93,13 +63,11 @@ if not st.session_state["authenticated"]:
|
|
| 93 |
|
| 94 |
# Main Dashboard After Login
|
| 95 |
st.sidebar.title(f"Welcome, {st.session_state['email']}")
|
| 96 |
-
menu = st.sidebar.radio("Go to", ["Dashboard View", "Task Entry", "View Tasks
|
| 97 |
email = st.session_state['email']
|
| 98 |
|
| 99 |
if menu == "Dashboard View":
|
| 100 |
st.title("π Dashboard Overview")
|
| 101 |
-
|
| 102 |
-
# Fetch tasks for the logged-in user
|
| 103 |
tasks_ref = db.collection("tasks").where("user", "==", email)
|
| 104 |
tasks = [task.to_dict() for task in tasks_ref.stream()]
|
| 105 |
|
|
@@ -107,29 +75,17 @@ if menu == "Dashboard View":
|
|
| 107 |
st.info("No tasks found.")
|
| 108 |
else:
|
| 109 |
df = pd.DataFrame(tasks)
|
| 110 |
-
|
| 111 |
-
# Key Stats
|
| 112 |
total_tasks = len(df)
|
| 113 |
completed_tasks = len(df[df['status'] == "Completed"])
|
| 114 |
-
pending_tasks = len(df[df['status'] == "Pending"])
|
| 115 |
|
| 116 |
-
col1, col2
|
| 117 |
col1.metric("Total Tasks", total_tasks)
|
| 118 |
col2.metric("Completed Tasks", completed_tasks)
|
| 119 |
-
col3.metric("Pending Tasks", pending_tasks)
|
| 120 |
|
| 121 |
-
# Pie Chart: Tasks by Status
|
| 122 |
st.subheader("Tasks by Status")
|
| 123 |
status_counts = df['status'].value_counts().reset_index()
|
| 124 |
-
status_counts
|
| 125 |
-
fig = px.pie(status_counts, values='Count', names='Status', hole=0.3)
|
| 126 |
st.plotly_chart(fig)
|
| 127 |
-
|
| 128 |
-
# Tasks by Project (Optional)
|
| 129 |
-
st.subheader("Tasks by Project")
|
| 130 |
-
project_counts = df['project'].value_counts().reset_index()
|
| 131 |
-
project_counts.columns = ['Project', 'Count']
|
| 132 |
-
st.dataframe(project_counts)
|
| 133 |
|
| 134 |
elif menu == "Task Entry":
|
| 135 |
st.title("π Add New Task")
|
|
@@ -140,16 +96,15 @@ elif menu == "Task Entry":
|
|
| 140 |
with st.form("task_form"):
|
| 141 |
task = st.text_input("Task Description:")
|
| 142 |
task_type = st.selectbox("Task Type:", ["Design", "Procurement", "Construction", "Testing", "Other"])
|
| 143 |
-
selected_project = st.selectbox("Project Name:", projects
|
| 144 |
if selected_project == "Add New Project":
|
| 145 |
-
new_project = st.text_input("Enter New Project Name:"
|
| 146 |
if new_project:
|
| 147 |
db.collection("projects").document(new_project).set({"created_by": email})
|
| 148 |
selected_project = new_project
|
| 149 |
status = st.selectbox("Status:", ["Pending", "In Progress", "Completed"])
|
| 150 |
date = st.date_input("Task Date:")
|
| 151 |
-
|
| 152 |
-
if submit and task:
|
| 153 |
db.collection("tasks").add({
|
| 154 |
"user": email,
|
| 155 |
"task": task,
|
|
@@ -165,27 +120,52 @@ elif menu == "Add New Project":
|
|
| 165 |
st.title("ποΈ Add New Project")
|
| 166 |
with st.form("project_form"):
|
| 167 |
new_project_name = st.text_input("Enter New Project Name:")
|
| 168 |
-
|
| 169 |
-
if submit_project and new_project_name:
|
| 170 |
db.collection("projects").document(new_project_name).set({"created_by": email})
|
| 171 |
st.success("Project Added Successfully!")
|
| 172 |
st.rerun()
|
| 173 |
|
| 174 |
-
elif menu == "View Tasks
|
| 175 |
-
st.subheader("
|
| 176 |
-
|
| 177 |
-
for
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import pandas as pd
|
| 5 |
import plotly.express as px
|
| 6 |
from datetime import datetime
|
|
|
|
|
|
|
| 7 |
|
| 8 |
# Initialize Firebase
|
| 9 |
if not firebase_admin._apps:
|
|
|
|
| 32 |
except Exception:
|
| 33 |
return False
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
# UI Layout
|
| 36 |
st.set_page_config(page_title="Construction To-Do List", layout="wide")
|
| 37 |
|
|
|
|
| 63 |
|
| 64 |
# Main Dashboard After Login
|
| 65 |
st.sidebar.title(f"Welcome, {st.session_state['email']}")
|
| 66 |
+
menu = st.sidebar.radio("Go to", ["Dashboard View", "Task Entry", "View Tasks", "Add New Project", "Edit Task"])
|
| 67 |
email = st.session_state['email']
|
| 68 |
|
| 69 |
if menu == "Dashboard View":
|
| 70 |
st.title("π Dashboard Overview")
|
|
|
|
|
|
|
| 71 |
tasks_ref = db.collection("tasks").where("user", "==", email)
|
| 72 |
tasks = [task.to_dict() for task in tasks_ref.stream()]
|
| 73 |
|
|
|
|
| 75 |
st.info("No tasks found.")
|
| 76 |
else:
|
| 77 |
df = pd.DataFrame(tasks)
|
|
|
|
|
|
|
| 78 |
total_tasks = len(df)
|
| 79 |
completed_tasks = len(df[df['status'] == "Completed"])
|
|
|
|
| 80 |
|
| 81 |
+
col1, col2 = st.columns(2)
|
| 82 |
col1.metric("Total Tasks", total_tasks)
|
| 83 |
col2.metric("Completed Tasks", completed_tasks)
|
|
|
|
| 84 |
|
|
|
|
| 85 |
st.subheader("Tasks by Status")
|
| 86 |
status_counts = df['status'].value_counts().reset_index()
|
| 87 |
+
fig = px.pie(status_counts, values='count', names='status', hole=0.3)
|
|
|
|
| 88 |
st.plotly_chart(fig)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
elif menu == "Task Entry":
|
| 91 |
st.title("π Add New Task")
|
|
|
|
| 96 |
with st.form("task_form"):
|
| 97 |
task = st.text_input("Task Description:")
|
| 98 |
task_type = st.selectbox("Task Type:", ["Design", "Procurement", "Construction", "Testing", "Other"])
|
| 99 |
+
selected_project = st.selectbox("Project Name:", projects)
|
| 100 |
if selected_project == "Add New Project":
|
| 101 |
+
new_project = st.text_input("Enter New Project Name:")
|
| 102 |
if new_project:
|
| 103 |
db.collection("projects").document(new_project).set({"created_by": email})
|
| 104 |
selected_project = new_project
|
| 105 |
status = st.selectbox("Status:", ["Pending", "In Progress", "Completed"])
|
| 106 |
date = st.date_input("Task Date:")
|
| 107 |
+
if st.form_submit_button("Add Task"):
|
|
|
|
| 108 |
db.collection("tasks").add({
|
| 109 |
"user": email,
|
| 110 |
"task": task,
|
|
|
|
| 120 |
st.title("ποΈ Add New Project")
|
| 121 |
with st.form("project_form"):
|
| 122 |
new_project_name = st.text_input("Enter New Project Name:")
|
| 123 |
+
if st.form_submit_button("Add Project"):
|
|
|
|
| 124 |
db.collection("projects").document(new_project_name).set({"created_by": email})
|
| 125 |
st.success("Project Added Successfully!")
|
| 126 |
st.rerun()
|
| 127 |
|
| 128 |
+
elif menu == "View Tasks":
|
| 129 |
+
st.subheader("π All Tasks")
|
| 130 |
+
tasks_ref = db.collection("tasks").where("user", "==", email)
|
| 131 |
+
tasks = [task.to_dict() for task in tasks_ref.stream()]
|
| 132 |
+
|
| 133 |
+
if tasks:
|
| 134 |
+
df = pd.DataFrame(tasks)
|
| 135 |
+
st.dataframe(df[['task', 'type', 'project', 'status', 'date']])
|
| 136 |
+
else:
|
| 137 |
+
st.info("No tasks found.")
|
| 138 |
+
|
| 139 |
+
elif menu == "Edit Task":
|
| 140 |
+
st.title("βοΈ Edit Task")
|
| 141 |
+
tasks_ref = db.collection("tasks").where("user", "==", email)
|
| 142 |
+
tasks = [{"id": task.id, **task.to_dict()} for task in tasks_ref.stream()]
|
| 143 |
+
|
| 144 |
+
if not tasks:
|
| 145 |
+
st.info("No tasks to edit")
|
| 146 |
+
else:
|
| 147 |
+
task_options = [f"{task['task']} ({task['id']})" for task in tasks]
|
| 148 |
+
selected_task = st.selectbox("Select Task to Edit", task_options)
|
| 149 |
+
task_id = selected_task.split("(")[-1].strip(")")
|
| 150 |
+
|
| 151 |
+
# Find the selected task
|
| 152 |
+
task_to_edit = next((t for t in tasks if t['id'] == task_id), None)
|
| 153 |
+
|
| 154 |
+
if task_to_edit:
|
| 155 |
+
with st.form("edit_form"):
|
| 156 |
+
new_task = st.text_input("Task Description", value=task_to_edit['task'])
|
| 157 |
+
new_type = st.selectbox("Task Type", ["Design", "Procurement", "Construction", "Testing", "Other"],
|
| 158 |
+
index=["Design", "Procurement", "Construction", "Testing", "Other"].index(task_to_edit['type']))
|
| 159 |
+
new_status = st.selectbox("Status", ["Pending", "In Progress", "Completed"],
|
| 160 |
+
index=["Pending", "In Progress", "Completed"].index(task_to_edit['status']))
|
| 161 |
+
new_date = st.date_input("Date", value=datetime.strptime(task_to_edit['date'], "%Y-%m-%d"))
|
| 162 |
+
|
| 163 |
+
if st.form_submit_button("Update Task"):
|
| 164 |
+
db.collection("tasks").document(task_id).update({
|
| 165 |
+
"task": new_task,
|
| 166 |
+
"type": new_type,
|
| 167 |
+
"status": new_status,
|
| 168 |
+
"date": str(new_date)
|
| 169 |
+
})
|
| 170 |
+
st.success("Task updated successfully!")
|
| 171 |
+
st.rerun()
|