Files
website/src/routes/projects/worldwide-todo/+page.server.ts
2026-10-26 08:38:51 +00:00

38 lines
1.7 KiB
TypeScript

import { counts, listTasks, type Sort } from '#lib/server/worldtodo/store.js';
import { WORLDTODO_SCALES } from '#lib/worldtodo/shared.js';
import type { PageServerLoad } from './$types';
const STATUSES = ['todo', 'open', 'in_progress', 'done', 'all'];
const SORTS: Sort[] = ['updated', 'scale', 'title'];
// Filters live in the query string (shareable, SSR, works without JS). A GET form submits
// toggle buttons that come before hidden copies of the current values, so the first value of
// each name wins.
export const load: PageServerLoad = async ({ url, parent }) => {
const first = (key: string) => url.searchParams.getAll(key)[0]?.trim() ?? '';
const { categories } = await parent();
const scale = (WORLDTODO_SCALES as readonly string[]).includes(first('scale'))
? first('scale')
: '';
const category = categories.some((c) => c.slug === first('category')) ? first('category') : '';
const status = STATUSES.includes(first('status')) ? first('status') : 'todo';
const sort = (SORTS as string[]).includes(first('sort')) ? (first('sort') as Sort) : 'updated';
const q = first('q').slice(0, 100);
const view = first('view') === 'map' ? 'map' : 'list';
const filter = { scale, category, status, q };
const [list, totals] = await Promise.all([listTasks(filter, sort, 500), counts(filter)]);
return {
filter,
sort,
view,
tasks: list.tasks,
counts: totals,
seo: {
title: 'The worldwide todo list',
description:
'A public todo list of real, sourced problems, from planet-scale to a single street. Anyone can suggest additions, edits and removals.',
index: !scale && !category && status === 'todo' && !q && sort === 'updated' && view === 'list'
}
};
};