Skip to content

Commit e0d60f4

Browse files
committed
feat(blueprint): update search page layout
1 parent 47caa9a commit e0d60f4

File tree

5 files changed

+475
-192
lines changed

5 files changed

+475
-192
lines changed

src/lib/search.schema.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { z } from "zod";
2+
import { PAGINATION_PAGE_DEFAULT, PAGINATION_PER_PAGE_DEFAULT, SEARCH_ORDER_OPTION_DEFAULT, SEARCH_SORT_OPTION_DEFAULT } from "./search";
3+
4+
const SEARCH_SORT_SCHEMA =
5+
z.union([z.literal('created'), z.literal('updated'), z.literal('version'), z.literal('buildingCount'), z.literal('islandCount'), z.literal('viewCount'), z.literal('downloadCount'), z.literal('bookmarkCount')]);
6+
export type SearchSortOption = z.infer<typeof SEARCH_SORT_SCHEMA>;
7+
8+
const SEARCH_ORDER_SCHEMA = z.union([z.literal('asc'), z.literal('desc')]);
9+
export type SearchOrderOption = z.infer<typeof SEARCH_ORDER_SCHEMA>;
10+
11+
export const SEARCH_SCHEMA = z.object({
12+
query: z.string().optional(),
13+
filter: z.string().optional(),
14+
sort: SEARCH_SORT_SCHEMA.optional().default(SEARCH_SORT_OPTION_DEFAULT),
15+
order: SEARCH_ORDER_SCHEMA.optional().default(SEARCH_ORDER_OPTION_DEFAULT),
16+
});
17+
18+
export const PAGINATION_SCHEMA = z.object({
19+
page: z.number().optional().default(PAGINATION_PAGE_DEFAULT),
20+
perPage: z.number().optional().default(PAGINATION_PER_PAGE_DEFAULT),
21+
})

src/lib/search.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { SearchOrderOption, SearchSortOption } from "./search.schema";
2+
3+
export const SEARCH_SORT_OPTION_DEFAULT: SearchSortOption = 'created';
4+
export const SEARCH_SORT_OPTIONS: Record<SearchSortOption, string> = {
5+
created: "Created",
6+
updated: "Update",
7+
version: "Version",
8+
buildingCount: "Buildings",
9+
islandCount: "Islands",
10+
viewCount: "Views",
11+
downloadCount: "Download",
12+
bookmarkCount: "Bookmarks",
13+
};
14+
15+
export const SEARCH_ORDER_OPTION_DEFAULT: SearchOrderOption = 'desc';
16+
export const SEARCH_ORDER_OPTIONS: Record<SearchOrderOption, string> = {
17+
asc: "Ascending",
18+
desc: "Descending",
19+
};
20+
21+
22+
export const PAGINATION_PAGE_DEFAULT = 1;
23+
export const PAGINATION_PER_PAGE_DEFAULT = 10;

src/lib/server/blueprint.api.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '$lib/blueprint.schema';
1616
import type { BlueprintRecord, BlueprintTag } from '$lib/blueprint.types';
1717
import type { User } from '$lib/user.types';
18+
import { PAGINATION_PAGE_DEFAULT, PAGINATION_PER_PAGE_DEFAULT } from '$lib/search';
1819

1920
type BlueprintGetOptions = {
2021
query: string;
@@ -36,14 +37,12 @@ const GET_FIELDS = [
3637
'expand.tags.name',
3738
'expand.creator.displayname',
3839
];
39-
const DEFAULT_GET_PAGE = 1;
40-
const DEFAULT_GET_PAGE_ENTRIES = 10;
4140
const DEFAULT_GET_OPTIONS: BlueprintGetOptions = {
4241
query: '',
4342
sort: 'created',
4443
order: 'desc',
45-
page: DEFAULT_GET_PAGE,
46-
perPage: DEFAULT_GET_PAGE_ENTRIES,
44+
page: PAGINATION_PAGE_DEFAULT,
45+
perPage: PAGINATION_PER_PAGE_DEFAULT,
4746
};
4847

4948
export const get = async (pb: PocketBase, options?: BlueprintGetOptions) => {
@@ -191,7 +190,7 @@ const getBlueprintFormData = (
191190
return formData;
192191
};
193192

194-
export const getBlueprintOptions = (url: URL) => {
193+
export const getBlueprintOptions = (url: URL): BlueprintGetOptions => {
195194
const filterParams = String(url.searchParams.get('filter'));
196195
const filterEntries = filterParams.split(';');
197196
const filter = filterEntries.reduce<Record<string, Array<string>>>(
@@ -206,8 +205,8 @@ export const getBlueprintOptions = (url: URL) => {
206205
const options: BlueprintGetOptions = {
207206
query: url.searchParams.get('query') ?? '',
208207
filter,
209-
page: Number(url.searchParams.get('page')),
210-
perPage: Number(url.searchParams.get('perPage')),
208+
page: Number(url.searchParams.get('page') ?? DEFAULT_GET_OPTIONS.page),
209+
perPage: Number(url.searchParams.get('perPage') ?? DEFAULT_GET_OPTIONS.perPage),
211210
};
212211
const sort = url.searchParams.get('sort');
213212
if (sort) {
Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
import { z } from 'zod';
2+
import type { Actions, PageServerLoad } from './$types';
3+
import { fail, superValidate } from 'sveltekit-superforms';
4+
import { zod } from 'sveltekit-superforms/adapters';
15
import type { BlueprintTag } from '$lib/blueprint.types';
6+
import { PAGINATION_SCHEMA, SEARCH_SCHEMA, type SearchOrderOption, type SearchSortOption } from '$lib/search.schema';
27
import { get, getBlueprintOptions } from '$lib/server/blueprint.api';
3-
import type { PageServerLoad } from './$types';
48

59
export const load = (async ({ locals, url }) => {
6-
const result = await get(locals.pb, getBlueprintOptions(url));
10+
const options = getBlueprintOptions(url);
11+
const result = await get(locals.pb, options);
712
const images = result.items?.reduce<Record<string, string>>(
813
(result, current) => {
914
if (current.images.length <= 0) return result;
@@ -14,26 +19,23 @@ export const load = (async ({ locals, url }) => {
1419
},
1520
{},
1621
);
17-
1822
const tags = await locals.pb.collection<BlueprintTag>('tags').getFullList();
19-
const query = url.searchParams.get('query');
20-
const filter = url.searchParams.get('filter');
21-
const sort = url.searchParams.get('sort');
22-
const order = url.searchParams.get('order');
23+
24+
const query = url.searchParams.get('query') ?? undefined;
25+
const filter = url.searchParams.get('filter') ?? undefined;
26+
const sort = (url.searchParams.get('sort') ?? 'created') as SearchSortOption;
27+
const order = (url.searchParams.get('order') ?? 'desc') as SearchOrderOption;
28+
29+
const form = await superValidate({ query, filter, sort, order, page: options.page, perPage: options.perPage }, zod(z.intersection(SEARCH_SCHEMA, PAGINATION_SCHEMA)));
2330

2431
return {
2532
seo: {
26-
title: `Browse blueprints`,
27-
description: query
28-
? `List of blueprints for “${query}”.`
29-
: 'List of all blueprints.',
33+
title: 'Browse blueprints',
34+
description: 'Search the whole collection of blueprints. Filter & sort to find the blueprint that suits your requirements.'
3035
},
3136
result,
3237
images,
3338
tags,
34-
query,
35-
filter,
36-
sort,
37-
order,
39+
form,
3840
};
39-
}) satisfies PageServerLoad;
41+
}) satisfies PageServerLoad;

0 commit comments

Comments
 (0)