mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-21 22:09:36 +02:00
Add i18n support for transportation, notes, checklist, and collection components
This commit is contained in:
parent
c0aaec1436
commit
3df124b250
11 changed files with 305 additions and 213 deletions
|
@ -3,6 +3,7 @@
|
|||
import type { Checklist, Collection, User } from '$lib/types';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
const dispatch = createEventDispatcher();
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
import Launch from '~icons/mdi/launch';
|
||||
import TrashCan from '~icons/mdi/trash-can';
|
||||
|
@ -21,10 +22,10 @@
|
|||
method: 'DELETE'
|
||||
});
|
||||
if (res.ok) {
|
||||
addToast('success', 'Checklist deleted successfully');
|
||||
addToast('success', $t('checklist.checklist_deleted'));
|
||||
dispatch('delete', checklist.id);
|
||||
} else {
|
||||
addToast('Failed to delete checklist', 'error');
|
||||
addToast($t('checklist.checklist_delete_error'), 'error');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -38,9 +39,12 @@
|
|||
{checklist.name}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="badge badge-primary">Checklist</div>
|
||||
<div class="badge badge-primary">{$t('adventures.checklist')}</div>
|
||||
{#if checklist.items.length > 0}
|
||||
<p>{checklist.items.length} {checklist.items.length > 1 ? 'Items' : 'Item'}</p>
|
||||
<p>
|
||||
{checklist.items.length}
|
||||
{checklist.items.length > 1 ? $t('checklist.items') : $t('checklist.item')}
|
||||
</p>
|
||||
{/if}
|
||||
{#if checklist.date && checklist.date !== ''}
|
||||
<div class="inline-flex items-center">
|
||||
|
@ -49,11 +53,8 @@
|
|||
</div>
|
||||
{/if}
|
||||
<div class="card-actions justify-end">
|
||||
<!-- <button class="btn btn-neutral mb-2" on:click={() => goto(`/notes/${note.id}`)}
|
||||
><Launch class="w-6 h-6" />Open Details</button
|
||||
> -->
|
||||
<button class="btn btn-neutral-200 mb-2" on:click={editChecklist}>
|
||||
<Launch class="w-6 h-6" />Open
|
||||
<Launch class="w-6 h-6" />{$t('notes.open')}
|
||||
</button>
|
||||
{#if checklist.user_id == user?.pk || (collection && user && collection.shared_with.includes(user.uuid))}
|
||||
<button
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { isValidUrl } from '$lib';
|
||||
import type { Collection, Checklist, User, ChecklistItem } from '$lib/types';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from 'svelte';
|
||||
let modal: HTMLDialogElement;
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
export let checklist: Checklist | null = null;
|
||||
export let collection: Collection;
|
||||
|
@ -21,11 +21,11 @@
|
|||
|
||||
function addItem() {
|
||||
if (newItem.trim() == '') {
|
||||
warning = 'Item cannot be empty';
|
||||
warning = $t('checklist.item_cannot_be_empty');
|
||||
return;
|
||||
}
|
||||
if (newChecklist.items.find((item) => item.name.trim() == newItem)) {
|
||||
warning = 'Item already exists';
|
||||
warning = $t('checklist.item_already_exists');
|
||||
return;
|
||||
}
|
||||
items = [
|
||||
|
@ -130,15 +130,15 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg mb-2">Checklist Editor</h3>
|
||||
<h3 class="font-bold text-lg mb-2">{$t('checklist.checklist_editor')}</h3>
|
||||
{#if initialName}
|
||||
<p class="font-semibold text-md mb-2">Editing checklist {initialName}</p>
|
||||
<p class="font-semibold text-md mb-2">{$t('checklist.editing_checklist')} {initialName}</p>
|
||||
{/if}
|
||||
|
||||
{#if (checklist && user?.pk == checklist?.user_id) || (user && collection && collection.shared_with.includes(user.uuid)) || !checklist}
|
||||
<form on:submit|preventDefault>
|
||||
<div class="form-control mb-2">
|
||||
<label for="name">Name</label>
|
||||
<label for="name">{$t('adventures.name')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
|
@ -147,7 +147,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Date</label>
|
||||
<label for="content">{$t('adventures.date')}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date"
|
||||
|
@ -163,7 +163,7 @@
|
|||
<input
|
||||
type="text"
|
||||
id="new_item"
|
||||
placeholder="New Item"
|
||||
placeholder={$t('checklist.new_item')}
|
||||
name="new_item"
|
||||
bind:value={newItem}
|
||||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
|
@ -179,12 +179,12 @@
|
|||
class="btn btn-sm btn-primary absolute right-0 mt-2.5 mr-4"
|
||||
on:click={addItem}
|
||||
>
|
||||
Add
|
||||
{$t('adventures.add')}
|
||||
</button>
|
||||
</div>
|
||||
{#if items.length > 0}
|
||||
<div class="divider"></div>
|
||||
<h2 class=" text-xl font-semibold mb-4 -mt-3">Items</h2>
|
||||
<h2 class=" text-xl font-semibold mb-4 -mt-3">{$t('checklist.items')}</h2>
|
||||
{/if}
|
||||
|
||||
{#each items as item, i}
|
||||
|
@ -202,7 +202,7 @@
|
|||
class="btn btn-sm btn-error absolute right-0 mt-2.5 mr-4"
|
||||
on:click={() => removeItem(i)}
|
||||
>
|
||||
Remove
|
||||
{$t('adventures.remove')}
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
|
@ -226,8 +226,8 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
<button class="btn btn-primary mr-1" on:click={save}>Save</button>
|
||||
<button class="btn btn-neutral" on:click={close}>Close</button>
|
||||
<button class="btn btn-primary mr-1" on:click={save}>{$t('notes.save')}</button>
|
||||
<button class="btn btn-neutral" on:click={close}>{$t('about.close')}</button>
|
||||
|
||||
{#if collection.is_public}
|
||||
<div role="alert" class="alert mt-4">
|
||||
|
@ -244,14 +244,14 @@
|
|||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>This checklist is public because it is in a public collection.</span>
|
||||
<span>{$t('checklist.checklist_public')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</form>
|
||||
{:else}
|
||||
<form>
|
||||
<div class="form-control mb-2">
|
||||
<label for="name">Name</label>
|
||||
<label for="name">{$t('adventures.name')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
|
@ -261,7 +261,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Date</label>
|
||||
<label for="content">{$t('adventures.date')}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date"
|
||||
|
@ -276,7 +276,7 @@
|
|||
|
||||
{#if items.length > 0}
|
||||
<div class="divider"></div>
|
||||
<h2 class=" text-xl font-semibold mb-4 -mt-3">Items</h2>
|
||||
<h2 class=" text-xl font-semibold mb-4 -mt-3">{$t('checklist.items')}</h2>
|
||||
{/if}
|
||||
|
||||
{#each items as item, i}
|
||||
|
@ -299,7 +299,7 @@
|
|||
</div>
|
||||
{/each}
|
||||
|
||||
<button class="btn btn-neutral" on:click={close}>Close</button>
|
||||
<button class="btn btn-neutral" on:click={close}>{$t('about.close')}</button>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<script lang="ts">
|
||||
export let collectionToEdit: Collection;
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { Adventure, Collection } from '$lib/types';
|
||||
import type { Collection } from '$lib/types';
|
||||
import { t } from 'svelte-i18n';
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from 'svelte';
|
||||
import { addToast } from '$lib/toasts';
|
||||
|
@ -41,17 +42,17 @@
|
|||
|
||||
if (collectionToEdit.end_date && collectionToEdit.start_date) {
|
||||
if (new Date(collectionToEdit.start_date) > new Date(collectionToEdit.end_date)) {
|
||||
addToast('error', 'Start date must be before end date');
|
||||
addToast('error', $t('adventures.start_before_end_error'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (collectionToEdit.end_date && !collectionToEdit.start_date) {
|
||||
addToast('error', 'Please provide a start date');
|
||||
addToast('error', $t('adventures.no_start_date'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (collectionToEdit.start_date && !collectionToEdit.end_date) {
|
||||
addToast('error', 'Please provide an end date');
|
||||
addToast('error', $t('adventures.no_end_date'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -66,12 +67,12 @@
|
|||
console.log(data);
|
||||
|
||||
if (data) {
|
||||
addToast('success', 'Adventure edited successfully!');
|
||||
addToast('success', $t('collection.collection_edit_success'));
|
||||
dispatch('saveEdit', collectionToEdit);
|
||||
close();
|
||||
} else {
|
||||
addToast('warning', 'Error editing adventure');
|
||||
console.log('Error editing adventure');
|
||||
addToast('warning', $t('collection.error_editing_collection'));
|
||||
console.log('Error editing collection');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +82,7 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg">Edit Collection: {originalName}</h3>
|
||||
<h3 class="font-bold text-lg">{$t('adventures.edit_collection')}: {originalName}</h3>
|
||||
<div
|
||||
class="modal-action items-center"
|
||||
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
|
||||
|
@ -97,7 +98,7 @@
|
|||
bind:value={collectionToEdit.id}
|
||||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/>
|
||||
<label for="name">Name</label><br />
|
||||
<label for="name">{$t('adventures.name')}</label><br />
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
|
@ -107,7 +108,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="date">Description <Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
<label for="date"
|
||||
>{$t('adventures.description')}
|
||||
<Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<div class="flex">
|
||||
<input
|
||||
|
@ -127,7 +130,8 @@
|
|||
> -->
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="start_date">Start Date <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="start_date"
|
||||
>{$t('adventures.start_date')} <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="date"
|
||||
|
@ -138,8 +142,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="end_date">End Date <Calendar class="inline-block mb-1 w-6 h-6" /></label><br
|
||||
/>
|
||||
<label for="end_date"
|
||||
>{$t('adventures.end_date')} <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="date"
|
||||
id="end_date"
|
||||
|
@ -149,7 +154,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="end_date">Link </label><br />
|
||||
<label for="end_date">{$t('adventures.link')} </label><br />
|
||||
<input
|
||||
type="url"
|
||||
id="link"
|
||||
|
@ -160,8 +165,9 @@
|
|||
</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
|
||||
/>
|
||||
<label for="is_public"
|
||||
>{$t('adventures.public')} <Earth class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle toggle-primary"
|
||||
|
@ -173,7 +179,7 @@
|
|||
|
||||
{#if collectionToEdit.is_public}
|
||||
<div class="bg-neutral p-4 rounded-md shadow-sm">
|
||||
<p class=" font-semibold">Share this Adventure!</p>
|
||||
<p class=" font-semibold">{$t('adventures.share_adventure')}</p>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-card-foreground font-mono">
|
||||
{window.location.origin}/collections/{collectionToEdit.id}
|
||||
|
@ -187,7 +193,7 @@
|
|||
}}
|
||||
class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-10 px-4 py-2"
|
||||
>
|
||||
Copy Link
|
||||
{$t('adventures.copy_link')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -195,7 +201,7 @@
|
|||
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4" on:click={submit}>Edit</button>
|
||||
<!-- if there is a button in form, it will close the modal -->
|
||||
<button class="btn mt-4" on:click={close}>Close</button>
|
||||
<button class="btn mt-4" on:click={close}>{$t('about.close')}</button>
|
||||
</form>
|
||||
<div class="flex items-center justify-center flex-wrap gap-4 mt-4"></div>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import { onMount } from 'svelte';
|
||||
import { addToast } from '$lib/toasts';
|
||||
let modal: HTMLDialogElement;
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
console.log(transportationToEdit.id);
|
||||
|
||||
|
@ -64,7 +65,7 @@
|
|||
transportationToEdit.date &&
|
||||
transportationToEdit.date > transportationToEdit.end_date
|
||||
) {
|
||||
addToast('error', 'End date cannot be before start date');
|
||||
addToast('error', $t('adventures.start_before_end_error'));
|
||||
return;
|
||||
}
|
||||
// make sure end_date has a start_date
|
||||
|
@ -83,11 +84,11 @@
|
|||
|
||||
transportationToEdit = result;
|
||||
|
||||
addToast('success', 'Transportation edited successfully!');
|
||||
addToast('success', $t('transportation.transportation_edit_success'));
|
||||
dispatch('saveEdit', transportationToEdit);
|
||||
close();
|
||||
} else {
|
||||
addToast('error', 'Error editing transportaion');
|
||||
addToast('error', $t('transportation.error_editing_transportation'));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -96,7 +97,7 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg">Edit Transportation: {originalName}</h3>
|
||||
<h3 class="font-bold text-lg">{$t('transportation.edit_transportation')}: {originalName}</h3>
|
||||
<div
|
||||
class="modal-action items-center"
|
||||
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
|
||||
|
@ -122,26 +123,28 @@
|
|||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/>
|
||||
<div class="mb-2">
|
||||
<label for="type">Type <PlaneCar class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="type"
|
||||
>{$t('transportation.type')} <PlaneCar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
name="type"
|
||||
id="type"
|
||||
bind:value={transportationToEdit.type}
|
||||
>
|
||||
<option disabled selected>Transport Type</option>
|
||||
<option value="car">Car</option>
|
||||
<option value="plane">Plane</option>
|
||||
<option value="train">Train</option>
|
||||
<option value="bus">Bus</option>
|
||||
<option value="boat">Boat</option>
|
||||
<option value="bike">Bike</option>
|
||||
<option value="walking">Walking</option>
|
||||
<option value="other">Other</option>
|
||||
<option disabled selected>{$t('transportation.type')}</option>
|
||||
<option value="car">{$t('transportation.modes.car')}</option>
|
||||
<option value="plane">{$t('transportation.modes.plane')}</option>
|
||||
<option value="train">{$t('transportation.modes.train')}</option>
|
||||
<option value="bus">{$t('transportation.modes.bus')}</option>
|
||||
<option value="boat">{$t('transportation.modes.boat')}</option>
|
||||
<option value="bike">{$t('transportation.modes.bike')}</option>
|
||||
<option value="walking">{$t('transportation.modes.walking')}</option>
|
||||
<option value="other">{$t('transportation.modes.other')}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label for="name">Name</label><br />
|
||||
<label for="name">{$t('adventures.name')}</label><br />
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
|
@ -151,7 +154,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="date">Description <Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
<label for="date"
|
||||
>{$t('adventures.description')}
|
||||
<Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<div class="flex">
|
||||
<input
|
||||
|
@ -164,9 +169,10 @@
|
|||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="start_date"
|
||||
>{transportationToEdit.date ? 'Start ' : ''}Date & Time <Calendar
|
||||
class="inline-block mb-1 w-6 h-6"
|
||||
/></label
|
||||
>{transportationToEdit.date ? `${$t('transportation.start')} ` : ''}{$t(
|
||||
'transportation.date_and_time'
|
||||
)}
|
||||
<Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="datetime-local"
|
||||
|
@ -181,7 +187,8 @@
|
|||
{#if transportationToEdit.date}
|
||||
<div class="mb-2">
|
||||
<label for="end_date"
|
||||
>End Date & Time <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
>{$t('transportation.end_date_time')}
|
||||
<Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="datetime-local"
|
||||
|
@ -195,7 +202,9 @@
|
|||
</div>
|
||||
{/if}
|
||||
<div class="mb-2">
|
||||
<label for="rating">Rating <Star class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="rating"
|
||||
>{$t('adventures.rating')} <Star class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="number"
|
||||
max="5"
|
||||
|
@ -207,7 +216,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="rating">Link <LinkVariant class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="rating"
|
||||
>{$t('adventures.link')} <LinkVariant class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="url"
|
||||
id="link"
|
||||
|
@ -220,7 +231,8 @@
|
|||
{#if transportationToEdit.type == 'plane'}
|
||||
<div class="mb-2">
|
||||
<label for="flight_number"
|
||||
>Flight Number <Airplane class="inline-block mb-1 w-6 h-6" /></label
|
||||
>{$t('transportation.flight_number')}
|
||||
<Airplane class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -232,7 +244,9 @@
|
|||
</div>
|
||||
{/if}
|
||||
<div class="mb-2">
|
||||
<label for="rating">From Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="rating"
|
||||
>{$t('transportation.from_location')}
|
||||
<MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -243,7 +257,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="rating">To Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="rating"
|
||||
>{$t('transportation.to_location')}
|
||||
<MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -255,9 +271,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4">Edit</button>
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4">{$t('transportation.edit')}</button>
|
||||
<!-- if there is a button in form, it will close the modal -->
|
||||
<button class="btn mt-4" on:click={close}>Close</button>
|
||||
<button class="btn mt-4" on:click={close}>{$t('about.close')}</button>
|
||||
</form>
|
||||
<div class="flex items-center justify-center flex-wrap gap-4 mt-4"></div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import type { Adventure, Collection } from '$lib/types';
|
||||
import { onMount } from 'svelte';
|
||||
import { enhance } from '$app/forms';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { addToast } from '$lib/toasts';
|
||||
|
||||
import Calendar from '~icons/mdi/calendar';
|
||||
|
@ -45,18 +45,18 @@
|
|||
|
||||
// make sure that start_date is before end_date
|
||||
if (new Date(newCollection.start_date ?? '') > new Date(newCollection.end_date ?? '')) {
|
||||
addToast('error', 'Start date must be before end date');
|
||||
addToast('error', $t('adventures.start_before_end_error'));
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure end date has a start date
|
||||
if (newCollection.end_date && !newCollection.start_date) {
|
||||
addToast('error', 'Please provide a start date');
|
||||
addToast('error', $t('adventures.no_start_date'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newCollection.start_date && !newCollection.end_date) {
|
||||
addToast('error', 'Please provide an end date');
|
||||
addToast('error', $t('adventures.no_end_date'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,10 @@
|
|||
newCollection.user_id = user_id;
|
||||
console.log(newCollection);
|
||||
dispatch('create', newCollection);
|
||||
addToast('success', 'Collection created successfully!');
|
||||
addToast('success', $t('collection.collection_created'));
|
||||
close();
|
||||
} else {
|
||||
addToast('error', 'Error creating collection');
|
||||
addToast('error', $t('collection.error_creating_collection'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg">New Collection</h3>
|
||||
<h3 class="font-bold text-lg">{$t('collection.new_collection')}</h3>
|
||||
<div
|
||||
class="modal-action items-center"
|
||||
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
|
||||
|
@ -107,7 +107,7 @@
|
|||
action="/collections?/create"
|
||||
>
|
||||
<div class="mb-2">
|
||||
<label for="name">Name</label><br />
|
||||
<label for="name">{$t('adventures.name')}</label><br />
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
|
@ -119,7 +119,9 @@
|
|||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="description"
|
||||
>Description<iconify-icon icon="mdi:notebook" class="text-lg ml-1 -mb-0.5"
|
||||
>$t('adventures.description')<iconify-icon
|
||||
icon="mdi:notebook"
|
||||
class="text-lg ml-1 -mb-0.5"
|
||||
></iconify-icon></label
|
||||
><br />
|
||||
<div class="flex">
|
||||
|
@ -132,7 +134,8 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="start_date">Start Date <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="start_date"
|
||||
>{$t('adventures.start_date')} <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="date"
|
||||
|
@ -143,8 +146,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="end_date">End Date <Calendar class="inline-block mb-1 w-6 h-6" /></label><br
|
||||
/>
|
||||
<label for="end_date"
|
||||
>{$t('adventures.end_date')} <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="date"
|
||||
id="end_date"
|
||||
|
@ -154,7 +158,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="end_date">Link </label><br />
|
||||
<label for="end_date">{$t('adventures.link')} </label><br />
|
||||
<input
|
||||
type="url"
|
||||
id="link"
|
||||
|
@ -164,8 +168,10 @@
|
|||
/>
|
||||
</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>
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4">
|
||||
{$t('collection.create')}
|
||||
</button>
|
||||
<button type="button" class="btn mt-4" on:click={close}>{$t('about.close')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,27 +1,11 @@
|
|||
<script lang="ts">
|
||||
// let newTransportation: Transportation = {
|
||||
// id:NaN,
|
||||
// user_id: NaN,
|
||||
// type: '',
|
||||
// name: '',
|
||||
// description: null,
|
||||
// rating: NaN,
|
||||
// link: null,
|
||||
// date: null,
|
||||
// flight_number: null,
|
||||
// from_location: null,
|
||||
// to_location: null,
|
||||
// is_public: false,
|
||||
// collection: null,
|
||||
// created_at: '',
|
||||
// updated_at: ''
|
||||
// };
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { Collection, Transportation } from '$lib/types';
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from 'svelte';
|
||||
import { addToast } from '$lib/toasts';
|
||||
let modal: HTMLDialogElement;
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
export let collection: Collection;
|
||||
|
||||
|
@ -74,7 +58,7 @@
|
|||
|
||||
// make sure there is a start date if there is an end date
|
||||
if (formData.get('end_date') && !formData.get('date')) {
|
||||
addToast('error', 'Please provide a start date');
|
||||
addToast('error', $t('transportation.provide_start_date'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -86,11 +70,11 @@
|
|||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
|
||||
addToast('success', 'Transportation added successfully!');
|
||||
addToast('success', $t('transportation.transportation_added'));
|
||||
dispatch('add', result);
|
||||
close();
|
||||
} else {
|
||||
addToast('error', 'Error editing transportation');
|
||||
addToast('error', $t('transportation.error_editing_transportation'));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -99,22 +83,13 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg">New Transportation</h3>
|
||||
<h3 class="font-bold text-lg">{$t('transportation.new_transportation')}</h3>
|
||||
<div
|
||||
class="modal-action items-center"
|
||||
style="display: flex; flex-direction: column; align-items: center; width: 100%;"
|
||||
>
|
||||
<form method="post" style="width: 100%;" on:submit={handleSubmit}>
|
||||
<div class="mb-2">
|
||||
<!-- <input
|
||||
type="text"
|
||||
id="id"
|
||||
name="id"
|
||||
hidden
|
||||
readonly
|
||||
bind:value={newTransportation.id}
|
||||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/> -->
|
||||
<input
|
||||
type="text"
|
||||
id="collection"
|
||||
|
@ -134,26 +109,28 @@
|
|||
class="input input-bordered w-full max-w-xs mt-1"
|
||||
/>
|
||||
<div class="mb-2">
|
||||
<label for="type">Type <PlaneCar class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="type"
|
||||
>{$t('transportation.type')} <PlaneCar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
name="type"
|
||||
id="type"
|
||||
bind:value={type}
|
||||
>
|
||||
<option disabled selected>Transport Type</option>
|
||||
<option value="car">Car</option>
|
||||
<option value="plane">Plane</option>
|
||||
<option value="train">Train</option>
|
||||
<option value="bus">Bus</option>
|
||||
<option value="boat">Boat</option>
|
||||
<option value="bike">Bike</option>
|
||||
<option value="walking">Walking</option>
|
||||
<option value="other">Other</option>
|
||||
<option disabled selected>{$t('transportation.type')}</option>
|
||||
<option value="car">{$t('transportation.modes.car')}</option>
|
||||
<option value="plane">{$t('transportation.modes.plane')}</option>
|
||||
<option value="train">{$t('transportation.modes.train')}</option>
|
||||
<option value="bus">{$t('transportation.modes.bus')}</option>
|
||||
<option value="boat">{$t('transportation.modes.boat')}</option>
|
||||
<option value="bike">{$t('transportation.modes.bike')}</option>
|
||||
<option value="walking">{$t('transportation.modes.walking')}</option>
|
||||
<option value="other">{$t('transportation.modes.other')}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label for="name">Name</label><br />
|
||||
<label for="name">{$t('adventures.name')}</label><br />
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
|
@ -162,7 +139,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="date">Description <Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
<label for="date"
|
||||
>{$t('adventures.description')}
|
||||
<Notebook class="inline-block -mt-1 mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<div class="flex">
|
||||
<input
|
||||
|
@ -174,7 +153,8 @@
|
|||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="start_date"
|
||||
>Start Date & Time <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
>{$t('transportation.date_time')}
|
||||
<Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="datetime-local"
|
||||
|
@ -188,7 +168,8 @@
|
|||
|
||||
<div class="mb-2">
|
||||
<label for="end_date"
|
||||
>End Date & Time <Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
>{$t('transportation.end_date_time')}
|
||||
<Calendar class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="datetime-local"
|
||||
|
@ -201,7 +182,9 @@
|
|||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label for="rating">Rating <Star class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="rating"
|
||||
>{$t('adventures.rating')} <Star class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="number"
|
||||
max="5"
|
||||
|
@ -212,7 +195,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="rating">Link <LinkVariant class="inline-block mb-1 w-6 h-6" /></label><br />
|
||||
<label for="rating"
|
||||
>{$t('adventures.link')} <LinkVariant class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="url"
|
||||
id="link"
|
||||
|
@ -224,7 +209,8 @@
|
|||
{#if type == 'plane'}
|
||||
<div class="mb-2">
|
||||
<label for="flight_number"
|
||||
>Flight Number <Airplane class="inline-block mb-1 w-6 h-6" /></label
|
||||
>{$t('transportation.flight_number')}
|
||||
<Airplane class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -235,7 +221,9 @@
|
|||
</div>
|
||||
{/if}
|
||||
<div class="mb-2">
|
||||
<label for="rating">From Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="rating"
|
||||
>{$t('transportation.from_location')}
|
||||
<MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -245,7 +233,9 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="rating">To Location <MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
<label for="rating"
|
||||
>{$t('transportation.to_location')}
|
||||
<MapMarker class="inline-block mb-1 w-6 h-6" /></label
|
||||
><br />
|
||||
<input
|
||||
type="text"
|
||||
|
@ -256,9 +246,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4">Edit</button>
|
||||
<button type="submit" class="btn btn-primary mr-4 mt-4">{$t('transportation.edit')}</button>
|
||||
<!-- if there is a button in form, it will close the modal -->
|
||||
<button class="btn mt-4" on:click={close}>Close</button>
|
||||
<button class="btn mt-4" on:click={close}>{$t('about.close')}</button>
|
||||
</form>
|
||||
<div class="flex items-center justify-center flex-wrap gap-4 mt-4"></div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { addToast } from '$lib/toasts';
|
||||
import type { Collection, Note, User } from '$lib/types';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
@ -22,10 +22,10 @@
|
|||
method: 'DELETE'
|
||||
});
|
||||
if (res.ok) {
|
||||
addToast('success', 'Note deleted successfully');
|
||||
addToast('success', $t('notes.note_deleted'));
|
||||
dispatch('delete', note.id);
|
||||
} else {
|
||||
addToast('Failed to delete note', 'error');
|
||||
addToast($t('notes.note_delete_error'), 'error');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -39,9 +39,12 @@
|
|||
{note.name}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="badge badge-primary">Note</div>
|
||||
<div class="badge badge-primary">{$t('adventures.note')}</div>
|
||||
{#if note.links && note.links.length > 0}
|
||||
<p>{note.links.length} {note.links.length > 1 ? 'Links' : 'Link'}</p>
|
||||
<p>
|
||||
{note.links.length}
|
||||
{note.links.length > 1 ? $t('adventures.links') : $t('adventures.link')}
|
||||
</p>
|
||||
{/if}
|
||||
{#if note.date && note.date !== ''}
|
||||
<div class="inline-flex items-center">
|
||||
|
@ -54,7 +57,7 @@
|
|||
><Launch class="w-6 h-6" />Open Details</button
|
||||
> -->
|
||||
<button class="btn btn-neutral-200 mb-2" on:click={editNote}>
|
||||
<Launch class="w-6 h-6" />Open
|
||||
<Launch class="w-6 h-6" />{$t('notes.open')}
|
||||
</button>
|
||||
{#if note.user_id == user?.pk || (collection && user && collection.shared_with.includes(user.uuid))}
|
||||
<button
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from 'svelte';
|
||||
import ShareModal from './ShareModal.svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
let modal: HTMLDialogElement;
|
||||
|
||||
export let note: Note | null = null;
|
||||
|
@ -98,8 +98,7 @@
|
|||
}
|
||||
} else {
|
||||
let data = await res.json();
|
||||
console.error('Failed to save note', data);
|
||||
console.error('Failed to save note');
|
||||
console.error($t('notes.failed_to_save'), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,15 +108,15 @@
|
|||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div class="modal-box" role="dialog" on:keydown={handleKeydown} tabindex="0">
|
||||
<h3 class="font-bold text-lg">Note Editor</h3>
|
||||
<h3 class="font-bold text-lg">{$t('notes.note_editor')}</h3>
|
||||
{#if initialName}
|
||||
<p class="font-semibold text-md mb-2">Editing note {initialName}</p>
|
||||
<p class="font-semibold text-md mb-2">{$t('notes.editing_note')} {initialName}</p>
|
||||
{/if}
|
||||
|
||||
{#if (note && user?.pk == note?.user_id) || (collection && user && collection.shared_with.includes(user.uuid)) || !note}
|
||||
<form on:submit|preventDefault>
|
||||
<div class="form-control mb-2">
|
||||
<label for="name">Name</label>
|
||||
<label for="name">{$t('adventures.name')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
|
@ -126,7 +125,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Date</label>
|
||||
<label for="content">{$t('adventures.date')}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date"
|
||||
|
@ -138,7 +137,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Content</label>
|
||||
<label for="content">{$t('notes.content')}</label>
|
||||
<textarea
|
||||
id="content"
|
||||
class="textarea textarea-bordered"
|
||||
|
@ -147,11 +146,11 @@
|
|||
></textarea>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Links</label>
|
||||
<label for="content">{$t('adventures.links')}</label>
|
||||
<input
|
||||
type="url"
|
||||
class="input input-bordered w-full mb-1"
|
||||
placeholder="Add a link (e.g. https://example.com)"
|
||||
placeholder="${$t('notes.add_a_link')} (e.g. https://example.com)"
|
||||
bind:value={newLink}
|
||||
on:keydown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
|
@ -160,7 +159,9 @@
|
|||
}
|
||||
}}
|
||||
/>
|
||||
<button type="button" class="btn btn-sm btn-primary" on:click={addLink}>Add</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" on:click={addLink}
|
||||
>{$t('adventures.add')}</button
|
||||
>
|
||||
</div>
|
||||
{#if newNote.links.length > 0}
|
||||
<ul class="list-none">
|
||||
|
@ -174,7 +175,7 @@
|
|||
newNote.links = newNote.links.filter((_, index) => index !== i);
|
||||
}}
|
||||
>
|
||||
Remove
|
||||
{$t('adventures.remove')}
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
|
@ -200,8 +201,8 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
<button class="btn btn-primary mr-1" on:click={save}>Save</button>
|
||||
<button class="btn btn-neutral" on:click={close}>Close</button>
|
||||
<button class="btn btn-primary mr-1" on:click={save}>{$t('notes.save')}</button>
|
||||
<button class="btn btn-neutral" on:click={close}>{$t('about.close')}</button>
|
||||
|
||||
{#if collection.is_public}
|
||||
<div role="alert" class="alert mt-4">
|
||||
|
@ -218,14 +219,14 @@
|
|||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<span>This note is public because it is in a public collection.</span>
|
||||
<span>{$t('notes.note_public')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</form>
|
||||
{:else}
|
||||
<form>
|
||||
<div class="form-control mb-2">
|
||||
<label for="name">Name</label>
|
||||
<label for="name">{$t('adventures.public')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
|
@ -235,7 +236,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Date</label>
|
||||
<label for="content">{$t('adventures.date')}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date"
|
||||
|
@ -248,7 +249,7 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Content</label>
|
||||
<label for="content">{$t('notes.content')}</label>
|
||||
<textarea
|
||||
id="content"
|
||||
class="textarea textarea-bordered"
|
||||
|
@ -258,7 +259,7 @@
|
|||
></textarea>
|
||||
</div>
|
||||
<div class="form-control mb-2">
|
||||
<label for="content">Links</label>
|
||||
<label for="content">{$t('adventures.links')}</label>
|
||||
</div>
|
||||
{#if newNote.links.length > 0}
|
||||
<ul class="list-none">
|
||||
|
@ -270,7 +271,7 @@
|
|||
</ul>
|
||||
{/if}
|
||||
|
||||
<button class="btn btn-neutral" on:click={close}>Close</button>
|
||||
<button class="btn btn-neutral" on:click={close}>{$t('about.close')}</button>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import FileDocumentEdit from '~icons/mdi/file-document-edit';
|
||||
import type { Collection, Transportation, User } from '$lib/types';
|
||||
import { addToast } from '$lib/toasts';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
import ArrowDownThick from '~icons/mdi/arrow-down-thick';
|
||||
|
||||
|
@ -25,10 +26,9 @@
|
|||
}
|
||||
});
|
||||
if (!res.ok) {
|
||||
console.log('Error deleting transportation');
|
||||
console.log($t('transportation.transportation_delete_error'));
|
||||
} else {
|
||||
console.log('Collection deleted');
|
||||
addToast('info', 'Transportation deleted successfully!');
|
||||
addToast('info', $t('transportation.transportation_deleted'));
|
||||
dispatch('delete', transportation.id);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
|||
>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title overflow-ellipsis">{transportation.name}</h2>
|
||||
<div class="badge badge-secondary">{transportation.type}</div>
|
||||
<div class="badge badge-secondary">{$t(`transportation.modes.${transportation.type}`)}</div>
|
||||
<div>
|
||||
{#if transportation.from_location}
|
||||
<p class="break-words text-wrap">{transportation.from_location}</p>
|
||||
|
|
|
@ -79,7 +79,6 @@
|
|||
"count_txt": "results matching your search",
|
||||
"sort": "Sort",
|
||||
"order_direction": "Order Direction",
|
||||
"order_by": "Order By",
|
||||
"ascending": "Ascending",
|
||||
"descending": "Descending",
|
||||
"updated": "Updated",
|
||||
|
@ -119,6 +118,7 @@
|
|||
"public_adventure": "Public Adventure",
|
||||
"location_information": "Location Information",
|
||||
"link": "Link",
|
||||
"links": "Links",
|
||||
"description": "Description",
|
||||
"sources": "Sources",
|
||||
"collection_adventures": "Include Collection Adventures",
|
||||
|
@ -162,6 +162,7 @@
|
|||
"start_before_end_error": "Start date must be before end date",
|
||||
"activity": "Activity",
|
||||
"actions": "Actions",
|
||||
"no_end_date": "Please enter an end date",
|
||||
"see_adventures": "See Adventures",
|
||||
"image_fetch_failed": "Failed to fetch image",
|
||||
"no_location": "Please enter a location",
|
||||
|
@ -183,6 +184,23 @@
|
|||
"visited_region_check_desc": "By selecting this, the server will check all of your visited adventures and mark the regions they are located in as visited in world travel.",
|
||||
"update_visited_regions": "Update Visited Regions",
|
||||
"update_visited_regions_disclaimer": "This may take a while depending on the number of adventures you have visited.",
|
||||
"link_new": "Link New...",
|
||||
"add_new": "Add New...",
|
||||
"transportation": "Transportation",
|
||||
"note": "Note",
|
||||
"checklist": "Checklist",
|
||||
"collection_archived": "This collection has been archived.",
|
||||
"visit_link": "Visit Link",
|
||||
"collection_completed": "You've completed this collection!",
|
||||
"collection_stats": "Collection Stats",
|
||||
"keep_exploring": "Keep Exploring!",
|
||||
"linked_adventures": "Linked Adventures",
|
||||
"notes": "Notes",
|
||||
"checklists": "Checklists",
|
||||
"transportations": "Transportations",
|
||||
"itineary_by_date": "Itinerary by Date",
|
||||
"nothing_planned": "Nothing planned for this day. Enjoy the journey!<",
|
||||
"days": "days",
|
||||
"activities": {
|
||||
"general": "General 🌍",
|
||||
"outdoor": "Outdoor 🏞️",
|
||||
|
@ -261,5 +279,71 @@
|
|||
"password_does_not_match": "Passwords do not match",
|
||||
"password_is_required": "Password is required",
|
||||
"invalid_token": "Token is invalid or has expired"
|
||||
},
|
||||
"collection": {
|
||||
"collection_created": "Collection created successfully!",
|
||||
"error_creating_collection": "Error creating collection",
|
||||
"new_collection": "New Collection",
|
||||
"create": "Create",
|
||||
"collection_edit_success": "Collection edited successfully!",
|
||||
"error_editing_collection": "Error editing collection",
|
||||
"edit_collection": "Edit Collection"
|
||||
},
|
||||
"notes": {
|
||||
"note_deleted": "Note deleted successfully!",
|
||||
"note_delete_error": "Error deleting note",
|
||||
"open": "Open",
|
||||
"failed_to_save": "Failed to save note",
|
||||
"note_editor": "Note Editor",
|
||||
"editing_note": "Editing note",
|
||||
"content": "Content",
|
||||
"save": "Save",
|
||||
"note_public": "This note is public because it is in a public collection.",
|
||||
"add_a_link": "Add a link"
|
||||
},
|
||||
"checklist": {
|
||||
"checklist_deleted": "Checklist deleted successfully!",
|
||||
"checklist_delete_error": "Error deleting checklist",
|
||||
"failed_to_save": "Failed to save checklist",
|
||||
"checklist_editor": "Checklist Editor",
|
||||
"editing_checklist": "Editing checklist",
|
||||
"item": "Item",
|
||||
"items": "Items",
|
||||
"add_item": "Add Item",
|
||||
"new_item": "New Item",
|
||||
"save": "Save",
|
||||
"checklist_public": "This checklist is public because it is in a public collection.",
|
||||
"item_cannot_be_empty": "Item cannot be empty",
|
||||
"item_already_exists": "Item already exists"
|
||||
},
|
||||
"transportation": {
|
||||
"transportation_deleted": "Transportation deleted successfully!",
|
||||
"transportation_delete_error": "Error deleting transportation",
|
||||
"provide_start_date": "Please provide a start date",
|
||||
"transport_type": "Transport Type",
|
||||
"type": "Type",
|
||||
"transportation_added": "Transportation added successfully!",
|
||||
"error_editing_transportation": "Error editing transportation",
|
||||
"new_transportation": "New Transportation",
|
||||
"date_time": "Start Date & Time",
|
||||
"end_date_time": "End Date & Time",
|
||||
"flight_number": "Flight Number",
|
||||
"from_location": "From Location",
|
||||
"to_location": "To Location",
|
||||
"edit": "Edit",
|
||||
"modes": {
|
||||
"car": "Car",
|
||||
"plane": "Plane",
|
||||
"train": "Train",
|
||||
"bus": "Bus",
|
||||
"boat": "Boat",
|
||||
"bike": "Bike",
|
||||
"walking": "Walking",
|
||||
"other": "Other"
|
||||
},
|
||||
"transportation_edit_success": "Transportation edited successfully!",
|
||||
"edit_transportation": "Edit Transportation",
|
||||
"start": "Start",
|
||||
"date_and_time": "Date & Time"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import type { PageData } from './$types';
|
||||
import { goto } from '$app/navigation';
|
||||
import Lost from '$lib/assets/undraw_lost.svg';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
import Plus from '~icons/mdi/plus';
|
||||
import AdventureCard from '$lib/components/AdventureCard.svelte';
|
||||
|
@ -106,19 +107,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function changeType(event: CustomEvent<string>) {
|
||||
adventures = adventures.map((adventure) => {
|
||||
if (adventure.id == event.detail) {
|
||||
if (adventure.type == 'visited') {
|
||||
adventure.type = 'planned';
|
||||
} else {
|
||||
adventure.type = 'visited';
|
||||
}
|
||||
}
|
||||
return adventure;
|
||||
});
|
||||
}
|
||||
|
||||
let adventureToEdit: Adventure | null = null;
|
||||
let transportationToEdit: Transportation;
|
||||
let isAdventureModalOpen: boolean = false;
|
||||
|
@ -255,14 +243,15 @@
|
|||
<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">
|
||||
Adventure not Found
|
||||
{$t('adventures.not_found')}
|
||||
</h1>
|
||||
<p class="mt-4 text-muted-foreground">
|
||||
The adventure you were looking for could not be found. Please try a different adventure or
|
||||
check back later.
|
||||
{$t('adventures.not_found_desc')}
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<button class="btn btn-primary" on:click={() => goto('/')}>Homepage</button>
|
||||
<button class="btn btn-primary" on:click={() => goto('/')}
|
||||
>{$t('adventures.homepage')}</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -287,17 +276,17 @@
|
|||
class="dropdown-content z-[1] menu p-4 shadow bg-base-300 text-base-content rounded-box w-52 gap-4"
|
||||
>
|
||||
{#if collection.user_id === data.user.pk}
|
||||
<p class="text-center font-bold text-lg">Link new...</p>
|
||||
<p class="text-center font-bold text-lg">{$t('adventures.link_new')}</p>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
on:click={() => {
|
||||
isShowingLinkModal = true;
|
||||
}}
|
||||
>
|
||||
Adventure</button
|
||||
{$t('adventures.adventure')}</button
|
||||
>
|
||||
{/if}
|
||||
<p class="text-center font-bold text-lg">Add new...</p>
|
||||
<p class="text-center font-bold text-lg">{$t('adventures.add_new')}</p>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
on:click={() => {
|
||||
|
@ -305,7 +294,7 @@
|
|||
adventureToEdit = null;
|
||||
}}
|
||||
>
|
||||
Adventure</button
|
||||
{$t('adventures.adventure')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
|
@ -315,7 +304,7 @@
|
|||
newType = '';
|
||||
}}
|
||||
>
|
||||
Transportation</button
|
||||
{$t('adventures.transportation')}</button
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
|
@ -325,7 +314,7 @@
|
|||
noteToEdit = null;
|
||||
}}
|
||||
>
|
||||
Note</button
|
||||
{$t('adventures.note')}</button
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
|
@ -335,7 +324,7 @@
|
|||
checklistToEdit = null;
|
||||
}}
|
||||
>
|
||||
Checklist</button
|
||||
{$t('adventures.checklist')}</button
|
||||
>
|
||||
|
||||
<!-- <button
|
||||
|
@ -363,7 +352,7 @@
|
|||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
||||
/>
|
||||
</svg>
|
||||
<span>This collection has been archived.</span>
|
||||
<span>{$t('adventures.collection_archived')}</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -373,7 +362,7 @@
|
|||
{#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
|
||||
{$t('adventures.visit_link')}
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -385,12 +374,12 @@
|
|||
<div class="flex items-center justify-center mb-4">
|
||||
<div class="stats shadow bg-base-300">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Collection Stats</div>
|
||||
<div class="stat-title">{$t('adventures.collection_stats')}</div>
|
||||
<div class="stat-value">{numVisited}/{numAdventures} Visited</div>
|
||||
{#if numAdventures === numVisited}
|
||||
<div class="stat-desc">You've completed this collection! 🎉!</div>
|
||||
<div class="stat-desc">{$t('adventures.collection_completed')}</div>
|
||||
{:else}
|
||||
<div class="stat-desc">Keep exploring!</div>
|
||||
<div class="stat-desc">{$t('adventures.keep_exploring')}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -401,7 +390,7 @@
|
|||
<NotFound error={undefined} />
|
||||
{/if}
|
||||
{#if adventures.length > 0}
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-2">Linked Adventures</h1>
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-2">{$t('adventures.linked_adventures')}</h1>
|
||||
|
||||
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
|
||||
{#each adventures as adventure}
|
||||
|
@ -411,7 +400,6 @@
|
|||
on:delete={deleteAdventure}
|
||||
type={adventure.type}
|
||||
{adventure}
|
||||
on:typeChange={changeType}
|
||||
{collection}
|
||||
/>
|
||||
{/each}
|
||||
|
@ -419,7 +407,7 @@
|
|||
{/if}
|
||||
|
||||
{#if transportations.length > 0}
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">Transportation</h1>
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">{$t('adventures.transportations')}</h1>
|
||||
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
|
||||
{#each transportations as transportation}
|
||||
<TransportationCard
|
||||
|
@ -439,7 +427,7 @@
|
|||
{/if}
|
||||
|
||||
{#if notes.length > 0}
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">Notes</h1>
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">{$t('adventures.notes')}</h1>
|
||||
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
|
||||
{#each notes as note}
|
||||
<NoteCard
|
||||
|
@ -459,7 +447,7 @@
|
|||
{/if}
|
||||
|
||||
{#if checklists.length > 0}
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">Checklists</h1>
|
||||
<h1 class="text-center font-bold text-4xl mt-4 mb-4">{$t('adventures.checklists')}</h1>
|
||||
<div class="flex flex-wrap gap-4 mr-4 justify-center content-center">
|
||||
{#each checklists as checklist}
|
||||
<ChecklistCard
|
||||
|
@ -480,9 +468,12 @@
|
|||
|
||||
{#if collection.start_date && collection.end_date}
|
||||
<div class="divider"></div>
|
||||
<h1 class="text-center font-bold text-4xl mt-4">Itinerary by Date</h1>
|
||||
<h1 class="text-center font-bold text-4xl mt-4">{$t('adventures.itineary_by_date')}</h1>
|
||||
{#if numberOfDays}
|
||||
<p class="text-center text-lg pl-16 pr-16">Duration: {numberOfDays} days</p>
|
||||
<p class="text-center text-lg pl-16 pr-16">
|
||||
{$t('adventures.duration')}: {numberOfDays}
|
||||
{$t('adventures.days')}
|
||||
</p>
|
||||
{/if}
|
||||
<p class="text-center text-lg pl-16 pr-16">
|
||||
Dates: {new Date(collection.start_date).toLocaleDateString(undefined, { timeZone: 'UTC' })} - {new Date(
|
||||
|
@ -531,7 +522,6 @@
|
|||
on:delete={deleteAdventure}
|
||||
type={adventure.type}
|
||||
{adventure}
|
||||
on:typeChange={changeType}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
|
@ -582,7 +572,7 @@
|
|||
{/if}
|
||||
|
||||
{#if dayAdventures.length == 0 && dayTransportations.length == 0 && dayNotes.length == 0 && dayChecklists.length == 0}
|
||||
<p class="text-center text-lg mt-2">Nothing planned for this day. Enjoy the journey!</p>
|
||||
<p class="text-center text-lg mt-2">{$t('adventures.nothing_planned')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
|
@ -605,11 +595,6 @@
|
|||
<p class="font-semibold text-black text-md">
|
||||
{adventure.type.charAt(0).toUpperCase() + adventure.type.slice(1)}
|
||||
</p>
|
||||
<!-- <p>
|
||||
{adventure.
|
||||
? new Date(adventure.date).toLocaleDateString(undefined, { timeZone: 'UTC' })
|
||||
: ''}
|
||||
</p> -->
|
||||
</Popup>
|
||||
</DefaultMarker>
|
||||
{/if}
|
||||
|
@ -622,7 +607,7 @@
|
|||
<title
|
||||
>{data.props.adventure && data.props.adventure.name
|
||||
? `${data.props.adventure.name}`
|
||||
: 'Collection'}</title
|
||||
: $t('adventures.collection')}</title
|
||||
>
|
||||
<meta
|
||||
name="description"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue