Compare commits
1 Commits
e945fc2f79
...
d3361cb8f3
| Author | SHA1 | Date |
|---|---|---|
|
|
d3361cb8f3 |
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { LayoutData } from './$types';
|
import type { LayoutData } from './$types';
|
||||||
import { goto, invalidateAll } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import SearchBox from '$lib/SearchBox.svelte';
|
import SearchBox from '$lib/SearchBox.svelte';
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<ul class="flex w-full py-3 items-center justify-between">
|
<ul class="flex w-full py-3 items-center justify-between">
|
||||||
<li class="flex grow justify-center">
|
<li class="flex grow justify-center">
|
||||||
<span class="flex grow" style="max-width: 75%;">
|
<span class="flex grow" style="max-width: 75%;">
|
||||||
<SearchBox on:search={onSubmit} page={data.page} />
|
<SearchBox on:search={onSubmit} query={data.query} page={data.page} />
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="px-6">
|
<li class="px-6">
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,19 @@
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
|
function buildQueryString({ query, page }: { query: string; page: number }): string {
|
||||||
|
const qs = [query === '' ? query : `query=${query}`, page <= 1 ? '' : `page=${page}`]
|
||||||
|
.filter((x) => x !== '')
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
return qs !== '' ? `?${qs}` : qs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { query, page } = data;
|
||||||
$: hasResults = (data.results || []).length > 0;
|
$: hasResults = (data.results || []).length > 0;
|
||||||
$: currentPage = data.page + 1;
|
$: currentPage = data.page + 1;
|
||||||
$: pageCount = Math.max(1, Math.floor(data.found / data.limit));
|
$: pageCount = Math.max(1, Math.ceil(data.found / data.limit));
|
||||||
$: console.log(data.found, ' / ', data.limit, ' = ', data.found / data.limit);
|
$: console.log(`page: ${currentPage}, count: ${pageCount}, `);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if hasResults}
|
{#if hasResults}
|
||||||
|
|
@ -17,7 +26,7 @@
|
||||||
<ol class="flex justify-between w-full center" style="padding: 0 10%;">
|
<ol class="flex justify-between w-full center" style="padding: 0 10%;">
|
||||||
{#if currentPage > 1}
|
{#if currentPage > 1}
|
||||||
<li in:fade>
|
<li in:fade>
|
||||||
<a href="/?query={data.query}&page={data.page - 1}"><Previous</a>
|
<a href="/{buildQueryString({ query, page: currentPage - 1 })}"><Previous</a>
|
||||||
</li>
|
</li>
|
||||||
{:else}
|
{:else}
|
||||||
<li />
|
<li />
|
||||||
|
|
@ -25,7 +34,7 @@
|
||||||
<li>Page {currentPage} of {pageCount}</li>
|
<li>Page {currentPage} of {pageCount}</li>
|
||||||
{#if currentPage < pageCount}
|
{#if currentPage < pageCount}
|
||||||
<li in:fade>
|
<li in:fade>
|
||||||
<a href="/?query={data.query}&page={data.page + 1}">Next></a>
|
<a href="/{buildQueryString({ query, page: currentPage + 1 })}">Next></a>
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
</ol>
|
</ol>
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,19 @@ interface SearchPageData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const load = (async ({ fetch, url }): Promise<SearchPageData> => {
|
export const load = (async ({ fetch, url }): Promise<SearchPageData> => {
|
||||||
// TODO: refactor to one source of truth for all query param value fetching
|
const searchParams = new SearchParameters(url);
|
||||||
const searchTerm = url.searchParams.get('query') || '';
|
const limit = searchParams.getLimit();
|
||||||
const currentPage = Number(url.searchParams.get('page') || 0);
|
const searchTerm = searchParams.getSearchTerm();
|
||||||
const currentLimit = Number(url.searchParams.get('limit') || 64);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: refactor to one source of truth for all query string building
|
// TODO: refactor to one source of truth for all query string building
|
||||||
const response = await fetch(API_HOST + `/upcoming?searchTerm=${searchTerm}&page=${currentPage}&limit=${currentLimit}`);
|
const response = await fetch(API_HOST + `/upcoming${searchParams.toQueryString()}`);
|
||||||
const { page, total, found, results } = await response.json() || {};
|
const { page, total, found, results } = await response.json() || {};
|
||||||
|
|
||||||
// TODO: return found results so we can do upperbound on pagination
|
// TODO: return found results so we can do upperbound on pagination
|
||||||
return {
|
return {
|
||||||
page,
|
page,
|
||||||
limit: currentLimit,
|
limit,
|
||||||
query: searchTerm,
|
query: searchTerm,
|
||||||
found,
|
found,
|
||||||
total,
|
total,
|
||||||
|
|
@ -37,7 +36,7 @@ export const load = (async ({ fetch, url }): Promise<SearchPageData> => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
return {
|
return {
|
||||||
page: 0,
|
page: 0,
|
||||||
limit: currentLimit,
|
limit,
|
||||||
query: searchTerm,
|
query: searchTerm,
|
||||||
found: 0,
|
found: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
|
|
@ -46,3 +45,41 @@ export const load = (async ({ fetch, url }): Promise<SearchPageData> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
}) satisfies PageLoad;
|
}) satisfies PageLoad;
|
||||||
|
|
||||||
|
class SearchParameters {
|
||||||
|
page: number
|
||||||
|
limit: number
|
||||||
|
searchTerm?: string
|
||||||
|
|
||||||
|
constructor(url: URL) {
|
||||||
|
this.searchTerm = url.searchParams.get('query') || undefined;
|
||||||
|
this.page = Number(url.searchParams.get('page') || 1) - 1;
|
||||||
|
if (this.page < 0 ) {
|
||||||
|
this.page = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.limit = Number(url.searchParams.get('limit') || 64);
|
||||||
|
if (this.limit > 128) {
|
||||||
|
this.limit = 128;
|
||||||
|
} else if (this.limit < 32) {
|
||||||
|
this.limit = 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPage(): number {
|
||||||
|
return this.page || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSearchTerm(): string {
|
||||||
|
return this.searchTerm || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
getLimit(): number {
|
||||||
|
return this.limit || 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
toQueryString(): string {
|
||||||
|
const qs = Object.entries(this).filter(t => t.length > 0 && t[1]).map(t => `${t[0]}=${t[1]}`).join('&');
|
||||||
|
return qs === '' ? '' : `?${qs}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue