diff --git a/backend/server/adventures/migrations/0010_collection_link.py b/backend/server/adventures/migrations/0010_collection_link.py new file mode 100644 index 0000000..85a5341 --- /dev/null +++ b/backend/server/adventures/migrations/0010_collection_link.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.8 on 2024-10-08 03:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('adventures', '0009_alter_adventure_type'), + ] + + operations = [ + migrations.AddField( + model_name='collection', + name='link', + field=models.URLField(blank=True, max_length=2083, null=True), + ), + ] diff --git a/backend/server/adventures/models.py b/backend/server/adventures/models.py index e79ef24..5dc49f7 100644 --- a/backend/server/adventures/models.py +++ b/backend/server/adventures/models.py @@ -117,6 +117,7 @@ class Collection(models.Model): updated_at = models.DateTimeField(auto_now=True) is_archived = models.BooleanField(default=False) shared_with = models.ManyToManyField(User, related_name='shared_with', blank=True) + link = models.URLField(blank=True, null=True, max_length=2083) # if connected adventures are private and collection is public, raise an error diff --git a/backend/server/adventures/serializers.py b/backend/server/adventures/serializers.py index 4bf7e8c..f2a10de 100644 --- a/backend/server/adventures/serializers.py +++ b/backend/server/adventures/serializers.py @@ -176,8 +176,7 @@ class CollectionSerializer(serializers.ModelSerializer): class Meta: model = Collection - # fields are all plus the adventures field - fields = ['id', 'description', 'user_id', 'name', 'is_public', 'adventures', 'created_at', 'start_date', 'end_date', 'transportations', 'notes', 'updated_at', 'checklists', 'is_archived', 'shared_with'] + fields = ['id', 'description', 'user_id', 'name', 'is_public', 'adventures', 'created_at', 'start_date', 'end_date', 'transportations', 'notes', 'updated_at', 'checklists', 'is_archived', 'shared_with', 'link'] read_only_fields = ['id', 'created_at', 'updated_at', 'user_id'] def to_representation(self, instance): diff --git a/frontend/src/lib/components/EditCollection.svelte b/frontend/src/lib/components/EditCollection.svelte index eac47d0..e46d251 100644 --- a/frontend/src/lib/components/EditCollection.svelte +++ b/frontend/src/lib/components/EditCollection.svelte @@ -11,16 +11,8 @@ let originalName = collectionToEdit.name; - let isPointModalOpen: boolean = false; - - import MapMarker from '~icons/mdi/map-marker'; import Calendar from '~icons/mdi/calendar'; import Notebook from '~icons/mdi/notebook'; - import ClipboardList from '~icons/mdi/clipboard-list'; - import Image from '~icons/mdi/image'; - import Star from '~icons/mdi/star'; - import Attachment from '~icons/mdi/attachment'; - import PointSelectionModal from './PointSelectionModal.svelte'; import Earth from '~icons/mdi/earth'; onMount(async () => { @@ -156,6 +148,16 @@ class="input input-bordered w-full max-w-xs mt-1" /> +
+
+ +

+
+
+ +
diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index ac862fb..f02822e 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -87,6 +87,7 @@ export type Collection = { checklists?: Checklist[]; is_archived?: boolean; shared_with: string[]; + link?: string | null; }; export type OpenStreetMapPlace = { diff --git a/frontend/src/routes/collections/+page.server.ts b/frontend/src/routes/collections/+page.server.ts index 90bce78..9d2477f 100644 --- a/frontend/src/routes/collections/+page.server.ts +++ b/frontend/src/routes/collections/+page.server.ts @@ -53,6 +53,11 @@ export const actions: Actions = { const description = formData.get('description') as string | null; const start_date = formData.get('start_date') as string | null; const end_date = formData.get('end_date') as string | null; + let link = formData.get('link') as string | null; + + if (link) { + link = checkLink(link); + } if (!name) { return { @@ -66,6 +71,7 @@ export const actions: Actions = { formDataToSend.append('description', description || ''); formDataToSend.append('start_date', start_date || ''); formDataToSend.append('end_date', end_date || ''); + formDataToSend.append('link', link || ''); let auth = event.cookies.get('auth'); if (!auth) { @@ -142,6 +148,7 @@ export const actions: Actions = { let is_public = formData.get('is_public') as string | null | boolean; const start_date = formData.get('start_date') as string | null; const end_date = formData.get('end_date') as string | null; + let link = formData.get('link') as string | null; if (is_public) { is_public = true; @@ -149,6 +156,10 @@ export const actions: Actions = { is_public = false; } + if (link) { + link = checkLink(link); + } + if (!name) { return { status: 400, @@ -162,6 +173,7 @@ export const actions: Actions = { formDataToSend.append('is_public', is_public.toString()); formDataToSend.append('start_date', start_date || ''); formDataToSend.append('end_date', end_date || ''); + formDataToSend.append('link', link || ''); let auth = event.cookies.get('auth'); diff --git a/frontend/src/routes/collections/[id]/+page.svelte b/frontend/src/routes/collections/[id]/+page.svelte index 97fe05d..240514c 100644 --- a/frontend/src/routes/collections/[id]/+page.svelte +++ b/frontend/src/routes/collections/[id]/+page.svelte @@ -20,7 +20,8 @@ groupAdventuresByDate, groupNotesByDate, groupTransportationsByDate, - groupChecklistsByDate + groupChecklistsByDate, + isAdventureVisited } from '$lib'; import ChecklistCard from '$lib/components/ChecklistCard.svelte'; import ChecklistModal from '$lib/components/ChecklistModal.svelte'; @@ -43,8 +44,8 @@ let numberOfDays: number = NaN; $: { - numAdventures = adventures.filter((a) => a.type === 'visited' || a.type === 'planned').length; - numVisited = adventures.filter((a) => a.type === 'visited').length; + numAdventures = adventures.length; + numVisited = adventures.filter(isAdventureVisited).length; } let notFound: boolean = false; @@ -371,6 +372,14 @@ {#if collection.name}

{collection.name}

{/if} + {#if collection.link} +
+ + Visit Link + +
+ {/if} + {#if collection.description}

{collection.description}

{/if}