From e3a4dd0750d5876ab7010b6b71f8fda36057ffc2 Mon Sep 17 00:00:00 2001 From: Copilot User Date: Tue, 4 Aug 2026 23:53:50 +0530 Subject: [PATCH] Add minimal Flask work form management app Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- work-form-management/README.md | 15 +++ .../__pycache__/app.cpython-314.pyc | Bin 0 -> 7235 bytes work-form-management/app.py | 102 ++++++++++++++++++ work-form-management/requirements.txt | 1 + work-form-management/static/style.css | 12 +++ work-form-management/templates/base.html | 22 ++++ work-form-management/templates/edit.html | 12 +++ work-form-management/templates/index.html | 25 +++++ 8 files changed, 189 insertions(+) create mode 100644 work-form-management/README.md create mode 100644 work-form-management/__pycache__/app.cpython-314.pyc create mode 100644 work-form-management/app.py create mode 100644 work-form-management/requirements.txt create mode 100644 work-form-management/static/style.css create mode 100644 work-form-management/templates/base.html create mode 100644 work-form-management/templates/edit.html create mode 100644 work-form-management/templates/index.html diff --git a/work-form-management/README.md b/work-form-management/README.md new file mode 100644 index 0000000000..5cc7506d7e --- /dev/null +++ b/work-form-management/README.md @@ -0,0 +1,15 @@ +Work Form Management System + +A minimal Flask + SQLite app to maintain workflow, due list, priorities and stages. + +Quick start (Windows): +1. Create a virtualenv: python -m venv .venv +2. Activate: .\.venv\Scripts\activate +3. Install: pip install -r requirements.txt +4. Run: set FLASK_APP=app.py && flask run + +Use the web UI at http://127.0.0.1:5000 to add tasks, edit, mark complete, and view due dates. + +Notes: +- Database is stored at work-form-management/instance/tasks.db +- Fields: title, description, status, workflow_stage, due_date, priority diff --git a/work-form-management/__pycache__/app.cpython-314.pyc b/work-form-management/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b88d25fa2d5a89bf0440024534bbf0ed2017c198 GIT binary patch literal 7235 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 literal 0 HcmV?d00001 diff --git a/work-form-management/app.py b/work-form-management/app.py new file mode 100644 index 0000000000..972d50b4f2 --- /dev/null +++ b/work-form-management/app.py @@ -0,0 +1,102 @@ +from flask import Flask, g, render_template, request, redirect, url_for +import sqlite3 +import os +import datetime + +BASE_DIR = os.path.dirname(__file__) +DB_PATH = os.path.join(BASE_DIR, 'instance', 'tasks.db') +os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) + +app = Flask(__name__) + +def get_db(): + db = getattr(g, '_database', None) + if db is None: + db = g._database = sqlite3.connect(DB_PATH) + db.row_factory = sqlite3.Row + return db + +def init_db(): + db = get_db() + db.execute('''CREATE TABLE IF NOT EXISTS tasks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + description TEXT, + status TEXT NOT NULL DEFAULT 'pending', + workflow_stage TEXT, + due_date TEXT, + priority INTEGER DEFAULT 3, + created_at TEXT, + updated_at TEXT + )''') + db.commit() + +@app.teardown_appcontext +def close_connection(exception): + db = getattr(g, '_database', None) + if db is not None: + db.close() + +@app.before_request +def before_request(): + init_db() + +@app.route('/') +def index(): + db = get_db() + rows = db.execute('SELECT * FROM tasks ORDER BY due_date IS NULL, due_date, priority').fetchall() + tasks = [dict(r) for r in rows] + return render_template('index.html', tasks=tasks, today=str(datetime.date.today())) + +@app.route('/add', methods=['GET','POST']) +def add(): + if request.method == 'POST': + title = request.form['title'].strip() + description = request.form.get('description','').strip() + due_date = request.form.get('due_date') or None + workflow_stage = request.form.get('workflow_stage','Backlog') + priority = int(request.form.get('priority',3)) + created = datetime.datetime.utcnow().isoformat() + db = get_db() + db.execute('INSERT INTO tasks (title, description, due_date, workflow_stage, priority, created_at, updated_at) VALUES (?,?,?,?,?,?,?)', + (title, description, due_date, workflow_stage, priority, created, created)) + db.commit() + return redirect(url_for('index')) + return render_template('edit.html', task=None) + +@app.route('/edit/', methods=['GET','POST']) +def edit(task_id): + db = get_db() + if request.method == 'POST': + title = request.form['title'].strip() + description = request.form.get('description','').strip() + due_date = request.form.get('due_date') or None + workflow_stage = request.form.get('workflow_stage','Backlog') + priority = int(request.form.get('priority',3)) + updated = datetime.datetime.utcnow().isoformat() + db.execute('UPDATE tasks SET title=?, description=?, due_date=?, workflow_stage=?, priority=?, updated_at=? WHERE id=?', + (title, description, due_date, workflow_stage, priority, updated, task_id)) + db.commit() + return redirect(url_for('index')) + row = db.execute('SELECT * FROM tasks WHERE id=?', (task_id,)).fetchone() + if not row: + return redirect(url_for('index')) + task = dict(row) + return render_template('edit.html', task=task) + +@app.route('/complete/') +def complete(task_id): + db = get_db() + db.execute("UPDATE tasks SET status='done', updated_at=? WHERE id=?", (datetime.datetime.utcnow().isoformat(), task_id)) + db.commit() + return redirect(url_for('index')) + +@app.route('/delete/') +def delete(task_id): + db = get_db() + db.execute('DELETE FROM tasks WHERE id=?', (task_id,)) + db.commit() + return redirect(url_for('index')) + +if __name__ == '__main__': + app.run(debug=True) diff --git a/work-form-management/requirements.txt b/work-form-management/requirements.txt new file mode 100644 index 0000000000..047e9501aa --- /dev/null +++ b/work-form-management/requirements.txt @@ -0,0 +1 @@ +Flask==3.0.0 diff --git a/work-form-management/static/style.css b/work-form-management/static/style.css new file mode 100644 index 0000000000..c0fe52a502 --- /dev/null +++ b/work-form-management/static/style.css @@ -0,0 +1,12 @@ +body{font-family:Segoe UI, Arial, sans-serif;background:#f7f7f7;color:#222} +.container{max-width:900px;margin:24px auto;padding:16px;background:#fff;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.06)} +header h1{margin:0} +nav{margin-top:6px} +table{width:100%;border-collapse:collapse;margin-top:12px} +th,td{padding:8px;border-bottom:1px solid #eee;text-align:left} +tr.overdue{background:#fff0f0} +tr.done{color:#888;text-decoration:line-through} +footer{margin-top:18px;color:#666} +label{display:block;margin:8px 0} +input[type=text], textarea, input[type=number]{width:100%;padding:6px;border:1px solid #ddd;border-radius:4px} +button{background:#0069d9;color:white;padding:8px 12px;border:none;border-radius:4px} diff --git a/work-form-management/templates/base.html b/work-form-management/templates/base.html new file mode 100644 index 0000000000..23af6cef0d --- /dev/null +++ b/work-form-management/templates/base.html @@ -0,0 +1,22 @@ + + + + + Work Form Management + + + +

+
+

Work Form Management

+ +
+
+ {% block content %}{% endblock %} +
+
+ Minimal app — customize as needed. +
+
+ + \ No newline at end of file diff --git a/work-form-management/templates/edit.html b/work-form-management/templates/edit.html new file mode 100644 index 0000000000..aad81c0816 --- /dev/null +++ b/work-form-management/templates/edit.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} +{% block content %} +

{% if task %}Edit Task{% else %}Add Task{% endif %}

+
+
+
+
+
+
+ +
+{% endblock %} \ No newline at end of file diff --git a/work-form-management/templates/index.html b/work-form-management/templates/index.html new file mode 100644 index 0000000000..84135f896f --- /dev/null +++ b/work-form-management/templates/index.html @@ -0,0 +1,25 @@ +{% extends 'base.html' %} +{% block content %} +

Tasks

+ {% if tasks %} + + + {% for t in tasks %} + + + + + + + + + {% endfor %} +
TitleStageDuePriorityStatusActions
{{ t.title }}{{ t.workflow_stage or 'Backlog' }}{{ t.due_date or '-' }}{{ t.priority or 3 }}{{ t.status }} + Edit | + Complete | + Delete +
+ {% else %} +

No tasks yet. Add one.

+ {% endif %} +{% endblock %} \ No newline at end of file