mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-04 20:55:19 +02:00
commit
4e79484b30
4 changed files with 223 additions and 102 deletions
|
@ -18,16 +18,20 @@
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (window.location.pathname === "/search") {
|
if (window.location.pathname === "/search") {
|
||||||
searchVal = new URLSearchParams(window.location.search).get("all") || "";
|
searchVal =
|
||||||
|
new URLSearchParams(window.location.search).get("value") || "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function goToSearch() {
|
async function goToSearch() {
|
||||||
|
if (searchVal === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let reload: boolean = false;
|
let reload: boolean = false;
|
||||||
if (window.location.pathname === "/search") {
|
if (window.location.pathname === "/search") {
|
||||||
reload = true;
|
reload = true;
|
||||||
}
|
}
|
||||||
await goto("/search?all=" + searchVal);
|
await goto("/search?value=" + searchVal);
|
||||||
if (reload) {
|
if (reload) {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
@ -96,9 +100,12 @@
|
||||||
<li>
|
<li>
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<input type="text" class="grow" placeholder="Search" />
|
<input type="text" class="grow" placeholder="Search" />
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
on:click={() => goToSearch()}
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="w-4 h-4 opacity-70"
|
class="w-4 h-4 opacity-70"
|
||||||
><path
|
><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
|
// +page.server.js
|
||||||
import { redirect } from "@sveltejs/kit";
|
import { redirect } from "@sveltejs/kit";
|
||||||
import type { PageServerLoad } from "./$types";
|
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.
|
* 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.
|
* @param {PageServerLoadParams} params - The parameters for loading the page.
|
||||||
* @returns {Promise<PageServerLoadResult>} The result of 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) {
|
if (!locals.user) {
|
||||||
return redirect(301, "/login");
|
return redirect(301, "/login");
|
||||||
}
|
}
|
||||||
let param: string = "";
|
if (!url.searchParams.has("value")) {
|
||||||
let value: string = "";
|
return { props: { adventures: [] } };
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
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">
|
<script lang="ts">
|
||||||
|
import { enhance } from "$app/forms";
|
||||||
import AdventureCard from "$lib/components/AdventureCard.svelte";
|
import AdventureCard from "$lib/components/AdventureCard.svelte";
|
||||||
import type { Adventure } from "$lib/utils/types";
|
import type { Adventure } from "$lib/utils/types";
|
||||||
|
import type { SubmitFunction } from "@sveltejs/kit";
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
|
|
||||||
|
// let visitedValue = "all";
|
||||||
|
// let typeValue = "";
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
let adventureArray: Adventure[] = data.props?.adventures as Adventure[];
|
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>
|
</script>
|
||||||
|
|
||||||
<main>
|
<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>
|
<h1 class="text-center font-bold text-4xl">Search Results</h1>
|
||||||
{#if adventureArray.length > 0}
|
{#if adventureArray.length > 0}
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue