2024-07-03 17:38:43 +00:00
|
|
|
import { RouteSectionProps, createAsync, useParams } from '@solidjs/router'
|
2024-07-01 13:27:45 +00:00
|
|
|
import { ErrorBoundary, Suspense, createMemo, createReaction } from 'solid-js'
|
|
|
|
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
|
|
|
import { TopicView } from '~/components/Views/Topic'
|
|
|
|
import { Loading } from '~/components/_shared/Loading'
|
|
|
|
import { PageLayout } from '~/components/_shared/PageLayout'
|
|
|
|
import { useLocalize } from '~/context/localize'
|
|
|
|
import { ReactionsProvider } from '~/context/reactions'
|
|
|
|
import { useTopics } from '~/context/topics'
|
|
|
|
import { LoadShoutsOptions, Shout, Topic } from '~/graphql/schema/core.gen'
|
2024-07-03 17:38:43 +00:00
|
|
|
import { loadShouts } from '~/lib/api/public'
|
2024-07-01 13:27:45 +00:00
|
|
|
import { SHOUTS_PER_PAGE } from '../(home)'
|
|
|
|
|
2024-07-03 17:38:43 +00:00
|
|
|
const fetchTopicShouts = async (slug: string, offset?: number) => {
|
|
|
|
const opts: LoadShoutsOptions = { filters: { topic: slug }, limit: SHOUTS_PER_PAGE, offset }
|
2024-07-01 13:27:45 +00:00
|
|
|
const shoutsLoader = loadShouts(opts)
|
|
|
|
return await shoutsLoader()
|
|
|
|
}
|
|
|
|
|
|
|
|
export const route = {
|
2024-07-03 17:38:43 +00:00
|
|
|
load: async ({ params, location: { query } }: RouteSectionProps<{ articles: Shout[] }>) => {
|
|
|
|
const offset: number = Number.parseInt(query.offset, 10)
|
|
|
|
const result = await fetchTopicShouts(params.slug, offset)
|
|
|
|
return result
|
|
|
|
}
|
2024-07-01 13:27:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const TopicPage = (props: RouteSectionProps<{ articles: Shout[] }>) => {
|
2024-07-03 17:38:43 +00:00
|
|
|
const params = useParams()
|
2024-07-01 13:41:22 +00:00
|
|
|
const articles = createAsync(
|
2024-07-03 17:38:43 +00:00
|
|
|
async () => props.data.articles || (await fetchTopicShouts(params.slug)) || []
|
2024-07-01 13:41:22 +00:00
|
|
|
)
|
2024-07-01 13:27:45 +00:00
|
|
|
const { topicEntities } = useTopics()
|
|
|
|
const { t } = useLocalize()
|
2024-07-03 17:38:43 +00:00
|
|
|
const topic = createMemo(() => topicEntities?.()[params.slug])
|
2024-07-01 13:27:45 +00:00
|
|
|
const title = createMemo(() => `${t('Discours')}: ${topic()?.title || ''}`)
|
|
|
|
|
|
|
|
// docs: `a side effect that is run the first time the expression
|
|
|
|
// wrapped by the returned tracking function is notified of a change`
|
|
|
|
createReaction(() => {
|
|
|
|
if (topic()) {
|
|
|
|
console.debug('[routes.slug] article signal changed once')
|
|
|
|
window.gtag?.('event', 'page_view', {
|
|
|
|
page_title: topic()?.title,
|
|
|
|
page_location: window.location.href,
|
|
|
|
page_path: window.location.pathname
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
return (
|
|
|
|
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
|
|
|
<Suspense fallback={<Loading />}>
|
|
|
|
<PageLayout
|
|
|
|
title={title()}
|
|
|
|
headerTitle={topic()?.title || ''}
|
|
|
|
slug={topic()?.slug}
|
|
|
|
articleBody={topic()?.body || ''}
|
|
|
|
cover={topic()?.pic || ''}
|
|
|
|
>
|
|
|
|
<ReactionsProvider>
|
2024-07-01 13:41:22 +00:00
|
|
|
<TopicView
|
|
|
|
topic={topic() as Topic}
|
|
|
|
topicSlug={props.params.slug}
|
|
|
|
shouts={articles() as Shout[]}
|
|
|
|
/>
|
2024-07-01 13:27:45 +00:00
|
|
|
</ReactionsProvider>
|
|
|
|
</PageLayout>
|
|
|
|
</Suspense>
|
|
|
|
</ErrorBoundary>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-07-03 21:25:03 +00:00
|
|
|
export default TopicPage
|