1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-19 12:59:36 +02:00

Enhance Adventure model and serializers with visited status logic and toast notifications for marking visits

This commit is contained in:
Sean Morley 2025-05-22 21:13:31 -04:00
parent 84cd136401
commit a1062e72cf
4 changed files with 45 additions and 12 deletions

View file

@ -9,8 +9,9 @@ from django.contrib.auth import get_user_model
from django.contrib.postgres.fields import ArrayField
from django.forms import ValidationError
from django_resized import ResizedImageField
from worldtravel.models import City, Country, Region
from worldtravel.models import City, Country, Region, VisitedCity, VisitedRegion
from adventures.geocoding import reverse_geocode
from django.utils import timezone
def validate_file_extension(value):
import os
@ -549,6 +550,17 @@ class Adventure(models.Model):
# end_date = models.DateField(blank=True, null=True)
# type = models.CharField(max_length=100, choices=ADVENTURE_TYPES, default='general')
def is_visited_status(self):
current_date = timezone.now().date()
for visit in self.visits.all():
start_date = visit.start_date.date() if isinstance(visit.start_date, timezone.datetime) else visit.start_date
end_date = visit.end_date.date() if isinstance(visit.end_date, timezone.datetime) else visit.end_date
if start_date and end_date and (start_date <= current_date):
return True
elif start_date and not end_date and (start_date <= current_date):
return True
return False
def clean(self):
if self.collection:
if self.collection.is_public and not self.is_public:
@ -578,15 +590,26 @@ class Adventure(models.Model):
self.category = category
if self.latitude and self.longitude:
is_visited = self.is_visited_status()
reverse_geocode_result = reverse_geocode(self.latitude, self.longitude, self.user_id)
if 'region_id' in reverse_geocode_result:
region = Region.objects.filter(id=reverse_geocode_result['region_id']).first()
if region:
self.region = region
if is_visited:
visited_region, created = VisitedRegion.objects.get_or_create(
user_id=self.user_id,
region=region
)
if 'city_id' in reverse_geocode_result:
city = City.objects.filter(id=reverse_geocode_result['city_id']).first()
if city:
self.city = city
if is_visited:
visited_city, created = VisitedCity.objects.get_or_create(
user_id=self.user_id,
city=city
)
if 'country_id' in reverse_geocode_result:
country = Country.objects.filter(country_code=reverse_geocode_result['country_id']).first()
if country:

View file

@ -138,15 +138,7 @@ class AdventureSerializer(CustomModelSerializer):
return CustomUserDetailsSerializer(user).data
def get_is_visited(self, obj):
current_date = timezone.now().date()
for visit in obj.visits.all():
start_date = visit.start_date.date() if isinstance(visit.start_date, timezone.datetime) else visit.start_date
end_date = visit.end_date.date() if isinstance(visit.end_date, timezone.datetime) else visit.end_date
if start_date and end_date and (start_date <= current_date):
return True
elif start_date and not end_date and (start_date <= current_date):
return True
return False
return obj.is_visited_status()
def create(self, validated_data):
visits_data = validated_data.pop('visits', None)
@ -159,7 +151,8 @@ class AdventureSerializer(CustomModelSerializer):
if category_data:
category = self.get_or_create_category(category_data)
adventure.category = category
adventure.save()
adventure.save()
return adventure
@ -196,6 +189,9 @@ class AdventureSerializer(CustomModelSerializer):
visits_to_delete = current_visit_ids - updated_visit_ids
instance.visits.filter(id__in=visits_to_delete).delete()
# call save on the adventure to update the updated_at field and trigger any geocoding
instance.save()
return instance
class TransportationSerializer(CustomModelSerializer):

View file

@ -55,7 +55,7 @@
}
$: if (triggerMarkVisted && willBeMarkedVisited) {
markVisited();
displaySuccessToast(); // since the server will trigger the geocode automatically, we just need to show the toast and let the server handle the rest. It's kinda a placebo effect...
triggerMarkVisted = false;
}
@ -102,6 +102,17 @@
}
}
function displaySuccessToast() {
if (reverseGeocodePlace) {
if (reverseGeocodePlace.region) {
addToast('success', `Visit to ${reverseGeocodePlace.region} marked`);
}
if (reverseGeocodePlace.city) {
addToast('success', `Visit to ${reverseGeocodePlace.city} marked`);
}
}
}
async function markVisited() {
console.log(reverseGeocodePlace);
if (reverseGeocodePlace) {

View file

@ -45,6 +45,9 @@ export type Adventure = {
category: Category | null;
attachments: Attachment[];
user?: User | null;
city?: string | null;
region?: string | null;
country?: string | null;
};
export type AdditionalAdventure = Adventure & {