diff --git a/server/notes/models.py b/server/notes/models.py index 1ae0e55..915cdf0 100644 --- a/server/notes/models.py +++ b/server/notes/models.py @@ -11,10 +11,34 @@ class User(AbstractUser): ) expiry_seconds = models.PositiveIntegerField(default=86400) + @property + def alive_created_notes(self) -> models.QuerySet["Note"]: + return ( + self.created_notes.filter(expiry__gt=timezone.now()) + .select_related("from_user", "to_user") + .order_by("-created_at") + ) + + @property + def all_created_notes(self) -> models.QuerySet["Note"]: + return self.created_notes.select_related("from_user", "to_user").order_by( + "-created_at" + ) + @property def alive_received_notes(self) -> models.QuerySet["Note"]: - return self.received_notes.filter(expiry__gt=timezone.now()).select_related( - "from_user", "to_user" + return ( + self.received_notes.filter(expiry__gt=timezone.now()) + .select_related("from_user", "to_user") + .order_by("-created_at") + ) + + @property + def expired_received_notes(self) -> models.QuerySet["Note"]: + return ( + self.received_notes.filter(expiry__lte=timezone.now()) + .select_related("from_user", "to_user") + .order_by("-created_at") ) @property diff --git a/server/notes/static/notes/stylesheets/style.css b/server/notes/static/notes/stylesheets/style.css index 965d436..4217125 100644 --- a/server/notes/static/notes/stylesheets/style.css +++ b/server/notes/static/notes/stylesheets/style.css @@ -119,8 +119,9 @@ select:nth-child(3n + 2), textarea:nth-child(3n + 2), button:nth-child(3n + 2), background-color: #a4d6f7; } -.note-from, .note-at { +.note-from, .note-to, .note-at { text-align: right; + color: #333; } @@ -137,3 +138,9 @@ select:nth-child(3n + 2), textarea:nth-child(3n + 2), button:nth-child(3n + 2), border-radius: 25px 155px 15px 25px / 115px 25px 225px 150px; background-color: #fac9dc; } + +.title-and-link { + display: flex; + justify-content: space-between; + align-items: center; +} diff --git a/server/notes/templates/notes/home.html b/server/notes/templates/notes/home.html index f25c20a..b0ab331 100644 --- a/server/notes/templates/notes/home.html +++ b/server/notes/templates/notes/home.html @@ -20,4 +20,40 @@ {% else %}
No Notes found
{% endif %} + + + {% if alive_created %} +
+ {% for note in alive_created %} +
+

{{ note.note }}

+

From {{ note.from_user.visible_name }}

+

{{ note.created_at|date:"j M Y, H:i"}}

+
+ {% endfor %} +
+ {% else %} +
No Notes found
+ {% endif %} + + + {% if archive %} +
+ {% for note in archive %} +
+

{{ note.note }}

+

From {{ note.from_user.visible_name }}

+

{{ note.created_at|date:"j M Y, H:i"}}

+
+ {% endfor %} +
+ {% else %} +
No Notes found
+ {% endif %} {% endblock %} diff --git a/server/notes/templates/notes/note_list.html b/server/notes/templates/notes/note_list.html new file mode 100644 index 0000000..9c9571e --- /dev/null +++ b/server/notes/templates/notes/note_list.html @@ -0,0 +1,24 @@ +{% extends "notes/base.html" %} + +{% block title %}{{ title }}{% endblock %} + +{% block body %} +

{{ title }}

+ {% include "notes/messages.html" %} + + {% if object_list %} +
+ {% for note in object_list %} +
+

{{ note.note }}

+ {% if show_from %}

From {{ note.from_user.visible_name }}

{% endif %} + {% if show_to %}

To {{ note.to_user.visible_name }}

{% endif %} +

{{ note.created_at|date:"j M Y, H:i"}}

+
+ {% endfor %} +
+ {% else %} +
No Notes found
+ {% endif %} + +{% endblock %} diff --git a/server/notes/urls.py b/server/notes/urls.py index 2dcd4fe..49594b8 100644 --- a/server/notes/urls.py +++ b/server/notes/urls.py @@ -5,11 +5,13 @@ from notes import views, api_views urlpatterns = [ - path("", views.HomePage.as_view(), name="home"), + path("", views.HomePageView.as_view(), name="home"), path("post-a-note/", views.PostNoteView.as_view(), name="post-a-note"), path("profile/", views.ProfileView.as_view(), name="profile"), path("login/", LoginView.as_view(), name="login"), path("logout/", LogoutView.as_view(), name="logout"), + path("archive/", views.ArchiveView.as_view(), name="archive"), + path("sent-notes/", views.SentNotesView.as_view(), name="sent-notes"), path("api/notes/", api_views.NoteListView.as_view(), name="api-notes-list"), path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), ] diff --git a/server/notes/views.py b/server/notes/views.py index 51983f6..2dbd2dd 100644 --- a/server/notes/views.py +++ b/server/notes/views.py @@ -2,23 +2,63 @@ from datetime import timedelta from typing import Any from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.exceptions import ImproperlyConfigured from django.urls import reverse_lazy from django.utils import timezone -from django.views.generic import CreateView, TemplateView, UpdateView +from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic.edit import FormMixin from notes.models import Note, User # Create your views here. -class HomePage(LoginRequiredMixin, TemplateView): +class HomePageView(LoginRequiredMixin, TemplateView): template_name = "notes/home.html" def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ctx = super().get_context_data(**kwargs) ctx["notes"] = self.request.user.alive_received_notes + ctx["archive"] = self.request.user.expired_received_notes[:5] + ctx["alive_created"] = self.request.user.alive_created_notes return ctx +class NoteView(LoginRequiredMixin, ListView): + # TODO: Add pagination to the template + template_name = "notes/note_list.html" + show_from = True + show_to = True + + def get_title(self): + if not hasattr(self, "title"): + raise ImproperlyConfigured( + "Set a `title` attribute on subclass or override `get_title(self)`" + ) + return self.title + + def get_context_data(self, **kwargs: Any) -> dict[str, Any]: + ctx = super().get_context_data(**kwargs) + ctx["title"] = self.get_title() + ctx["show_from"] = self.show_from + ctx["show_to"] = self.show_to + return ctx + + +class ArchiveView(NoteView): + title = "Archive" + show_to = False + + def get_queryset(self): + return self.request.user.expired_received_notes + + +class SentNotesView(NoteView): + title = "Sent Notes" + show_from = False + + def get_queryset(self): + return self.request.user.all_created_notes + + class PostNoteView(LoginRequiredMixin, CreateView): model = Note fields = ["to_user", "note"]