diff --git a/backend/server/adventures/migrations/0016_alter_note_date.py b/backend/server/adventures/migrations/0016_alter_note_date.py new file mode 100644 index 0000000..4e1b961 --- /dev/null +++ b/backend/server/adventures/migrations/0016_alter_note_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.7 on 2024-08-04 02:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('adventures', '0015_alter_note_date'), + ] + + operations = [ + migrations.AlterField( + model_name='note', + name='date', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/backend/server/adventures/migrations/0017_alter_note_date.py b/backend/server/adventures/migrations/0017_alter_note_date.py new file mode 100644 index 0000000..ca0b8e6 --- /dev/null +++ b/backend/server/adventures/migrations/0017_alter_note_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.7 on 2024-08-04 02:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('adventures', '0016_alter_note_date'), + ] + + operations = [ + migrations.AlterField( + model_name='note', + name='date', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/backend/server/adventures/urls.py b/backend/server/adventures/urls.py index 7f876da..a914fc6 100644 --- a/backend/server/adventures/urls.py +++ b/backend/server/adventures/urls.py @@ -1,6 +1,6 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter -from .views import AdventureViewSet, CollectionViewSet, StatsViewSet, GenerateDescription, ActivityTypesView, TransportationViewSet +from .views import AdventureViewSet, CollectionViewSet, NoteViewSet, StatsViewSet, GenerateDescription, ActivityTypesView, TransportationViewSet router = DefaultRouter() router.register(r'adventures', AdventureViewSet, basename='adventures') @@ -9,6 +9,7 @@ router.register(r'stats', StatsViewSet, basename='stats') router.register(r'generate', GenerateDescription, basename='generate') router.register(r'activity-types', ActivityTypesView, basename='activity-types') router.register(r'transportations', TransportationViewSet, basename='transportations') +router.register(r'notes', NoteViewSet, basename='notes') urlpatterns = [ diff --git a/backend/server/adventures/views.py b/backend/server/adventures/views.py index aa93c06..d208bbd 100644 --- a/backend/server/adventures/views.py +++ b/backend/server/adventures/views.py @@ -6,7 +6,7 @@ from django.db.models.functions import Lower from rest_framework.response import Response from .models import Adventure, Collection, Transportation, Note from worldtravel.models import VisitedRegion, Region, Country -from .serializers import AdventureSerializer, CollectionSerializer, TransportationSerializer +from .serializers import AdventureSerializer, CollectionSerializer, NoteSerializer, TransportationSerializer from rest_framework.permissions import IsAuthenticated from django.db.models import Q, Prefetch from .permissions import IsOwnerOrReadOnly, IsPublicReadOnly @@ -431,7 +431,7 @@ class TransportationViewSet(viewsets.ModelViewSet): # return error message if user is not authenticated on the root endpoint def list(self, request, *args, **kwargs): # Prevent listing all adventures - return Response({"detail": "Listing all adventures is not allowed."}, + return Response({"detail": "Listing all transportations is not allowed."}, status=status.HTTP_403_FORBIDDEN) @action(detail=False, methods=['get']) @@ -457,4 +457,37 @@ class TransportationViewSet(viewsets.ModelViewSet): def perform_create(self, serializer): serializer.save(user_id=self.request.user) - \ No newline at end of file +class NoteViewSet(viewsets.ModelViewSet): + queryset = Note.objects.all() + serializer_class = NoteSerializer + permission_classes = [IsAuthenticated] + filterset_fields = ['is_public', 'collection'] + + # return error message if user is not authenticated on the root endpoint + def list(self, request, *args, **kwargs): + # Prevent listing all adventures + return Response({"detail": "Listing all notes is not allowed."}, + status=status.HTTP_403_FORBIDDEN) + + @action(detail=False, methods=['get']) + def all(self, request): + if not request.user.is_authenticated: + return Response({"error": "User is not authenticated"}, status=400) + queryset = Note.objects.filter( + Q(user_id=request.user.id) + ) + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) + + + def get_queryset(self): + + """ + This view should return a list of all notes + for the currently authenticated user. + """ + user = self.request.user + return Note.objects.filter(user_id=user) + + def perform_create(self, serializer): + serializer.save(user_id=self.request.user) \ No newline at end of file diff --git a/frontend/src/lib/components/NoteCard.svelte b/frontend/src/lib/components/NoteCard.svelte new file mode 100644 index 0000000..a2e3fd9 --- /dev/null +++ b/frontend/src/lib/components/NoteCard.svelte @@ -0,0 +1,32 @@ + + +
+
+

{note.name}

+
+ + +
+
+
diff --git a/frontend/src/lib/components/NoteModal.svelte b/frontend/src/lib/components/NoteModal.svelte new file mode 100644 index 0000000..e165632 --- /dev/null +++ b/frontend/src/lib/components/NoteModal.svelte @@ -0,0 +1,75 @@ + + + + + + + diff --git a/frontend/src/routes/collections/[id]/+page.svelte b/frontend/src/routes/collections/[id]/+page.svelte index 8c8fb60..4623ebe 100644 --- a/frontend/src/routes/collections/[id]/+page.svelte +++ b/frontend/src/routes/collections/[id]/+page.svelte @@ -15,6 +15,8 @@ import TransportationCard from '$lib/components/TransportationCard.svelte'; import EditTransportation from '$lib/components/EditTransportation.svelte'; import NewTransportation from '$lib/components/NewTransportation.svelte'; + import NoteCard from '$lib/components/NoteCard.svelte'; + import NoteModal from '$lib/components/NoteModal.svelte'; export let data: PageData; console.log(data); @@ -180,6 +182,8 @@ let transportationToEdit: Transportation; let isEditModalOpen: boolean = false; let isTransportationEditModalOpen: boolean = false; + let isNoteModalOpen: boolean = false; + let noteToEdit: Note; let newType: string; @@ -239,6 +243,15 @@ /> {/if} +{#if isNoteModalOpen} + (isNoteModalOpen = false)} + startDate={collection.start_date} + endDate={collection.end_date} + /> +{/if} + {#if isShowingCreateModal} 0} {#each notes as note} {#if note.date && new Date(note.date).toISOString().split('T')[0] === dateString} -
-

{note.name}

-

{note.date}

-

{note.content}

-
+ { + noteToEdit = event.detail; + isNoteModalOpen = true; + }} + /> {/if} {/each} {/if} @@ -502,7 +517,7 @@