mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-05 13:15:18 +02:00
commit
25f773eaa9
11 changed files with 682 additions and 85 deletions
|
@ -31,6 +31,10 @@
|
||||||
console.log(adventure.id);
|
console.log(adventure.id);
|
||||||
goto(`/adventure/${adventure.id}`);
|
goto(`/adventure/${adventure.id}`);
|
||||||
}
|
}
|
||||||
|
function markVisited() {
|
||||||
|
console.log(adventure.id);
|
||||||
|
dispatch("markVisited", adventure);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -77,6 +81,10 @@
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{#if type == "planner"}
|
{#if type == "planner"}
|
||||||
|
<button class="btn btn-success" on:click={markVisited}
|
||||||
|
><iconify-icon icon="mdi:check-bold" class="text-2xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
<button class="btn btn-primary" on:click={moreInfo}
|
<button class="btn btn-primary" on:click={moreInfo}
|
||||||
><iconify-icon icon="mdi:launch" class="text-2xl"
|
><iconify-icon icon="mdi:launch" class="text-2xl"
|
||||||
></iconify-icon></button
|
></iconify-icon></button
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import type { Adventure } from "$lib/utils/types";
|
import type { Adventure } from "$lib/utils/types";
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { addActivityType } from "$lib";
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
addActivityType();
|
activitySetup();
|
||||||
if (newAdventure.name.trim() === "") {
|
if (newAdventure.name.trim() === "") {
|
||||||
alert("Name is required");
|
alert("Name is required");
|
||||||
return;
|
return;
|
||||||
|
@ -46,15 +47,9 @@
|
||||||
|
|
||||||
let activityInput: string = "";
|
let activityInput: string = "";
|
||||||
|
|
||||||
function addActivityType() {
|
function activitySetup() {
|
||||||
if (activityInput.trim() !== "") {
|
newAdventure = addActivityType(activityInput, newAdventure);
|
||||||
const activities = activityInput
|
activityInput = "";
|
||||||
.split(" ")
|
|
||||||
.filter((activity) => activity.trim() !== "");
|
|
||||||
newAdventure.activityTypes = activities;
|
|
||||||
activityInput = "";
|
|
||||||
}
|
|
||||||
console.log(newAdventure.activityTypes);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import type { Adventure } from "$lib/utils/types";
|
import type { Adventure } from "$lib/utils/types";
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { addActivityType } from "$lib";
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
|
|
||||||
console.log(adventureToEdit.id);
|
console.log(adventureToEdit.id);
|
||||||
|
@ -19,7 +20,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
addActivityType();
|
activitySetup();
|
||||||
dispatch("submit", adventureToEdit);
|
dispatch("submit", adventureToEdit);
|
||||||
console.log(adventureToEdit);
|
console.log(adventureToEdit);
|
||||||
}
|
}
|
||||||
|
@ -36,15 +37,9 @@
|
||||||
|
|
||||||
let activityInput: string = "";
|
let activityInput: string = "";
|
||||||
|
|
||||||
function addActivityType() {
|
function activitySetup() {
|
||||||
if (activityInput.trim() !== "") {
|
adventureToEdit = addActivityType(activityInput, adventureToEdit);
|
||||||
const activities = activityInput
|
activityInput = "";
|
||||||
.split(",")
|
|
||||||
.filter((activity) => activity.trim() !== "");
|
|
||||||
adventureToEdit.activityTypes = activities;
|
|
||||||
activityInput = "";
|
|
||||||
}
|
|
||||||
console.log(adventureToEdit.activityTypes);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
169
src/lib/components/Navbar copy.svelte
Normal file
169
src/lib/components/Navbar copy.svelte
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from "$app/forms";
|
||||||
|
import { visitCount } from "$lib/utils/stores/visitCountStore";
|
||||||
|
import { goto } from "$app/navigation";
|
||||||
|
import type { DatabaseUser } from "$lib/server/auth";
|
||||||
|
export let user: any;
|
||||||
|
import UserAvatar from "./UserAvatar.svelte";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import InfoModal from "./InfoModal.svelte";
|
||||||
|
import infoIcon from "$lib/assets/info.svg";
|
||||||
|
import type { SubmitFunction } from "@sveltejs/kit";
|
||||||
|
async function goHome() {
|
||||||
|
goto("/");
|
||||||
|
}
|
||||||
|
async function goToLog() {
|
||||||
|
goto("/log");
|
||||||
|
}
|
||||||
|
async function goToFeatured() {
|
||||||
|
goto("/featured");
|
||||||
|
}
|
||||||
|
async function toToLogin() {
|
||||||
|
goto("/login");
|
||||||
|
}
|
||||||
|
async function goToSignup() {
|
||||||
|
goto("/signup");
|
||||||
|
}
|
||||||
|
async function goToWorldTravel() {
|
||||||
|
goto("/worldtravel");
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitUpdateTheme: SubmitFunction = ({ action }) => {
|
||||||
|
const theme = action.searchParams.get("theme");
|
||||||
|
if (theme) {
|
||||||
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
let infoModalOpen = false;
|
||||||
|
|
||||||
|
function showModal() {
|
||||||
|
infoModalOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
infoModalOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get value from fetch /api/visitcount
|
||||||
|
|
||||||
|
$: if (user) {
|
||||||
|
onMount(async () => {
|
||||||
|
const res = await fetch("/api/visitcount");
|
||||||
|
const data = await res.json();
|
||||||
|
visitCount.set(data.visitCount);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
visitCount.subscribe((value) => {
|
||||||
|
count = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the visit count to the number of adventures stored in local storage
|
||||||
|
const isBrowser = typeof window !== "undefined";
|
||||||
|
if (isBrowser) {
|
||||||
|
const storedAdventures = localStorage.getItem("adventures");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="navbar bg-base-100 flex flex-col md:flex-row">
|
||||||
|
<div class="navbar-start flex justify-around md:justify-start">
|
||||||
|
<button
|
||||||
|
class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2"
|
||||||
|
on:click={goHome}>Home</button
|
||||||
|
>
|
||||||
|
{#if user}
|
||||||
|
<button class="btn btn-primary my-2 md:my-0 md:mr-4" on:click={goToLog}
|
||||||
|
>My Log</button
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
||||||
|
on:click={() => goto("/planner")}>Planner</button
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- <button
|
||||||
|
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
||||||
|
on:click={() => goto("/planner")}>Planner</button
|
||||||
|
> -->
|
||||||
|
{/if}
|
||||||
|
<button
|
||||||
|
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
||||||
|
on:click={goToWorldTravel}>World Tavel Log</button
|
||||||
|
>
|
||||||
|
<button class="btn btn-primary my-2 md:my-0" on:click={goToFeatured}
|
||||||
|
>Featured</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-center flex justify-center md:justify-center">
|
||||||
|
<a class="btn btn-ghost text-xl" href="/">AdventureLog 🗺️</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if infoModalOpen}
|
||||||
|
<InfoModal on:close={closeModal} />
|
||||||
|
{/if}
|
||||||
|
<div class="navbar-end flex justify-around md:justify-end mr-4">
|
||||||
|
{#if !user}
|
||||||
|
<button class="btn btn-primary ml-4" on:click={toToLogin}>Login</button>
|
||||||
|
<button class="btn btn-primary ml-4" on:click={goToSignup}>Signup</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if user}
|
||||||
|
<p class="font-bold">Adventures: {count}</p>
|
||||||
|
<UserAvatar {user} />
|
||||||
|
{/if}
|
||||||
|
<button class="btn btn-neutral ml-4 btn-circle" on:click={showModal}
|
||||||
|
><iconify-icon icon="mdi:information" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
<div class="dropdown dropdown-bottom dropdown-end">
|
||||||
|
<div tabindex="0" role="button" class="btn m-1 ml-4">
|
||||||
|
<iconify-icon icon="mdi:theme-light-dark" class="text-xl"
|
||||||
|
></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||||
|
<ul
|
||||||
|
tabindex="0"
|
||||||
|
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52"
|
||||||
|
>
|
||||||
|
<form method="POST" use:enhance={submitUpdateTheme}>
|
||||||
|
<li>
|
||||||
|
<button formaction="/?/setTheme&theme=light"
|
||||||
|
>Light<iconify-icon icon="mdi:weather-sunny" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button formaction="/?/setTheme&theme=dark"
|
||||||
|
>Dark<iconify-icon icon="mdi:weather-night" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button formaction="/?/setTheme&theme=night"
|
||||||
|
>Night<iconify-icon icon="mdi:weather-night" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<!-- <li><button formaction="/?/setTheme&theme=nord">Nord</button></li> -->
|
||||||
|
<!-- <li><button formaction="/?/setTheme&theme=retro">Retro</button></li> -->
|
||||||
|
<li>
|
||||||
|
<button formaction="/?/setTheme&theme=forest"
|
||||||
|
>Forest<iconify-icon icon="mdi:forest" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
<button formaction="/?/setTheme&theme=garden"
|
||||||
|
>Garden<iconify-icon icon="mdi:flower" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
<button formaction="/?/setTheme&theme=aqua"
|
||||||
|
>Aqua<iconify-icon icon="mdi:water" class="text-xl"
|
||||||
|
></iconify-icon></button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</form>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -68,55 +68,90 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="navbar bg-base-100 flex flex-col md:flex-row">
|
<div class="navbar bg-base-100">
|
||||||
<div class="navbar-start flex justify-around md:justify-start">
|
<div class="navbar-start">
|
||||||
<button
|
<div class="dropdown">
|
||||||
class="btn btn-primary my-2 md:my-0 md:mr-4 md:ml-2"
|
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||||
on:click={goHome}>Home</button
|
<svg
|
||||||
>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
{#if user}
|
class="h-5 w-5"
|
||||||
<button class="btn btn-primary my-2 md:my-0 md:mr-4" on:click={goToLog}
|
fill="none"
|
||||||
>My Log</button
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
><path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 6h16M4 12h8m-8 6h16"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||||
|
<ul
|
||||||
|
tabindex="0"
|
||||||
|
class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52 gap-2"
|
||||||
>
|
>
|
||||||
<button
|
<li>
|
||||||
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
<button on:click={() => goto("/log")}>My Log</button>
|
||||||
on:click={() => goto("/planner")}>Planner</button
|
</li>
|
||||||
>
|
<li>
|
||||||
|
<button on:click={() => goto("/planner")}>Planner</button>
|
||||||
<!-- <button
|
</li>
|
||||||
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
<li>
|
||||||
on:click={() => goto("/planner")}>Planner</button
|
<button on:click={() => goto("/worldtravel")}>World Travel</button>
|
||||||
> -->
|
</li>
|
||||||
{/if}
|
<li>
|
||||||
<button
|
<button on:click={() => goto("/featured")}>Featured</button>
|
||||||
class="btn btn-primary my-2 md:my-0 md:mr-4"
|
</li>
|
||||||
on:click={goToWorldTravel}>World Tavel Log</button
|
{#if !user}
|
||||||
>
|
<li>
|
||||||
<button class="btn btn-primary my-2 md:my-0" on:click={goToFeatured}
|
<button class="btn btn-primary" on:click={toToLogin}>Login</button>
|
||||||
>Featured</button
|
</li>
|
||||||
>
|
<li>
|
||||||
</div>
|
<button class="btn btn-primary" on:click={goToSignup}>Signup</button
|
||||||
<div class="navbar-center flex justify-center md:justify-center">
|
>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<a class="btn btn-ghost text-xl" href="/">AdventureLog 🗺️</a>
|
<a class="btn btn-ghost text-xl" href="/">AdventureLog 🗺️</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="navbar-center hidden lg:flex">
|
||||||
{#if infoModalOpen}
|
<ul class="menu menu-horizontal px-1 gap-2">
|
||||||
<InfoModal on:close={closeModal} />
|
<li>
|
||||||
{/if}
|
<button class="btn btn-neutral" on:click={() => goto("/log")}
|
||||||
<div class="navbar-end flex justify-around md:justify-end mr-4">
|
>My Log</button
|
||||||
{#if !user}
|
>
|
||||||
<button class="btn btn-primary ml-4" on:click={toToLogin}>Login</button>
|
</li>
|
||||||
<button class="btn btn-primary ml-4" on:click={goToSignup}>Signup</button>
|
<li>
|
||||||
{/if}
|
<button class="btn btn-neutral" on:click={() => goto("/planner")}
|
||||||
|
>Planner</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-neutral" on:click={() => goto("/worldtravel")}
|
||||||
|
>World Travel</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-neutral" on:click={() => goto("/featured")}
|
||||||
|
>Featured</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{#if !user}
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-primary" on:click={toToLogin}>Login</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-primary" on:click={goToSignup}>Signup</button>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-end">
|
||||||
{#if user}
|
{#if user}
|
||||||
<p class="font-bold">Adventures: {count}</p>
|
|
||||||
<UserAvatar {user} />
|
<UserAvatar {user} />
|
||||||
{/if}
|
{/if}
|
||||||
<button class="btn btn-neutral ml-4 btn-circle" on:click={showModal}
|
|
||||||
><iconify-icon icon="mdi:information" class="text-xl"
|
|
||||||
></iconify-icon></button
|
|
||||||
>
|
|
||||||
<div class="dropdown dropdown-bottom dropdown-end">
|
<div class="dropdown dropdown-bottom dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn m-1 ml-4">
|
<div tabindex="0" role="button" class="btn m-1 ml-4">
|
||||||
<iconify-icon icon="mdi:theme-light-dark" class="text-xl"
|
<iconify-icon icon="mdi:theme-light-dark" class="text-xl"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { enhance } from "$app/forms";
|
import { enhance } from "$app/forms";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
|
import InfoModal from "./InfoModal.svelte";
|
||||||
export let user: any;
|
export let user: any;
|
||||||
|
|
||||||
let icon: string = "";
|
let icon: string = "";
|
||||||
|
@ -17,6 +18,8 @@
|
||||||
async function navToLog() {
|
async function navToLog() {
|
||||||
goto("/log");
|
goto("/log");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isInfoModalOpen: boolean = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="dropdown dropdown-bottom dropdown-end" tabindex="0" role="button">
|
<div class="dropdown dropdown-bottom dropdown-end" tabindex="0" role="button">
|
||||||
|
@ -42,8 +45,17 @@
|
||||||
<button on:click={() => goto("/settings/admin")}>Admin Settings</button>
|
<button on:click={() => goto("/settings/admin")}>Admin Settings</button>
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
|
<li>
|
||||||
|
<button on:click={() => (isInfoModalOpen = true)}
|
||||||
|
>About AdventureLog</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<li><button formaction="/?/logout">Logout</button></li>
|
<li><button formaction="/?/logout">Logout</button></li>
|
||||||
</form>
|
</form>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if isInfoModalOpen}
|
||||||
|
<InfoModal on:close={() => (isInfoModalOpen = false)} />
|
||||||
|
{/if}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import inspirationalQuotes from "./json/quotes.json";
|
import inspirationalQuotes from "./json/quotes.json";
|
||||||
import countryCodes from "./json/countries.json";
|
import countryCodes from "./json/countries.json";
|
||||||
|
import type { Adventure } from "./utils/types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a country code to its corresponding country name.
|
* Converts a country code to its corresponding country name.
|
||||||
|
@ -8,7 +9,8 @@ import countryCodes from "./json/countries.json";
|
||||||
*/
|
*/
|
||||||
export function countryCodeToName(countryCode: string): string | null {
|
export function countryCodeToName(countryCode: string): string | null {
|
||||||
// Look up the country name using the provided country code
|
// Look up the country name using the provided country code
|
||||||
const countryName = countryCodes[countryCode.toLowerCase() as keyof typeof countryCodes];
|
const countryName =
|
||||||
|
countryCodes[countryCode.toLowerCase() as keyof typeof countryCodes];
|
||||||
// Return the country name if found, otherwise return null
|
// Return the country name if found, otherwise return null
|
||||||
return countryName || null;
|
return countryName || null;
|
||||||
}
|
}
|
||||||
|
@ -19,10 +21,10 @@ export function countryCodeToName(countryCode: string): string | null {
|
||||||
* @param country - The 2 digit country code representing the desired flag.
|
* @param country - The 2 digit country code representing the desired flag.
|
||||||
* @returns The URL of the flag image.
|
* @returns The URL of the flag image.
|
||||||
*/
|
*/
|
||||||
export function getFlag(size:number,country: string) {
|
export function getFlag(size: number, country: string) {
|
||||||
return `https://flagcdn.com/h${size}/${country}.png`;
|
return `https://flagcdn.com/h${size}/${country}.png`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a random string consisting of alphanumeric characters.
|
* Generates a random string consisting of alphanumeric characters.
|
||||||
* @returns {string} The randomly generated string.
|
* @returns {string} The randomly generated string.
|
||||||
|
@ -48,5 +50,30 @@ export function getRandomQuote() {
|
||||||
const randomIndex = Math.floor(Math.random() * quotes.length);
|
const randomIndex = Math.floor(Math.random() * quotes.length);
|
||||||
let quoteString = quotes[randomIndex].quote;
|
let quoteString = quotes[randomIndex].quote;
|
||||||
let authorString = quotes[randomIndex].author;
|
let authorString = quotes[randomIndex].author;
|
||||||
return "\"" + quoteString + "\" - " + authorString;
|
return '"' + quoteString + '" - ' + authorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds activity types to the adventure.
|
||||||
|
*
|
||||||
|
* @param activityInput - The input string containing activity types separated by commas.
|
||||||
|
* @param adventureToEdit - The adventure object to which the activity types will be added.
|
||||||
|
* @returns The adventure object with the updated activity types.
|
||||||
|
*/
|
||||||
|
export function addActivityType(
|
||||||
|
activityInput: string,
|
||||||
|
adventureToEdit: Adventure
|
||||||
|
) {
|
||||||
|
if (activityInput.trim() !== "") {
|
||||||
|
const activities = activityInput
|
||||||
|
.split(",")
|
||||||
|
.filter((activity) => activity.trim() !== "");
|
||||||
|
// trims the whitespace from the activities
|
||||||
|
for (let i = 0; i < activities.length; i++) {
|
||||||
|
activities[i] = activities[i].trim();
|
||||||
|
}
|
||||||
|
adventureToEdit.activityTypes = activities;
|
||||||
|
activityInput = "";
|
||||||
|
}
|
||||||
|
return adventureToEdit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,26 +12,281 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col items-center justify-center">
|
<!--
|
||||||
{#if data.user && data.user.username != ""}
|
// v0 by Vercel.
|
||||||
<h1 class="mb-6 text-4xl font-extrabold">
|
// https://v0.dev/t/PyTNahbwxVP
|
||||||
Welcome {data.user.first_name}. Let's get Exploring!
|
-->
|
||||||
</h1>
|
|
||||||
{:else}
|
|
||||||
<h1 class="mb-6 text-4xl font-extrabold">Welcome. Let's get Exploring!</h1>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<img src={campingDrawing} class="w-1/4 mb-4" alt="Logo" />
|
<section class="w-full py-12 md:py-24 lg:py-32">
|
||||||
<button on:click={navToLog} class="btn btn-primary mb-4">Open Log</button>
|
<div class="container px-4 md:px-6">
|
||||||
|
<div
|
||||||
<div class="stats shadow">
|
class="grid gap-6 lg:grid-cols-[1fr_550px] lg:gap-12 xl:grid-cols-[1fr_650px]"
|
||||||
<div class="stat">
|
>
|
||||||
<div class="stat-title">Logged Adventures</div>
|
<div class="flex flex-col justify-center space-y-4">
|
||||||
<div class="stat-value text-center">{$visitCount}</div>
|
<div class="space-y-2">
|
||||||
<!-- <div class="stat-desc">21% more than last month</div> -->
|
<h1
|
||||||
|
class="text-3xl font-bold tracking-tighter sm:text-5xl xl:text-6xl/none"
|
||||||
|
>
|
||||||
|
Discover the World's Most Thrilling Adventures
|
||||||
|
</h1>
|
||||||
|
<p class="max-w-[600px] text-gray-500 md:text-xl dark:text-gray-400">
|
||||||
|
Discover and plan your next epic adventure with our cutting-edge
|
||||||
|
travel app. Explore breathtaking destinations, create custom
|
||||||
|
itineraries, and stay connected on the go.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2 min-[400px]:flex-row">
|
||||||
|
<button
|
||||||
|
on:click={() => goto("/log")}
|
||||||
|
class="inline-flex h-10 items-center justify-center rounded-md bg-gray-900 px-8 text-sm font-medium text-gray-50 shadow transition-colors hover:bg-gray-900/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:pointer-events-none disabled:opacity-50 dark:bg-gray-50 dark:text-gray-900 dark:hover:bg-gray-50/90 dark:focus-visible:ring-gray-300"
|
||||||
|
>
|
||||||
|
Go To AdventureLog
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1463693396721-8ca0cfa2b3b5?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
|
||||||
|
width="550"
|
||||||
|
height="550"
|
||||||
|
alt="Hero"
|
||||||
|
class="mx-auto aspect-video overflow-hidden rounded-xl object-cover sm:w-full lg:order-last"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
<section class="w-full py-12 md:py-24 lg:py-32 bg-gray-100 dark:bg-gray-800">
|
||||||
|
<div class="container px-4 md:px-6">
|
||||||
|
<div
|
||||||
|
class="flex flex-col items-center justify-center space-y-4 text-center"
|
||||||
|
>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div
|
||||||
|
class="inline-block rounded-lg bg-gray-100 px-3 py-1 text-sm dark:bg-gray-800"
|
||||||
|
>
|
||||||
|
Key Features
|
||||||
|
</div>
|
||||||
|
<h2 class="text-3xl font-bold tracking-tighter sm:text-5xl">
|
||||||
|
Discover, Plan, and Explore with Ease
|
||||||
|
</h2>
|
||||||
|
<p
|
||||||
|
class="max-w-[900px] text-gray-500 md:text-xl/relaxed lg:text-base/relaxed xl:text-xl/relaxed dark:text-gray-400"
|
||||||
|
>
|
||||||
|
Our adventure travel app is designed to simplify your journey,
|
||||||
|
providing you with the tools and resources to plan, pack, and navigate
|
||||||
|
your next epic adventure.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx-auto grid max-w-5xl items-center gap-6 py-12 lg:grid-cols-2 lg:gap-12"
|
||||||
|
>
|
||||||
|
<!-- svelte-ignore a11y-img-redundant-alt -->
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1516738901171-8eb4fc13bd20?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
|
||||||
|
width="550"
|
||||||
|
height="310"
|
||||||
|
alt="Image"
|
||||||
|
class="mx-auto aspect-video overflow-hidden rounded-xl object-cover object-center sm:w-full lg:order-last"
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col justify-center space-y-4">
|
||||||
|
<ul class="grid gap-6">
|
||||||
|
<li>
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h3 class="text-xl font-bold">Trip Planning</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400">
|
||||||
|
Easily create custom itineraries and get real-time updates on
|
||||||
|
your trip.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h3 class="text-xl font-bold">Packing Lists</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400">
|
||||||
|
Never forget a thing with our comprehensive packing lists.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h3 class="text-xl font-bold">Destination Guides</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400">
|
||||||
|
Discover the best attractions, activities, and hidden gems in
|
||||||
|
your destination.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- <section class="w-full py-12 md:py-24 lg:py-32 border-t">
|
||||||
|
<div
|
||||||
|
class="container grid items-center justify-center gap-4 px-4 text-center md:px-6"
|
||||||
|
>
|
||||||
|
<div class="space-y-3">
|
||||||
|
<h2 class="text-3xl font-bold tracking-tighter md:text-4xl/tight">
|
||||||
|
Explore the World's Most Breathtaking Destinations
|
||||||
|
</h2>
|
||||||
|
<p
|
||||||
|
class="mx-auto max-w-[600px] text-gray-500 md:text-xl/relaxed lg:text-base/relaxed xl:text-xl/relaxed dark:text-gray-400"
|
||||||
|
>
|
||||||
|
F
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-roledescription="carousel"
|
||||||
|
class="relative w-full max-w-5xl"
|
||||||
|
role="region"
|
||||||
|
>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<div class="flex -ml-4" style="transform: translate3d(0px, 0px, 0px);">
|
||||||
|
<div
|
||||||
|
aria-roledescription="slide"
|
||||||
|
class="min-w-0 shrink-0 grow-0 basis-full pl-4 md:basis-1/2 lg:basis-1/3"
|
||||||
|
role="group"
|
||||||
|
>
|
||||||
|
<div class="p-1">
|
||||||
|
<div
|
||||||
|
class="rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||||
|
data-v0-t="card"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/placeholder.svg"
|
||||||
|
width="400"
|
||||||
|
height="300"
|
||||||
|
alt="Destination"
|
||||||
|
class="aspect-[4/3] overflow-hidden rounded-t-xl object-cover"
|
||||||
|
/>
|
||||||
|
<div class="space-y-2 p-4">
|
||||||
|
<h3 class="text-xl font-bold">Machu Pic</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-roledescription="slide"
|
||||||
|
class="min-w-0 shrink-0 grow-0 basis-full pl-4 md:basis-1/2 lg:basis-1/3"
|
||||||
|
role="group"
|
||||||
|
>
|
||||||
|
<div class="p-1">
|
||||||
|
<div
|
||||||
|
class="rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||||
|
data-v0-t="card"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/placeholder.svg"
|
||||||
|
width="400"
|
||||||
|
height="300"
|
||||||
|
alt="Destination"
|
||||||
|
class="aspect-[4/3] overflow-hidden rounded-t-xl object-cover"
|
||||||
|
/>
|
||||||
|
<div class="space-y-2 p-4">
|
||||||
|
<h3 class="text-xl font-bold">Patagonia, Argentina</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-roledescription="slide"
|
||||||
|
class="min-w-0 shrink-0 grow-0 basis-full pl-4 md:basis-1/2 lg:basis-1/3"
|
||||||
|
role="group"
|
||||||
|
>
|
||||||
|
<div class="p-1">
|
||||||
|
<div
|
||||||
|
class="rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||||
|
data-v0-t="card"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/placeholder.svg"
|
||||||
|
width="400"
|
||||||
|
height="300"
|
||||||
|
alt="Destination"
|
||||||
|
class="aspect-[4/3] overflow-hidden rounded-t-xl object-cover"
|
||||||
|
/>
|
||||||
|
<div class="space-y-2 p-4">
|
||||||
|
<h3 class="text-xl font-bold">Bali, Indonesia</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400">
|
||||||
|
Discover lush jungles, stunning beaches, and ancient
|
||||||
|
temples.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-roledescription="slide"
|
||||||
|
class="min-w-0 shrink-0 grow-0 basis-full pl-4 md:basis-1/2 lg:basis-1/3"
|
||||||
|
role="group"
|
||||||
|
>
|
||||||
|
<div class="p-1">
|
||||||
|
<div
|
||||||
|
class="rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||||
|
data-v0-t="card"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/placeholder.svg"
|
||||||
|
width="400"
|
||||||
|
height="300"
|
||||||
|
alt="Destination"
|
||||||
|
class="aspect-[4/3] overflow-hidden rounded-t-xl object-cover"
|
||||||
|
/>
|
||||||
|
<div class="space-y-2 p-4">
|
||||||
|
<h3 class="text-xl font-bold">Banff, Canada</h3>
|
||||||
|
<p class="text-gray-500 dark:text-gray-400"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="inline-flex items-center justify-center whitespace-nowrap 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 border border-input bg-background hover:bg-accent hover:text-accent-foreground absolute h-8 w-8 rounded-full -left-12 top-1/2 -translate-y-1/2"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-4 w-4"
|
||||||
|
>
|
||||||
|
<path d="m12 19-7-7 7-7"></path>
|
||||||
|
<path d="M19 12H5"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Previous slide</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="inline-flex items-center justify-center whitespace-nowrap 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 border border-input bg-background hover:bg-accent hover:text-accent-foreground absolute h-8 w-8 rounded-full -right-12 top-1/2 -translate-y-1/2"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-4 w-4"
|
||||||
|
>
|
||||||
|
<path d="M5 12h14"></path>
|
||||||
|
<path d="m12 5 7 7-7 7"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Next slide</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section> -->
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Home | AdventureLog</title>
|
<title>Home | AdventureLog</title>
|
||||||
|
|
|
@ -180,7 +180,7 @@ export async function PUT(event: RequestEvent): Promise<Response> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, location, date, description, activityTypes, id, rating } =
|
const { name, location, date, description, activityTypes, id, rating, type } =
|
||||||
body.detailAdventure;
|
body.detailAdventure;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
|
@ -189,11 +189,18 @@ export async function PUT(event: RequestEvent): Promise<Response> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "featured") {
|
||||||
|
return error(400, {
|
||||||
|
message: "Featured adventures cannot be created at the moment",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// update the adventure in the user's visited list
|
// update the adventure in the user's visited list
|
||||||
await db
|
await db
|
||||||
.update(adventureTable)
|
.update(adventureTable)
|
||||||
.set({
|
.set({
|
||||||
name: name,
|
name: name,
|
||||||
|
type: type,
|
||||||
location: location,
|
location: location,
|
||||||
date: date,
|
date: date,
|
||||||
description: description,
|
description: description,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
saveAdventure,
|
saveAdventure,
|
||||||
removeAdventure,
|
removeAdventure,
|
||||||
addAdventure,
|
addAdventure,
|
||||||
|
changeType,
|
||||||
} from "../../services/adventureService.js";
|
} from "../../services/adventureService.js";
|
||||||
import SucessToast from "$lib/components/SucessToast.svelte";
|
import SucessToast from "$lib/components/SucessToast.svelte";
|
||||||
import mapDrawing from "$lib/assets/adventure_map.svg";
|
import mapDrawing from "$lib/assets/adventure_map.svg";
|
||||||
|
@ -87,6 +88,18 @@
|
||||||
showToast("Failed to add adventure");
|
showToast("Failed to add adventure");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function markVisited(event: { detail: Adventure }) {
|
||||||
|
let initialLength: number = plans.length;
|
||||||
|
let newArray = await changeType(event.detail, "mylog", plans);
|
||||||
|
if (newArray.length + 1 == initialLength) {
|
||||||
|
plans = newArray;
|
||||||
|
showToast("Adventure moved to visit log!");
|
||||||
|
} else {
|
||||||
|
showToast("Failed to moves adventure");
|
||||||
|
}
|
||||||
|
adventureToEdit = undefined;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isShowingToast}
|
{#if isShowingToast}
|
||||||
|
@ -131,6 +144,7 @@
|
||||||
type="planner"
|
type="planner"
|
||||||
on:edit={editPlan}
|
on:edit={editPlan}
|
||||||
on:remove={remove}
|
on:remove={remove}
|
||||||
|
on:markVisited={markVisited}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@ -153,3 +167,52 @@
|
||||||
type="planner"
|
type="planner"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<!-- ----------------------- -->
|
||||||
|
|
||||||
|
<!-- {#if plans.length == 0 && !isLoading}
|
||||||
|
<div class="flex flex-col items-center justify-center mt-16">
|
||||||
|
<article class="prose mb-4"><h2>Add some adventures!</h2></article>
|
||||||
|
<img src={mapDrawing} width="25%" alt="Logo" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if plans.length != 0 && !isLoading}
|
||||||
|
<div class="flex justify-center items-center w-full mt-4">
|
||||||
|
<article class="prose">
|
||||||
|
<h2 class="text-center">Actions</h2>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex flex-row items-center justify-center mt-2 gap-4 mb-4 flex-wrap"
|
||||||
|
>
|
||||||
|
<button class="btn btn-neutral" on:click={exportData}>
|
||||||
|
<img src={exportFile} class="inline-block -mt-1" alt="Logo" /> Save as File
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-neutral" on:click={() => (confirmModalOpen = true)}>
|
||||||
|
<img src={deleteIcon} class="inline-block -mt-1" alt="Logo" /> Delete Data
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-neutral" on:click={shareLink}>
|
||||||
|
<iconify-icon icon="mdi:share-variant" class="text-xl"></iconify-icon> Share
|
||||||
|
as Link
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if confirmModalOpen}
|
||||||
|
<ConfirmModal
|
||||||
|
on:close={handleClose}
|
||||||
|
on:confirm={deleteData}
|
||||||
|
title="Delete all Adventures"
|
||||||
|
isWarning={false}
|
||||||
|
message="Are you sure you want to delete all adventures?"
|
||||||
|
/>
|
||||||
|
{/if} -->
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>My Plans | AdventureLog</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Create and manage your adventure plans here!"
|
||||||
|
/>
|
||||||
|
</svelte:head>
|
||||||
|
|
|
@ -124,6 +124,37 @@ export async function addAdventure(
|
||||||
return adventureArray;
|
return adventureArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function changeType(
|
||||||
|
newAdventure: Adventure,
|
||||||
|
newType: string,
|
||||||
|
adventureArray: Adventure[]
|
||||||
|
) {
|
||||||
|
newAdventure.type = newType;
|
||||||
|
let detailAdventure = newAdventure;
|
||||||
|
|
||||||
|
const response = await fetch("/api/visits", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ detailAdventure }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
// remove adventure from array where id matches
|
||||||
|
adventureArray = adventureArray.filter(
|
||||||
|
(existingAdventure) => existingAdventure.id !== newAdventure.id
|
||||||
|
);
|
||||||
|
// showToast("Adventure removed successfully!");
|
||||||
|
} else {
|
||||||
|
console.error("Error:", response.statusText);
|
||||||
|
adventureArray = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(adventureArray);
|
||||||
|
|
||||||
|
return adventureArray;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Increments the visit count by the specified amount.
|
* Increments the visit count by the specified amount.
|
||||||
* @param {number} amount - The amount to increment the visit count by.
|
* @param {number} amount - The amount to increment the visit count by.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue