Skip to content

Commit

Permalink
feat: Add Transportation and Lodging models to AdventureViewSet; upda…
Browse files Browse the repository at this point in the history
…te Avatar and TransportationModal components for improved user experience
  • Loading branch information
seanmorley15 committed Feb 22, 2025
1 parent 232e01b commit ea36b10
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 7 deletions.
50 changes: 48 additions & 2 deletions backend/server/adventures/views/adventure_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from adventures.models import Adventure, Category
from adventures.models import Adventure, Category, Transportation, Lodging
from adventures.permissions import IsOwnerOrSharedWithFullAccess
from adventures.serializers import AdventureSerializer
from adventures.serializers import AdventureSerializer, TransportationSerializer, LodgingSerializer
from adventures.utils import pagination

class AdventureViewSet(viewsets.ModelViewSet):
Expand Down Expand Up @@ -198,3 +198,49 @@ def paginate_and_respond(self, queryset, request):

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

# @action(detail=True, methods=['post'])
# def convert(self, request, pk=None):
# """
# Convert an Adventure instance into a Transportation or Lodging instance.
# Expects a JSON body with "target_type": "transportation" or "lodging".
# """
# adventure = self.get_object()
# target_type = request.data.get("target_type", "").lower()

# if target_type not in ["transportation", "lodging"]:
# return Response(
# {"error": "Invalid target type. Must be 'transportation' or 'lodging'."},
# status=400
# )
# if not adventure.collection:
# return Response(
# {"error": "Adventure must be part of a collection to be converted."},
# status=400
# )

# # Define the overlapping fields that both the Adventure and target models share.
# overlapping_fields = ["name", "description", "is_public", 'collection']

# # Gather the overlapping data from the adventure instance.
# conversion_data = {}
# for field in overlapping_fields:
# if hasattr(adventure, field):
# conversion_data[field] = getattr(adventure, field)

# # Make sure to include the user reference
# conversion_data["user_id"] = adventure.user_id

# # Convert the adventure instance within an atomic transaction.
# with transaction.atomic():
# if target_type == "transportation":
# new_instance = Transportation.objects.create(**conversion_data)
# serializer = TransportationSerializer(new_instance)
# else: # target_type == "lodging"
# new_instance = Lodging.objects.create(**conversion_data)
# serializer = LodgingSerializer(new_instance)

# # Optionally, delete the original adventure to avoid duplicates.
# adventure.delete()

# return Response(serializer.data)
2 changes: 1 addition & 1 deletion frontend/src/lib/components/Avatar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
</li>
<li><button on:click={() => goto('/adventures')}>{$t('navbar.my_adventures')}</button></li>
<li><button on:click={() => goto('/shared')}>{$t('navbar.shared_with_me')}</button></li>
<li><button on:click={() => goto('/settings')}>{$t('navbar.settings')}</button></li>
{#if user.is_staff}
<li><button on:click={() => goto('/admin')}>{$t('navbar.admin_panel')}</button></li>
{/if}
<li><button on:click={() => goto('/settings')}>{$t('navbar.settings')}</button></li>
<form method="post">
<li><button formaction="/?/logout">{$t('navbar.logout')}</button></li>
</form>
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/lib/components/TransportationModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
'User-Agent': `AdventureLog / ${appVersion} `
}
});
console.log(query);
let data = await res.json();
return data;
};
Expand Down Expand Up @@ -464,7 +465,7 @@
bind:value={starting_airport}
name="starting_airport"
class="input input-bordered w-full"
placeholder="Enter starting airport code (e.g., JFK)"
placeholder={$t('transportation.starting_airport_desc')}
/>
<label for="ending_airport" class="label">
<span class="label-text">{$t('adventures.ending_airport')}</span>
Expand All @@ -475,10 +476,10 @@
bind:value={ending_airport}
name="ending_airport"
class="input input-bordered w-full"
placeholder="Enter ending airport code (e.g., LAX)"
placeholder={$t('transportation.ending_airport_desc')}
/>
<button type="button" class="btn btn-primary mt-2" on:click={geocode}>
Fetch Location Information
{$t('transportation.fetch_location_information')}
</button>
</div>
{/if}
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,9 @@
"flight_number": "Flight Number",
"from_location": "From Location",
"to_location": "To Location",
"fetch_location_information": "Fetch Location Information",
"starting_airport_desc": "Enter starting airport code (e.g., JFK)",
"ending_airport_desc": "Enter ending airport code (e.g., LAX)",
"edit": "Edit",
"modes": {
"car": "Car",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/map/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
</MapLibre>

<svelte:head>
<title>Travel Map</title>
<title>Adventure Map</title>
<meta name="description" content="View your travels on a map." />
</svelte:head>

Expand Down

0 comments on commit ea36b10

Please sign in to comment.