diff --git a/README.md b/README.md index a771ba5..8634f3d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # AdventureLog: Embark, Explore, Remember. 🌍 _**âš ī¸ AdventureLog is in early development and is not recommended for production use until version 1.0!**_ -### *"Never forget an adventure with AdventureLog - Your ultimate travel companion!"* ------ + +### _"Never forget an adventure with AdventureLog - Your ultimate travel companion!"_ + +--- + ## Installation ### Docker 🐋 (Recomended) + 1. Clone the repository 2. Edit the `docker-compose.yml` file and change the database password 3. Run `docker compose up -d` to build the image and start the container @@ -14,3 +18,22 @@ _**âš ī¸ AdventureLog is in early development and is not recommended for produc **Note**: The `ORIGIN` variable is required for CSRF protection. It can be omitted if using a reverse proxy or other HTTPS service. +## About AdventureLog â„šī¸ + +AdventureLog is a Svelte Kit application that utilizes a PostgreSQL database. Users can log the adventures they have experienced, as well as plan future ones. Key features include: + +- Logging past adventures with fields like name, date, location, description, and rating. +- Planning future adventures with similar fields. +- Tagging different activity types for better organization. +- Viewing countries, regions, and marking visited regions. + +AdventureLog aims to be your ultimate travel companion, helping you document your adventures and plan new ones effortlessly. + +AdventureLog is liscensed under the GNU General Public License v3.0. + +## Roadmap đŸ›Ŗī¸ + +- Improved mobile device support +- Password reset functionality +- Improved error handling +- Handling of adventure cards with variable width diff --git a/src/lib/components/CreateNewAdventure.svelte b/src/lib/components/CreateNewAdventure.svelte index 615b8e4..7dd1639 100644 --- a/src/lib/components/CreateNewAdventure.svelte +++ b/src/lib/components/CreateNewAdventure.svelte @@ -26,6 +26,10 @@ function create() { addActivityType(); + if (newAdventure.name.trim() === "") { + alert("Name is required"); + return; + } dispatch("create", newAdventure); console.log(newAdventure); } @@ -70,6 +74,7 @@ diff --git a/src/lib/config.ts b/src/lib/config.ts index dad49ef..5f179f3 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,3 +1,3 @@ -export let appVersion = "Web 0.1.6-alpha"; +export let appVersion = "Web 0.1.7-alpha"; export let appTitle = "AdventureLog"; -export let copyrightYear = "2024" +export let copyrightYear = "2024"; diff --git a/src/routes/log/+page.svelte b/src/routes/log/+page.svelte index ac491b6..1326ead 100644 --- a/src/routes/log/+page.svelte +++ b/src/routes/log/+page.svelte @@ -7,6 +7,7 @@ import type { Adventure } from "$lib/utils/types"; import { onMount } from "svelte"; import exportFile from "$lib/assets/exportFile.svg"; + import ConfirmModal from "$lib/components/ConfirmModal.svelte"; import deleteIcon from "$lib/assets/deleteIcon.svg"; import SucessToast from "$lib/components/SucessToast.svelte"; import mapDrawing from "$lib/assets/adventure_map.svg"; @@ -14,6 +15,11 @@ import { generateRandomString } from "$lib"; import { visitCount } from "$lib/utils/stores/visitCountStore"; import MoreFieldsInput from "$lib/components/CreateNewAdventure.svelte"; + import { + addAdventure, + removeAdventure, + saveAdventure, + } from "../../services/adventureService.js"; let isShowingMoreFields = false; @@ -21,6 +27,7 @@ let isShowingToast: boolean = false; let toastAction: string = ""; + let confirmModalOpen: boolean = false; // Sets the adventures array to the data from the server onMount(async () => { @@ -56,72 +63,26 @@ URL.revokeObjectURL(url); } - const createNewAdventure = (event: { detail: Adventure }) => { + const createNewAdventure = async (event: { detail: Adventure }) => { isShowingMoreFields = false; - let detailAdventure = event.detail; - console.log("Event" + event.detail.name); - - fetch("/api/visits", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - detailAdventure, - }), - }) - .then((response) => { - if (!response.ok) { - return response.json().then((data) => { - throw new Error( - data.error || `Failed to add adventure - ${data?.message}` - ); - }); - } - return response.json(); - }) - .then((data) => { - // add to local array for instant view update - adventures = [...adventures, data.adventure]; - showToast("Adventure added successfully!"); - visitCount.update((n) => n + 1); - }) - .catch((error) => { - console.error("Error:", error); - showToast(error.message); - }); + let newArray = await addAdventure(event.detail, adventures); + if (newArray.length > 0) { + adventures = newArray; + showToast("Adventure added successfully!"); + } else { + showToast("Failed to add adventure"); + } }; - function saveAdventure(event: { detail: Adventure }) { - console.log("Event", event.detail); - let detailAdventure = event.detail; - - // put request to /api/visits with id and adventure data - fetch("/api/visits", { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - detailAdventure, - }), - }) - .then((response) => response.json()) - .then((data) => { - console.log("Success:", data); - // update local array with new data - const index = adventures.findIndex( - (adventure) => adventure.id === detailAdventure.id - ); - if (index !== -1) { - adventures[index] = detailAdventure; - } - adventureToEdit = undefined; - showToast("Adventure edited successfully!"); - }) - .catch((error) => { - console.error("Error:", error); - }); + async function save(event: { detail: Adventure }) { + let newArray = await saveAdventure(event.detail, adventures); + if (newArray.length > 0) { + adventures = newArray; + showToast("Adventure updated successfully!"); + } else { + showToast("Failed to update adventure"); + } + adventureToEdit = undefined; } function editAdventure(event: { detail: number }) { @@ -163,6 +124,7 @@ function handleClose() { adventureToEdit = undefined; + confirmModalOpen = false; isShowingMoreFields = false; } @@ -186,29 +148,20 @@ }); } - function removeAdventure(event: { detail: number }) { - console.log("Event ID " + event.detail); - // send delete request to server at /api/visits - fetch("/api/visits", { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ id: event.detail }), - }) - .then((response) => response.json()) - .then((data) => { - console.log("Success:", data); - // remove adventure from array where id matches - adventures = adventures.filter( - (adventure) => adventure.id !== event.detail - ); + async function remove(event: { detail: number }) { + let initialLength: number = adventures.length; + let theAdventure = adventures.find( + (adventure) => adventure.id === event.detail + ); + if (theAdventure) { + let newArray = await removeAdventure(theAdventure, adventures); + if (newArray.length === initialLength - 1) { + adventures = newArray; showToast("Adventure removed successfully!"); - visitCount.update((n) => n - 1); - }) - .catch((error) => { - console.error("Error:", error); - }); + } else { + showToast("Failed to remove adventure"); + } + } } @@ -254,11 +207,7 @@ {/if} {#if adventureToEdit && adventureToEdit.id != undefined} - + {/if}
{/each}
@@ -293,7 +242,7 @@ -