webapp/src/routes/author/(all-authors).tsx

86 lines
2.9 KiB
TypeScript
Raw Normal View History

2024-07-01 13:41:22 +00:00
import { RouteDefinition, RouteLoadFuncArgs, type RouteSectionProps, createAsync } from '@solidjs/router'
2024-07-07 13:48:53 +00:00
import { Suspense, createEffect, on } from 'solid-js'
2024-07-01 13:41:22 +00:00
import { AllAuthors } from '~/components/Views/AllAuthors'
2024-07-06 00:59:01 +00:00
import { AUTHORS_PER_PAGE } from '~/components/Views/AllAuthors/AllAuthors'
2024-07-03 21:25:03 +00:00
import { Loading } from '~/components/_shared/Loading'
import { PageLayout } from '~/components/_shared/PageLayout'
2024-07-05 22:45:42 +00:00
import { useAuthors } from '~/context/authors'
2024-07-03 21:25:03 +00:00
import { useLocalize } from '~/context/localize'
2024-07-06 00:59:01 +00:00
import { loadAuthors, loadAuthorsAll } from '~/graphql/api/public'
import { Author, AuthorsBy } from '~/graphql/schema/core.gen'
2024-07-01 13:41:22 +00:00
2024-07-06 00:59:01 +00:00
const fetchAuthorsWithStat = async (offset = 0, order?: string) => {
const by: AuthorsBy = { order }
const authorsFetcher = loadAuthors({ by, offset, limit: AUTHORS_PER_PAGE })
return await authorsFetcher()
2024-07-01 13:41:22 +00:00
}
2024-07-06 00:59:01 +00:00
const fetchAllAuthors = async () => {
const authorsAllFetcher = loadAuthorsAll()
return await authorsAllFetcher()
}
2024-07-01 13:41:22 +00:00
export const route = {
2024-07-07 13:48:53 +00:00
load: async ({ location: { query } }: RouteLoadFuncArgs) => {
2024-07-07 14:07:11 +00:00
const by = query.by
const isAll = !by || by === 'name'
return {
authors: isAll && (await fetchAllAuthors()),
2024-07-09 09:13:13 +00:00
authorsByFollowers: await fetchAuthorsWithStat(10, 'followers'),
authorsByShouts: await fetchAuthorsWithStat(10, 'shouts')
2024-07-07 14:07:11 +00:00
} as AllAuthorsData
2024-07-07 13:48:53 +00:00
}
2024-07-01 13:41:22 +00:00
} satisfies RouteDefinition
2024-07-09 09:13:13 +00:00
type AllAuthorsData = { authors: Author[]; authorsByFollowers: Author[]; authorsByShouts: Author[] }
2024-07-07 13:48:53 +00:00
// addAuthors to context
export default function AllAuthorsPage(props: RouteSectionProps<AllAuthorsData>) {
2024-07-01 13:41:22 +00:00
const { t } = useLocalize()
2024-07-07 13:48:53 +00:00
const { addAuthors } = useAuthors()
// async load data: from ssr or fetch
const data = createAsync<AllAuthorsData>(async () => {
if (props.data) return props.data
return {
authors: await fetchAllAuthors(),
2024-07-09 09:13:13 +00:00
authorsByFollowers: await fetchAuthorsWithStat(10, 'followers'),
authorsByShouts: await fetchAuthorsWithStat(10, 'shouts')
2024-07-07 13:48:53 +00:00
} as AllAuthorsData
})
// update context when data is loaded
2024-07-07 14:07:11 +00:00
createEffect(
on(
[data, () => addAuthors],
([data, aa]) => {
if (data && aa) {
aa(data.authors as Author[])
2024-07-09 09:13:13 +00:00
aa(data.authorsByFollowers as Author[])
aa(data.authorsByShouts as Author[])
2024-07-07 14:07:11 +00:00
console.debug('[routes.author] added all authors:', data.authors)
}
},
{ defer: true }
)
)
2024-07-07 13:48:53 +00:00
2024-07-01 13:41:22 +00:00
return (
2024-07-09 09:13:13 +00:00
<PageLayout
withPadding={true}
title={`${t('Discours')} :: ${t('All authors')}`}
desc="List of authors of the open editorial community"
>
2024-07-01 13:41:22 +00:00
<Suspense fallback={<Loading />}>
2024-07-07 13:48:53 +00:00
<AllAuthors
isLoaded={Boolean(data()?.authors)}
authors={data()?.authors || []}
2024-07-09 09:13:13 +00:00
authorsByFollowers={data()?.authorsByFollowers}
authorsByShouts={data()?.authorsByShouts}
2024-07-07 14:07:11 +00:00
/>
2024-07-01 13:41:22 +00:00
</Suspense>
</PageLayout>
)
}