diff --git a/tmproj/db.sqlite3 b/tmproj/db.sqlite3 new file mode 100644 index 0000000..f4261f1 Binary files /dev/null and b/tmproj/db.sqlite3 differ diff --git a/tmproj/manage.py b/tmproj/manage.py new file mode 100644 index 0000000..9373f7f --- /dev/null +++ b/tmproj/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tmproj.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/tmproj/static/create_task.css b/tmproj/static/create_task.css new file mode 100644 index 0000000..b088643 --- /dev/null +++ b/tmproj/static/create_task.css @@ -0,0 +1,127 @@ +body { + position: relative; + height: 100vh; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + color: #fff; + margin: 0; +} + + +body::before { + content: ""; + position: absolute; + top: -25px; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +header { + text-align: center; + margin-bottom: 20px; +} + +h2 { + color: #ccffd5; + font-size: 24px; + text-align: center; + margin-bottom: 0px; + font-family: cursive; + background-color: #123f11; + width: 75%; + padding: 5px; + border-radius: 5px; + box-shadow: 0 0 15px 4px #8cb7056e; +} + +main { + margin: 0 auto; +} + +form { + text-align: -webkit-center; + max-width: 600px; + margin: 0 auto; +} + +p { + margin: 0px; +} + +label { + display: block; + margin-bottom: 5px; + color: #f9ff00d6; + font-family: monospace; + font-size: 20px; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; +} + +input[type="text"], +textarea, +input[type="datetime-local"] { + width: 100%; + padding: 10px; + border: 1px solid #000; + border-radius: 4px; + margin-bottom: 10px; + font-size: 15px; + outline: none; + font-family: monospace; + box-shadow: 0 0 12px 2px; + text-align: center; +} + +button[type="submit"] { + background-color: #062804; + color: #fff; + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; + width: 48%; + margin-left: 1%; + font-size: 20px; + box-shadow: 0 0 12px 2px #197b12b5; +} + +button[type="submit"]:hover { + background-color: #359333; +} + + +.task-list-button { + background-color: #21501b; + color: #fff; + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; + width: 100%; + margin-top: 10px; +} + +label[for="id_priority"] { + display: block; + margin-bottom: 5px; +} + +select#id_priority { + width: 104%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 20px; + font-family: monospace; + text-align: center; + box-shadow: 0 0 12px 2px; +} + +p select#id_priority { + margin-bottom: 20px; +} diff --git a/tmproj/static/home.css b/tmproj/static/home.css new file mode 100644 index 0000000..5488fd3 --- /dev/null +++ b/tmproj/static/home.css @@ -0,0 +1,77 @@ +body { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + color: #fff; + margin: 0; +} + +body::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +header, nav { + text-align: center; + margin-bottom: 20px; +} + +h1, h2 { + font-family: cursive, 'Arial', sans-serif; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; +} + +.links { + background-color: #0b6511; + color: #fff; + padding: 12px 24px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 18px; + margin-bottom: 10px; + transition: background-color 0.3s ease, color 0.3s ease; + box-shadow: 0 0 6px 5px #cbcd25; +} + +.links:hover { + background-color: #094909; + color: #fff; +} + + +#logout { + background-color: #c0392b; + color: #fff; + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; +} + +p.description { + display: block; + font-size: 20px; + font-family: cursive; + width: 70%; + text-align: center; + background-color: rgba(197, 213, 211, 0.93); + color: #000; + border-radius: 5px; + padding: 20px; + border: 2px solid #008000; + box-shadow: 0 0 13px 5px; +} \ No newline at end of file diff --git a/tmproj/static/home.jpg b/tmproj/static/home.jpg new file mode 100644 index 0000000..ecd6e4d Binary files /dev/null and b/tmproj/static/home.jpg differ diff --git a/tmproj/static/login.css b/tmproj/static/login.css new file mode 100644 index 0000000..a08c2c1 --- /dev/null +++ b/tmproj/static/login.css @@ -0,0 +1,143 @@ +body { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + color: #fff; + margin: 0; +} + +body::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +.login-container { + max-width: 25%; + font-family: cursive; + padding: 20px; + background-color: #ffffffd1; + box-shadow: 0 0 12px 5px rgb(0 0 0); +} + +h1 { + text-align: center; + margin-bottom: 20px; + color: #000; +} + +form { + margin-bottom: 20px; +} + +.form-group { + margin-bottom: 10px; +} + +label { + display: block; + font-weight: bold; + font-size: 20px; + font-family: monospace; + margin-top: 25px; + color: #000; +} + +input[type="text"], +input[type="password"] { + width: 90%; + padding: 10px; + margin: 5px; + border: none; + border-bottom: 2.5px solid; + outline: none; + background-color: #ffffff00; + font-size: 19px; + font-family: sans-serif; +} + +button.login { + background-color: #269b76; + color: #fff; + padding: 8px 16px; + font-size: 22px; + font-family: monospace; + border: none; + border-radius: 4px; + cursor: pointer; + width: 50%; + display: block; + margin: 0 auto; +} + +p.register-text { + text-align: center; + margin-top: 10px; + color: #000; +} + +p.register-text button { + border: none; + color: #007500; + cursor: pointer; + font-size: 22px; + background-color: #fff; + padding: 10px 20px; + font-family: monospace; + border-radius: 5px; +} + + +ul.messages { + list-style: none; + padding: 0; + margin-bottom: 20px; + text-align: center; + max-width: 300px; +} + +ul.messages li { + margin-bottom: 5px; + font-size: 18px; +} + + +ul.messages li.error { + color: red; +} + + +ul.messages li.success { + color: #007500; +} + + +ul.messages li.info { + color: #269b76; +} + + + +button.login:hover { + background-color: #1e7e5e; +} + + +p.register-text button:hover { + background-color: #269b76; + color: #fff; +} + + diff --git a/tmproj/static/register.css b/tmproj/static/register.css new file mode 100644 index 0000000..d1eaf7c --- /dev/null +++ b/tmproj/static/register.css @@ -0,0 +1,135 @@ +body { + background-color: #f2f2f2; + display: flex; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + align-items: center; + justify-content: center; + height: 100vh; +} + +body::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +.register-container { + min-width: 300px; + font-family: cursive; + padding: 20px; + background-color: #ffffffd1; + box-shadow: 0 0 12px 5px rgb(0 0 0); +} + +h1 { + text-align: center; + margin-bottom: 20px; + margin-top: 0; +} + +form { + margin-bottom: 20px; +} + +.form-group { + margin-bottom: 10px; +} + +label { + display: block; + font-weight: bold; + font-size: 20px; + font-family: monospace; + margin-top: 25px; +} + +input[type="text"], +input[type="password"], +input[type="email"] { + width: 90%; + padding: 5px; + margin: 5px; + border: none; + border-bottom: 2.5px solid; + outline: none; + background-color: #ffffff00; + font-size: 19px; + font-family: sans-serif; +} + +button.register { + background-color: #269b76; + color: #fff; + padding: 8px 16px; + font-size: 22px; + font-family: monospace; + border: none; + border-radius: 4px; + cursor: pointer; + width: 50%; + display: block; + margin: 0 auto; +} + +button.register:hover { + background-color: #1e7e5e; +} + +p.login-text { + text-align: center; + margin-top: 10px; + margin-bottom: 0; +} + +p.login-text button { + border: none; + color: #007500; + cursor: pointer; + font-size: 22px; + background-color: #fff; + padding: 10px 20px; + font-family: monospace; + border-radius: 5px; +} + +p.login-text button:hover { + background-color: #269b76; + color: #fff; +} + + +ul.messages { + list-style: none; + padding: 0; + margin-bottom: 20px; + text-align: center; + max-width: 300px; +} + +ul.messages li { + margin-bottom: 5px; + font-size: 18px; +} + + +ul.messages li.error { + color: red; +} + + +ul.messages li.success { + color: #007500; +} + + +ul.messages li.info { + color: #269b76; +} diff --git a/tmproj/static/remove_task.css b/tmproj/static/remove_task.css new file mode 100644 index 0000000..6ad2d04 --- /dev/null +++ b/tmproj/static/remove_task.css @@ -0,0 +1,81 @@ +body { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + color: #fff; + margin: 0; +} + +body::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +h2 { + text-align: center; + color: #950000; + font-size: 30px; + font-family: monospace; + margin-top: 20px; +} + +p { + text-align: center; + font-size: 26px; + font-family: monospace; + margin: 10px; + color: #000; +} + +form { + text-align: center; + margin-top: 20px; + background-color: #ffffffa3; + border-radius: 5px; + box-shadow: 0 0 10px 4px #000; +} + +button[type="submit"] { + background-color: #c0392b; + color: #fff; + font-size: 20px; + padding: 10px 20px; + border: none; + margin: 10px; + border-radius: 4px; + cursor: pointer; +} + +button:hover, +a:hover { + filter: brightness(1.2); +} + +a { + color: #269b76; + text-decoration: none; + padding: 8px 16px; + background-color: #fff; + border: 1px solid #269b76; + font-size: 21px; + border-radius: 4px; + transition: background-color 0.3s ease, color 0.3s ease; +} + +a:hover { + background-color: #269b76; + color: #fff; +} diff --git a/tmproj/static/task_list.css b/tmproj/static/task_list.css new file mode 100644 index 0000000..576b483 --- /dev/null +++ b/tmproj/static/task_list.css @@ -0,0 +1,170 @@ +body { + position: relative; + height: 100vh; + background-image: url('home.jpg'); + background-size: cover; + background-position: center; + color: #fff; + margin: 0; +} + + +body::before { + content: ""; + position: absolute; + top: -25px; + right: 0; + bottom: 0; + left: 0; + background: rgba(113, 145, 119, 0.6); + z-index: -1; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); +} + +h1 { + text-align: center; + color: #000; + font-size: 30px; + font-family: monospace; + margin-top: 20px; + background-color: #fff; + padding: 5px; + border-radius: 5px; + box-shadow: 0 0 15px 4px #000; +} + +ul { + list-style-type: none; + padding: 0; +} + +li { + background-color: #fff; + margin-bottom: 10px; + border-radius: 4px; + padding: 10px; + position: relative; + width: 96%; + left: 1%; + box-shadow: 0 0 15px 4px #000000c7; +} + +li:hover { + background-color: #f5f5f5; +} + +.task-title { + background-color: #269b76; + color: #fff; + padding: 20px 35px; + border-radius: 4px; + font-weight: bold; + font-size: 25px; + margin-bottom: 10px; +} +.description p , +p.task_notes { + color: #000; + font-family: monospace; + font-size: 15px; +} +.more-button { + background-color: #87b310; + color: #fff; + padding: 17px 40px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 30px; + position: absolute; + top: 10px; + right: 10px; +} + +.task-details { + display: none; + margin-top: 10px; + padding: 10px; + background-color: #fff; + border-radius: 4px; +} + +.description { + border: 1px solid #ccc; + padding: 10px; + border-radius: 4px; + margin-bottom: 10px; +} + +.details-footer { + display: flex; + justify-content: space-between; + font-size: 12px; +} + +.notes { + border: 1px solid #ccc; + padding: 10px; + border-radius: 4px; + font-size: 12px; +} + +.edit-button { + background-color: #e8b025; + color: #fff; + padding: 9px 33px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 20px; + margin-right: 10px; +} + +.remove-button { + background-color: #c0392b; + color: #fff; + padding: 9px 33px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 20px; +} + +#create { + background-color: #132da1; + color: #fff; + padding: 18px 16px; + position: relative; + border: none; + font-family: monospace; + left: 1%; + border-radius: 4px; + cursor: pointer; + margin-top: 10px; + font-size: 20px; + box-shadow: 0 0 10px 4px; +} + +#home { + background-color: #21501b; + color: #fff; + padding: 18px 16px; + border: none; + font-family: monospace; + border-radius: 4px; + cursor: pointer; + margin-top: 10px; + left: 1%; + position: relative; + font-size: 20px; + margin-left: 10px; + box-shadow: 0 0 10px 4px; +} + +.edit-button:hover, +.remove-button:hover, +#create:hover, +#home:hover { + filter: brightness(1.2); + transition: filter 0.3s ease; +} diff --git a/tmproj/templates/create_task.html b/tmproj/templates/create_task.html new file mode 100644 index 0000000..9ebb3b1 --- /dev/null +++ b/tmproj/templates/create_task.html @@ -0,0 +1,25 @@ +{% load static %} + + + + + + + Create Task + + + + +
+
+

Create Task

+ {% csrf_token %} + {{ form.as_p }} + + +
+
+ + + + diff --git a/tmproj/templates/edit_task.html b/tmproj/templates/edit_task.html new file mode 100644 index 0000000..255ceb7 --- /dev/null +++ b/tmproj/templates/edit_task.html @@ -0,0 +1,23 @@ +{% load static %} + + + + + + + Edit Task + + + + +
+
+

Edit Task

+ {% csrf_token %} + {{ form.as_p }} + +
+
+ + + diff --git a/tmproj/templates/home.html b/tmproj/templates/home.html new file mode 100644 index 0000000..b87bfe5 --- /dev/null +++ b/tmproj/templates/home.html @@ -0,0 +1,38 @@ +{% load static %} + + + + + + + Task Manager + + + + + {% if user.is_authenticated %} +
+

Hello, {{ user.username }}!
Welcome back

+
+ + {% else %} +
+

Wellcome to Task Manager!

+ +
+

Task Manager is your personal assistant for staying organized. Create tasks, set due dates, + and add notes, and even alerts to ensure you never forget important activities. Log in or register to get started!

+ + {% endif %} + + + diff --git a/tmproj/templates/login.html b/tmproj/templates/login.html new file mode 100644 index 0000000..e98986c --- /dev/null +++ b/tmproj/templates/login.html @@ -0,0 +1,41 @@ +{% load static %} + + + + + + + Login + + + + +
+ {% if messages %} + + {% endif %} + +

Login

+
+ {% csrf_token %} +
+ + +
+
+ + +
+ +
+

Don't have an account?
+ +

+
+ + + diff --git a/tmproj/templates/register.html b/tmproj/templates/register.html new file mode 100644 index 0000000..7e0d03a --- /dev/null +++ b/tmproj/templates/register.html @@ -0,0 +1,51 @@ +{% load static %} + + + + + + + Register + + + + +
+ +
+
+
+ {% csrf_token %} + {% if messages %} + + {% endif %} +

Register

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+ + + diff --git a/tmproj/templates/remove_task.html b/tmproj/templates/remove_task.html new file mode 100644 index 0000000..bcf0c33 --- /dev/null +++ b/tmproj/templates/remove_task.html @@ -0,0 +1,25 @@ +{% load static %} + + + + + + + Remove Task + + + + + +
+

Remove Task

+

Are you sure you want to remove this task?

+ {% csrf_token %} + + Cancel +
+ + + + + diff --git a/tmproj/templates/task_list.html b/tmproj/templates/task_list.html new file mode 100644 index 0000000..0c846db --- /dev/null +++ b/tmproj/templates/task_list.html @@ -0,0 +1,55 @@ +{% load static %} + + + + + + + Task List + + + + + + + + + + + + diff --git a/tmproj/tmapp/__init__.py b/tmproj/tmapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tmproj/tmapp/__pycache__/__init__.cpython-311.pyc b/tmproj/tmapp/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..d2fe97b Binary files /dev/null and b/tmproj/tmapp/__pycache__/__init__.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/admin.cpython-311.pyc b/tmproj/tmapp/__pycache__/admin.cpython-311.pyc new file mode 100644 index 0000000..3cd685d Binary files /dev/null and b/tmproj/tmapp/__pycache__/admin.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/apps.cpython-311.pyc b/tmproj/tmapp/__pycache__/apps.cpython-311.pyc new file mode 100644 index 0000000..60bcc5d Binary files /dev/null and b/tmproj/tmapp/__pycache__/apps.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/forms.cpython-311.pyc b/tmproj/tmapp/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..7a1c6df Binary files /dev/null and b/tmproj/tmapp/__pycache__/forms.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/models.cpython-311.pyc b/tmproj/tmapp/__pycache__/models.cpython-311.pyc new file mode 100644 index 0000000..f601723 Binary files /dev/null and b/tmproj/tmapp/__pycache__/models.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/urls.cpython-311.pyc b/tmproj/tmapp/__pycache__/urls.cpython-311.pyc new file mode 100644 index 0000000..039577a Binary files /dev/null and b/tmproj/tmapp/__pycache__/urls.cpython-311.pyc differ diff --git a/tmproj/tmapp/__pycache__/views.cpython-311.pyc b/tmproj/tmapp/__pycache__/views.cpython-311.pyc new file mode 100644 index 0000000..00e4737 Binary files /dev/null and b/tmproj/tmapp/__pycache__/views.cpython-311.pyc differ diff --git a/tmproj/tmapp/admin.py b/tmproj/tmapp/admin.py new file mode 100644 index 0000000..7e3e287 --- /dev/null +++ b/tmproj/tmapp/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from .models import Task +# Register your models here. + +admin.site.register(Task) \ No newline at end of file diff --git a/tmproj/tmapp/apps.py b/tmproj/tmapp/apps.py new file mode 100644 index 0000000..5da013d --- /dev/null +++ b/tmproj/tmapp/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TmappConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'tmapp' diff --git a/tmproj/tmapp/forms.py b/tmproj/tmapp/forms.py new file mode 100644 index 0000000..8b9e260 --- /dev/null +++ b/tmproj/tmapp/forms.py @@ -0,0 +1,19 @@ +from django import forms +from .models import Task, User +from django.forms import DateTimeInput +class TaskForm(forms.ModelForm): + class Meta: + model = Task + fields = ['title', 'description', 'due_date', 'notes', 'priority'] + widgets = { + 'due_date': forms.DateTimeInput(attrs={'type': 'datetime-local'}), + 'description': forms.Textarea(attrs={'cols': 60, 'rows': 6}), + 'notes': forms.Textarea(attrs={'cols': 60, 'rows': 3}), + 'priority': forms.Select(choices=Task.PRIORITY_CHOICES), + } + +class RegistrationForm(forms.ModelForm): + class Meta: + model = User + fields = '__all__' + diff --git a/tmproj/tmapp/migrations/0001_initial.py b/tmproj/tmapp/migrations/0001_initial.py new file mode 100644 index 0000000..a05230f --- /dev/null +++ b/tmproj/tmapp/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.2 on 2023-06-15 07:53 + +from django.db import migrations, models +import taggit.managers + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('taggit', '0005_auto_20220424_2025'), + ] + + operations = [ + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50)), + ('description', models.TextField(max_length=1000)), + ('timestamp', models.DateTimeField(auto_now=True)), + ('tag', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')), + ], + ), + ] diff --git a/tmproj/tmapp/migrations/0002_task_due_date.py b/tmproj/tmapp/migrations/0002_task_due_date.py new file mode 100644 index 0000000..a4a81a0 --- /dev/null +++ b/tmproj/tmapp/migrations/0002_task_due_date.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-06-15 09:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmapp', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='due_date', + field=models.DateTimeField(null=True), + ), + ] diff --git a/tmproj/tmapp/migrations/0003_user.py b/tmproj/tmapp/migrations/0003_user.py new file mode 100644 index 0000000..394ba71 --- /dev/null +++ b/tmproj/tmapp/migrations/0003_user.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.2 on 2023-06-20 07:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmapp', '0002_task_due_date'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('username', models.CharField(max_length=100)), + ('email', models.EmailField(max_length=100)), + ('password', models.CharField(max_length=100)), + ], + ), + ] diff --git a/tmproj/tmapp/migrations/0004_task_user.py b/tmproj/tmapp/migrations/0004_task_user.py new file mode 100644 index 0000000..ab1c2b2 --- /dev/null +++ b/tmproj/tmapp/migrations/0004_task_user.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.2 on 2023-06-24 07:46 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('tmapp', '0003_user'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='user', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/tmproj/tmapp/migrations/0005_task_checked.py b/tmproj/tmapp/migrations/0005_task_checked.py new file mode 100644 index 0000000..338c0f0 --- /dev/null +++ b/tmproj/tmapp/migrations/0005_task_checked.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-06-24 08:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmapp', '0004_task_user'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='checked', + field=models.BooleanField(default=False), + ), + ] diff --git a/tmproj/tmapp/migrations/0006_task_notes.py b/tmproj/tmapp/migrations/0006_task_notes.py new file mode 100644 index 0000000..810e44a --- /dev/null +++ b/tmproj/tmapp/migrations/0006_task_notes.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-06-28 07:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmapp', '0005_task_checked'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='notes', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/tmproj/tmapp/migrations/0007_remove_task_tag_task_priority_alter_task_description.py b/tmproj/tmapp/migrations/0007_remove_task_tag_task_priority_alter_task_description.py new file mode 100644 index 0000000..77c2fdc --- /dev/null +++ b/tmproj/tmapp/migrations/0007_remove_task_tag_task_priority_alter_task_description.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.2 on 2023-11-21 13:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmapp', '0006_task_notes'), + ] + + operations = [ + migrations.RemoveField( + model_name='task', + name='tag', + ), + migrations.AddField( + model_name='task', + name='priority', + field=models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High')], default='Medium', max_length=10), + ), + migrations.AlterField( + model_name='task', + name='description', + field=models.TextField(max_length=500), + ), + ] diff --git a/tmproj/tmapp/migrations/__init__.py b/tmproj/tmapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tmproj/tmapp/migrations/__pycache__/0001_initial.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..c04d8a5 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0002_task_due_date.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0002_task_due_date.cpython-311.pyc new file mode 100644 index 0000000..c6abef3 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0002_task_due_date.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0003_user.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0003_user.cpython-311.pyc new file mode 100644 index 0000000..01fd551 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0003_user.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0004_task_user.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0004_task_user.cpython-311.pyc new file mode 100644 index 0000000..9cbce0a Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0004_task_user.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0005_task_checked.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0005_task_checked.cpython-311.pyc new file mode 100644 index 0000000..0a9451e Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0005_task_checked.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0006_task_notes.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0006_task_notes.cpython-311.pyc new file mode 100644 index 0000000..82743a3 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0006_task_notes.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/0007_remove_task_tag_task_priority_alter_task_description.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/0007_remove_task_tag_task_priority_alter_task_description.cpython-311.pyc new file mode 100644 index 0000000..c4b5576 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/0007_remove_task_tag_task_priority_alter_task_description.cpython-311.pyc differ diff --git a/tmproj/tmapp/migrations/__pycache__/__init__.cpython-311.pyc b/tmproj/tmapp/migrations/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..4af40d3 Binary files /dev/null and b/tmproj/tmapp/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/tmproj/tmapp/models.py b/tmproj/tmapp/models.py new file mode 100644 index 0000000..1fcca8f --- /dev/null +++ b/tmproj/tmapp/models.py @@ -0,0 +1,32 @@ +from django.db import models +from taggit.managers import TaggableManager +from django.contrib.auth import get_user_model +# Create your models here. + +class Task(models.Model): + PRIORITY_CHOICES = [ + ('low', 'Low'), + ('medium', 'Medium'), + ('high', 'High'), + ] + + User = get_user_model() + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) + title = models.CharField(max_length=50) + description = models.TextField(max_length=500) + due_date = models.DateTimeField(null = True) + timestamp = models.DateTimeField(auto_now=True) + notes = models.TextField(blank=True, null=True) + priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='Medium') + checked = models.BooleanField(default=False) + + def __str__(self): + return ', '.join(self.tag.names()) + +class User(models.Model): + username = models.CharField(max_length=100) + email = models.EmailField(max_length=100) + password = models.CharField(max_length=100) + + def __str__(self): + return ', '.join(self.username.names()) \ No newline at end of file diff --git a/tmproj/tmapp/tests.py b/tmproj/tmapp/tests.py new file mode 100644 index 0000000..de8bdc0 --- /dev/null +++ b/tmproj/tmapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/tmproj/tmapp/urls.py b/tmproj/tmapp/urls.py new file mode 100644 index 0000000..0efaac0 --- /dev/null +++ b/tmproj/tmapp/urls.py @@ -0,0 +1,12 @@ +from django.urls import path +from . import views +urlpatterns = [ + path('', views.home, name = 'home'), + path('task/', views.task_list, name = 'task-list'), + path('task/create/', views.create_task, name = 'create-task'), + path('edit-task/', views.edit_task, name = 'edit-task'), + path('remove-task/', views.remove_task, name = 'remove-task'), + path('register/', views.register, name = 'register'), + path('login/', views.login, name = 'login'), + path('logout/', views.logout, name = 'logout') +] \ No newline at end of file diff --git a/tmproj/tmapp/views.py b/tmproj/tmapp/views.py new file mode 100644 index 0000000..535c9f1 --- /dev/null +++ b/tmproj/tmapp/views.py @@ -0,0 +1,91 @@ +from django.shortcuts import render, redirect +from django.http import request +from django.contrib import messages +from django.contrib.auth.models import auth, User +from django.contrib.auth.decorators import login_required +from .forms import TaskForm +from .models import Task +# Create your views here. + +def home(request): + return render(request, 'home.html') +@login_required(login_url='login') +def create_task(request): + if request.method == 'POST': + form = TaskForm(request.POST) + if form.is_valid(): + task = form.save(commit=False) + task.user = request.user + task.save() + return redirect('task-list') + else: + form = TaskForm() + return render(request, 'create_task.html', {'form':form}) +@login_required(login_url='login') +def task_list(request): + tasks = Task.objects.filter(user=request.user) + user = request.user + if not user.is_authenticated: + messages.error(request, 'you have to login to see the tasks') + return render(request, 'task_list.html', {'tasks':tasks}) + +def edit_task(request, task_id): + task = Task.objects.get(id = task_id) + if request.method == 'POST': + form = TaskForm(request.POST, instance= task) + if form.is_valid(): + form.save() + return redirect('task-list') + else: + form = TaskForm(instance = task) + return render(request, 'edit_task.html', {'form':form, 'task':task}) + +def remove_task(request, task_id): + task = Task.objects.get(id = task_id) + if request.method == 'POST': + task.delete() + return redirect('task-list') + return render(request, 'remove_task.html', {'task':task}) + + + +def register(request): + if request.method == 'POST': + username = request.POST['username'] + email = request.POST['email'] + password = request.POST['password'] + password2 = request.POST['password2'] + + if password == password2: + if User.objects.filter(username = username).exists(): + messages.error(request, 'Username already exists') + return redirect('register') + elif User.objects.filter(email = email).exists(): + messages.error(request, 'Email already in use') + return redirect('register') + user = User.objects.create_user(username = username, email = email, password = password) + user.save() + messages.success(request, 'user creation successful') + return redirect('login') + messages.error(request, 'passwords you entered are not the same') + return redirect('register') + return render(request, 'register.html') + +def login(request): + if request.method == 'POST': + username = request.POST['username'] + password = request.POST['password'] + + user = auth.authenticate(username = username, password = password) + + if user is not None: + auth.login(request, user) + return redirect('home') + else: + messages.error(request, 'username or password is invalid') + return redirect('login') + return render(request, 'login.html') + +def logout(request): + auth.logout(request) + return redirect('home') \ No newline at end of file diff --git a/tmproj/tmproj/__init__.py b/tmproj/tmproj/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tmproj/tmproj/__pycache__/__init__.cpython-311.pyc b/tmproj/tmproj/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..b6c5098 Binary files /dev/null and b/tmproj/tmproj/__pycache__/__init__.cpython-311.pyc differ diff --git a/tmproj/tmproj/__pycache__/settings.cpython-311.pyc b/tmproj/tmproj/__pycache__/settings.cpython-311.pyc new file mode 100644 index 0000000..0ff5c08 Binary files /dev/null and b/tmproj/tmproj/__pycache__/settings.cpython-311.pyc differ diff --git a/tmproj/tmproj/__pycache__/urls.cpython-311.pyc b/tmproj/tmproj/__pycache__/urls.cpython-311.pyc new file mode 100644 index 0000000..6f36c44 Binary files /dev/null and b/tmproj/tmproj/__pycache__/urls.cpython-311.pyc differ diff --git a/tmproj/tmproj/__pycache__/wsgi.cpython-311.pyc b/tmproj/tmproj/__pycache__/wsgi.cpython-311.pyc new file mode 100644 index 0000000..2c4668b Binary files /dev/null and b/tmproj/tmproj/__pycache__/wsgi.cpython-311.pyc differ diff --git a/tmproj/tmproj/asgi.py b/tmproj/tmproj/asgi.py new file mode 100644 index 0000000..e30cccf --- /dev/null +++ b/tmproj/tmproj/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for tmproj project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tmproj.settings') + +application = get_asgi_application() diff --git a/tmproj/tmproj/settings.py b/tmproj/tmproj/settings.py new file mode 100644 index 0000000..c21a80e --- /dev/null +++ b/tmproj/tmproj/settings.py @@ -0,0 +1,127 @@ +""" +Django settings for tmproj project. + +Generated by 'django-admin startproject' using Django 4.2.2. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" + +from pathlib import Path +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-apm6+cep$!k_741b69r0@h2m92cn^i=dd6m_j5n8*l#sopkn66' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'taggit', + 'tmapp' +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'tmproj.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR, 'templates'], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'tmproj.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = '/static/' +STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),) +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + diff --git a/tmproj/tmproj/urls.py b/tmproj/tmproj/urls.py new file mode 100644 index 0000000..b83c6e3 --- /dev/null +++ b/tmproj/tmproj/urls.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('tmapp.urls')) +] diff --git a/tmproj/tmproj/wsgi.py b/tmproj/tmproj/wsgi.py new file mode 100644 index 0000000..4496377 --- /dev/null +++ b/tmproj/tmproj/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for tmproj project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tmproj.settings') + +application = get_wsgi_application()