Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import firebase_admin
|
|
| 3 |
from firebase_admin import credentials, firestore, auth
|
| 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:
|
|
@@ -66,10 +66,27 @@ 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 |
-
|
| 72 |
-
tasks = [task.to_dict() for task in tasks_ref.stream()]
|
| 73 |
|
| 74 |
if not tasks:
|
| 75 |
st.info("No tasks found.")
|
|
@@ -78,14 +95,30 @@ if menu == "Dashboard View":
|
|
| 78 |
total_tasks = len(df)
|
| 79 |
completed_tasks = len(df[df['status'] == "Completed"])
|
| 80 |
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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")
|
|
@@ -103,7 +136,7 @@ elif menu == "Task Entry":
|
|
| 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("
|
| 107 |
if st.form_submit_button("Add Task"):
|
| 108 |
db.collection("tasks").add({
|
| 109 |
"user": email,
|
|
@@ -127,19 +160,42 @@ elif menu == "Add New Project":
|
|
| 127 |
|
| 128 |
elif menu == "View Tasks":
|
| 129 |
st.subheader("π All Tasks")
|
| 130 |
-
|
| 131 |
-
tasks = [task.to_dict() for task in tasks_ref.stream()]
|
| 132 |
|
| 133 |
if tasks:
|
| 134 |
df = pd.DataFrame(tasks)
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
else:
|
| 137 |
st.info("No tasks found.")
|
| 138 |
|
| 139 |
elif menu == "Edit Task":
|
| 140 |
st.title("βοΈ Edit Task")
|
| 141 |
-
|
| 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")
|
|
@@ -148,7 +204,6 @@ elif menu == "Edit Task":
|
|
| 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:
|
|
@@ -158,7 +213,7 @@ elif menu == "Edit Task":
|
|
| 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({
|
|
|
|
| 3 |
from firebase_admin import credentials, firestore, auth
|
| 4 |
import pandas as pd
|
| 5 |
import plotly.express as px
|
| 6 |
+
from datetime import datetime, timedelta
|
| 7 |
|
| 8 |
# Initialize Firebase
|
| 9 |
if not firebase_admin._apps:
|
|
|
|
| 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 |
+
def get_tasks():
|
| 70 |
+
tasks_ref = db.collection("tasks").where("user", "==", email)
|
| 71 |
+
return [{"id": task.id, **task.to_dict()} for task in tasks_ref.stream()]
|
| 72 |
+
|
| 73 |
+
def calculate_deadline_status(task_date):
|
| 74 |
+
today = datetime.today().date()
|
| 75 |
+
task_date = datetime.strptime(task_date, "%Y-%m-%d").date()
|
| 76 |
+
delta = (task_date - today).days
|
| 77 |
+
|
| 78 |
+
if delta < 0:
|
| 79 |
+
return "Overdue", abs(delta)
|
| 80 |
+
elif delta == 0:
|
| 81 |
+
return "Due Today", 0
|
| 82 |
+
elif delta <= 3:
|
| 83 |
+
return f"Due in {delta} days", delta
|
| 84 |
+
else:
|
| 85 |
+
return "On Track", delta
|
| 86 |
+
|
| 87 |
if menu == "Dashboard View":
|
| 88 |
st.title("π Dashboard Overview")
|
| 89 |
+
tasks = get_tasks()
|
|
|
|
| 90 |
|
| 91 |
if not tasks:
|
| 92 |
st.info("No tasks found.")
|
|
|
|
| 95 |
total_tasks = len(df)
|
| 96 |
completed_tasks = len(df[df['status'] == "Completed"])
|
| 97 |
|
| 98 |
+
# Add deadline calculations
|
| 99 |
+
df['deadline_status'] = df['date'].apply(lambda x: calculate_deadline_status(x)[0])
|
| 100 |
+
overdue_tasks = df[(df['status'].isin(["Pending", "In Progress"])) &
|
| 101 |
+
(df['deadline_status'].isin(["Overdue", "Due Today", "Due in 1-3 days"]))]
|
| 102 |
+
|
| 103 |
+
col1, col2, col3 = st.columns(3)
|
| 104 |
col1.metric("Total Tasks", total_tasks)
|
| 105 |
col2.metric("Completed Tasks", completed_tasks)
|
| 106 |
+
col3.metric("Urgent Tasks", len(overdue_tasks))
|
| 107 |
|
| 108 |
st.subheader("Tasks by Status")
|
| 109 |
status_counts = df['status'].value_counts().reset_index()
|
| 110 |
fig = px.pie(status_counts, values='count', names='status', hole=0.3)
|
| 111 |
st.plotly_chart(fig)
|
| 112 |
+
|
| 113 |
+
# Deadline Alerts
|
| 114 |
+
st.subheader("β οΈ Upcoming Deadlines")
|
| 115 |
+
if not overdue_tasks.empty:
|
| 116 |
+
for _, task in overdue_tasks.iterrows():
|
| 117 |
+
status, days = calculate_deadline_status(task['date'])
|
| 118 |
+
emoji = "β" if "Overdue" in status else "β³"
|
| 119 |
+
st.write(f"{emoji} {task['task']} ({task['project']}) - {status}")
|
| 120 |
+
else:
|
| 121 |
+
st.info("No upcoming deadlines!")
|
| 122 |
|
| 123 |
elif menu == "Task Entry":
|
| 124 |
st.title("π Add New Task")
|
|
|
|
| 136 |
db.collection("projects").document(new_project).set({"created_by": email})
|
| 137 |
selected_project = new_project
|
| 138 |
status = st.selectbox("Status:", ["Pending", "In Progress", "Completed"])
|
| 139 |
+
date = st.date_input("Target Date:")
|
| 140 |
if st.form_submit_button("Add Task"):
|
| 141 |
db.collection("tasks").add({
|
| 142 |
"user": email,
|
|
|
|
| 160 |
|
| 161 |
elif menu == "View Tasks":
|
| 162 |
st.subheader("π All Tasks")
|
| 163 |
+
tasks = get_tasks()
|
|
|
|
| 164 |
|
| 165 |
if tasks:
|
| 166 |
df = pd.DataFrame(tasks)
|
| 167 |
+
|
| 168 |
+
# Add filtering options
|
| 169 |
+
col1, col2 = st.columns(2)
|
| 170 |
+
with col1:
|
| 171 |
+
selected_status = st.selectbox("Filter by Status:", ["All"] + ["Pending", "In Progress", "Completed"])
|
| 172 |
+
with col2:
|
| 173 |
+
projects = ["All"] + list(df['project'].unique())
|
| 174 |
+
selected_project = st.selectbox("Filter by Project:", projects)
|
| 175 |
+
|
| 176 |
+
# Apply filters
|
| 177 |
+
if selected_status != "All":
|
| 178 |
+
df = df[df['status'] == selected_status]
|
| 179 |
+
if selected_project != "All":
|
| 180 |
+
df = df[df['project'] == selected_project]
|
| 181 |
+
|
| 182 |
+
# Add deadline status column
|
| 183 |
+
df['deadline_status'] = df['date'].apply(lambda x: calculate_deadline_status(x)[0])
|
| 184 |
+
|
| 185 |
+
# Display table with styling
|
| 186 |
+
st.dataframe(
|
| 187 |
+
df[['task', 'type', 'project', 'status', 'date', 'deadline_status']]
|
| 188 |
+
.style.apply(lambda x: ['background: #ffcccc' if v == "Overdue" else
|
| 189 |
+
'background: #fff3cd' if "Due" in v else ''
|
| 190 |
+
for v in x], subset=['deadline_status']),
|
| 191 |
+
height=400
|
| 192 |
+
)
|
| 193 |
else:
|
| 194 |
st.info("No tasks found.")
|
| 195 |
|
| 196 |
elif menu == "Edit Task":
|
| 197 |
st.title("βοΈ Edit Task")
|
| 198 |
+
tasks = get_tasks()
|
|
|
|
| 199 |
|
| 200 |
if not tasks:
|
| 201 |
st.info("No tasks to edit")
|
|
|
|
| 204 |
selected_task = st.selectbox("Select Task to Edit", task_options)
|
| 205 |
task_id = selected_task.split("(")[-1].strip(")")
|
| 206 |
|
|
|
|
| 207 |
task_to_edit = next((t for t in tasks if t['id'] == task_id), None)
|
| 208 |
|
| 209 |
if task_to_edit:
|
|
|
|
| 213 |
index=["Design", "Procurement", "Construction", "Testing", "Other"].index(task_to_edit['type']))
|
| 214 |
new_status = st.selectbox("Status", ["Pending", "In Progress", "Completed"],
|
| 215 |
index=["Pending", "In Progress", "Completed"].index(task_to_edit['status']))
|
| 216 |
+
new_date = st.date_input("Target Date", value=datetime.strptime(task_to_edit['date'], "%Y-%m-%d"))
|
| 217 |
|
| 218 |
if st.form_submit_button("Update Task"):
|
| 219 |
db.collection("tasks").document(task_id).update({
|