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 a266a4e6..9ed56867 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 83c5e09d..2addc31c 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 b19ed75b..dedf2b23 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 fa7fff87..1f38e8df 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 dd6d0532..1d217400 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 9ed56867..9576bc3c 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 742d9a59..57ca82ef 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 f332b5b2..2b144751 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 9576bc3c..7bb1cbe7 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 57ca82ef..7bfba3ec 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 24342527..9d2324af 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 dedf2b23..37cf3932 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 11e78146..a1f9a3e5 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 37cf3932..ce2c654f 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 1d217400..59c29f22 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 9d2324af..923c1e38 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 2addc31c..579b6ebc 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 579b6ebc..25a0ec93 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 ce2c654f..3afa6bae 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 8d0cd465..176392e2 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 923c1e38..e5bed984 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"} + +