feat(collections): enhance collections page with sorting, filtering, and pagination features

- Updated the collections loading logic to include sorting and pagination parameters from the URL.
- Refactored the collections page to manage owned, shared, and archived collections with a tabbed interface.
- Added sorting functionality to allow users to sort collections by different attributes.
- Implemented a sidebar for filtering and sorting options.
- Improved the UI for better user experience, including a floating action button for creating new collections.
- Added a not found page for collections that do not exist, enhancing error handling.
This commit is contained in:
Sean Morley
2025-06-13 12:11:42 -04:00
parent 7eb96bcc2a
commit 14eb4ca802
23 changed files with 1691 additions and 1251 deletions

View File

@@ -3,7 +3,7 @@ import type { PageServerLoad } from './$types';
const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL'];
import type { Adventure, Collection } from '$lib/types';
import type { Actions, RequestEvent } from '@sveltejs/kit';
import type { Actions } from '@sveltejs/kit';
import { fetchCSRFToken } from '$lib/index.server';
import { checkLink } from '$lib';
@@ -16,16 +16,27 @@ export const load = (async (event) => {
let next = null;
let previous = null;
let count = 0;
let adventures: Adventure[] = [];
let collections: Adventure[] = [];
let sessionId = event.cookies.get('sessionid');
let initialFetch = await fetch(`${serverEndpoint}/api/collections/?order_by=updated_at`, {
// Get sorting parameters from URL
const order_by = event.url.searchParams.get('order_by') || 'updated_at';
const order_direction = event.url.searchParams.get('order_direction') || 'desc';
const page = event.url.searchParams.get('page') || '1';
// Build API URL with parameters
let apiUrl = `${serverEndpoint}/api/collections/?order_by=${order_by}&order_direction=${order_direction}&page=${page}`;
console.log('Fetching collections from:', apiUrl);
let initialFetch = await fetch(apiUrl, {
headers: {
Cookie: `sessionid=${sessionId}`
},
credentials: 'include'
});
if (!initialFetch.ok) {
console.error('Failed to fetch visited adventures');
console.error('Failed to fetch collections');
return redirect(302, '/login');
} else {
let res = await initialFetch.json();
@@ -33,15 +44,45 @@ export const load = (async (event) => {
next = res.next;
previous = res.previous;
count = res.count;
adventures = [...adventures, ...visited];
collections = [...collections, ...visited];
}
let sharedRes = await fetch(`${serverEndpoint}/api/collections/shared/`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
});
if (!sharedRes.ok) {
console.error('Failed to fetch shared collections');
return redirect(302, '/login');
}
let sharedCollections = (await sharedRes.json()) as Collection[];
let archivedRes = await fetch(`${serverEndpoint}/api/collections/archived/`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
});
if (!archivedRes.ok) {
console.error('Failed to fetch archived collections');
return redirect(302, '/login');
}
let archivedCollections = (await archivedRes.json()) as Collection[];
// Calculate current page from URL
const currentPage = parseInt(page);
return {
props: {
adventures,
adventures: collections,
next,
previous,
count
count,
sharedCollections,
currentPage,
order_by,
order_direction,
archivedCollections
}
};
}