mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-22 14:29:36 +02:00
Add link field to collection and fix the visited counter in collection page
This commit is contained in:
parent
7d9bc16588
commit
1e61032692
8 changed files with 68 additions and 14 deletions
18
backend/server/adventures/migrations/0010_collection_link.py
Normal file
18
backend/server/adventures/migrations/0010_collection_link.py
Normal file
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -117,6 +117,7 @@ class Collection(models.Model):
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
is_archived = models.BooleanField(default=False)
|
is_archived = models.BooleanField(default=False)
|
||||||
shared_with = models.ManyToManyField(User, related_name='shared_with', blank=True)
|
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
|
# if connected adventures are private and collection is public, raise an error
|
||||||
|
|
|
@ -176,8 +176,7 @@ class CollectionSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Collection
|
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', 'link']
|
||||||
fields = ['id', 'description', 'user_id', 'name', 'is_public', 'adventures', 'created_at', 'start_date', 'end_date', 'transportations', 'notes', 'updated_at', 'checklists', 'is_archived', 'shared_with']
|
|
||||||
read_only_fields = ['id', 'created_at', 'updated_at', 'user_id']
|
read_only_fields = ['id', 'created_at', 'updated_at', 'user_id']
|
||||||
|
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
|
|
|
@ -11,16 +11,8 @@
|
||||||
|
|
||||||
let originalName = collectionToEdit.name;
|
let originalName = collectionToEdit.name;
|
||||||
|
|
||||||
let isPointModalOpen: boolean = false;
|
|
||||||
|
|
||||||
import MapMarker from '~icons/mdi/map-marker';
|
|
||||||
import Calendar from '~icons/mdi/calendar';
|
import Calendar from '~icons/mdi/calendar';
|
||||||
import Notebook from '~icons/mdi/notebook';
|
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';
|
import Earth from '~icons/mdi/earth';
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
@ -156,6 +148,16 @@
|
||||||
class="input input-bordered w-full max-w-xs mt-1"
|
class="input input-bordered w-full max-w-xs mt-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<label for="end_date">Link </label><br />
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
id="link"
|
||||||
|
name="link"
|
||||||
|
bind:value={collectionToEdit.link}
|
||||||
|
class="input input-bordered w-full max-w-xs mt-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label for="is_public">Public <Earth class="inline-block -mt-1 mb-1 w-6 h-6" /></label><br
|
<label for="is_public">Public <Earth class="inline-block -mt-1 mb-1 w-6 h-6" /></label><br
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
adventures: [] as Adventure[],
|
adventures: [] as Adventure[],
|
||||||
is_public: false
|
is_public: false,
|
||||||
|
shared_with: [],
|
||||||
|
link: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
@ -151,6 +153,16 @@
|
||||||
class="input input-bordered w-full max-w-xs mt-1"
|
class="input input-bordered w-full max-w-xs mt-1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<label for="end_date">Link </label><br />
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
id="link"
|
||||||
|
name="link"
|
||||||
|
bind:value={newCollection.link}
|
||||||
|
class="input input-bordered w-full max-w-xs mt-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<button type="submit" class="btn btn-primary mr-4 mt-4">Create</button>
|
<button type="submit" class="btn btn-primary mr-4 mt-4">Create</button>
|
||||||
<button type="button" class="btn mt-4" on:click={close}>Close</button>
|
<button type="button" class="btn mt-4" on:click={close}>Close</button>
|
||||||
|
|
|
@ -87,6 +87,7 @@ export type Collection = {
|
||||||
checklists?: Checklist[];
|
checklists?: Checklist[];
|
||||||
is_archived?: boolean;
|
is_archived?: boolean;
|
||||||
shared_with: string[];
|
shared_with: string[];
|
||||||
|
link?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OpenStreetMapPlace = {
|
export type OpenStreetMapPlace = {
|
||||||
|
|
|
@ -53,6 +53,11 @@ export const actions: Actions = {
|
||||||
const description = formData.get('description') as string | null;
|
const description = formData.get('description') as string | null;
|
||||||
const start_date = formData.get('start_date') as string | null;
|
const start_date = formData.get('start_date') as string | null;
|
||||||
const end_date = formData.get('end_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) {
|
if (!name) {
|
||||||
return {
|
return {
|
||||||
|
@ -66,6 +71,7 @@ export const actions: Actions = {
|
||||||
formDataToSend.append('description', description || '');
|
formDataToSend.append('description', description || '');
|
||||||
formDataToSend.append('start_date', start_date || '');
|
formDataToSend.append('start_date', start_date || '');
|
||||||
formDataToSend.append('end_date', end_date || '');
|
formDataToSend.append('end_date', end_date || '');
|
||||||
|
formDataToSend.append('link', link || '');
|
||||||
let auth = event.cookies.get('auth');
|
let auth = event.cookies.get('auth');
|
||||||
|
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
|
@ -142,6 +148,7 @@ export const actions: Actions = {
|
||||||
let is_public = formData.get('is_public') as string | null | boolean;
|
let is_public = formData.get('is_public') as string | null | boolean;
|
||||||
const start_date = formData.get('start_date') as string | null;
|
const start_date = formData.get('start_date') as string | null;
|
||||||
const end_date = formData.get('end_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) {
|
if (is_public) {
|
||||||
is_public = true;
|
is_public = true;
|
||||||
|
@ -149,6 +156,10 @@ export const actions: Actions = {
|
||||||
is_public = false;
|
is_public = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link) {
|
||||||
|
link = checkLink(link);
|
||||||
|
}
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return {
|
return {
|
||||||
status: 400,
|
status: 400,
|
||||||
|
@ -162,6 +173,7 @@ export const actions: Actions = {
|
||||||
formDataToSend.append('is_public', is_public.toString());
|
formDataToSend.append('is_public', is_public.toString());
|
||||||
formDataToSend.append('start_date', start_date || '');
|
formDataToSend.append('start_date', start_date || '');
|
||||||
formDataToSend.append('end_date', end_date || '');
|
formDataToSend.append('end_date', end_date || '');
|
||||||
|
formDataToSend.append('link', link || '');
|
||||||
|
|
||||||
let auth = event.cookies.get('auth');
|
let auth = event.cookies.get('auth');
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
groupAdventuresByDate,
|
groupAdventuresByDate,
|
||||||
groupNotesByDate,
|
groupNotesByDate,
|
||||||
groupTransportationsByDate,
|
groupTransportationsByDate,
|
||||||
groupChecklistsByDate
|
groupChecklistsByDate,
|
||||||
|
isAdventureVisited
|
||||||
} from '$lib';
|
} from '$lib';
|
||||||
import ChecklistCard from '$lib/components/ChecklistCard.svelte';
|
import ChecklistCard from '$lib/components/ChecklistCard.svelte';
|
||||||
import ChecklistModal from '$lib/components/ChecklistModal.svelte';
|
import ChecklistModal from '$lib/components/ChecklistModal.svelte';
|
||||||
|
@ -43,8 +44,8 @@
|
||||||
let numberOfDays: number = NaN;
|
let numberOfDays: number = NaN;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
numAdventures = adventures.filter((a) => a.type === 'visited' || a.type === 'planned').length;
|
numAdventures = adventures.length;
|
||||||
numVisited = adventures.filter((a) => a.type === 'visited').length;
|
numVisited = adventures.filter(isAdventureVisited).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
let notFound: boolean = false;
|
let notFound: boolean = false;
|
||||||
|
@ -371,6 +372,14 @@
|
||||||
{#if collection.name}
|
{#if collection.name}
|
||||||
<h1 class="text-center font-extrabold text-4xl mb-2">{collection.name}</h1>
|
<h1 class="text-center font-extrabold text-4xl mb-2">{collection.name}</h1>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if collection.link}
|
||||||
|
<div class="flex items-center justify-center mb-2">
|
||||||
|
<a href={collection.link} target="_blank" rel="noopener noreferrer" class="btn btn-primary">
|
||||||
|
Visit Link
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if collection.description}
|
{#if collection.description}
|
||||||
<p class="text-center text-lg mb-2">{collection.description}</p>
|
<p class="text-center text-lg mb-2">{collection.description}</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue