From 50a2cbcd4c2adfd27e3b1780ca277c745287988c Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Mon, 3 Jun 2024 23:10:08 +0000 Subject: [PATCH 1/5] New search api refactoring --- src/lib/components/Navbar.svelte | 8 ++- src/routes/api/search/+server.ts | 105 ++++++++++++++++++++++++++++++ src/routes/search/+page.server.ts | 105 ++---------------------------- src/routes/search/+page.svelte | 1 - 4 files changed, 117 insertions(+), 102 deletions(-) create mode 100644 src/routes/api/search/+server.ts diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte index 85acb2c..109efbb 100644 --- a/src/lib/components/Navbar.svelte +++ b/src/lib/components/Navbar.svelte @@ -18,16 +18,20 @@ onMount(() => { if (window.location.pathname === "/search") { - searchVal = new URLSearchParams(window.location.search).get("all") || ""; + searchVal = + new URLSearchParams(window.location.search).get("value") || ""; } }); async function goToSearch() { + if (searchVal === "") { + return; + } let reload: boolean = false; if (window.location.pathname === "/search") { reload = true; } - await goto("/search?all=" + searchVal); + await goto("/search?value=" + searchVal); if (reload) { location.reload(); } diff --git a/src/routes/api/search/+server.ts b/src/routes/api/search/+server.ts new file mode 100644 index 0000000..68d0358 --- /dev/null +++ b/src/routes/api/search/+server.ts @@ -0,0 +1,105 @@ +import { db } from "$lib/db/db.server"; +import { adventureTable } from "$lib/db/schema"; +import { json, type RequestHandler } from "@sveltejs/kit"; +import { ilike, and, eq, arrayContains, or } from "drizzle-orm"; + +export const GET: RequestHandler = async ({ + url, + locals, +}): Promise => { + const value = url.searchParams.get("value") as string; + const type = url.searchParams.get("type") as string; + const user = locals.user; + const visited = url.searchParams.get("visited"); + let isVisited: boolean | undefined = undefined; + if (visited === "true") { + isVisited = true; + } else if (visited === "false") { + isVisited = false; + } + + if (!user) { + return json({ error: "Unauthorized" }, { status: 401 }); + } + if (!type) { + const activityResults = await activitySearch(value, locals, isVisited); + const locationResults = await locationSearch(value, locals); + const namesResults = await nameSearch(value, locals); + + return json({ + adventures: [ + ...activityResults.adventures, + ...locationResults.adventures, + ...namesResults.adventures, + ], + }); + } else if (type === "activity") { + return json(await activitySearch(value, locals, isVisited)); + } else if (type === "location") { + return json(await locationSearch(value, locals)); + } else if (type === "name") { + return json(await nameSearch(value, locals)); + } + return json({ error: "No results found." }, { status: 400 }); +}; + +async function activitySearch( + value: string, + locals: any, + visited: boolean | undefined +) { + let arr: string[] = []; + arr.push(value.toLowerCase()); + let res = await db + .select() + .from(adventureTable) + .where( + and( + arrayContains(adventureTable.activityTypes, arr), + eq(adventureTable.userId, locals.user.id), + or( + visited === true ? eq(adventureTable.type, "mylog") : undefined, + visited === false ? eq(adventureTable.type, "planner") : undefined + ) + ) + ) + .execute(); + + return { + adventures: res, + }; +} + +async function locationSearch(value: string, locals: any) { + let res = await db + .select() + .from(adventureTable) + .where( + and( + ilike(adventureTable.location, `%${value}%`), + eq(adventureTable.userId, locals.user.id) + ) + ) + .execute(); + + return { + adventures: res, + }; +} + +async function nameSearch(value: string, locals: any) { + let res = await db + .select() + .from(adventureTable) + .where( + and( + ilike(adventureTable.name, `%${value}%`), + eq(adventureTable.userId, locals.user.id) + ) + ) + .execute(); + + return { + adventures: res, + }; +} diff --git a/src/routes/search/+page.server.ts b/src/routes/search/+page.server.ts index 870892b..7dc3dc4 100644 --- a/src/routes/search/+page.server.ts +++ b/src/routes/search/+page.server.ts @@ -1,9 +1,6 @@ // +page.server.js import { redirect } from "@sveltejs/kit"; import type { PageServerLoad } from "./$types"; -import { db } from "$lib/db/db.server"; -import { adventureTable } from "$lib/db/schema"; -import { and, eq, arrayContains, ilike } from "drizzle-orm"; /** * Loads the page data based on the provided URL and locals. @@ -11,104 +8,14 @@ import { and, eq, arrayContains, ilike } from "drizzle-orm"; * @param {PageServerLoadParams} params - The parameters for loading the page. * @returns {Promise} The result of loading the page. */ -export const load: PageServerLoad = async ({ url, locals }) => { +export const load: PageServerLoad = async ({ url, locals, fetch }) => { if (!locals.user) { return redirect(301, "/login"); } - let param: string = ""; - let value: string = ""; - if (Array.from(url.searchParams.entries()).length > 0) { - const params = Array.from(url.searchParams.entries()); - param = params[0][0]; - value = params[0][1]; - } else { - param = "all"; - value = ""; - } - // Activity type search - if (param === "activity") { - return { - props: await activitySearch(value, locals), - }; - } - - if (param === "location") { - return { - props: await locationSearch(value, locals), - }; - } - if (param === "name") { - return { - props: await nameSearch(value, locals), - }; - } - if (param == "all" || param == "") { - console.log("all"); - const activityResults = await activitySearch(value, locals); - const locationResults = await locationSearch(value, locals); - const namesResults = await nameSearch(value, locals); - - return { - props: { - adventures: [ - ...activityResults.adventures, - ...locationResults.adventures, - ...namesResults.adventures, - ], - }, - }; - } - - async function activitySearch(value: string, locals: any) { - let arr: string[] = []; - arr.push(value.toLowerCase()); - let res = await db - .select() - .from(adventureTable) - .where( - and( - arrayContains(adventureTable.activityTypes, arr), - eq(adventureTable.userId, locals.user.id) - ) - ) - .execute(); - - return { - adventures: res, - }; - } - - async function locationSearch(value: string, locals: any) { - let res = await db - .select() - .from(adventureTable) - .where( - and( - ilike(adventureTable.location, `%${value}%`), - eq(adventureTable.userId, locals.user.id) - ) - ) - .execute(); - - return { - adventures: res, - }; - } - - async function nameSearch(value: string, locals: any) { - let res = await db - .select() - .from(adventureTable) - .where( - and( - ilike(adventureTable.name, `%${value}%`), - eq(adventureTable.userId, locals.user.id) - ) - ) - .execute(); - - return { - adventures: res, - }; + if (!url.searchParams.has("value")) { + return { props: { adventures: [] } }; } + let data = await fetch("/api/search?value=" + url.searchParams.get("value")); + let json = await data.json(); + return { props: { adventures: json.adventures } }; }; diff --git a/src/routes/search/+page.svelte b/src/routes/search/+page.svelte index f3ccea5..a290b48 100644 --- a/src/routes/search/+page.svelte +++ b/src/routes/search/+page.svelte @@ -5,7 +5,6 @@ export let data: PageData; let adventureArray: Adventure[] = data.props?.adventures as Adventure[]; - console.log(adventureArray);
From ca04bc0095e5ca8beae3e85ce9493a690ae10ca8 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 4 Jun 2024 13:13:40 +0000 Subject: [PATCH 2/5] chore: Remove duplicate adventures in search results --- src/routes/api/search/+server.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/routes/api/search/+server.ts b/src/routes/api/search/+server.ts index 68d0358..4c6f84b 100644 --- a/src/routes/api/search/+server.ts +++ b/src/routes/api/search/+server.ts @@ -26,12 +26,20 @@ export const GET: RequestHandler = async ({ const locationResults = await locationSearch(value, locals); const namesResults = await nameSearch(value, locals); + // remove duplicates by id + let adventures: any = {}; + activityResults.adventures.forEach((a: any) => { + adventures[a.id] = a; + }); + locationResults.adventures.forEach((a: any) => { + adventures[a.id] = a; + }); + namesResults.adventures.forEach((a: any) => { + adventures[a.id] = a; + }); + return json({ - adventures: [ - ...activityResults.adventures, - ...locationResults.adventures, - ...namesResults.adventures, - ], + adventures: Object.values(adventures), }); } else if (type === "activity") { return json(await activitySearch(value, locals, isVisited)); From 18b4dfa922c9daf0cac41c83f64b2d0e996dafce Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Tue, 4 Jun 2024 21:09:10 +0000 Subject: [PATCH 3/5] refactor: Improve search functionality by using case-insensitive search for adventure location and name --- src/routes/api/search/+server.ts | 33 +++++++++--- src/routes/search/+page.server.ts | 7 +++ src/routes/search/+page.svelte | 85 +++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 8 deletions(-) diff --git a/src/routes/api/search/+server.ts b/src/routes/api/search/+server.ts index 4c6f84b..6a00ce5 100644 --- a/src/routes/api/search/+server.ts +++ b/src/routes/api/search/+server.ts @@ -17,14 +17,15 @@ export const GET: RequestHandler = async ({ } else if (visited === "false") { isVisited = false; } + console.log("visited", visited, isVisited); if (!user) { return json({ error: "Unauthorized" }, { status: 401 }); } if (!type) { const activityResults = await activitySearch(value, locals, isVisited); - const locationResults = await locationSearch(value, locals); - const namesResults = await nameSearch(value, locals); + const locationResults = await locationSearch(value, locals, isVisited); + const namesResults = await nameSearch(value, locals, isVisited); // remove duplicates by id let adventures: any = {}; @@ -44,9 +45,9 @@ export const GET: RequestHandler = async ({ } else if (type === "activity") { return json(await activitySearch(value, locals, isVisited)); } else if (type === "location") { - return json(await locationSearch(value, locals)); + return json(await locationSearch(value, locals, isVisited)); } else if (type === "name") { - return json(await nameSearch(value, locals)); + return json(await nameSearch(value, locals, isVisited)); } return json({ error: "No results found." }, { status: 400 }); }; @@ -78,14 +79,22 @@ async function activitySearch( }; } -async function locationSearch(value: string, locals: any) { +async function locationSearch( + value: string, + locals: any, + visited: boolean | undefined +) { let res = await db .select() .from(adventureTable) .where( and( ilike(adventureTable.location, `%${value}%`), - eq(adventureTable.userId, locals.user.id) + eq(adventureTable.userId, locals.user.id), + or( + visited === true ? eq(adventureTable.type, "mylog") : undefined, + visited === false ? eq(adventureTable.type, "planner") : undefined + ) ) ) .execute(); @@ -95,14 +104,22 @@ async function locationSearch(value: string, locals: any) { }; } -async function nameSearch(value: string, locals: any) { +async function nameSearch( + value: string, + locals: any, + visited: boolean | undefined +) { let res = await db .select() .from(adventureTable) .where( and( ilike(adventureTable.name, `%${value}%`), - eq(adventureTable.userId, locals.user.id) + eq(adventureTable.userId, locals.user.id), + or( + visited === true ? eq(adventureTable.type, "mylog") : undefined, + visited === false ? eq(adventureTable.type, "planner") : undefined + ) ) ) .execute(); diff --git a/src/routes/search/+page.server.ts b/src/routes/search/+page.server.ts index 7dc3dc4..4033fbe 100644 --- a/src/routes/search/+page.server.ts +++ b/src/routes/search/+page.server.ts @@ -19,3 +19,10 @@ export const load: PageServerLoad = async ({ url, locals, fetch }) => { let json = await data.json(); return { props: { adventures: json.adventures } }; }; + +export const actions = { + default: async () => { + console.log("default"); + return { props: {} }; + }, +}; diff --git a/src/routes/search/+page.svelte b/src/routes/search/+page.svelte index a290b48..f2c59a3 100644 --- a/src/routes/search/+page.svelte +++ b/src/routes/search/+page.svelte @@ -1,13 +1,98 @@
+
+ + All + + Not Visited + + Visited +
+ + All + + Activity + + Location + + Name + + +

Search Results

{#if adventureArray.length > 0}
Date: Tue, 4 Jun 2024 21:18:30 +0000 Subject: [PATCH 4/5] feat: Add search functionality to navbar --- src/lib/components/Navbar.svelte | 3 +++ src/routes/search/+page.svelte | 33 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte index 109efbb..6627940 100644 --- a/src/lib/components/Navbar.svelte +++ b/src/lib/components/Navbar.svelte @@ -100,9 +100,12 @@