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);
|
||||
goto(`/adventure/${adventure.id}`);
|
||||
}
|
||||
function markVisited() {
|
||||
console.log(adventure.id);
|
||||
dispatch("markVisited", adventure);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
@ -77,6 +81,10 @@
|
|||
>
|
||||
{/if}
|
||||
{#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}
|
||||
><iconify-icon icon="mdi:launch" class="text-2xl"
|
||||
></iconify-icon></button
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import type { Adventure } from "$lib/utils/types";
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from "svelte";
|
||||
import { addActivityType } from "$lib";
|
||||
let modal: HTMLDialogElement;
|
||||
|
||||
onMount(() => {
|
||||
|
@ -25,7 +26,7 @@
|
|||
});
|
||||
|
||||
function create() {
|
||||
addActivityType();
|
||||
activitySetup();
|
||||
if (newAdventure.name.trim() === "") {
|
||||
alert("Name is required");
|
||||
return;
|
||||
|
@ -46,15 +47,9 @@
|
|||
|
||||
let activityInput: string = "";
|
||||
|
||||
function addActivityType() {
|
||||
if (activityInput.trim() !== "") {
|
||||
const activities = activityInput
|
||||
.split(" ")
|
||||
.filter((activity) => activity.trim() !== "");
|
||||
newAdventure.activityTypes = activities;
|
||||
activityInput = "";
|
||||
}
|
||||
console.log(newAdventure.activityTypes);
|
||||
function activitySetup() {
|
||||
newAdventure = addActivityType(activityInput, newAdventure);
|
||||
activityInput = "";
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import type { Adventure } from "$lib/utils/types";
|
||||
const dispatch = createEventDispatcher();
|
||||
import { onMount } from "svelte";
|
||||
import { addActivityType } from "$lib";
|
||||
let modal: HTMLDialogElement;
|
||||
|
||||
console.log(adventureToEdit.id);
|
||||
|
@ -19,7 +20,7 @@
|
|||
});
|
||||
|
||||
function submit() {
|
||||
addActivityType();
|
||||
activitySetup();
|
||||
dispatch("submit", adventureToEdit);
|
||||
console.log(adventureToEdit);
|
||||
}
|
||||
|
@ -36,15 +37,9 @@
|
|||
|
||||
let activityInput: string = "";
|
||||
|
||||
function addActivityType() {
|
||||
if (activityInput.trim() !== "") {
|
||||
const activities = activityInput
|
||||
.split(",")
|
||||
.filter((activity) => activity.trim() !== "");
|
||||
adventureToEdit.activityTypes = activities;
|
||||
activityInput = "";
|
||||
}
|
||||
console.log(adventureToEdit.activityTypes);
|
||||
function activitySetup() {
|
||||
adventureToEdit = addActivityType(activityInput, adventureToEdit);
|
||||
activityInput = "";
|
||||
}
|
||||
</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>
|
||||
|
||||
<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
|
||||
<div class="navbar bg-base-100">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
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
|
||||
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">
|
||||
<li>
|
||||
<button on:click={() => goto("/log")}>My Log</button>
|
||||
</li>
|
||||
<li>
|
||||
<button on:click={() => goto("/planner")}>Planner</button>
|
||||
</li>
|
||||
<li>
|
||||
<button on:click={() => goto("/worldtravel")}>World Travel</button>
|
||||
</li>
|
||||
<li>
|
||||
<button 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>
|
||||
<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}
|
||||
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal px-1 gap-2">
|
||||
<li>
|
||||
<button class="btn btn-neutral" on:click={() => goto("/log")}
|
||||
>My Log</button
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<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}
|
||||
<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"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { enhance } from "$app/forms";
|
||||
import { goto } from "$app/navigation";
|
||||
import InfoModal from "./InfoModal.svelte";
|
||||
export let user: any;
|
||||
|
||||
let icon: string = "";
|
||||
|
@ -17,6 +18,8 @@
|
|||
async function navToLog() {
|
||||
goto("/log");
|
||||
}
|
||||
|
||||
let isInfoModalOpen: boolean = false;
|
||||
</script>
|
||||
|
||||
<div class="dropdown dropdown-bottom dropdown-end" tabindex="0" role="button">
|
||||
|
@ -42,8 +45,17 @@
|
|||
<button on:click={() => goto("/settings/admin")}>Admin Settings</button>
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
<button on:click={() => (isInfoModalOpen = true)}
|
||||
>About AdventureLog</button
|
||||
>
|
||||
</li>
|
||||
<form method="post">
|
||||
<li><button formaction="/?/logout">Logout</button></li>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{#if isInfoModalOpen}
|
||||
<InfoModal on:close={() => (isInfoModalOpen = false)} />
|
||||
{/if}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import inspirationalQuotes from "./json/quotes.json";
|
||||
import countryCodes from "./json/countries.json";
|
||||
import type { Adventure } from "./utils/types";
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
// 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 countryName || null;
|
||||
}
|
||||
|
@ -19,7 +21,7 @@ export function countryCodeToName(countryCode: string): string | null {
|
|||
* @param country - The 2 digit country code representing the desired flag.
|
||||
* @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`;
|
||||
}
|
||||
|
||||
|
@ -48,5 +50,30 @@ export function getRandomQuote() {
|
|||
const randomIndex = Math.floor(Math.random() * quotes.length);
|
||||
let quoteString = quotes[randomIndex].quote;
|
||||
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>
|
||||
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
{#if data.user && data.user.username != ""}
|
||||
<h1 class="mb-6 text-4xl font-extrabold">
|
||||
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}
|
||||
<!--
|
||||
// v0 by Vercel.
|
||||
// https://v0.dev/t/PyTNahbwxVP
|
||||
-->
|
||||
|
||||
<img src={campingDrawing} class="w-1/4 mb-4" alt="Logo" />
|
||||
<button on:click={navToLog} class="btn btn-primary mb-4">Open Log</button>
|
||||
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Logged Adventures</div>
|
||||
<div class="stat-value text-center">{$visitCount}</div>
|
||||
<!-- <div class="stat-desc">21% more than last month</div> -->
|
||||
<section class="w-full py-12 md:py-24 lg:py-32">
|
||||
<div class="container px-4 md:px-6">
|
||||
<div
|
||||
class="grid gap-6 lg:grid-cols-[1fr_550px] lg:gap-12 xl:grid-cols-[1fr_650px]"
|
||||
>
|
||||
<div class="flex flex-col justify-center space-y-4">
|
||||
<div class="space-y-2">
|
||||
<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>
|
||||
</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>
|
||||
<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;
|
||||
|
||||
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
|
||||
await db
|
||||
.update(adventureTable)
|
||||
.set({
|
||||
name: name,
|
||||
type: type,
|
||||
location: location,
|
||||
date: date,
|
||||
description: description,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
saveAdventure,
|
||||
removeAdventure,
|
||||
addAdventure,
|
||||
changeType,
|
||||
} from "../../services/adventureService.js";
|
||||
import SucessToast from "$lib/components/SucessToast.svelte";
|
||||
import mapDrawing from "$lib/assets/adventure_map.svg";
|
||||
|
@ -87,6 +88,18 @@
|
|||
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>
|
||||
|
||||
{#if isShowingToast}
|
||||
|
@ -131,6 +144,7 @@
|
|||
type="planner"
|
||||
on:edit={editPlan}
|
||||
on:remove={remove}
|
||||
on:markVisited={markVisited}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -153,3 +167,52 @@
|
|||
type="planner"
|
||||
/>
|
||||
{/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;
|
||||
}
|
||||
|
||||
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.
|
||||
* @param {number} amount - The amount to increment the visit count by.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue