diff --git a/README.md b/README.md index 8634f3d..f4d9294 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ _**⚠️ 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 ℹ️ +## 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: @@ -29,7 +29,7 @@ AdventureLog is a Svelte Kit application that utilizes a PostgreSQL database. Us 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. +AdventureLog is licensed under the GNU General Public License v3.0. ## Roadmap 🛣️ diff --git a/src/lib/components/TripCard.svelte b/src/lib/components/TripCard.svelte new file mode 100644 index 0000000..2c291e2 --- /dev/null +++ b/src/lib/components/TripCard.svelte @@ -0,0 +1,67 @@ + + +
+
+

{trip.name}

+ {#if trip.description && trip.description !== ""} +
+ +

{trip.description}

+
+ {/if} + {#if trip.startDate && trip.startDate !== ""} +
+ +

{trip.startDate}

+
+ {/if} + {#if trip.endDate && trip.endDate !== ""} +
+ +

{trip.endDate}

+
+ {/if} +
+ + +
+
+
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 1575536..f8b51db 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -7,6 +7,7 @@ import campingDrawing from "$lib/assets/camping.svg"; import AdventureOverlook from "$lib/assets/AdventureOverlook.webp"; import MapWithPins from "$lib/assets/MapWithPins.webp"; + import { onMount } from "svelte"; async function navToLog() { goto("/log"); @@ -27,11 +28,29 @@ >
-

- Discover the World's Most Thrilling Adventures -

+ {#if data.user} + {#if data.user.first_name && data.user.first_name !== null} +

+ {data.user.first_name.charAt(0).toUpperCase() + + data.user.first_name.slice(1)}, Discover the World's Most + Thrilling Adventures +

+ {:else} +

+ Discover the World's Most Thrilling Adventures +

+ {/if} + {:else} +

+ Discover the World's Most Thrilling Adventures +

+ {/if}

Discover and plan your next epic adventure with our cutting-edge travel app. Explore breathtaking destinations, create custom diff --git a/src/routes/api/trip/+server.ts b/src/routes/api/trip/+server.ts new file mode 100644 index 0000000..3073abd --- /dev/null +++ b/src/routes/api/trip/+server.ts @@ -0,0 +1,51 @@ +import { db } from "$lib/db/db.server"; +import { adventureTable, userPlannedTrips } from "$lib/db/schema"; +import type { Adventure, Trip } from "$lib/utils/types"; +import { json, type RequestEvent, type RequestHandler } from "@sveltejs/kit"; +import { and, eq } from "drizzle-orm"; + +/** + * Handles the GET request for retrieving a trip. + * @param {Request} request - The request object. + * @param {Response} response - The response object. + * @returns {Promise} - A promise that resolves when the request is handled. + */ +export const GET: RequestHandler = async ({ url, locals }) => { + const id = url.searchParams.get("id"); + const user = locals.user; + + if (!user) { + return json({ error: "Unauthorized" }, { status: 401 }); + } + + if (!id) { + return json({ error: "Missing adventure ID" }, { status: 400 }); + } + + const trip = await db + .select() + .from(userPlannedTrips) + .where( + and( + eq(userPlannedTrips.id, Number(id)), // Convert id to number + eq(userPlannedTrips.userId, user.id) + ) + ) + .limit(1) + .execute(); + + if (trip.length === 0) { + return json({ error: "Trip not found" }, { status: 404 }); + } + + JSON.stringify( + trip.map((r) => { + const adventure: Trip = r as Trip; + }) + ); + + // console.log("GET /api/adventure?id=", id); + // console.log("User:", user); + + return json({ trip }, { status: 200 }); +}; diff --git a/src/routes/api/trips/+server.ts b/src/routes/api/trips/+server.ts index 4dc6fe3..50b0e40 100644 --- a/src/routes/api/trips/+server.ts +++ b/src/routes/api/trips/+server.ts @@ -1,7 +1,7 @@ import { db } from "$lib/db/db.server"; import { userPlannedTrips } from "$lib/db/schema"; import { error, type RequestEvent } from "@sveltejs/kit"; -import { eq } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; export async function POST(event: RequestEvent): Promise { if (!event.locals.user) { @@ -92,3 +92,38 @@ export async function GET(event: RequestEvent): Promise { }, }); } + +export async function DELETE(event: RequestEvent): Promise { + if (!event.locals.user) { + return new Response(JSON.stringify({ error: "No user found" }), { + status: 401, + headers: { + "Content-Type": "application/json", + }, + }); + } + + const body = await event.request.json(); + if (!body.id) { + return error(400, { + message: "No trip id provided", + }); + } + + let res = await db + .delete(userPlannedTrips) + .where( + and( + eq(userPlannedTrips.userId, event.locals.user.id), + eq(userPlannedTrips.id, body.id) + ) + ) + .execute(); + + return new Response(JSON.stringify({ message: "Trip deleted" }), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }); +} diff --git a/src/routes/planner/+page.svelte b/src/routes/planner/+page.svelte index 1a6dafa..53add80 100644 --- a/src/routes/planner/+page.svelte +++ b/src/routes/planner/+page.svelte @@ -13,6 +13,7 @@ import SucessToast from "$lib/components/SucessToast.svelte"; import mapDrawing from "$lib/assets/adventure_map.svg"; import CreateNewTripPlan from "$lib/components/CreateNewTripPlan.svelte"; + import TripCard from "$lib/components/TripCard.svelte"; export let data; let adventuresPlans: Adventure[] = []; @@ -154,6 +155,34 @@ showToast("Failed to get trips"); }); } + + async function removeTrip(event: { detail: number }) { + let initialLength: number = tripPlans.length; + const response = await fetch("/api/trips", { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ id: event.detail }), + }) + .then((response) => response.json()) + .then((data) => { + console.log("Success:", data); + let theTrip = tripPlans.find((trip) => trip.id === event.detail); + if (theTrip) { + let newArray = tripPlans.filter((trip) => trip.id !== event.detail); + if (newArray.length === initialLength - 1) { + tripPlans = newArray; + showToast("Trip removed successfully!"); + } else { + showToast("Failed to remove trip"); + } + } + }) + .catch((error) => { + showToast("Failed to get trips"); + }); + } {#if isShowingToast} @@ -247,19 +276,20 @@

{/if} -{#each tripPlans as trip (trip.id)} -
-
-

{trip.name}

-

{trip.description}

-

- Start Date: - {trip.startDate} End Date: - {trip.endDate} -

-
+
+ {#each tripPlans as trip (trip.id)} + + {/each} +
+ +{#if tripPlans.length == 0 && !isLoadingIdeas && !isLoadingTrips && !isShowingMoreFields && !isShowingNewTrip} +
+

Add some trips!

+ Logo
-{/each} +{/if} My Plans | AdventureLog diff --git a/src/routes/trip/[id]/+page.server.ts b/src/routes/trip/[id]/+page.server.ts new file mode 100644 index 0000000..d0ebb4d --- /dev/null +++ b/src/routes/trip/[id]/+page.server.ts @@ -0,0 +1,32 @@ +import { redirect } from "@sveltejs/kit"; +import type { PageServerLoad } from "./$types"; +import { db } from "$lib/db/db.server"; +import { and, eq } from "drizzle-orm"; +import { adventureTable, userPlannedTrips } from "$lib/db/schema"; + +export const load: PageServerLoad = (async (event) => { + if (!event.locals.user) { + return redirect(302, "/login"); + } + + let adventureUserId: any[] = await db + .select({ userId: userPlannedTrips.userId }) + .from(userPlannedTrips) + .where(eq(userPlannedTrips.id, Number(event.params.id))) + .limit(1) + .execute(); + + console.log(adventureUserId); + + if ( + adventureUserId && + adventureUserId[0]?.userId !== event.locals.user.id && + adventureUserId !== null + ) { + return redirect(302, "/log"); + } + + let trip = await event.fetch(`/api/trip?id=${event.params.id}`); + + return { trip: await trip.json() }; +}) satisfies PageServerLoad; diff --git a/src/routes/trip/[id]/+page.svelte b/src/routes/trip/[id]/+page.svelte new file mode 100644 index 0000000..758cf1e --- /dev/null +++ b/src/routes/trip/[id]/+page.svelte @@ -0,0 +1,27 @@ + + +
+ {#if trip} +

{trip.name}

+

{trip.description}

+

{trip.startDate}

+

{trip.endDate}

+ {/if} +