mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-02 19:55:18 +02:00
commit
4e79484b30
4 changed files with 223 additions and 102 deletions
|
@ -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();
|
||||
}
|
||||
|
@ -96,9 +100,12 @@
|
|||
<li>
|
||||
<label class="input input-bordered flex items-center gap-2">
|
||||
<input type="text" class="grow" placeholder="Search" />
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
on:click={() => goToSearch()}
|
||||
fill="currentColor"
|
||||
class="w-4 h-4 opacity-70"
|
||||
><path
|
||||
|
|
130
src/routes/api/search/+server.ts
Normal file
130
src/routes/api/search/+server.ts
Normal file
|
@ -0,0 +1,130 @@
|
|||
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<Response> => {
|
||||
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;
|
||||
}
|
||||
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, isVisited);
|
||||
const namesResults = await nameSearch(value, locals, isVisited);
|
||||
|
||||
// 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: Object.values(adventures),
|
||||
});
|
||||
} else if (type === "activity") {
|
||||
return json(await activitySearch(value, locals, isVisited));
|
||||
} else if (type === "location") {
|
||||
return json(await locationSearch(value, locals, isVisited));
|
||||
} else if (type === "name") {
|
||||
return json(await nameSearch(value, locals, isVisited));
|
||||
}
|
||||
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,
|
||||
visited: boolean | undefined
|
||||
) {
|
||||
let res = await db
|
||||
.select()
|
||||
.from(adventureTable)
|
||||
.where(
|
||||
and(
|
||||
ilike(adventureTable.location, `%${value}%`),
|
||||
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 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),
|
||||
or(
|
||||
visited === true ? eq(adventureTable.type, "mylog") : undefined,
|
||||
visited === false ? eq(adventureTable.type, "planner") : undefined
|
||||
)
|
||||
)
|
||||
)
|
||||
.execute();
|
||||
|
||||
return {
|
||||
adventures: res,
|
||||
};
|
||||
}
|
|
@ -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,21 @@ import { and, eq, arrayContains, ilike } from "drizzle-orm";
|
|||
* @param {PageServerLoadParams} params - The parameters for loading the page.
|
||||
* @returns {Promise<PageServerLoadResult>} 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 } };
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
default: async () => {
|
||||
console.log("default");
|
||||
return { props: {} };
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,14 +1,84 @@
|
|||
<script lang="ts">
|
||||
import { enhance } from "$app/forms";
|
||||
import AdventureCard from "$lib/components/AdventureCard.svelte";
|
||||
import type { Adventure } from "$lib/utils/types";
|
||||
import type { SubmitFunction } from "@sveltejs/kit";
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
// let visitedValue = "all";
|
||||
// let typeValue = "";
|
||||
|
||||
export let data: PageData;
|
||||
let adventureArray: Adventure[] = data.props?.adventures as Adventure[];
|
||||
console.log(adventureArray);
|
||||
|
||||
const filter: SubmitFunction = async ({ formData }) => {
|
||||
const radioValue = formData.get("visited") as string;
|
||||
let typeValue = formData.get("type") as string;
|
||||
if (!typeValue) {
|
||||
typeValue = "";
|
||||
}
|
||||
const value = new URLSearchParams(location.search).get("value");
|
||||
console.log(value);
|
||||
console.log(
|
||||
`/api/search?value=${value}&type=${typeValue}&visited=${radioValue}`
|
||||
);
|
||||
let data = await fetch(
|
||||
`/api/search?value=${value}&type=${typeValue}&visited=${radioValue}`
|
||||
);
|
||||
console.log(data);
|
||||
adventureArray = [];
|
||||
let res = await data.json();
|
||||
adventureArray = res.adventures as Adventure[];
|
||||
console.log(radioValue);
|
||||
};
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<form method="post" use:enhance={filter}>
|
||||
<input
|
||||
type="radio"
|
||||
name="visited"
|
||||
value="all"
|
||||
checked
|
||||
class="radio radio-primary"
|
||||
/>
|
||||
All
|
||||
<input
|
||||
type="radio"
|
||||
name="visited"
|
||||
value="false"
|
||||
class="radio radio-primary"
|
||||
/>
|
||||
Not Visited
|
||||
<input
|
||||
type="radio"
|
||||
name="visited"
|
||||
value="true"
|
||||
class="radio radio-primary"
|
||||
/>
|
||||
Visited
|
||||
<br />
|
||||
<input type="radio" name="type" value="" class="radio radio-primary" />
|
||||
All
|
||||
<input
|
||||
type="radio"
|
||||
name="type"
|
||||
value="activity"
|
||||
class="radio radio-primary"
|
||||
/>
|
||||
Activity
|
||||
<input
|
||||
type="radio"
|
||||
name="type"
|
||||
value="location"
|
||||
class="radio radio-primary"
|
||||
/>
|
||||
Location
|
||||
<input type="radio" name="type" value="name" class="radio radio-primary" />
|
||||
Name
|
||||
<!-- submit button -->
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</form>
|
||||
<h1 class="text-center font-bold text-4xl">Search Results</h1>
|
||||
{#if adventureArray.length > 0}
|
||||
<div
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue