From 895522b2ac4ce0acaa1f8a743c88ea62e654cce5 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 30 Apr 2024 21:52:05 +0000 Subject: [PATCH 01/13] Refactor adventure page layout to use a responsive image size in +page.svelte --- src/routes/adventure/[id]/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/adventure/[id]/+page.svelte b/src/routes/adventure/[id]/+page.svelte index a266a4e..9ed5686 100644 --- a/src/routes/adventure/[id]/+page.svelte +++ b/src/routes/adventure/[id]/+page.svelte @@ -59,7 +59,7 @@ {adventure.name} {/if} From 296659ea277c6541009666705026fd361aaf7119 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 30 Apr 2024 22:39:09 +0000 Subject: [PATCH 02/13] Refactor CreateNewAdventure component to add activity types and update server files --- src/lib/components/CreateNewAdventure.svelte | 33 ++++++++++++++++++-- src/routes/api/visits/+server.ts | 20 ++++++++++-- src/routes/log/+page.server.ts | 1 - src/routes/log/+page.svelte | 2 ++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/lib/components/CreateNewAdventure.svelte b/src/lib/components/CreateNewAdventure.svelte index 83c5e09..2addc31 100644 --- a/src/lib/components/CreateNewAdventure.svelte +++ b/src/lib/components/CreateNewAdventure.svelte @@ -7,6 +7,7 @@ name: "", location: "", date: "", + activityTypes: [], }; import { createEventDispatcher } from "svelte"; @@ -23,6 +24,7 @@ }); function create() { + addActivityType(); dispatch("create", newAdventure); console.log(newAdventure); } @@ -36,6 +38,22 @@ close(); } } + + let activityInput: string = ""; + + function addActivityType() { + if (activityInput.trim() !== "") { + const activities = activityInput + .split(",") + .map((activity) => activity.trim()); + newAdventure.activityTypes = [ + ...(newAdventure.activityTypes || []), + ...activities, + ]; + activityInput = ""; + } + console.log(newAdventure.activityTypes); + } @@ -85,8 +103,19 @@ class="input input-bordered w-full max-w-xs" /> - + + + + diff --git a/src/routes/api/visits/+server.ts b/src/routes/api/visits/+server.ts index b19ed75..dedf2b2 100644 --- a/src/routes/api/visits/+server.ts +++ b/src/routes/api/visits/+server.ts @@ -22,7 +22,20 @@ export async function GET(event: RequestEvent): Promise { .execute(); return new Response( // turn the result into an Adventure object array - JSON.stringify(result.map((r) => r as Adventure)), + JSON.stringify( + result.map((r) => { + const adventure: Adventure = r as Adventure; + if (typeof adventure.activityTypes === "string") { + try { + adventure.activityTypes = JSON.parse(adventure.activityTypes); + } catch (error) { + console.error("Error parsing activityTypes:", error); + adventure.activityTypes = undefined; + } + } + return adventure; + }) + ), { status: 200, headers: { @@ -86,7 +99,7 @@ export async function POST(event: RequestEvent): Promise { const { newAdventure } = await event.request.json(); console.log(newAdventure); - const { name, location, date, description } = newAdventure; + const { name, location, date, description, activityTypes } = newAdventure; if (!name) { return error(400, { @@ -94,6 +107,8 @@ export async function POST(event: RequestEvent): Promise { }); } + console.log(activityTypes); + // insert the adventure to the user's visited list let res = await db .insert(adventureTable) @@ -104,6 +119,7 @@ export async function POST(event: RequestEvent): Promise { location: location || null, date: date || null, description: description || null, + activityTypes: JSON.stringify(activityTypes) || null, }) .returning({ insertedId: adventureTable.id }) .execute(); diff --git a/src/routes/log/+page.server.ts b/src/routes/log/+page.server.ts index fa7fff8..1f38e8d 100644 --- a/src/routes/log/+page.server.ts +++ b/src/routes/log/+page.server.ts @@ -8,7 +8,6 @@ export const load: PageServerLoad = async (event) => { } const response = await event.fetch("/api/visits"); const result = await response.json(); - // let array = result.adventures as Adventure[]; return { result, }; diff --git a/src/routes/log/+page.svelte b/src/routes/log/+page.svelte index dd6d053..1d21740 100644 --- a/src/routes/log/+page.svelte +++ b/src/routes/log/+page.svelte @@ -67,6 +67,7 @@ date: event.detail.date, description: event.detail.description, id: -1, + activityTypes: event.detail.activityTypes, }; fetch("/api/visits", { @@ -123,6 +124,7 @@ date: event.detail.date, id: event.detail.id, description: event.detail.description, + activityTypes: event.detail.activityTypes, }; // put request to /api/visits with id and advneture data From 9f9f0c3d8741ffbc9e57fe292f8524afe69ccfcc Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 30 Apr 2024 22:52:07 +0000 Subject: [PATCH 03/13] Refactor adventure page layout to display activity types in +page.svelte and update server files --- src/routes/adventure/[id]/+page.svelte | 9 +++++++++ src/routes/api/adventure/+server.ts | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/routes/adventure/[id]/+page.svelte b/src/routes/adventure/[id]/+page.svelte index 9ed5686..9576bc3 100644 --- a/src/routes/adventure/[id]/+page.svelte +++ b/src/routes/adventure/[id]/+page.svelte @@ -11,6 +11,7 @@ onMount(() => { if (data.adventure.adventure) { adventure = data.adventure.adventure[0]; + console.log(adventure.activityTypes); } else { goto("/404"); } @@ -63,4 +64,12 @@ /> {/if} + {#if adventure.activityTypes && adventure.activityTypes.length > 0} +
+

Activities:

+
    + {adventure.activityTypes.toString()} +
+
+ {/if} {/if} diff --git a/src/routes/api/adventure/+server.ts b/src/routes/api/adventure/+server.ts index 742d9a5..57ca82e 100644 --- a/src/routes/api/adventure/+server.ts +++ b/src/routes/api/adventure/+server.ts @@ -1,5 +1,6 @@ import { db } from "$lib/db/db.server"; import { adventureTable } from "$lib/db/schema"; +import type { Adventure } from "$lib/utils/types"; import { json, type RequestEvent, type RequestHandler } from "@sveltejs/kit"; import { and, eq } from "drizzle-orm"; @@ -38,6 +39,20 @@ export const GET: RequestHandler = async ({ url, locals }) => { return json({ error: "Adventure not found" }, { status: 404 }); } + let adventureData = JSON.stringify( + adventure.map((r) => { + const adventure: Adventure = r as Adventure; + if (typeof adventure.activityTypes === "string") { + try { + adventure.activityTypes = JSON.parse(adventure.activityTypes); + } catch (error) { + console.error("Error parsing activityTypes:", error); + adventure.activityTypes = undefined; + } + } + }) + ); + // console.log("GET /api/adventure?id=", id); // console.log("User:", user); From 6d4e860e433b64a8608bd3a39d437585e71cc308 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 30 Apr 2024 23:04:12 +0000 Subject: [PATCH 04/13] Refactor adventure page layout to display activity types in +page.svelte and update server files --- src/routes/adventure/[id]/+page.server.ts | 2 +- src/routes/adventure/[id]/+page.svelte | 10 ++++++++-- src/routes/api/adventure/+server.ts | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/routes/adventure/[id]/+page.server.ts b/src/routes/adventure/[id]/+page.server.ts index f332b5b..2b14475 100644 --- a/src/routes/adventure/[id]/+page.server.ts +++ b/src/routes/adventure/[id]/+page.server.ts @@ -9,7 +9,7 @@ export const load = (async (event) => { return redirect(302, "/login"); } - let adventureUserId = await db + let adventureUserId: any[] = await db .select({ userId: adventureTable.userId }) .from(adventureTable) .where(eq(adventureTable.id, Number(event.params.id))) diff --git a/src/routes/adventure/[id]/+page.svelte b/src/routes/adventure/[id]/+page.svelte index 9576bc3..7bb1cbe 100644 --- a/src/routes/adventure/[id]/+page.svelte +++ b/src/routes/adventure/[id]/+page.svelte @@ -66,9 +66,15 @@ {/if} {#if adventure.activityTypes && adventure.activityTypes.length > 0}
-

Activities:

+

Activities: 

    - {adventure.activityTypes.toString()} + {#each adventure.activityTypes as activity} +
    + {activity} +
    + {/each}
{/if} diff --git a/src/routes/api/adventure/+server.ts b/src/routes/api/adventure/+server.ts index 57ca82e..7bfba3e 100644 --- a/src/routes/api/adventure/+server.ts +++ b/src/routes/api/adventure/+server.ts @@ -39,7 +39,7 @@ export const GET: RequestHandler = async ({ url, locals }) => { return json({ error: "Adventure not found" }, { status: 404 }); } - let adventureData = JSON.stringify( + JSON.stringify( adventure.map((r) => { const adventure: Adventure = r as Adventure; if (typeof adventure.activityTypes === "string") { From 6a4771cecec031bfdb1dc79727d31df7530cb491 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 30 Apr 2024 23:10:59 +0000 Subject: [PATCH 05/13] Add activity types to AdventureCard component and update server files --- src/lib/components/AdventureCard.svelte | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lib/components/AdventureCard.svelte b/src/lib/components/AdventureCard.svelte index 2434252..9d2324a 100644 --- a/src/lib/components/AdventureCard.svelte +++ b/src/lib/components/AdventureCard.svelte @@ -49,6 +49,17 @@

{adventure.date}

{/if} + {#if adventure.activityTypes && adventure.activityTypes.length > 0} +
    + {#each adventure.activityTypes as activity} +
    + {activity} +
    + {/each} +
+ {/if}
{#if type == "mylog"}
+
+ + +
diff --git a/src/routes/api/visits/+server.ts b/src/routes/api/visits/+server.ts index dedf2b2..37cf393 100644 --- a/src/routes/api/visits/+server.ts +++ b/src/routes/api/visits/+server.ts @@ -157,7 +157,7 @@ export async function PUT(event: RequestEvent): Promise { // get properties from the body const { newAdventure } = await event.request.json(); console.log(newAdventure); - const { name, location, date, id, description } = newAdventure; + const { name, location, date, id, description, activityTypes } = newAdventure; // update the adventure in the user's visited list await db @@ -167,6 +167,7 @@ export async function PUT(event: RequestEvent): Promise { location: location, date: date, description: description, + activityTypes: JSON.stringify(activityTypes), }) .where( and( From 25adf07874a070e4b5d2f9fad1a520018924dee1 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Fri, 3 May 2024 21:29:35 +0000 Subject: [PATCH 07/13] Refactor adventure page layout to display activity types and update server files --- src/lib/components/EditModal.svelte | 2 + src/routes/api/visits/+server.ts | 38 +++++++++++----- src/routes/log/+page.svelte | 68 +++++++++-------------------- 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/lib/components/EditModal.svelte b/src/lib/components/EditModal.svelte index 11e7814..a1f9a3e 100644 --- a/src/lib/components/EditModal.svelte +++ b/src/lib/components/EditModal.svelte @@ -6,6 +6,8 @@ import { onMount } from "svelte"; let modal: HTMLDialogElement; + console.log(adventureToEdit.id); + let originalName = adventureToEdit.name; onMount(() => { diff --git a/src/routes/api/visits/+server.ts b/src/routes/api/visits/+server.ts index 37cf393..ce2c654 100644 --- a/src/routes/api/visits/+server.ts +++ b/src/routes/api/visits/+server.ts @@ -86,7 +86,6 @@ export async function DELETE(event: RequestEvent): Promise { }); } -// add the adventure to the user's visited list export async function POST(event: RequestEvent): Promise { if (!event.locals.user) { return new Response(JSON.stringify({ error: "No user found" }), { @@ -97,9 +96,15 @@ export async function POST(event: RequestEvent): Promise { }); } - const { newAdventure } = await event.request.json(); - console.log(newAdventure); - const { name, location, date, description, activityTypes } = newAdventure; + const body = await event.request.json(); + if (!body.detailAdventure) { + return error(400, { + message: "No adventure data provided", + }); + } + + const { name, location, date, description, activityTypes } = + body.detailAdventure; if (!name) { return error(400, { @@ -127,10 +132,12 @@ export async function POST(event: RequestEvent): Promise { let insertedId = res[0].insertedId; console.log(insertedId); + body.detailAdventure.id = insertedId; + // return a response with the adventure object values return new Response( JSON.stringify({ - adventure: { name, location, date }, + adventure: body.detailAdventure, message: { message: "Adventure added" }, id: insertedId, }), @@ -154,10 +161,21 @@ export async function PUT(event: RequestEvent): Promise { }); } - // get properties from the body - const { newAdventure } = await event.request.json(); - console.log(newAdventure); - const { name, location, date, id, description, activityTypes } = newAdventure; + const body = await event.request.json(); + if (!body.detailAdventure) { + return error(400, { + message: "No adventure data provided", + }); + } + + const { name, location, date, description, activityTypes, id } = + body.detailAdventure; + + if (!name) { + return error(400, { + message: "Name field is required!", + }); + } // update the adventure in the user's visited list await db @@ -179,7 +197,7 @@ export async function PUT(event: RequestEvent): Promise { return new Response( JSON.stringify({ - adventure: { id, name, location, date, description }, + adventure: body.detailAdventure, message: { message: "Adventure updated" }, }), { diff --git a/src/routes/log/+page.svelte b/src/routes/log/+page.svelte index 1d21740..59c29f2 100644 --- a/src/routes/log/+page.svelte +++ b/src/routes/log/+page.svelte @@ -15,9 +15,6 @@ import { visitCount } from "$lib/utils/stores/visitCountStore"; import MoreFieldsInput from "$lib/components/CreateNewAdventure.svelte"; - let newName = ""; - let newLocation = ""; - let isShowingMoreFields = false; let adventureToEdit: Adventure | undefined; @@ -60,15 +57,9 @@ } const createNewAdventure = (event: { detail: Adventure }) => { - let newAdventure: Adventure = { - type: "mylog", - name: event.detail.name, - location: event.detail.location, - date: event.detail.date, - description: event.detail.description, - id: -1, - activityTypes: event.detail.activityTypes, - }; + isShowingMoreFields = false; + let detailAdventure = event.detail; + console.log("Event" + event.detail.name); fetch("/api/visits", { method: "POST", @@ -76,7 +67,7 @@ "Content-Type": "application/json", }, body: JSON.stringify({ - newAdventure, + detailAdventure, }), }) .then((response) => { @@ -90,21 +81,8 @@ return response.json(); }) .then((data) => { - let newId = data.id; // add to local array for instant view update - adventures = [ - ...adventures, - { - id: newId, - type: "mylog", - name: event.detail.name, - location: event.detail.location, - date: event.detail.date, - description: event.detail.description, - }, - ]; - newName = ""; // Reset newName and newLocation after adding adventure - newLocation = ""; + adventures = [...adventures, data.adventure]; showToast("Adventure added successfully!"); visitCount.update((n) => n + 1); }) @@ -115,35 +93,29 @@ }; function saveAdventure(event: { detail: Adventure }) { - console.log("Event" + event.detail); + console.log("Event", event.detail); + let detailAdventure = event.detail; - let newAdventure: Adventure = { - type: "mylog", - name: event.detail.name, - location: event.detail.location, - date: event.detail.date, - id: event.detail.id, - description: event.detail.description, - activityTypes: event.detail.activityTypes, - }; - - // put request to /api/visits with id and advneture data + // put request to /api/visits with id and adventure data fetch("/api/visits", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ - newAdventure, + detailAdventure, }), }) .then((response) => response.json()) .then((data) => { console.log("Success:", data); // update local array with new data - adventures = adventures.map((adventure) => - adventure.id === event.detail.id ? event.detail : adventure + const index = adventures.findIndex( + (adventure) => adventure.id === detailAdventure.id ); + if (index !== -1) { + adventures[index] = detailAdventure; + } adventureToEdit = undefined; showToast("Adventure edited successfully!"); }) @@ -163,6 +135,12 @@ function shareLink() { let key = generateRandomString(); + + // console log each adventure in the array + for (let i = 0; i < adventures.length; i++) { + console.log(adventures[i]); + } + let data = JSON.stringify(adventures); fetch("/api/share", { method: "POST", @@ -268,11 +246,7 @@ {/if} {#if isShowingMoreFields} - + {/if} {#if adventureToEdit && adventureToEdit.id != undefined} From eab7cb6087ef94c19ff7699ea70dab091a855480 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Fri, 3 May 2024 21:39:31 +0000 Subject: [PATCH 08/13] feat: Add activity types to CreateNewAdventure and AdventureCard components The code changes include adding activity types functionality to the CreateNewAdventure and AdventureCard components. This allows users to specify different types of activities for each adventure. The changes also include updates to the server files to handle the new activity types. Recent user commits: - Refactor adventure page layout to display activity types and update server files - Add activity types to EditModal component and update server files - Add activity types to AdventureCard component and update server files - Refactor adventure page layout to display activity types in +page.svelte and update server files - Refactor adventure page layout to display activity types in +page.svelte and update server files - Refactor CreateNewAdventure component to add activity types and update server files - Refactor adventure page layout to use a responsive image size in +page.svelte - Merge pull request #52 from seanmorley15/development - Refactor error handling and add validation for adventure name in server and page files - Update config.ts --- src/lib/components/AdventureCard.svelte | 1 + src/lib/components/CreateNewAdventure.svelte | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/components/AdventureCard.svelte b/src/lib/components/AdventureCard.svelte index 9d2324a..923c1e3 100644 --- a/src/lib/components/AdventureCard.svelte +++ b/src/lib/components/AdventureCard.svelte @@ -20,6 +20,7 @@ dispatch("remove", adventure.id); } function edit() { + console.log(adventure.activityTypes); dispatch("edit", adventure.id); } function add() { diff --git a/src/lib/components/CreateNewAdventure.svelte b/src/lib/components/CreateNewAdventure.svelte index 2addc31..579b6eb 100644 --- a/src/lib/components/CreateNewAdventure.svelte +++ b/src/lib/components/CreateNewAdventure.svelte @@ -44,8 +44,8 @@ function addActivityType() { if (activityInput.trim() !== "") { const activities = activityInput - .split(",") - .map((activity) => activity.trim()); + .split(" ") + .filter((activity) => activity.trim() !== ""); newAdventure.activityTypes = [ ...(newAdventure.activityTypes || []), ...activities, From 312778463266943ebd3f74334b10645e0cb3fcd3 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Sat, 4 May 2024 00:43:18 +0000 Subject: [PATCH 09/13] feat: Add activity types functionality to CreateNewAdventure and AdventureCard components --- src/lib/components/CreateNewAdventure.svelte | 18 +++++++++++++----- src/lib/components/EditModal.svelte | 16 +++++++++++++--- src/routes/api/visits/+server.ts | 12 ++++++++++-- src/routes/featured/+page.svelte | 9 ++------- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/lib/components/CreateNewAdventure.svelte b/src/lib/components/CreateNewAdventure.svelte index 579b6eb..25a0ec9 100644 --- a/src/lib/components/CreateNewAdventure.svelte +++ b/src/lib/components/CreateNewAdventure.svelte @@ -46,10 +46,7 @@ const activities = activityInput .split(" ") .filter((activity) => activity.trim() !== ""); - newAdventure.activityTypes = [ - ...(newAdventure.activityTypes || []), - ...activities, - ]; + newAdventure.activityTypes = activities; activityInput = ""; } console.log(newAdventure.activityTypes); @@ -104,7 +101,7 @@ />
- +
+
+ + +
diff --git a/src/routes/api/visits/+server.ts b/src/routes/api/visits/+server.ts index ce2c654..3afa6ba 100644 --- a/src/routes/api/visits/+server.ts +++ b/src/routes/api/visits/+server.ts @@ -103,7 +103,7 @@ export async function POST(event: RequestEvent): Promise { }); } - const { name, location, date, description, activityTypes } = + const { name, location, date, description, activityTypes, rating } = body.detailAdventure; if (!name) { @@ -112,6 +112,12 @@ export async function POST(event: RequestEvent): Promise { }); } + if (rating && (rating < 1 || rating > 5)) { + return error(400, { + message: "Rating must be between 1 and 5", + }); + } + console.log(activityTypes); // insert the adventure to the user's visited list @@ -125,6 +131,7 @@ export async function POST(event: RequestEvent): Promise { date: date || null, description: description || null, activityTypes: JSON.stringify(activityTypes) || null, + rating: rating || null, }) .returning({ insertedId: adventureTable.id }) .execute(); @@ -168,7 +175,7 @@ export async function PUT(event: RequestEvent): Promise { }); } - const { name, location, date, description, activityTypes, id } = + const { name, location, date, description, activityTypes, id, rating } = body.detailAdventure; if (!name) { @@ -185,6 +192,7 @@ export async function PUT(event: RequestEvent): Promise { location: location, date: date, description: description, + rating: rating, activityTypes: JSON.stringify(activityTypes), }) .where( diff --git a/src/routes/featured/+page.svelte b/src/routes/featured/+page.svelte index 8d0cd46..176392e 100644 --- a/src/routes/featured/+page.svelte +++ b/src/routes/featured/+page.svelte @@ -11,12 +11,7 @@ }); async function add(event: CustomEvent) { - let newAdventure: Adventure = { - name: event.detail.name, - location: event.detail.location, - type: "mylog", - id: -1, - }; + let detailAdventure = event.detail; const response = await fetch("/api/visits", { method: "POST", @@ -24,7 +19,7 @@ "Content-Type": "application/json", }, body: JSON.stringify({ - newAdventure, + detailAdventure, }), }); From 716323657bd2af67429754ef3f6ea1140211a5f4 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Sat, 4 May 2024 15:00:02 +0000 Subject: [PATCH 10/13] feat: Add "Planner" button to Navbar component The code changes include adding a "Planner" button to the Navbar component. This button allows users to navigate to the Planner page. The changes involve modifying the Navbar component in the src/lib/components/Navbar.svelte file. --- src/lib/components/AdventureCard.svelte | 14 ++ src/lib/components/Navbar.svelte | 5 + src/routes/api/planner/+server.ts | 223 ++++++++++++++++++++++++ src/routes/api/visits/+server.ts | 7 +- src/routes/planner/+page.server.ts | 14 ++ src/routes/planner/+page.svelte | 163 ++++++++++++++++- 6 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 src/routes/api/planner/+server.ts diff --git a/src/lib/components/AdventureCard.svelte b/src/lib/components/AdventureCard.svelte index 923c1e3..e5bed98 100644 --- a/src/lib/components/AdventureCard.svelte +++ b/src/lib/components/AdventureCard.svelte @@ -76,6 +76,20 @@ > {/if} + {#if type == "planner"} + + + + {/if} {#if type == "featured"} + +