mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-31 10:49:37 +02:00
Add region map to worldtravel region page
This commit is contained in:
parent
d6eb4edddd
commit
c9dd5fe33d
4 changed files with 127 additions and 2 deletions
|
@ -55,9 +55,14 @@
|
||||||
<!-- Title and Type -->
|
<!-- Title and Type -->
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h2 class="card-title text-lg font-semibold truncate">{transportation.name}</h2>
|
<h2 class="card-title text-lg font-semibold truncate">{transportation.name}</h2>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
<div class="badge badge-secondary">
|
<div class="badge badge-secondary">
|
||||||
{$t(`transportation.modes.${transportation.type}`)}
|
{$t(`transportation.modes.${transportation.type}`)}
|
||||||
</div>
|
</div>
|
||||||
|
{#if transportation.type == 'plane' && transportation.flight_number}
|
||||||
|
<div class="badge badge-neutral-200">{transportation.flight_number}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Locations -->
|
<!-- Locations -->
|
||||||
|
|
|
@ -184,6 +184,10 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (transportation.type != 'plane') {
|
||||||
|
transportation.flight_number = '';
|
||||||
|
}
|
||||||
|
|
||||||
if (transportation.id === '') {
|
if (transportation.id === '') {
|
||||||
let res = await fetch('/api/transportations', {
|
let res = await fetch('/api/transportations', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
"rating": "Rating",
|
"rating": "Rating",
|
||||||
"my_images": "My Images",
|
"my_images": "My Images",
|
||||||
"add_an_activity": "Add an activity",
|
"add_an_activity": "Add an activity",
|
||||||
|
"show_region_labels": "Show Region Labels",
|
||||||
"no_images": "No Images",
|
"no_images": "No Images",
|
||||||
"upload_images_here": "Upload images here",
|
"upload_images_here": "Upload images here",
|
||||||
"share_adventure": "Share this Adventure!",
|
"share_adventure": "Share this Adventure!",
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import RegionCard from '$lib/components/RegionCard.svelte';
|
import RegionCard from '$lib/components/RegionCard.svelte';
|
||||||
import type { Region, VisitedRegion } from '$lib/types';
|
import type { Region, VisitedRegion } from '$lib/types';
|
||||||
|
import { MapLibre, Marker } from 'svelte-maplibre';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
import { addToast } from '$lib/toasts';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
let regions: Region[] = data.props?.regions || [];
|
let regions: Region[] = data.props?.regions || [];
|
||||||
|
@ -10,6 +13,70 @@
|
||||||
const country = data.props?.country || null;
|
const country = data.props?.country || null;
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
|
let showGeo: boolean = true;
|
||||||
|
|
||||||
|
function togleVisited(region: Region) {
|
||||||
|
return () => {
|
||||||
|
const visitedRegion = visitedRegions.find(
|
||||||
|
(visitedRegion) => visitedRegion.region === region.id
|
||||||
|
);
|
||||||
|
if (visitedRegion) {
|
||||||
|
visitedRegions = visitedRegions.filter(
|
||||||
|
(visitedRegion) => visitedRegion.region !== region.id
|
||||||
|
);
|
||||||
|
removeVisit(region, visitedRegion.id);
|
||||||
|
} else {
|
||||||
|
markVisited(region);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function markVisited(region: Region) {
|
||||||
|
let res = await fetch(`/worldtravel?/markVisited`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ regionId: region.id })
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
// visited = true;
|
||||||
|
const result = await res.json();
|
||||||
|
const data = JSON.parse(result.data);
|
||||||
|
if (data[1] !== undefined) {
|
||||||
|
console.log('New adventure created with id:', data[3]);
|
||||||
|
let visit_id = data[3];
|
||||||
|
let region_id = data[5];
|
||||||
|
let user_id = data[4];
|
||||||
|
|
||||||
|
visitedRegions = [
|
||||||
|
...visitedRegions,
|
||||||
|
{
|
||||||
|
id: visit_id,
|
||||||
|
region: region_id,
|
||||||
|
user_id: user_id,
|
||||||
|
longitude: 0,
|
||||||
|
latitude: 0,
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
addToast('success', `Visit to ${region.name} marked`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Failed to mark region as visited');
|
||||||
|
addToast('error', `Failed to mark visit to ${region.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function removeVisit(region: Region, visitId: number) {
|
||||||
|
let res = await fetch(`/worldtravel?/removeVisited`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ visitId: visitId })
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
addToast('info', `Visit to ${region.name} removed`);
|
||||||
|
} else {
|
||||||
|
console.error('Failed to remove visit');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let numRegions: number = country?.num_regions || 0;
|
let numRegions: number = country?.num_regions || 0;
|
||||||
let numVisitedRegions: number = country?.num_visits || 0;
|
let numVisitedRegions: number = country?.num_visits || 0;
|
||||||
|
|
||||||
|
@ -49,6 +116,54 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-center border-neutral p-4 rounded-lg border-4 max-w-lg m-auto mt-4">
|
||||||
|
<label for="show-geo">{$t('adventures.show_region_labels')}</label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="show-geo"
|
||||||
|
name="show-geo"
|
||||||
|
class="checkbox ml-2"
|
||||||
|
bind:checked={showGeo}
|
||||||
|
on:click={() => (showGeo = !showGeo)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 mb-4 flex justify-center">
|
||||||
|
<!-- checkbox to toggle marker -->
|
||||||
|
|
||||||
|
<MapLibre
|
||||||
|
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
|
||||||
|
class="aspect-[9/16] max-h-[70vh] sm:aspect-video sm:max-h-full w-10/12 rounded-lg"
|
||||||
|
standardControls
|
||||||
|
center={[regions[0]?.longitude || 0, regions[0]?.latitude || 0]}
|
||||||
|
zoom={2}
|
||||||
|
>
|
||||||
|
<!-- 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 regions as region}
|
||||||
|
{#if region.latitude && region.longitude && showGeo}
|
||||||
|
<Marker
|
||||||
|
lngLat={[region.longitude, region.latitude]}
|
||||||
|
class="grid px-2 py-1 place-items-center rounded-full border border-gray-200 {visitedRegions.some(
|
||||||
|
(visitedRegion) => visitedRegion.region === region.id
|
||||||
|
)
|
||||||
|
? 'bg-red-300'
|
||||||
|
: 'bg-blue-300'} text-black focus:outline-6 focus:outline-black"
|
||||||
|
on:click={togleVisited(region)}
|
||||||
|
>
|
||||||
|
<span class="text-xs">
|
||||||
|
{region.name}
|
||||||
|
</span>
|
||||||
|
</Marker>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</MapLibre>
|
||||||
|
<!-- button to clear to and from location -->
|
||||||
|
</div>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title
|
<title
|
||||||
>{data.props && data.props.country ? `Regions in ${data.props.country.name}` : 'Regions'}</title
|
>{data.props && data.props.country ? `Regions in ${data.props.country.name}` : 'Regions'}</title
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue