diff --git a/package.json b/package.json index 847b2c2..b986b2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "adventurelog", - "version": "0.1.6", + "version": "0.2.0", "description": "Embark, Explore, Remember. 🌍", "private": true, "scripts": { diff --git a/src/lib/components/AddLocationChooser.svelte b/src/lib/components/AddLocationChooser.svelte new file mode 100644 index 0000000..41895cc --- /dev/null +++ b/src/lib/components/AddLocationChooser.svelte @@ -0,0 +1,74 @@ + + +{#if tripModal} + +{/if} + + + + + + diff --git a/src/lib/components/AdventureCard.svelte b/src/lib/components/AdventureCard.svelte index ceaf5e4..7ae6205 100644 --- a/src/lib/components/AdventureCard.svelte +++ b/src/lib/components/AdventureCard.svelte @@ -109,6 +109,10 @@ > --> + { @@ -46,6 +46,28 @@ } } + async function generate() { + try { + console.log(newAdventure.name); + const desc = await generateDescription(newAdventure.name); + newAdventure.description = desc; + // Do something with the updated newAdventure object + } catch (error) { + console.error(error); + // Handle the error + } + } + + async function searchImage() { + try { + const imageUrl = await getImage(newAdventure.name); + newAdventure.imageUrl = imageUrl; + } catch (error) { + console.error(error); + // Handle the error + } + } + let activityInput: string = ""; function activitySetup() { @@ -102,6 +124,7 @@ class="input input-bordered w-full max-w-xs" /> +
+ +
diff --git a/src/lib/components/TripCard.svelte b/src/lib/components/TripCard.svelte index 2c291e2..a7fc61b 100644 --- a/src/lib/components/TripCard.svelte +++ b/src/lib/components/TripCard.svelte @@ -19,11 +19,7 @@ dispatch("add", trip); } - function moreInfo() { - console.log(trip.id); - goto(`/trip/${trip.id}`); - } - + // TODO: Implement markVisited function function markVisited() { console.log(trip.id); dispatch("markVisited", trip); diff --git a/src/lib/components/TripListModal.svelte b/src/lib/components/TripListModal.svelte new file mode 100644 index 0000000..d553cd8 --- /dev/null +++ b/src/lib/components/TripListModal.svelte @@ -0,0 +1,51 @@ + + + + + + + + + diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts index 5cb928b..a6298a8 100644 --- a/src/lib/db/schema.ts +++ b/src/lib/db/schema.ts @@ -9,12 +9,6 @@ import { integer, } from "drizzle-orm/pg-core"; -export const featuredAdventures = pgTable("featuredAdventures", { - id: serial("id").primaryKey(), - name: text("name").notNull().unique(), - location: text("location"), -}); - export const sharedAdventures = pgTable("sharedAdventures", { id: text("id").primaryKey(), data: json("data").notNull(), diff --git a/src/lib/index.ts b/src/lib/index.ts index 07c1c49..078bef0 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -63,3 +63,64 @@ export function addActivityType( } return adventureToEdit; } + +/** + * Generates a description for an adventure using the adventure title. + * @param adventureTitle - The title of the adventure. + * @returns A Promise that resolves to the description of the adventure. + */ +export async function generateDescription(adventureTitle: string) { + const url = `https://en.wikipedia.org/w/api.php?origin=*&action=query&prop=extracts&exintro&explaintext&format=json&titles=${encodeURIComponent( + adventureTitle + )}`; + + try { + const res = await fetch(url); + const data = await res.json(); + + // Check if the query was successful + if (data.query && data.query.pages) { + const pageId = Object.keys(data.query.pages)[0]; + const page = data.query.pages[pageId]; + + // Check if the page exists + if (page.extract) { + return page.extract; + } else { + return `No Wikipedia article found for "${adventureTitle}".`; + } + } else { + return `Error: ${data.error.info}`; + } + } catch (error) { + console.error("Error fetching Wikipedia data:", error); + return `Error fetching Wikipedia data for "${adventureTitle}".`; + } +} + +export async function getImage(adventureTitle: string) { + const url = `https://en.wikipedia.org/w/api.php?origin=*&action=query&prop=pageimages&format=json&piprop=original&titles=${adventureTitle}`; + + try { + const res = await fetch(url); + const data = await res.json(); + + // Check if the query was successful + if (data.query && data.query.pages) { + const pageId = Object.keys(data.query.pages)[0]; + const page = data.query.pages[pageId]; + + // Check if the page has an image + if (page.original && page.original.source) { + return page.original.source; + } else { + return `No image found for "${adventureTitle}".`; + } + } else { + return `Error: ${data.error.info}`; + } + } catch (error) { + console.error("Error fetching Wikipedia data:", error); + return `Error fetching Wikipedia data for "${adventureTitle}".`; + } +} diff --git a/src/routes/api/trips/+server.ts b/src/routes/api/trips/+server.ts index 50b0e40..4699e1c 100644 --- a/src/routes/api/trips/+server.ts +++ b/src/routes/api/trips/+server.ts @@ -1,7 +1,8 @@ import { db } from "$lib/db/db.server"; -import { userPlannedTrips } from "$lib/db/schema"; +import { adventureTable, userPlannedTrips } from "$lib/db/schema"; import { error, type RequestEvent } from "@sveltejs/kit"; import { and, eq } from "drizzle-orm"; +import type { Trip } from "$lib/utils/types"; export async function POST(event: RequestEvent): Promise { if (!event.locals.user) { @@ -37,7 +38,6 @@ export async function POST(event: RequestEvent): Promise { description: description || null, startDate: startDate || null, endDate: endDate || null, - adventures: JSON.stringify([]), }) .returning({ insertedId: userPlannedTrips.id }) .execute(); @@ -78,13 +78,6 @@ export async function GET(event: RequestEvent): Promise { .where(eq(userPlannedTrips.userId, event.locals.user.id)) .execute(); - // json parse the adventures into an Adventure array - for (let trip of trips) { - if (trip.adventures) { - trip.adventures = JSON.parse(trip.adventures as unknown as string); - } - } - return new Response(JSON.stringify(trips), { status: 200, headers: { @@ -110,6 +103,11 @@ export async function DELETE(event: RequestEvent): Promise { }); } + let deleted = await db + .delete(adventureTable) + .where(eq(adventureTable.tripId, body.id)) + .execute(); + let res = await db .delete(userPlannedTrips) .where( diff --git a/src/routes/featured/+page.server.ts b/src/routes/featured/+page.server.ts index c60aa47..50b0180 100644 --- a/src/routes/featured/+page.server.ts +++ b/src/routes/featured/+page.server.ts @@ -1,5 +1,5 @@ import { db } from "$lib/db/db.server"; -import { adventureTable, featuredAdventures } from "$lib/db/schema"; +import { adventureTable } from "$lib/db/schema"; import type { Adventure } from "$lib/utils/types"; import { eq } from "drizzle-orm"; diff --git a/src/routes/featured/+page.svelte b/src/routes/featured/+page.svelte index 1f6c57c..4433eb5 100644 --- a/src/routes/featured/+page.svelte +++ b/src/routes/featured/+page.svelte @@ -2,10 +2,60 @@ export let data; import { goto } from "$app/navigation"; import AdventureCard from "$lib/components/AdventureCard.svelte"; - import type { Adventure } from "$lib/utils/types.js"; + import type { Adventure, Trip } from "$lib/utils/types.js"; + import AddFromFeatured from "$lib/components/AddLocationChooser.svelte"; + import { addAdventure } from "../../services/adventureService.js"; + import SucessToast from "$lib/components/SucessToast.svelte"; + + let isShowingToast: boolean = false; + let toastAction: string = ""; + + let adventureToAdd: Adventure | null = null; + + function showToast(action: string) { + toastAction = action; + isShowingToast = true; + + setTimeout(() => { + isShowingToast = false; + toastAction = ""; + }, 3000); + } async function add(event: CustomEvent) { - let detailAdventure = event.detail; + adventureToAdd = event.detail; + } + + const addToTrip = async (event: { detail: Trip }) => { + if (!adventureToAdd) { + showToast("Failed to add adventure"); + adventureToAdd = null; + } else { + let detailAdventure = adventureToAdd; + detailAdventure.tripId = event.detail.id; + detailAdventure.type = "planner"; + console.log(detailAdventure); + let res = await fetch("/api/planner", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + detailAdventure, + }), + }); + if (res.status === 401) { + goto("/login"); + } else { + showToast("Adventure added to trip!"); + adventureToAdd = null; + } + } + }; + + async function addToVisted() { + let detailAdventure = adventureToAdd; + adventureToAdd = null; const response = await fetch("/api/visits", { method: "POST", @@ -19,10 +69,47 @@ if (response.status === 401) { goto("/login"); + } else { + showToast("Adventure added to visited list!"); + } + } + + async function addIdea() { + let detailAdventure = adventureToAdd; + adventureToAdd = null; + + const response = await fetch("/api/planner", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + detailAdventure, + }), + }); + + if (response.status === 401) { + goto("/login"); + } else { + showToast("Adventure added to idea list!"); } } +{#if isShowingToast} + +{/if} + +{#if adventureToAdd} + (adventureToAdd = null)} + on:visited={addToVisted} + on:idea={addIdea} + on:trip={addToTrip} + /> +{/if} +

Featured Adventure Locations

diff --git a/src/routes/planner/+page.svelte b/src/routes/planner/+page.svelte index 9ee26a2..4377748 100644 --- a/src/routes/planner/+page.svelte +++ b/src/routes/planner/+page.svelte @@ -271,7 +271,7 @@ {#if tripPlans.length !== 0}
-

My Trip Plans

+

My Trip Ideas

{/if}