GauravSingh72388 commited on
Commit
bf84448
·
verified ·
1 Parent(s): 49d69d2

Upload 12 files

Browse files
app/__init__.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask
2
+ from flask_sqlalchemy import SQLAlchemy
3
+
4
+ # create database obj globallysecrect_key
5
+ db = SQLAlchemy()
6
+
7
+ def create_app():
8
+ app = Flask(__name__)
9
+
10
+
11
+ app.config['SECRET_KEY'] = 'secret_key'
12
+ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
13
+ app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
14
+
15
+ db.init_app(app)
16
+
17
+ from app.routes.auth import auth_bp
18
+ from app.routes.tasks import tasks_bp
19
+ app.register_blueprint(auth_bp)
20
+ app.register_blueprint(tasks_bp)
21
+
22
+ return app
app/models.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from app import db
2
+
3
+ class Task(db.Model):
4
+ id = db.Column(db.Integer, primary_key=True)
5
+ title = db.Column(db.String(100), nullable=False)
6
+ status = db.Column(db.String(20), default="Pending")
7
+
8
+
app/routes/__init__.py ADDED
File without changes
app/routes/auth.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Blueprint, request ,session, redirect, render_template, url_for, flash
2
+
3
+ auth_bp = Blueprint('auth' , __name__)
4
+
5
+ USER_CRIDINTAILS = {
6
+ "username" : "Gaurav",
7
+ "password" : "1234"
8
+ }
9
+
10
+ @auth_bp.route('/login', methods = ["GET","POST"])
11
+ def login():
12
+ if request.method == "POST":
13
+ username = request.form.get('username')
14
+ password = request.form.get('password')
15
+
16
+ if username == USER_CRIDINTAILS['username'] and password == USER_CRIDINTAILS['password'] :
17
+ session['user'] = username
18
+ flash('Login Successful', 'success')
19
+ return redirect(url_for("tasks.view_tasks")) # ✅ This is critical!
20
+ else:
21
+ flash('Invalid username or password', 'danger')
22
+
23
+ return render_template('login.html')
24
+
25
+ @auth_bp.route('/logout')
26
+ def logout():
27
+ session.pop("user", None)
28
+ flash('Logout successful','info')
29
+ return redirect(url_for("auth.login"))
app/routes/tasks.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Blueprint, request ,session, redirect, render_template, url_for, flash
2
+ from app import db
3
+ from app.models import Task
4
+
5
+ tasks_bp = Blueprint('tasks' , __name__)
6
+
7
+ @tasks_bp.route('/')
8
+ def view_tasks():
9
+ if 'user' not in session:
10
+ #flash('Please log in first.', 'warning')
11
+ return redirect(url_for('auth.login'))
12
+
13
+ tasks = Task.query.all()
14
+ return render_template('tasks.html', tasks=tasks)
15
+
16
+ @tasks_bp.route('/add', methods = ["POST"])
17
+ def add_tasks():
18
+ if 'user' not in session:
19
+ return redirect(url_for('auth.login'))
20
+
21
+ title = request.form.get('title')
22
+ if title:
23
+ new_task = Task(title=title , status = 'Pending')
24
+ db.session.add(new_task)
25
+ db.session.commit()
26
+ flash('Task Added Successful' , 'success')
27
+
28
+ return redirect(url_for('tasks.view_tasks'))
29
+
30
+ @tasks_bp.route('/toggle/<int:task_id>', methods = ["POST"])
31
+ def toggle_status(task_id):
32
+ task = Task.query.get(task_id)
33
+ if task:
34
+ if task.status == 'Pending':
35
+ task.status = 'Working'
36
+ elif task.status == 'Working':
37
+ task.status = 'Done'
38
+ else:
39
+ task.status = 'Pending'
40
+ db.session.commit()
41
+ return redirect(url_for('tasks.view_tasks'))
42
+
43
+
44
+ @tasks_bp.route('/clear', methods=["POST"])
45
+ def clear_tasks():
46
+ Task.query.delete()
47
+ db.session.commit()
48
+ flash('All tasks cleared!', 'info')
49
+ return redirect(url_for('tasks.view_tasks'))
50
+
51
+
52
+ @tasks_bp.route('/debug')
53
+ def debug_tasks():
54
+ try:
55
+ tasks = Task.query.all()
56
+ return f"Tasks in DB: {[task.title for task in tasks]}"
57
+ except Exception as e:
58
+ return f"Error: {str(e)}"
app/static/css/style.css ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
4
+ background: #f8f9fa;
5
+ }
6
+
7
+ .container {
8
+ max-width: 800px;
9
+ margin: auto;
10
+ padding: 20px;
11
+ }
12
+
13
+ /* Header */
14
+ header {
15
+ background: linear-gradient(to right, #0062E6, #33AEFF);
16
+ color: white;
17
+ padding: 20px 0;
18
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
19
+ }
20
+
21
+ header h1 {
22
+ margin: 0;
23
+ font-size: 28px;
24
+ text-align: center;
25
+ letter-spacing: 1px;
26
+ }
27
+
28
+ nav {
29
+ text-align: center;
30
+ margin-top: 10px;
31
+ }
32
+ nav a {
33
+ color: white;
34
+ text-decoration: none;
35
+ margin: 0 15px;
36
+ font-weight: 500;
37
+ transition: color 0.3s ease;
38
+ }
39
+
40
+ nav a:hover {
41
+ color: #ffd700;
42
+ }
43
+
44
+ /* footer */
45
+ footer {
46
+ background-color: #343a40;
47
+ color: #ccc;
48
+ padding: 15px 0;
49
+ text-align: center;
50
+ font-size: 14px;
51
+ margin-top: 60px;
52
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
53
+ }
54
+
55
+ footer p {
56
+ margin: 0;
57
+ }
58
+
59
+
60
+ /* Flash messages */
61
+ .flash.success {color: green;}
62
+ .flash.danger {color: red;}
63
+ .flash.info { color: blue;}
64
+
65
+ /* Login form */
66
+ .login-box {
67
+ max-width: 400px;
68
+ margin: 40px auto;
69
+ padding: 30px;
70
+ background-color: white;
71
+ border-radius: 8px;
72
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
73
+ }
74
+
75
+
76
+ .login-box h2 {
77
+ text-align: center;
78
+ margin-bottom: 20px;
79
+ }
80
+
81
+ .form-group {
82
+ margin-bottom: 20px;
83
+ }
84
+
85
+ .form-group label {
86
+ display: block;
87
+ font-weight: bold;
88
+ margin-bottom: 6px;
89
+ }
90
+
91
+ .form-group input {
92
+ width: 100%;
93
+ padding: 12px;
94
+ font-size: 16px;
95
+ border-radius: 4px;
96
+ border: 1px solid #ccc;
97
+ box-sizing: border-box;
98
+ margin-bottom: 6px;
99
+ }
100
+
101
+ .btn {
102
+ background-color: #007bff;
103
+ color: white;
104
+ border: none;
105
+ padding: 12px;
106
+ width: 100%;
107
+ font-size: 16px;
108
+ border-radius: 4px;
109
+ cursor: pointer;
110
+ }
111
+
112
+ .btn:hover {
113
+ background-color: #0056b3;
114
+ }
115
+
116
+ .task-box {
117
+ max-width: 700px;
118
+ margin: 40px auto;
119
+ background-color: white;
120
+ padding: 25px;
121
+ border-radius: 8px;
122
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
123
+ }
124
+
125
+ .task-form {
126
+ display: flex;
127
+ gap: 10px;
128
+ margin-bottom: 25px;
129
+ }
130
+
131
+ .task-form input[type="text"] {
132
+ flex: 1;
133
+ padding: 12px;
134
+ font-size: 16px;
135
+ border: 1px solid #ccc;
136
+ border-radius: 4px;
137
+ }
138
+
139
+ .task-form .btn {
140
+ padding: 12px 20px;
141
+ font-size: 16px;
142
+ }
143
+
144
+ .task-table {
145
+ width: 100%;
146
+ border-collapse: collapse;
147
+ }
148
+
149
+ .task-table th,
150
+ .task-table td {
151
+ text-align: left;
152
+ padding: 12px;
153
+ border-bottom: 1px solid #ddd;
154
+ }
155
+
156
+ .task-table th {
157
+ background-color: #f2f2f2;
158
+ }
159
+
160
+ .btn-delete {
161
+ background-color: #dc3545;
162
+ color: white;
163
+ padding: 6px 12px;
164
+ font-size: 14px;
165
+ border-radius: 4px;
166
+ text-decoration: none;
167
+ }
168
+
169
+ .btn-delete:hover {
170
+ background-color: #c82333;
171
+ }
172
+
173
+ .badge {
174
+ padding: 5px 10px;
175
+ border-radius: 4px;
176
+ font-weight: bold;
177
+ color: white;
178
+ }
179
+
180
+ .badge.pending {
181
+ background-color: #ffc107;
182
+ }
183
+
184
+ .badge.working {
185
+ background-color: #17a2b8;
186
+ }
187
+
188
+ .badge.done {
189
+ background-color: #28a745;
190
+ }
191
+
192
+ .btn-small {
193
+ font-size: 12px;
194
+ padding: 6px 12px;
195
+ border: none;
196
+ background-color: #6c767d;
197
+ color: white;
198
+ border-radius: 4px;
199
+ cursor: pointer;
200
+ }
201
+
202
+ .btn-small:hover {
203
+ background-color: #495057;
204
+ }
205
+
206
+ .btn-clear {
207
+ background-color: #dc3545;
208
+ margin-bottom: 10px;
209
+ }
210
+
211
+ .btn-clear:hover {
212
+ background-color: #c82333;
213
+ }
app/static/js/script.js ADDED
@@ -0,0 +1 @@
 
 
1
+ console.log("To-Do app JavaS");
app/templates/base.html ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>{% block title %} To-Do App {% endblock %}</title>
6
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
7
+ </head>
8
+ <body>
9
+ <header>
10
+ <div class="container">
11
+ <h1>My To-Do App</h1>
12
+ <nav>
13
+ <a href="{{ url_for('tasks.view_tasks') }}">Home</a>
14
+ {% if 'user' in session %}
15
+ <a href="{{ url_for('auth.logout') }}">Logout</a>
16
+ {% else %}
17
+ <a href="{{ url_for('auth.login') }}">Login</a>
18
+ {% endif %}
19
+ </nav>
20
+ </div>
21
+ </header>
22
+
23
+ <main class="container">
24
+ {% with messages = get_flashed_messages(with_categories=True) %}
25
+ {% for category, message in messages %}
26
+ <div class="flash {{ category }}">{{ message }}</div>
27
+ {% endfor %}
28
+ {% endwith %}
29
+ </main>
30
+
31
+ {% block content %}
32
+ {% endblock %}
33
+
34
+ <footer>
35
+ <div class="container">
36
+ <p>&copy; {{ 2025 }} My Flask To-Do App</p>
37
+ </div>
38
+ </footer>
39
+
40
+ </body>
41
+ </html>
app/templates/login.html ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block title %}Login{% endblock %}
3
+
4
+ {% block content %}
5
+ <div class="login-box">
6
+ <h2>Login</h2>
7
+ <form method="POST">
8
+ <div class="form-group">
9
+ <label for="username">Username</label>
10
+ <input type="text" name="username" id="username" required>
11
+ </div>
12
+
13
+ <div class="form-group">
14
+ <label for="password">Password</label>
15
+ <input type="password" name="password" id="password" required>
16
+ </div>
17
+
18
+ <button type="submit" class="btn">Login</button>
19
+ </form>
20
+ </div>
21
+ {% endblock %}
app/templates/register.html ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block content %}
3
+ <p>Registration comming soon baby .....</p>
4
+ {% endblock %}
app/templates/tasks.html ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% extends "base.html" %}
2
+ {% block title %}Tasks{% endblock %}
3
+
4
+ {% block content %}
5
+ <div class="task-box">
6
+ <h2>Your Tasks</h2>
7
+ <form action="{{ url_for('tasks.add_tasks') }}" method="post" class="task-form">
8
+ <input type="text" name="title" placeholder="New task" required>
9
+ <button type="submit" class="btn">Add</button>
10
+ </form>
11
+
12
+ {% if tasks %}
13
+ <form method="POST" action="{{ url_for('tasks.clear_tasks') }}">
14
+ <button type="submit" class="btn btn-clear">Clear All Tasks</button>
15
+ </form>
16
+ <br>
17
+
18
+ <table class="task-table">
19
+ <thead>
20
+ <tr>
21
+ <th>Task</th>
22
+ <th>Status</th>
23
+ <th>Change</th>
24
+ </tr>
25
+ </thead>
26
+ <tbody>
27
+ {% for task in tasks %}
28
+ <tr>
29
+ <td>{{ loop.index }}</td>
30
+ <td>{{ task.title }}</td>
31
+ <td><span class="badge {{ task.status|lower }}">{{ task.status }}</span></td>
32
+ <td>
33
+ <form action="{{ url_for('tasks.toggle_status', task_id=task.id) }}" method="post">
34
+ <button class="btn-small" type="submit">Next</button>
35
+ </form>
36
+ </td>
37
+ </tr>
38
+ {% endfor %}
39
+ </tbody>
40
+ </table>
41
+ {% else %}
42
+ <p>No tasks yet. Add one above!</p>
43
+ {% endif %}
44
+ </div>
45
+
46
+ {% endblock %}
run.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from app import create_app, db
2
+ from app.models import Task
3
+
4
+ app = create_app()
5
+
6
+ with app.app_context():
7
+ db.create_all()
8
+
9
+ if __name__ == "__main__":
10
+ app.run(debug=True)