diff --git a/backend/server/adventures/serializers.py b/backend/server/adventures/serializers.py index cd065b2..5f9073d 100644 --- a/backend/server/adventures/serializers.py +++ b/backend/server/adventures/serializers.py @@ -92,11 +92,24 @@ class CategorySerializer(serializers.ModelSerializer): class TrailSerializer(CustomModelSerializer): provider = serializers.SerializerMethodField() wanderer_data = serializers.SerializerMethodField() + wanderer_link = serializers.SerializerMethodField() + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._wanderer_integration_cache = {} + class Meta: model = Trail - fields = ['id', 'user', 'name', 'location', 'created_at','link','wanderer_id', 'provider', 'wanderer_data'] + fields = ['id', 'user', 'name', 'location', 'created_at','link','wanderer_id', 'provider', 'wanderer_data', 'wanderer_link'] read_only_fields = ['id', 'created_at', 'user', 'provider'] + def _get_wanderer_integration(self, user): + """Cache wanderer integration to avoid multiple database queries""" + if user.id not in self._wanderer_integration_cache: + from integrations.models import WandererIntegration + self._wanderer_integration_cache[user.id] = WandererIntegration.objects.filter(user=user).first() + return self._wanderer_integration_cache[user.id] + def get_provider(self, obj): if obj.wanderer_id: return 'Wanderer' @@ -116,23 +129,39 @@ class TrailSerializer(CustomModelSerializer): if not obj.wanderer_id: return None + # Use cached integration + integration = self._get_wanderer_integration(obj.user) + if not integration: + return None + # Fetch the Wanderer trail data - from integrations.models import WandererIntegration from integrations.wanderer_services import fetch_trail_by_id try: - integration = WandererIntegration.objects.filter(user=obj.user).first() - if not integration: - return None - - # Assuming there's a method to fetch trail data by ID trail_data = fetch_trail_by_id(integration, obj.wanderer_id) if not trail_data: return None - obj.wanderer_data = trail_data + + # Cache the trail data and link on the object to avoid refetching + obj._wanderer_data = trail_data + base_url = integration.server_url.rstrip('/') + obj._wanderer_link = f"{base_url}/trails/{obj.wanderer_id}" + return trail_data except Exception as e: - logger.error(f"Error fetching Wanderer trail data for {obj.wanderer_id}") + logger.error(f"Error fetching Wanderer trail data for {obj.wanderer_id}: {e}") return None + + def get_wanderer_link(self, obj): + if not obj.wanderer_id: + return None + + # Use cached integration + integration = self._get_wanderer_integration(obj.user) + if not integration: + return None + + base_url = integration.server_url.rstrip('/') + return f"{base_url}/trail/view/@{integration.username}/{obj.wanderer_id}" class ActivitySerializer(CustomModelSerializer): diff --git a/frontend/src/lib/components/TrailCard.svelte b/frontend/src/lib/components/TrailCard.svelte index 5d585a7..e8a031c 100644 --- a/frontend/src/lib/components/TrailCard.svelte +++ b/frontend/src/lib/components/TrailCard.svelte @@ -140,9 +140,9 @@ {/if} - {#if trail.link} + {#if trail.link || trail.wanderer_link} total + (visit.activities @@ -183,10 +184,14 @@ : 0), 0 ); + + // Convert meters to km, then to miles if using imperial system + const totalKm = totalMeters / 1000; + return measurementSystem === 'imperial' ? totalKm * 0.621371 : totalKm; } function getTotalElevationGain(adventure: AdditionalLocation) { - return adventure.visits.reduce( + const totalMeters = adventure.visits.reduce( (total, visit) => total + (visit.activities @@ -194,6 +199,9 @@ : 0), 0 ); + + // Convert to feet if using imperial system + return measurementSystem === 'imperial' ? totalMeters * 3.28084 : totalMeters; } async function saveEdit(event: CustomEvent) { @@ -860,7 +868,9 @@
Total Distance
- {getTotalDistance(adventure).toFixed(1)} km + {getTotalDistance(adventure).toFixed(1)} + {#if measurementSystem === 'imperial'}mi + {:else}km{/if}
{/if} @@ -868,7 +878,9 @@
Total Elevation
- {getTotalElevationGain(adventure).toFixed(0)} m + {getTotalElevationGain(adventure).toFixed(0)} + {#if measurementSystem === 'imperial'}ft + {:else}m{/if}
{/if}