diff --git a/src/components/Views/AllAuthors/AllAuthors.tsx b/src/components/Views/AllAuthors/AllAuthors.tsx index 1a90d7d6..bb2d736c 100644 --- a/src/components/Views/AllAuthors/AllAuthors.tsx +++ b/src/components/Views/AllAuthors/AllAuthors.tsx @@ -11,6 +11,7 @@ import { useLocalize } from '~/context/localize' import type { Author } from '~/graphql/schema/core.gen' import { authorLetterReduce, translateAuthor } from '~/intl/translate' import { dummyFilter } from '~/lib/dummyFilter' +import { byFirstChar, byStat } from '~/lib/sortby' import { scrollHandler } from '~/utils/scroll' import styles from './AllAuthors.module.scss' import stylesAuthorList from './AuthorsList.module.scss' @@ -45,13 +46,13 @@ export const AllAuthors = (props: Props) => { let sortedAuthors = [...(props.authors || authorsSorted())] // Clone the array to avoid mutating the original console.log('Before Sorting:', sortedAuthors.slice(0, 5)) // Log the first 5 authors for comparison if (searchParams.by === 'name') { - sortedAuthors = sortedAuthors.sort((a, b) => (a.name||'').localeCompare(b.name||'')) + sortedAuthors = sortedAuthors.sort(byFirstChar) console.log('Sorted by Name:', sortedAuthors.slice(0, 5)) } else if (searchParams.by === 'shouts') { - sortedAuthors = sortedAuthors.sort((a, b) => (b.stat?.shouts || 0) - (a.stat?.shouts || 0)) + sortedAuthors = sortedAuthors.sort(byStat('shouts')) console.log('Sorted by Shouts:', sortedAuthors.slice(0, 5)) } else if (searchParams.by === 'followers') { - sortedAuthors = sortedAuthors.sort((a, b) => (b.stat?.followers || 0) - (a.stat?.followers || 0)) + sortedAuthors = sortedAuthors.sort(byStat('followers')) console.log('Sorted by Followers:', sortedAuthors.slice(0, 5)) } console.log('After Sorting:', sortedAuthors.slice(0, 5)) diff --git a/src/lib/sortby.ts b/src/lib/sortby.ts index 58e7edb5..ed937c4f 100644 --- a/src/lib/sortby.ts +++ b/src/lib/sortby.ts @@ -1,7 +1,9 @@ import type { Author, Maybe, Reaction, Shout, Topic, TopicStat } from '~/graphql/schema/core.gen' -export const byFirstChar = (a: { name?: string; title?: string }, b: { name?: string; title?: string }) => - (a.name || a.title || '').localeCompare(b.name || b.title || '') +export const byFirstChar = (a: Author | Topic, b: Author | Topic) => + ((a as Author).name || (a as Topic).title || '').localeCompare( + (b as Author).name || (b as Topic).title || '' + ) export const byCreated = (a: Shout | Reaction, b: Shout | Reaction) => { return a?.created_at - b?.created_at diff --git a/src/routes/author/[slug]/(profile).tsx b/src/routes/author/[slug]/(profile).tsx new file mode 100644 index 00000000..6c49969a --- /dev/null +++ b/src/routes/author/[slug]/(profile).tsx @@ -0,0 +1,104 @@ +import { RouteSectionProps, createAsync, useParams } from '@solidjs/router' +import { ErrorBoundary, Suspense, createEffect, createMemo } from 'solid-js' +import { AuthorView } from '~/components/Views/Author' +import { FourOuFourView } from '~/components/Views/FourOuFour' +import { Loading } from '~/components/_shared/Loading' +import { PageLayout } from '~/components/_shared/PageLayout' +import { useAuthors } from '~/context/authors' +import { useLocalize } from '~/context/localize' +import { ReactionsProvider } from '~/context/reactions' +import { loadAuthors, loadShouts, loadTopics } from '~/graphql/api/public' +import { + Author, + LoadShoutsOptions, + QueryLoad_Authors_ByArgs, + Shout, + Topic +} from '~/graphql/schema/core.gen' +import { getImageUrl } from '~/lib/getImageUrl' +import { SHOUTS_PER_PAGE } from '../../(home)' + +const fetchAuthorShouts = async (slug: string, offset?: number) => { + const opts: LoadShoutsOptions = { filters: { author: slug }, limit: SHOUTS_PER_PAGE, offset } + const shoutsLoader = loadShouts(opts) + return await shoutsLoader() +} + +const fetchAllTopics = async () => { + const topicsFetcher = loadTopics() + return await topicsFetcher() +} + +const fetchAuthor = async (slug: string) => { + const authorFetcher = loadAuthors({ by: { slug }, limit: 1 } as QueryLoad_Authors_ByArgs) + const aaa = await authorFetcher() + return aaa?.[0] +} + +export const route = { + load: async ({ params, location: { query } }: RouteSectionProps<{ articles: Shout[] }>) => { + const offset: number = Number.parseInt(query.offset, 10) + const result = await fetchAuthorShouts(params.slug, offset) + return { + author: await fetchAuthor(params.slug), + shouts: result || [], + topics: await fetchAllTopics() + } + } +} + +export default (props: RouteSectionProps<{ articles: Shout[]; author: Author; topics: Topic[] }>) => { + const params = useParams() + const { addAuthor } = useAuthors() + const articles = createAsync( + async () => props.data.articles || (await fetchAuthorShouts(params.slug)) || [] + ) + const author = createAsync(async () => { + const a = props.data.author || (await fetchAuthor(params.slug)) + addAuthor(a) + return a + }) + const topics = createAsync(async () => props.data.topics || (await fetchAllTopics())) + const { t } = useLocalize() + const title = createMemo(() => `${author()?.name || ''}`) + + createEffect(() => { + if (author()) { + console.debug('[routes] author/[slug] author loaded fx') + window?.gtag?.('event', 'page_view', { + page_title: author()?.name || '', + page_location: window?.location.href || '', + page_path: window?.location.pathname || '' + }) + } + }) + + const cover = createMemo(() => + author()?.pic + ? getImageUrl(author()?.pic || '', { width: 1200 }) + : getImageUrl('production/image/logo_image.png') + ) + return ( + }> + }> + + + + + + + + ) +} diff --git a/src/routes/author/[slug]/[tab].tsx b/src/routes/author/[slug]/[tab].tsx index 3d0e74c8..5aab27e3 100644 --- a/src/routes/author/[slug]/[tab].tsx +++ b/src/routes/author/[slug]/[tab].tsx @@ -62,8 +62,6 @@ export default (props: RouteSectionProps<{ articles: Shout[]; author: Author; to const { t } = useLocalize() const title = createMemo(() => `${author()?.name || ''}`) - // docs: `a side effect that is run the first time the expression - // wrapped by the returned tracking function is notified of a change` createEffect(() => { if (author()) { console.debug('[routes] author/[slug] author loaded fx') @@ -95,7 +93,7 @@ export default (props: RouteSectionProps<{ articles: Shout[]; author: Author; to author={author() as Author} authorSlug={params.slug} shouts={articles() as Shout[]} - selectedTab={params.tab || 'shouts'} + selectedTab={params.tab} topics={topics()} />