mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-28 09:19:37 +02:00
Refactor map component styles and update transportation location formatting
This commit is contained in:
parent
c3fddb1889
commit
d6eb4edddd
6 changed files with 217 additions and 164 deletions
|
@ -683,7 +683,7 @@
|
||||||
<div>
|
<div>
|
||||||
<MapLibre
|
<MapLibre
|
||||||
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full"
|
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full rounded-lg"
|
||||||
standardControls
|
standardControls
|
||||||
>
|
>
|
||||||
<!-- MapEvents gives you access to map events even from other components inside the map,
|
<!-- MapEvents gives you access to map events even from other components inside the map,
|
||||||
|
|
|
@ -111,7 +111,7 @@
|
||||||
<h3 class="font-bold text-lg mb-4">Choose a Point</h3>
|
<h3 class="font-bold text-lg mb-4">Choose a Point</h3>
|
||||||
<MapLibre
|
<MapLibre
|
||||||
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full"
|
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full rounded-lg"
|
||||||
standardControls
|
standardControls
|
||||||
>
|
>
|
||||||
<!-- MapEvents gives you access to map events even from other components inside the map,
|
<!-- MapEvents gives you access to map events even from other components inside the map,
|
||||||
|
|
|
@ -123,8 +123,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transportation.type == 'plane') {
|
if (transportation.type == 'plane') {
|
||||||
transportation.from_location = startingData[0].name + ' (' + starting_airport + ')';
|
transportation.from_location =
|
||||||
transportation.to_location = endingData[0].name + ' (' + ending_airport + ')';
|
startingData[0].name + ' (' + starting_airport.toUpperCase() + ')';
|
||||||
|
transportation.to_location = endingData[0].name + ' (' + ending_airport.toUpperCase() + ')';
|
||||||
} else {
|
} else {
|
||||||
transportation.from_location = startingData[0].display_name;
|
transportation.from_location = startingData[0].display_name;
|
||||||
transportation.to_location = endingData[0].display_name;
|
transportation.to_location = endingData[0].display_name;
|
||||||
|
@ -536,7 +537,7 @@
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<MapLibre
|
<MapLibre
|
||||||
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full"
|
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full rounded-lg"
|
||||||
standardControls
|
standardControls
|
||||||
>
|
>
|
||||||
<!-- MapEvents gives you access to map events even from other components inside the map,
|
<!-- MapEvents gives you access to map events even from other components inside the map,
|
||||||
|
@ -560,7 +561,7 @@ it would also work to just use on:click on the MapLibre component itself. -->
|
||||||
</MapLibre>
|
</MapLibre>
|
||||||
<!-- button to clear to and from location -->
|
<!-- button to clear to and from location -->
|
||||||
</div>
|
</div>
|
||||||
{#if transportation.from_location && transportation.to_location}
|
{#if transportation.from_location || transportation.to_location}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-error btn-sm mt-2"
|
class="btn btn-error btn-sm mt-2"
|
||||||
|
|
|
@ -329,7 +329,7 @@
|
||||||
</div>
|
</div>
|
||||||
<MapLibre
|
<MapLibre
|
||||||
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
class="flex items-center self-center justify-center aspect-[9/16] max-h-[70vh] sm:aspect-video sm:max-h-full w-10/12"
|
class="flex items-center self-center justify-center aspect-[9/16] max-h-[70vh] sm:aspect-video sm:max-h-full w-10/12 rounded-lg"
|
||||||
standardControls
|
standardControls
|
||||||
center={{ lng: adventure.longitude, lat: adventure.latitude }}
|
center={{ lng: adventure.longitude, lat: adventure.latitude }}
|
||||||
zoom={12}
|
zoom={12}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
import AdventureCard from '$lib/components/AdventureCard.svelte';
|
import AdventureCard from '$lib/components/AdventureCard.svelte';
|
||||||
import AdventureLink from '$lib/components/AdventureLink.svelte';
|
import AdventureLink from '$lib/components/AdventureLink.svelte';
|
||||||
import NotFound from '$lib/components/NotFound.svelte';
|
import NotFound from '$lib/components/NotFound.svelte';
|
||||||
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
|
import { DefaultMarker, MapLibre, Marker, Popup } from 'svelte-maplibre';
|
||||||
import TransportationCard from '$lib/components/TransportationCard.svelte';
|
import TransportationCard from '$lib/components/TransportationCard.svelte';
|
||||||
import NoteCard from '$lib/components/NoteCard.svelte';
|
import NoteCard from '$lib/components/NoteCard.svelte';
|
||||||
import NoteModal from '$lib/components/NoteModal.svelte';
|
import NoteModal from '$lib/components/NoteModal.svelte';
|
||||||
|
@ -42,6 +42,29 @@
|
||||||
|
|
||||||
let numberOfDays: number = NaN;
|
let numberOfDays: number = NaN;
|
||||||
|
|
||||||
|
function getTransportationEmoji(type: string): string {
|
||||||
|
switch (type) {
|
||||||
|
case 'car':
|
||||||
|
return '🚗';
|
||||||
|
case 'plane':
|
||||||
|
return '✈️';
|
||||||
|
case 'train':
|
||||||
|
return '🚆';
|
||||||
|
case 'bus':
|
||||||
|
return '🚌';
|
||||||
|
case 'boat':
|
||||||
|
return '⛵';
|
||||||
|
case 'bike':
|
||||||
|
return '🚲';
|
||||||
|
case 'walking':
|
||||||
|
return '🚶';
|
||||||
|
case 'other':
|
||||||
|
return '🚀';
|
||||||
|
default:
|
||||||
|
return '🚀';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
numAdventures = adventures.length;
|
numAdventures = adventures.length;
|
||||||
numVisited = adventures.filter((adventure) => adventure.is_visited).length;
|
numVisited = adventures.filter((adventure) => adventure.is_visited).length;
|
||||||
|
@ -229,29 +252,6 @@
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if notFound}
|
|
||||||
<div
|
|
||||||
class="flex min-h-[100dvh] flex-col items-center justify-center bg-background px-4 py-12 sm:px-6 lg:px-8 -mt-20"
|
|
||||||
>
|
|
||||||
<div class="mx-auto max-w-md text-center">
|
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
<img src={Lost} alt="Lost" class="w-1/2" />
|
|
||||||
</div>
|
|
||||||
<h1 class="mt-4 text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
|
|
||||||
{$t('adventures.not_found')}
|
|
||||||
</h1>
|
|
||||||
<p class="mt-4 text-muted-foreground">
|
|
||||||
{$t('adventures.not_found_desc')}
|
|
||||||
</p>
|
|
||||||
<div class="mt-6">
|
|
||||||
<button class="btn btn-primary" on:click={() => goto('/')}
|
|
||||||
>{$t('adventures.homepage')}</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if !collection && !notFound}
|
{#if !collection && !notFound}
|
||||||
<div class="flex justify-center items-center w-full mt-16">
|
<div class="flex justify-center items-center w-full mt-16">
|
||||||
<span class="loading loading-spinner w-24 h-24"></span>
|
<span class="loading loading-spinner w-24 h-24"></span>
|
||||||
|
@ -383,9 +383,6 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if adventures.length == 0 && transportations.length == 0 && notes.length == 0 && checklists.length == 0}
|
|
||||||
<NotFound error={undefined} />
|
|
||||||
{/if}
|
|
||||||
{#if adventures.length > 0}
|
{#if adventures.length > 0}
|
||||||
<h1 class="text-center font-bold text-4xl mt-4 mb-2">{$t('adventures.linked_adventures')}</h1>
|
<h1 class="text-center font-bold text-4xl mt-4 mb-2">{$t('adventures.linked_adventures')}</h1>
|
||||||
|
|
||||||
|
@ -460,54 +457,65 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if collection.start_date && collection.end_date}
|
{#if collection.start_date && collection.end_date}
|
||||||
<div class="divider"></div>
|
<div class="hero bg-base-200 py-8 mt-8">
|
||||||
<h1 class="text-center font-bold text-4xl mt-4">{$t('adventures.itineary_by_date')}</h1>
|
<div class="hero-content text-center">
|
||||||
|
<div class="max-w-md">
|
||||||
|
<h1 class="text-5xl font-bold mb-4">{$t('adventures.itineary_by_date')}</h1>
|
||||||
{#if numberOfDays}
|
{#if numberOfDays}
|
||||||
<p class="text-center text-lg pl-16 pr-16">
|
<p class="text-lg mb-2">
|
||||||
{$t('adventures.duration')}: {numberOfDays}
|
{$t('adventures.duration')}:
|
||||||
{$t('adventures.days')}
|
<span class="badge badge-primary">{numberOfDays} {$t('adventures.days')}</span>
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
<p class="text-center text-lg pl-16 pr-16">
|
<p class="text-lg">
|
||||||
Dates: {new Date(collection.start_date).toLocaleDateString(undefined, { timeZone: 'UTC' })} - {new Date(
|
Dates: <span class="font-semibold"
|
||||||
collection.end_date
|
>{new Date(collection.start_date).toLocaleDateString(undefined, { timeZone: 'UTC' })} -
|
||||||
).toLocaleDateString(undefined, { timeZone: 'UTC' })}
|
{new Date(collection.end_date).toLocaleDateString(undefined, {
|
||||||
|
timeZone: 'UTC'
|
||||||
|
})}</span
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
{#each Array(numberOfDays) as _, i}
|
{#each Array(numberOfDays) as _, i}
|
||||||
{@const startDate = new Date(collection.start_date)}
|
{@const startDate = new Date(collection.start_date)}
|
||||||
{@const tempDate = new Date(startDate.getTime())}
|
{@const tempDate = new Date(startDate.getTime())}
|
||||||
<!-- Clone startDate -->
|
|
||||||
{@const adjustedDate = new Date(tempDate.setUTCDate(tempDate.getUTCDate() + i))}
|
{@const adjustedDate = new Date(tempDate.setUTCDate(tempDate.getUTCDate() + i))}
|
||||||
<!-- Add i days in UTC -->
|
|
||||||
{@const dateString = adjustedDate.toISOString().split('T')[0]}
|
{@const dateString = adjustedDate.toISOString().split('T')[0]}
|
||||||
|
|
||||||
{@const dayAdventures =
|
{@const dayAdventures =
|
||||||
groupAdventuresByDate(adventures, new Date(collection.start_date), numberOfDays)[
|
groupAdventuresByDate(adventures, new Date(collection.start_date), numberOfDays)[
|
||||||
dateString
|
dateString
|
||||||
] || []}
|
] || []}
|
||||||
|
|
||||||
{@const dayTransportations =
|
{@const dayTransportations =
|
||||||
groupTransportationsByDate(transportations, new Date(collection.start_date), numberOfDays)[
|
groupTransportationsByDate(
|
||||||
dateString
|
transportations,
|
||||||
] || []}
|
new Date(collection.start_date),
|
||||||
|
numberOfDays
|
||||||
|
)[dateString] || []}
|
||||||
{@const dayNotes =
|
{@const dayNotes =
|
||||||
groupNotesByDate(notes, new Date(collection.start_date), numberOfDays)[dateString] || []}
|
groupNotesByDate(notes, new Date(collection.start_date), numberOfDays)[dateString] || []}
|
||||||
|
|
||||||
{@const dayChecklists =
|
{@const dayChecklists =
|
||||||
groupChecklistsByDate(checklists, new Date(collection.start_date), numberOfDays)[
|
groupChecklistsByDate(checklists, new Date(collection.start_date), numberOfDays)[
|
||||||
dateString
|
dateString
|
||||||
] || []}
|
] || []}
|
||||||
|
|
||||||
<h2 class="text-center font-bold text-3xl mt-4">
|
<div class="card bg-base-100 shadow-xl my-8">
|
||||||
|
<div class="card-body bg-base-200">
|
||||||
|
<h2 class="card-title text-3xl justify-center g">
|
||||||
{$t('adventures.day')}
|
{$t('adventures.day')}
|
||||||
{i + 1}
|
{i + 1}
|
||||||
</h2>
|
<div class="badge badge-lg">
|
||||||
<h3 class="text-center text-xl mb-2">
|
|
||||||
{adjustedDate.toLocaleDateString(undefined, { timeZone: 'UTC' })}
|
{adjustedDate.toLocaleDateString(undefined, { timeZone: 'UTC' })}
|
||||||
</h3>
|
</div>
|
||||||
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
|
</h2>
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{#if dayAdventures.length > 0}
|
{#if dayAdventures.length > 0}
|
||||||
{#each dayAdventures as adventure}
|
{#each dayAdventures as adventure}
|
||||||
<AdventureCard
|
<AdventureCard
|
||||||
|
@ -563,23 +571,24 @@
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if dayAdventures.length == 0 && dayTransportations.length == 0 && dayNotes.length == 0 && dayChecklists.length == 0}
|
{#if dayAdventures.length == 0 && dayTransportations.length == 0 && dayNotes.length == 0 && dayChecklists.length == 0}
|
||||||
<p class="text-center text-lg mt-2">{$t('adventures.nothing_planned')}</p>
|
<p class="text-center text-lg mt-2 italic">{$t('adventures.nothing_planned')}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card bg-base-200 shadow-xl my-8 mx-auto w-10/12">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-3xl justify-center mb-4">Trip Map</h2>
|
||||||
<MapLibre
|
<MapLibre
|
||||||
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
class="flex items-center self-center justify-center aspect-[9/16] max-h-[70vh] sm:aspect-video sm:max-h-full w-10/12 mt-4"
|
class="aspect-[9/16] max-h-[70vh] sm:aspect-video sm:max-h-full w-full rounded-lg"
|
||||||
standardControls
|
standardControls
|
||||||
>
|
>
|
||||||
<!-- MapEvents gives you access to map events even from other components inside the map,
|
|
||||||
where you might not have access to the top-level `MapLibre` component. In this case
|
|
||||||
it would also work to just use on:click on the MapLibre component itself. -->
|
|
||||||
<!-- <MapEvents on:click={addMarker} /> -->
|
|
||||||
|
|
||||||
{#each adventures as adventure}
|
{#each adventures as adventure}
|
||||||
{#if adventure.longitude && adventure.latitude}
|
{#if adventure.longitude && adventure.latitude}
|
||||||
<DefaultMarker lngLat={{ lng: adventure.longitude, lat: adventure.latitude }}>
|
<DefaultMarker lngLat={{ lng: adventure.longitude, lat: adventure.latitude }}>
|
||||||
|
@ -592,7 +601,51 @@
|
||||||
</DefaultMarker>
|
</DefaultMarker>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
{#each transportations as transportation}
|
||||||
|
{#if transportation.destination_latitude && transportation.destination_longitude}
|
||||||
|
<Marker
|
||||||
|
lngLat={{
|
||||||
|
lng: transportation.destination_longitude,
|
||||||
|
lat: transportation.destination_latitude
|
||||||
|
}}
|
||||||
|
class="grid h-8 w-8 place-items-center rounded-full border border-gray-200
|
||||||
|
bg-red-300 text-black focus:outline-6 focus:outline-black"
|
||||||
|
>
|
||||||
|
<span class="text-xl">
|
||||||
|
{getTransportationEmoji(transportation.type)}
|
||||||
|
</span>
|
||||||
|
<Popup openOn="click" offset={[0, -10]}>
|
||||||
|
<div class="text-lg text-black font-bold">{transportation.name}</div>
|
||||||
|
<p class="font-semibold text-black text-md">
|
||||||
|
{transportation.type}
|
||||||
|
</p>
|
||||||
|
</Popup>
|
||||||
|
</Marker>
|
||||||
|
{/if}
|
||||||
|
{#if transportation.origin_latitude && transportation.origin_longitude}
|
||||||
|
<Marker
|
||||||
|
lngLat={{
|
||||||
|
lng: transportation.origin_longitude,
|
||||||
|
lat: transportation.origin_latitude
|
||||||
|
}}
|
||||||
|
class="grid h-8 w-8 place-items-center rounded-full border border-gray-200
|
||||||
|
bg-green-300 text-black focus:outline-6 focus:outline-black"
|
||||||
|
>
|
||||||
|
<span class="text-xl">
|
||||||
|
{getTransportationEmoji(transportation.type)}
|
||||||
|
</span>
|
||||||
|
<Popup openOn="click" offset={[0, -10]}>
|
||||||
|
<div class="text-lg text-black font-bold">{transportation.name}</div>
|
||||||
|
<p class="font-semibold text-black text-md">
|
||||||
|
{transportation.type}
|
||||||
|
</p>
|
||||||
|
</Popup>
|
||||||
|
</Marker>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
</MapLibre>
|
</MapLibre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import { DefaultMarker, MapEvents, MapLibre, Popup, Marker } from 'svelte-maplibre';
|
import { DefaultMarker, MapEvents, MapLibre, Popup, Marker } from 'svelte-maplibre';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import type { Adventure, VisitedRegion } from '$lib/types.js';
|
import type { Adventure, VisitedRegion } from '$lib/types.js';
|
||||||
import { getAdventureTypeLabel } from '$lib';
|
|
||||||
import CardCarousel from '$lib/components/CardCarousel.svelte';
|
import CardCarousel from '$lib/components/CardCarousel.svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
export let data;
|
export let data;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue