feat: articles pagination

This commit is contained in:
Florian Sylvain committed 2026-10-11 19:14:37 +02:00
1 parent a2d224240c
commit 73f4b539fe
45 files changed
+3528 -317

No files matched your search

@@ -0,0 +1,70 @@
import type { Article, ArticlePage, ArticleStatus } from '@/composables/useArticles'
export interface EnvelopeParams {
page?: number
size?: number
q?: string
status?: ArticleStatus | ''
sort?: string
}
function fold(value: string) {
return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase()
}
export function articleEnvelope(all: Article[], params: EnvelopeParams = {}): ArticlePage {
const { page = 1, size = 25, q = '', status = '', sort = '' } = params
const filtered = all
.filter((article) => !status || article.is_online === (status === 'online'))
.filter((article) => !q || fold(article.title).includes(fold(q)))
if (sort) {
const [name, direction] = sort.split(':') as [string, string]
const field = (name === 'status' ? 'is_online' : name) as keyof Article
filtered.sort((left, right) => {
const order = String(left[field]).localeCompare(String(right[field]))
return direction === 'desc' ? -order : order
})
}
const online = all.filter((article) => article.is_online).length
return {
items: filtered.slice((page - 1) * size, page * size),
total: filtered.length,
page,
size,
counts: { all: all.length, online, draft: all.length - online },
}
}
export function articleListUrl(params: EnvelopeParams = {}) {
const { page = 1, size = 25, q = '', status = '', sort = '' } = params
const query = new URLSearchParams({
format: 'html',
page: String(page),
size: String(size),
})
if (q) {
query.set('q', q)
}
if (status) {
query.set('status', status)
}
if (sort) {
query.set('sort', sort)
}
return `/v1/article/?${query.toString()}`
}
export function articleListRoute(params: EnvelopeParams = {}) {
return `GET ${articleListUrl(params)}`
}
export function parseListUrl(url: string): EnvelopeParams {
const query = new URL(url, 'http://localhost').searchParams
return {
page: Number(query.get('page')),
size: Number(query.get('size')),
q: query.get('q') ?? '',
status: (query.get('status') ?? '') as ArticleStatus | '',
sort: query.get('sort') ?? '',
}
}