import streamlit as st from pathlib import Path from datetime import datetime # Application title st.set_page_config(page_title="To-Do List \n Notebook", page_icon="📝", layout="centered") # Create an uploads folder if it doesn't exist Path("uploads").mkdir(exist_ok=True) # App header st.title("📝 To-Do List \n Notebook") st.subheader("Your tasks, your way!") # App description st.write("Organize your tasks with notes, images, and audio. Edit, save, or delete tasks seamlessly!") # Initialize task list in the session state if "tasks" not in st.session_state: st.session_state.tasks = [] # Initialize task input fields in the session state if "title" not in st.session_state: st.session_state.title = "" if "description" not in st.session_state: st.session_state.description = "" if "bg_color" not in st.session_state: st.session_state.bg_color = "#ffffff" if "image_files" not in st.session_state: st.session_state.image_files = [] if "audio_file" not in st.session_state: st.session_state.audio_file = None if "editing_index" not in st.session_state: st.session_state.editing_index = None # To track which task is being edited # Helper function to save uploaded files def save_uploaded_file(uploaded_file): try: file_path = Path("uploads") / uploaded_file.name with open(file_path, "wb") as f: f.write(uploaded_file.getbuffer()) return str(file_path) except Exception as e: st.error(f"Error saving file: {e}") return None # Function to add a new task with exception handling def add_task(title, description, image_files, audio_file, bg_color): try: if not title.strip(): raise ValueError("Title cannot be empty.") if not description.strip(): raise ValueError("Description cannot be empty.") new_task = { "title": title, "description": description, "images": [save_uploaded_file(image) for image in image_files] if image_files else [], "audio": save_uploaded_file(audio_file) if audio_file else None, "bg_color": bg_color, } st.session_state.tasks.append(new_task) st.success(f"Task '{title}' added successfully!") # Clear the inputs after adding the task clear_fields() # Call the function to clear fields except ValueError as ve: st.error(f"Error: {ve}") except Exception as e: st.error(f"Error adding task: {e}") # Function to delete a task def delete_task(index): try: st.session_state.tasks.pop(index) st.success("Task deleted successfully!") st.session_state.editing_index = None # Reset editing index after deletion except Exception as e: st.error(f"Error deleting task: {e}") # Function to edit a task def edit_task(index, new_title, new_description, new_images, new_audio, new_bg_color): try: task = st.session_state.tasks[index] task["title"] = new_title task["description"] = new_description task["images"] = [save_uploaded_file(img) for img in new_images] if new_images else task["images"] task["audio"] = save_uploaded_file(new_audio) if new_audio else task["audio"] task["bg_color"] = new_bg_color st.success(f"Task '{new_title}' updated successfully!") st.session_state.editing_index = None # Reset editing index after task is edited except Exception as e: st.error(f"Error editing task: {e}") # Function to clear the fields after a task is added or edited def clear_fields(): st.session_state.title = "" st.session_state.description = "" st.session_state.bg_color = "#ffffff" st.session_state.image_files = [] st.session_state.audio_file = None st.session_state.editing_index = None # Reset editing index # Add task section with st.expander("➕ Add a New Task"): if st.session_state.editing_index is not None: # If editing, populate fields with the existing task data task_to_edit = st.session_state.tasks[st.session_state.editing_index] st.session_state.title = st.text_input("Title", value=task_to_edit["title"]) st.session_state.description = st.text_area("Description", value=task_to_edit["description"]) # Multiple images upload (without assigning directly to session state) image_files = st.file_uploader("Upload Images (optional)", type=["png", "jpg", "jpeg"], accept_multiple_files=True) if image_files: st.session_state.image_files = image_files audio_file = st.file_uploader("Upload Audio (optional)", type=["mp3", "wav"], accept_multiple_files=False) if audio_file: st.session_state.audio_file = audio_file st.session_state.bg_color = st.color_picker("Pick Background Color", value=task_to_edit["bg_color"]) if st.button("Save Changes"): edit_task(st.session_state.editing_index, st.session_state.title, st.session_state.description, st.session_state.image_files, st.session_state.audio_file, st.session_state.bg_color) st.button("Cancel Edit", on_click=clear_fields) else: # If not editing, show empty input fields st.session_state.title = st.text_input("Title", placeholder="Enter task title...", value=st.session_state.title) st.session_state.description = st.text_area("Description", placeholder="Write your task details here...", value=st.session_state.description) # Multiple images upload (without assigning directly to session state) image_files = st.file_uploader("Upload Images (optional)", type=["png", "jpg", "jpeg"], accept_multiple_files=True) if image_files: st.session_state.image_files = image_files audio_file = st.file_uploader("Upload Audio (optional)", type=["mp3", "wav"], accept_multiple_files=False) if audio_file: st.session_state.audio_file = audio_file st.session_state.bg_color = st.color_picker("Pick Background Color", value=st.session_state.bg_color) if st.button("Add Task"): add_task(st.session_state.title, st.session_state.description, st.session_state.image_files, st.session_state.audio_file, st.session_state.bg_color) # Add "Clear" button to reset all input fields if st.button("Clear"): clear_fields() # Show tasks if st.session_state.tasks: st.subheader("📋 Your Tasks") for i, task in enumerate(st.session_state.tasks): with st.container(): # Apply background color st.markdown( f"