Enhance collection management with modal updates and item handling

This commit is contained in:
Sean Morley
2025-12-30 11:57:48 -05:00
parent 52712bfbbf
commit 0e51b37a89
6 changed files with 574 additions and 220 deletions

View File

@@ -1,5 +1,6 @@
<script lang="ts">
import type { Collection } from '$lib/types';
import { createEventDispatcher } from 'svelte';
import LocationCard from '$lib/components/cards/LocationCard.svelte';
import TransportationCard from '$lib/components/cards/TransportationCard.svelte';
import LodgingCard from '$lib/components/cards/LodgingCard.svelte';
@@ -8,12 +9,13 @@
import Magnify from '~icons/mdi/magnify';
import ClipboardList from '~icons/mdi/clipboard-list';
const dispatch = createEventDispatcher();
export let collection: Collection;
export let user: any;
export let isFolderView: boolean = false;
// Whether the current user can modify this collection (owner or shared user)
export let canModify: boolean = false;
// Exported so a parent can bind to them if desired
export let locationSearch: string = '';
@@ -94,217 +96,284 @@
c.name.toLowerCase().includes(checklistSearch.toLowerCase())
);
})();
// Generic handlers for editing and deleting items in the collection.
// `type` should match the collection property name: 'locations', 'transportations', 'lodging', 'notes', 'checklists'
function handleItemDelete(type: string, detail: any) {
const id = detail?.id ?? detail;
if (!id) return;
const arr = (collection as any)[type];
if (!arr || !Array.isArray(arr)) return;
(collection as any) = {
...(collection as any),
[type]: arr.filter((item: any) => String(item.id) !== String(id))
};
}
function handleItemEdit(type: string, detail: any) {
const updated = detail;
if (!updated || !updated.id) return;
const arr = (collection as any)[type];
if (!arr || !Array.isArray(arr)) return;
(collection as any) = {
...(collection as any),
[type]: arr.map((item: any) => (String(item.id) === String(updated.id) ? updated : item))
};
// Bubble up so parent can open edit modals
dispatch('openEdit', { type, item: updated });
}
</script>
{#if collection.locations && collection.locations.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
📍 Locations ({sortedLocations.length}/{collection.locations.length})
</h2>
<!-- Show each section as its own card so transportations and others
render even when there are no locations. Use vertical spacing
between cards via a wrapper. -->
<div class="space-y-6">
{#if collection.locations && collection.locations.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
📍 Locations ({sortedLocations.length}/{collection.locations.length})
</h2>
{#if isFolderView}
<div class="flex flex-wrap gap-2">
<!-- Search -->
<div class="join">
<input
type="text"
placeholder="Search locations..."
class="input input-sm input-bordered join-item w-48"
bind:value={locationSearch}
/>
{#if isFolderView}
<div class="flex flex-wrap gap-2">
<!-- Search -->
<div class="join">
<input
type="text"
placeholder="Search locations..."
class="input input-sm input-bordered join-item w-48"
bind:value={locationSearch}
/>
</div>
<!-- Sort dropdown -->
<select class="select select-sm select-bordered" bind:value={locationSort}>
<option value="alphabetical-asc">A → Z</option>
<option value="alphabetical-desc">Z → A</option>
<option value="visited">Visited First</option>
<option value="date-asc">Oldest First</option>
<option value="date-desc">Newest First</option>
</select>
</div>
{/if}
</div>
<!-- Sort dropdown -->
<select class="select select-sm select-bordered" bind:value={locationSort}>
<option value="alphabetical-asc">A → Z</option>
<option value="alphabetical-desc">Z → A</option>
<option value="visited">Visited First</option>
<option value="date-asc">Oldest First</option>
<option value="date-desc">Newest First</option>
</select>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each sortedLocations as location}
<LocationCard
adventure={location}
{user}
{collection}
on:delete={(e) => handleItemDelete('locations', e.detail)}
on:edit={(e) => handleItemEdit('locations', e.detail)}
/>
{/each}
</div>
{#if sortedLocations.length === 0}
<div class="text-center py-8 opacity-70">
<p>No locations match your search</p>
</div>
{/if}
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch">
{#each sortedLocations as location}
<LocationCard adventure={location} {user} {collection} />
{/each}
</div>
{#if sortedLocations.length === 0}
<div class="text-center py-8 opacity-70">
<p>No locations match your search</p>
</div>
{/if}
<!-- Transportations Section -->
{#if collection.transportations && collection.transportations.length > 0}
<div class="card bg-base-200 shadow-xl mt-6">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
✈️ Transportation ({filteredTransportations.length}/{collection.transportations
.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search transportation..."
class="input input-sm input-bordered join-item w-48"
bind:value={transportationSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredTransportations as transport}
<TransportationCard transportation={transport} {user} {collection} />
{/each}
</div>
{#if filteredTransportations.length === 0}
<div class="text-center py-8 opacity-70">
<p>No transportation matches your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Lodging Section -->
{#if collection.lodging && collection.lodging.length > 0}
<div class="card bg-base-200 shadow-xl mt-6">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
🏨 Lodging ({filteredLodging.length}/{collection.lodging.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search lodging..."
class="input input-sm input-bordered join-item w-48"
bind:value={lodgingSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredLodging as lodging}
<LodgingCard {lodging} {user} {collection} />
{/each}
</div>
{#if filteredLodging.length === 0}
<div class="text-center py-8 opacity-70">
<p>No lodging matches your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Notes Section -->
{#if collection.notes && collection.notes.length > 0}
<div class="card bg-base-200 shadow-xl mt-6">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
📝 Notes ({filteredNotes.length}/{collection.notes.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search notes..."
class="input input-sm input-bordered join-item w-48"
bind:value={noteSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredNotes as note}
<NoteCard {note} {user} {collection} />
{/each}
</div>
{#if filteredNotes.length === 0}
<div class="text-center py-8 opacity-70">
<p>No notes match your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Checklists Section -->
{#if collection.checklists && collection.checklists.length > 0}
<div class="card bg-base-200 shadow-xl mt-6">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
<ClipboardList class="w-6 h-6" />
Checklists ({filteredChecklists.length}/{collection.checklists.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search checklists..."
class="input input-sm input-bordered join-item w-48"
bind:value={checklistSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredChecklists as checklist}
<ChecklistCard {checklist} {user} {collection} />
{/each}
</div>
{#if filteredChecklists.length === 0}
<div class="text-center py-8 opacity-70">
<p>No checklists match your search</p>
</div>
{/if}
</div>
</div>
{/if}
</div>
</div>
{/if}
{/if}
<!-- Transportations Section -->
{#if collection.transportations && collection.transportations.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
✈️ Transportation ({filteredTransportations.length}/{collection.transportations.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search transportation..."
class="input input-sm input-bordered join-item w-48"
bind:value={transportationSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredTransportations as transport}
<TransportationCard
transportation={transport}
{user}
{collection}
on:delete={(e) => handleItemDelete('transportations', e.detail)}
on:edit={(e) => handleItemEdit('transportations', e.detail)}
/>
{/each}
</div>
{#if filteredTransportations.length === 0}
<div class="text-center py-8 opacity-70">
<p>No transportation matches your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Lodging Section -->
{#if collection.lodging && collection.lodging.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
🏨 Lodging ({filteredLodging.length}/{collection.lodging.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search lodging..."
class="input input-sm input-bordered join-item w-48"
bind:value={lodgingSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredLodging as lodging}
<LodgingCard
{lodging}
{user}
{collection}
on:delete={(e) => handleItemDelete('lodging', e.detail)}
on:edit={(e) => handleItemEdit('lodging', e.detail)}
/>
{/each}
</div>
{#if filteredLodging.length === 0}
<div class="text-center py-8 opacity-70">
<p>No lodging matches your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Notes Section -->
{#if collection.notes && collection.notes.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
📝 Notes ({filteredNotes.length}/{collection.notes.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search notes..."
class="input input-sm input-bordered join-item w-48"
bind:value={noteSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredNotes as note}
<NoteCard
{note}
{user}
{collection}
on:delete={(e) => handleItemDelete('notes', e.detail)}
on:edit={(e) => handleItemEdit('notes', e.detail)}
/>
{/each}
</div>
{#if filteredNotes.length === 0}
<div class="text-center py-8 opacity-70">
<p>No notes match your search</p>
</div>
{/if}
</div>
</div>
{/if}
<!-- Checklists Section -->
{#if collection.checklists && collection.checklists.length > 0}
<div class="card bg-base-200 shadow-xl">
<div class="card-body">
<div class="flex flex-wrap justify-between items-center gap-4 mb-6">
<h2 class="card-title text-2xl">
<ClipboardList class="w-6 h-6" />
Checklists ({filteredChecklists.length}/{collection.checklists.length})
</h2>
{#if isFolderView}
<div class="join">
<input
type="text"
placeholder="Search checklists..."
class="input input-sm input-bordered join-item w-48"
bind:value={checklistSearch}
/>
<button class="btn btn-sm btn-square join-item">
<Magnify class="w-4 h-4" />
</button>
</div>
{/if}
</div>
<div
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr items-stretch"
>
{#each filteredChecklists as checklist}
<ChecklistCard
{checklist}
{user}
{collection}
on:delete={(e) => handleItemDelete('checklists', e.detail)}
on:edit={(e) => handleItemEdit('checklists', e.detail)}
/>
{/each}
</div>
{#if filteredChecklists.length === 0}
<div class="text-center py-8 opacity-70">
<p>No checklists match your search</p>
</div>
{/if}
</div>
</div>
{/if}
</div>

View File

@@ -20,6 +20,9 @@
let modal: HTMLDialogElement;
// Whether a save/create occurred during this modal session
let didSave = false;
let steps = [
{
name: $t('adventures.quick_start'),
@@ -116,6 +119,15 @@
});
function close() {
// If a save occurred, notify the parent with appropriate event
if (didSave) {
if (locationToEdit) {
dispatch('save', location);
} else {
dispatch('create', location);
}
}
dispatch('close');
}
@@ -289,6 +301,9 @@
location.user = e.detail.user;
location.id = e.detail.id;
// Mark that a save occurred so close() will notify parent
didSave = true;
steps[1].selected = false;
steps[2].selected = true;
}}

View File

@@ -18,6 +18,9 @@
let modal: HTMLDialogElement;
// Whether a save/create occurred during this modal session
let didSave = false;
let steps = [
{
name: $t('adventures.details'),
@@ -116,6 +119,15 @@
});
function close() {
// If a save occurred, notify the parent with appropriate event
if (didSave) {
if (lodgingToEdit) {
dispatch('save', lodging);
} else {
dispatch('create', lodging);
}
}
dispatch('close');
}
@@ -235,6 +247,9 @@
// Update the entire lodging object with all saved data
lodging = { ...lodging, ...e.detail };
// Mark that a save occurred so close() will notify parent
didSave = true;
// Only allow moving to Media once we have a persisted id.
if (!lodging?.id) {
addToast('error', $t('adventures.lodging_save_error'));

View File

@@ -18,6 +18,9 @@
let modal: HTMLDialogElement;
// Whether a save/create occurred during this modal session
let didSave = false;
let steps = [
{
name: $t('adventures.details'),
@@ -128,6 +131,15 @@
});
function close() {
// If a save occurred, notify the parent with appropriate event
if (didSave) {
if (transportationToEdit) {
dispatch('save', transportation);
} else {
dispatch('create', transportation);
}
}
dispatch('close');
}
@@ -249,6 +261,9 @@
// Update the entire transportation object with all saved data
transportation = { ...transportation, ...e.detail };
// Mark that a save occurred so close() will notify parent
didSave = true;
// Only allow moving to Media once we have a persisted id.
if (!transportation?.id) {
addToast('error', $t('adventures.lodging_save_error'));

View File

@@ -1,4 +1,4 @@
export let appVersion = 'v0.12.0-pre-dev-122825';
export let appVersion = 'v0.12.0-pre-dev-123025';
export let versionChangelog = 'https://github.com/seanmorley15/AdventureLog/releases/tag/v0.11.0';
export let appTitle = 'AdventureLog';
export let copyrightYear = '2023-2025';

View File

@@ -25,6 +25,11 @@
import Lightbulb from '~icons/mdi/lightbulb';
import Plus from '~icons/mdi/plus';
import { addToast } from '$lib/toasts';
import NoteModal from '$lib/components/NoteModal.svelte';
import ChecklistModal from '$lib/components/ChecklistModal.svelte';
import LodgingModal from '$lib/components/lodging/LodgingModal.svelte';
import TransportationModal from '$lib/components/transportation/TransportationModal.svelte';
import LocationModal from '$lib/components/locations/LocationModal.svelte';
const renderMarkdown = (markdown: string) => {
return marked(markdown) as string;
@@ -36,12 +41,42 @@
let collection: Collection = (data.props as any).collection || (data.props as any).adventure;
let currentSlide = 0;
let notFound: boolean = false;
let isEditModalOpen: boolean = false;
let isLocationModalOpen: boolean = false;
let isLodgingModalOpen: boolean = false;
let isTransportationModalOpen: boolean = false;
let isChecklistModalOpen: boolean = false;
let isNoteModalOpen: boolean = false;
// Edit placeholders used when creating new items from FAB dropdown
let adventureToEdit: any = null;
let transportationToEdit: any = null;
let noteToEdit: any = null;
let checklistToEdit: any = null;
let lodgingToEdit: any = null;
let heroImages: ContentImage[] = [];
let modalInitialIndex: number = 0;
let isImageModalOpen: boolean = false;
let isLocationLinkModalOpen: boolean = false;
// Shared helpers for keeping collection sub-items in sync after modal actions
type CollectionArrayKey = 'locations' | 'transportations' | 'lodging' | 'notes' | 'checklists';
function ensureCollectionArray(key: CollectionArrayKey) {
if (!collection) return [] as any[];
if (!(collection as any)[key]) {
(collection as any)[key] = [];
}
return (collection as any)[key] as any[];
}
function upsertCollectionItem(key: CollectionArrayKey, item: any) {
if (!item || item.id === undefined || item.id === null) return;
const items = ensureCollectionArray(key);
const exists = items.some((entry: any) => String(entry.id) === String(item.id));
(collection as any)[key] = exists
? items.map((entry: any) => (String(entry.id) === String(item.id) ? item : entry))
: [...items, item];
}
// View state from URL params
type ViewType = 'all' | 'itinerary' | 'map' | 'recommendations';
let currentView: ViewType = 'itinerary';
@@ -154,6 +189,35 @@
isLocationLinkModalOpen = false;
}
function handleOpenEdit(event: CustomEvent<{ type: CollectionArrayKey; item: any }>) {
const { type, item } = event.detail;
switch (type) {
case 'locations':
adventureToEdit = item;
isLocationModalOpen = true;
break;
case 'transportations':
transportationToEdit = item;
isTransportationModalOpen = true;
break;
case 'lodging':
lodgingToEdit = item;
isLodgingModalOpen = true;
break;
case 'notes':
noteToEdit = item;
isNoteModalOpen = true;
break;
case 'checklists':
checklistToEdit = item;
isChecklistModalOpen = true;
break;
default:
break;
}
}
async function handleLocationAdded(event: CustomEvent<Location>) {
// Link the location to this collection
const location = event.detail;
@@ -238,6 +302,115 @@
/>
{/if}
{#if isNoteModalOpen}
<NoteModal
on:close={() => {
noteToEdit = null;
isNoteModalOpen = false;
}}
note={noteToEdit}
{collection}
on:save={(e) => {
upsertCollectionItem('notes', e.detail);
noteToEdit = null;
isNoteModalOpen = false;
}}
on:create={(e) => {
upsertCollectionItem('notes', e.detail);
noteToEdit = null;
isNoteModalOpen = false;
}}
/>
{/if}
{#if isLocationModalOpen}
<LocationModal
on:close={() => {
adventureToEdit = null;
isLocationModalOpen = false;
}}
user={data.user}
{collection}
locationToEdit={adventureToEdit}
on:save={(e) => {
upsertCollectionItem('locations', e.detail);
adventureToEdit = null;
isLocationModalOpen = false;
}}
on:create={(e) => {
upsertCollectionItem('locations', e.detail);
adventureToEdit = null;
isLocationModalOpen = false;
}}
/>
{/if}
{#if isTransportationModalOpen}
<TransportationModal
on:close={() => {
transportationToEdit = null;
isTransportationModalOpen = false;
}}
user={data.user}
{collection}
{transportationToEdit}
on:save={(e) => {
upsertCollectionItem('transportations', e.detail);
transportationToEdit = null;
isTransportationModalOpen = false;
}}
on:create={(e) => {
upsertCollectionItem('transportations', e.detail);
transportationToEdit = null;
isTransportationModalOpen = false;
}}
/>
{/if}
{#if isChecklistModalOpen}
<ChecklistModal
on:close={() => {
checklistToEdit = null;
isChecklistModalOpen = false;
}}
{collection}
user={data.user}
checklist={checklistToEdit}
on:save={(e) => {
upsertCollectionItem('checklists', e.detail);
checklistToEdit = null;
isChecklistModalOpen = false;
}}
on:create={(e) => {
upsertCollectionItem('checklists', e.detail);
checklistToEdit = null;
isChecklistModalOpen = false;
}}
/>
{/if}
{#if isLodgingModalOpen}
<LodgingModal
on:close={() => {
lodgingToEdit = null;
isLodgingModalOpen = false;
}}
{collection}
user={data.user}
{lodgingToEdit}
on:save={(e) => {
upsertCollectionItem('lodging', e.detail);
lodgingToEdit = null;
isLodgingModalOpen = false;
}}
on:create={(e) => {
upsertCollectionItem('lodging', e.detail);
lodgingToEdit = null;
isLodgingModalOpen = false;
}}
/>
{/if}
{#if !collection && !notFound}
<div class="hero min-h-screen overflow-x-hidden">
<div class="hero-content">
@@ -434,12 +607,12 @@
{/if}
<!-- All Items View -->
{#if currentView === 'all' && collection.locations && collection.locations.length > 0}
{#if currentView === 'all'}
<CollectionAllItems
{collection}
bind:collection
user={data.user}
{isFolderView}
canModify={canModifyCollection}
on:openEdit={handleOpenEdit}
/>
{/if}
@@ -678,15 +851,82 @@
{/if}
<!-- Floating Action Button (FAB) - Only shown if user can modify collection -->
{#if collection && canModifyCollection}
<div class="fixed bottom-6 right-6 z-40">
<button
class="btn btn-primary btn-circle w-16 h-16 shadow-2xl hover:shadow-primary/25 transition-all duration-200"
on:click={openLocationLinkModal}
aria-label="Add locations to collection"
>
<Plus class="w-8 h-8" />
</button>
{#if collection && canModifyCollection && !collection.is_archived}
<div class="fixed bottom-4 right-4 z-[999]">
<div class="flex flex-row items-center justify-center gap-4">
<div class="dropdown dropdown-top dropdown-end z-[999]">
<div tabindex="0" role="button" class="btn m-1 size-16 btn-primary">
<Plus class="w-8 h-8" />
</div>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<ul
tabindex="0"
class="dropdown-content z-[1] menu p-4 shadow bg-base-300 text-base-content rounded-box w-52 gap-4"
>
<p class="text-center font-bold text-lg">{$t('adventures.link_new')}</p>
<!-- Link existing location to collection -->
<button
class="btn btn-primary"
on:click={() => {
isLocationLinkModalOpen = true;
}}
>
{$t('locations.location')}
</button>
<p class="text-center font-bold text-lg">{$t('adventures.add_new')}</p>
<button
class="btn btn-primary"
on:click={() => {
isLocationModalOpen = true;
adventureToEdit = null;
}}
>
{$t('locations.location')}
</button>
<button
class="btn btn-primary"
on:click={() => {
transportationToEdit = null;
isTransportationModalOpen = true;
}}
>
{$t('adventures.transportation')}
</button>
<button
class="btn btn-primary"
on:click={() => {
isNoteModalOpen = true;
noteToEdit = null;
}}
>
{$t('adventures.note')}
</button>
<button
class="btn btn-primary"
on:click={() => {
checklistToEdit = null;
isChecklistModalOpen = true;
}}
>
{$t('adventures.checklist')}
</button>
<button
class="btn btn-primary"
on:click={() => {
lodgingToEdit = null;
isLodgingModalOpen = true;
}}
>
{$t('adventures.lodging')}
</button>
</ul>
</div>
</div>
</div>
{/if}