1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-02 19:55:18 +02:00

Merge pull request #338 from seanmorley15/development

Development
This commit is contained in:
Sean Morley 2024-10-14 10:12:13 -04:00 committed by GitHub
commit 3508b3b04f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 206 additions and 127 deletions

View file

@ -18,8 +18,8 @@
import CollectionLink from './CollectionLink.svelte';
import DotsHorizontal from '~icons/mdi/dots-horizontal';
import DeleteWarning from './DeleteWarning.svelte';
import ImageDisplayModal from './ImageDisplayModal.svelte';
import { isAdventureVisited, typeToString } from '$lib';
import CardCarousel from './CardCarousel.svelte';
export let type: string;
export let user: User | null;
@ -28,7 +28,6 @@
let isCollectionModalOpen: boolean = false;
let isWarningModalOpen: boolean = false;
let image_url: string | null = null;
export let adventure: Adventure;
let activityTypes: string[] = [];
@ -120,12 +119,6 @@
dispatch('edit', adventure);
}
let currentSlide = 0;
function goToSlide(index: number) {
currentSlide = index;
}
function link() {
dispatch('link', adventure);
}
@ -146,48 +139,10 @@
/>
{/if}
{#if image_url}
<ImageDisplayModal image={image_url} on:close={() => (image_url = null)} {adventure} />
{/if}
<div
class="card w-full max-w-xs sm:max-w-sm md:max-w-md lg:max-w-md xl:max-w-md bg-neutral text-neutral-content shadow-xl"
>
<figure>
{#if adventure.images && adventure.images.length > 0}
<div class="carousel w-full">
{#each adventure.images as image, i}
<div
class="carousel-item w-full"
style="display: {i === currentSlide ? 'block' : 'none'}"
>
<!-- svelte-ignore a11y-invalid-attribute -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-missing-attribute -->
<a on:click={() => (image_url = image.image)}
><img src={image.image} class="w-full h-48 object-cover" alt={adventure.name} /></a
>
<div class="flex justify-center w-full py-2 gap-2">
{#each adventure.images as _, i}
<button
on:click={() => goToSlide(i)}
class="btn btn-xs {i === currentSlide ? 'btn-active' : ''}">{i + 1}</button
>
{/each}
</div>
</div>
{/each}
</div>
{:else}
<!-- svelte-ignore a11y-img-redundant-alt -->
<img
src={'https://placehold.co/300?text=No%20Image%20Found&font=roboto'}
alt="No image available"
class="w-full h-48 object-cover"
/>
{/if}
</figure>
<CardCarousel adventures={[adventure]} />
<div class="card-body">
<div class="flex justify-between">

View file

@ -0,0 +1,87 @@
<script lang="ts">
import type { Adventure } from '$lib/types';
import ImageDisplayModal from './ImageDisplayModal.svelte';
export let adventures: Adventure[] = [];
let currentSlide = 0;
let image_url: string | null = null;
$: adventure_images = adventures.flatMap((adventure) =>
adventure.images.map((image) => ({ image: image.image, adventure: adventure }))
);
$: {
if (adventure_images.length > 0) {
currentSlide = 0;
}
}
function changeSlide(direction: string) {
if (direction === 'next' && currentSlide < adventure_images.length - 1) {
currentSlide = currentSlide + 1;
} else if (direction === 'prev' && currentSlide > 0) {
currentSlide = currentSlide - 1;
}
}
</script>
{#if image_url}
<ImageDisplayModal
adventure={adventure_images[currentSlide].adventure}
image={image_url}
on:close={() => (image_url = null)}
/>
{/if}
<figure>
{#if adventure_images && adventure_images.length > 0}
<div class="carousel w-full relative">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="carousel-item w-full block">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-missing-attribute -->
<a
on:click|stopPropagation={() => (image_url = adventure_images[currentSlide].image)}
class="cursor-pointer"
>
<img
src={adventure_images[currentSlide].image}
class="w-full h-48 object-cover"
alt={adventure_images[currentSlide].adventure.name}
/>
</a>
{#if adventure_images.length > 1}
<div class="absolute inset-0 flex items-center justify-between pointer-events-none">
{#if currentSlide > 0}
<button
on:click|stopPropagation={() => changeSlide('prev')}
class="btn btn-circle btn-sm ml-2 pointer-events-auto"></button
>
{:else}
<div class="w-12"></div>
{/if}
{#if currentSlide < adventure_images.length - 1}
<button
on:click|stopPropagation={() => changeSlide('next')}
class="btn btn-circle mr-2 btn-sm pointer-events-auto"></button
>
{:else}
<div class="w-12"></div>
{/if}
</div>
{/if}
</div>
</div>
{:else}
<!-- svelte-ignore a11y-img-redundant-alt -->
<img
src={'https://placehold.co/300?text=No%20Image%20Found&font=roboto'}
alt="No image available"
class="w-full h-48 object-cover"
/>
{/if}
</figure>

View file

@ -9,7 +9,7 @@
import ArchiveArrowUp from '~icons/mdi/archive-arrow-up';
import { goto } from '$app/navigation';
import type { Collection } from '$lib/types';
import type { Adventure, Collection } from '$lib/types';
import { addToast } from '$lib/toasts';
import Plus from '~icons/mdi/plus';
@ -17,14 +17,14 @@
import TrashCan from '~icons/mdi/trashcan';
import DeleteWarning from './DeleteWarning.svelte';
import ShareModal from './ShareModal.svelte';
import CardCarousel from './CardCarousel.svelte';
const dispatch = createEventDispatcher();
export let type: String | undefined | null;
export let adventures: Adventure[] = [];
let isShareModalOpen: boolean = false;
// export let type: String;
function editAdventure() {
dispatch('edit', collection);
}
@ -86,6 +86,7 @@
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral text-neutral-content shadow-xl"
>
<CardCarousel {adventures} />
<div class="card-body">
<div class="flex justify-between">
<button

View file

@ -11,16 +11,8 @@
let originalName = collectionToEdit.name;
let isPointModalOpen: boolean = false;
import MapMarker from '~icons/mdi/map-marker';
import Calendar from '~icons/mdi/calendar';
import Notebook from '~icons/mdi/notebook';
import ClipboardList from '~icons/mdi/clipboard-list';
import Image from '~icons/mdi/image';
import Star from '~icons/mdi/star';
import Attachment from '~icons/mdi/attachment';
import PointSelectionModal from './PointSelectionModal.svelte';
import Earth from '~icons/mdi/earth';
onMount(async () => {
@ -156,6 +148,16 @@
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="end_date">Link </label><br />
<input
type="url"
id="link"
name="link"
bind:value={collectionToEdit.link}
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
</div>
<div class="mb-2">
<label for="is_public">Public <Earth class="inline-block -mt-1 mb-1 w-6 h-6" /></label><br

View file

@ -6,7 +6,7 @@
import type { Adventure } from '$lib/types';
export let image: string;
export let adventure: Adventure;
export let adventure: Adventure | null = null;
onMount(() => {
modal = document.getElementById('my_modal_1') as HTMLDialogElement;
@ -42,34 +42,36 @@
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div class="modal-box w-11/12 max-w-5xl" role="dialog" on:keydown={handleKeydown} tabindex="0">
<div class="modal-header flex justify-between items-center mb-4">
<h3 class="font-bold text-2xl">{adventure.name}</h3>
<button class="btn btn-circle btn-neutral" on:click={close}>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div
class="flex justify-center items-center"
style="display: flex; justify-content: center; align-items: center;"
>
<img
src={image}
alt={adventure.name}
style="max-width: 100%; max-height: 75vh; object-fit: contain;"
/>
</div>
{#if adventure}
<div class="modal-header flex justify-between items-center mb-4">
<h3 class="font-bold text-2xl">{adventure.name}</h3>
<button class="btn btn-circle btn-neutral" on:click={close}>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div
class="flex justify-center items-center"
style="display: flex; justify-content: center; align-items: center;"
>
<img
src={image}
alt={adventure.name}
style="max-width: 100%; max-height: 75vh; object-fit: contain;"
/>
</div>
{/if}
</div>
</dialog>

View file

@ -13,7 +13,9 @@
name: '',
description: '',
adventures: [] as Adventure[],
is_public: false
is_public: false,
shared_with: [],
link: ''
};
const dispatch = createEventDispatcher();
@ -151,6 +153,16 @@
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<label for="end_date">Link </label><br />
<input
type="url"
id="link"
name="link"
bind:value={newCollection.link}
class="input input-bordered w-full max-w-xs mt-1"
/>
</div>
<div class="mb-2">
<button type="submit" class="btn btn-primary mr-4 mt-4">Create</button>
<button type="button" class="btn mt-4" on:click={close}>Close</button>

View file

@ -57,11 +57,7 @@
class="card w-full max-w-xs sm:max-w-sm md:max-w-md lg:max-w-md xl:max-w-md bg-neutral text-neutral-content shadow-xl overflow-hidden"
>
<div class="card-body">
{#if region.name_en && region.name !== region.name_en}
<h2 class="card-title overflow-ellipsis">{region.name} ({region.name_en})</h2>
{:else}
<h2 class="card-title overflow-ellipsis">{region.name}</h2>
{/if}
<h2 class="card-title overflow-ellipsis">{region.name}</h2>
<p>{region.id}</p>
<div class="card-actions justify-end">
<!-- <button class="btn btn-info" on:click={moreInfo}>More Info</button> -->

View file

@ -87,6 +87,7 @@ export type Collection = {
checklists?: Checklist[];
is_archived?: boolean;
shared_with: string[];
link?: string | null;
};
export type OpenStreetMapPlace = {

View file

@ -53,6 +53,11 @@ export const actions: Actions = {
const description = formData.get('description') as string | null;
const start_date = formData.get('start_date') as string | null;
const end_date = formData.get('end_date') as string | null;
let link = formData.get('link') as string | null;
if (link) {
link = checkLink(link);
}
if (!name) {
return {
@ -66,6 +71,7 @@ export const actions: Actions = {
formDataToSend.append('description', description || '');
formDataToSend.append('start_date', start_date || '');
formDataToSend.append('end_date', end_date || '');
formDataToSend.append('link', link || '');
let auth = event.cookies.get('auth');
if (!auth) {
@ -142,6 +148,7 @@ export const actions: Actions = {
let is_public = formData.get('is_public') as string | null | boolean;
const start_date = formData.get('start_date') as string | null;
const end_date = formData.get('end_date') as string | null;
let link = formData.get('link') as string | null;
if (is_public) {
is_public = true;
@ -149,6 +156,10 @@ export const actions: Actions = {
is_public = false;
}
if (link) {
link = checkLink(link);
}
if (!name) {
return {
status: 400,
@ -162,6 +173,7 @@ export const actions: Actions = {
formDataToSend.append('is_public', is_public.toString());
formDataToSend.append('start_date', start_date || '');
formDataToSend.append('end_date', end_date || '');
formDataToSend.append('link', link || '');
let auth = event.cookies.get('auth');

View file

@ -180,6 +180,7 @@
{collection}
on:delete={deleteCollection}
on:edit={editCollection}
adventures={collection.adventures}
/>
{/each}
</div>

View file

@ -20,7 +20,8 @@
groupAdventuresByDate,
groupNotesByDate,
groupTransportationsByDate,
groupChecklistsByDate
groupChecklistsByDate,
isAdventureVisited
} from '$lib';
import ChecklistCard from '$lib/components/ChecklistCard.svelte';
import ChecklistModal from '$lib/components/ChecklistModal.svelte';
@ -43,13 +44,12 @@
let numberOfDays: number = NaN;
$: {
numAdventures = adventures.filter((a) => a.type === 'visited' || a.type === 'planned').length;
numVisited = adventures.filter((a) => a.type === 'visited').length;
numAdventures = adventures.length;
numVisited = adventures.filter(isAdventureVisited).length;
}
let notFound: boolean = false;
let isShowingLinkModal: boolean = false;
let isShowingCreateModal: boolean = false;
let isShowingTransportationModal: boolean = false;
let isShowingChecklistModal: boolean = false;
@ -371,6 +371,14 @@
{#if collection.name}
<h1 class="text-center font-extrabold text-4xl mb-2">{collection.name}</h1>
{/if}
{#if collection.link}
<div class="flex items-center justify-center mb-2">
<a href={collection.link} target="_blank" rel="noopener noreferrer" class="btn btn-primary">
Visit Link
</a>
</div>
{/if}
{#if collection.description}
<p class="text-center text-lg mb-2">{collection.description}</p>
{/if}

View file

@ -3,10 +3,9 @@
let stats: {
country_count: number;
planned_count: number;
total_regions: number;
trips_count: number;
visited_count: number;
adventure_count: number;
visited_region_count: number;
total_countries: number;
} | null;
@ -19,16 +18,6 @@
console.log(stats);
</script>
<!--
// v0 by Vercel.
// https://v0.dev/t/EtPnDdQYcbn
-->
<!--
// v0 by Vercel.
// https://v0.dev/t/DYwTru570WN
-->
{#if data.user.profile_pic}
<div class="avatar flex items-center justify-center">
<div class="w-24 rounded">
@ -65,17 +54,10 @@
<div class="flex justify-center items-center">
<div class="stats stats-vertical lg:stats-horizontal shadow bg-base-200">
<div class="stat">
<div class="stat-title">Completed Adventures</div>
<div class="stat-value text-center">{stats.visited_count}</div>
<div class="stat-title">Adventures</div>
<div class="stat-value text-center">{stats.adventure_count}</div>
<!-- <div class="stat-desc">Jan 1st - Feb 1st</div> -->
</div>
<div class="stat">
<div class="stat-title">Planned Adventures</div>
<div class="stat-value text-center">{stats.planned_count}</div>
<!-- <div class="stat-desc">↗︎ 400 (22%)</div> -->
</div>
<div class="stat">
<div class="stat-title">Collections</div>
<div class="stat-value text-center">{stats.trips_count}</div>

View file

@ -25,3 +25,8 @@
{/if}
</p>
{/if}
<svelte:head>
<title>Shared Collections</title>
<meta name="description" content="Collections shared with you by other users." />
</svelte:head>