diff --git a/pages/members/[id].tsx b/pages/members/[id].tsx new file mode 100644 index 00000000..c24d6a18 --- /dev/null +++ b/pages/members/[id].tsx @@ -0,0 +1,63 @@ +import { GetServerSideProps, InferGetServerSidePropsType } from 'next'; +import { ParsedUrlQuery } from 'querystring'; + +import * as React from 'react'; +import { DehydratedState } from 'react-query'; + +import { Api, DATA_KEYS, configureQueryClient } from '@graasp/query-client'; + +import Wrapper from '../../src/components/common/Wrapper'; +import Member from '../../src/components/pages/Member'; +import { QUERY_CLIENT_OPTIONS } from '../../src/config/queryClient'; + +const MemberPage = ({ + dehydratedState, + id, +}: InferGetServerSidePropsType) => { + return ( + + + + ); +}; + +type Props = { + dehydratedState: DehydratedState; + id?: string; +}; + +interface Params extends ParsedUrlQuery { + id: string; +} + +// This gets called on every request +export const getServerSideProps: GetServerSideProps = async ({ + params, +}) => { + const id = params?.id; + const { queryClient, dehydrate, axios } = + configureQueryClient(QUERY_CLIENT_OPTIONS); + if (id) { + // prefetch data in query client + await queryClient.prefetchQuery(DATA_KEYS.buildItemKey(id), () => + Promise.all([ + Api.getMember({ id }, { ...QUERY_CLIENT_OPTIONS, axios }).then( + (data) => { + return JSON.parse(JSON.stringify(data)); + }, + ), + Api.getPublishedItemsForMember(id, { + ...QUERY_CLIENT_OPTIONS, + axios, + }).then((data) => { + return JSON.parse(JSON.stringify(data)); + }), + ]), + ); + } + + // Pass data to the page via props + return { props: { id, dehydratedState: dehydrate(queryClient) } }; +}; + +export default MemberPage; diff --git a/src/components/collection/Authorship.tsx b/src/components/collection/Authorship.tsx index 08fe6695..561bd5c1 100644 --- a/src/components/collection/Authorship.tsx +++ b/src/components/collection/Authorship.tsx @@ -1,4 +1,5 @@ import dynamic from 'next/dynamic'; +import Link from 'next/link'; import React, { useContext } from 'react'; @@ -9,6 +10,7 @@ import { DiscriminatedItem, PermissionLevel, ThumbnailSize } from '@graasp/sdk'; import { DEFAULT_MEMBER_THUMBNAIL } from '../../config/constants'; import { useLibraryTranslation } from '../../config/i18n'; +import { buildMemberRoute } from '../../config/routes'; import { SUMMARY_AUTHOR_CONTAINER_ID } from '../../config/selectors'; import LIBRARY from '../../langs/constants'; import { QueryClientContext } from '../QueryClientContext'; @@ -63,7 +65,13 @@ const Authorship = ({ itemId, author, displayCoEditors }: Props) => { variant="circular" sx={{ maxWidth: 30, maxHeight: 30 }} /> - {author?.name} + + {author?.name} + )} diff --git a/src/components/collection/Contributors.tsx b/src/components/collection/Contributors.tsx index 1fa01585..d74eff2a 100644 --- a/src/components/collection/Contributors.tsx +++ b/src/components/collection/Contributors.tsx @@ -1,9 +1,12 @@ +import Link from 'next/link'; + import AvatarGroup from '@mui/lab/AvatarGroup'; import { Stack, Tooltip, Typography } from '@mui/material'; import { Member } from '@graasp/sdk'; import { useLibraryTranslation } from '../../config/i18n'; +import { buildMemberRoute } from '../../config/routes'; import { buildContributorId } from '../../config/selectors'; import LIBRARY from '../../langs/constants'; import MemberAvatar from '../layout/MemberAvatar'; @@ -34,7 +37,9 @@ const Contributors = ({ contributors, displayContributors }: Props) => { const { id, name: contributorName } = contributor; return ( - + + + ); })} diff --git a/src/components/pages/Member.tsx b/src/components/pages/Member.tsx new file mode 100644 index 00000000..865288b1 --- /dev/null +++ b/src/components/pages/Member.tsx @@ -0,0 +1,111 @@ +import dynamic from 'next/dynamic'; + +import { useContext } from 'react'; + +import { Box, Stack, Typography } from '@mui/material'; + +import { Context } from '@graasp/sdk'; + +import { APP_AUTHOR } from '../../config/constants'; +import { useLibraryTranslation } from '../../config/i18n'; +import { ERROR_UNEXPECTED_ERROR_CODE } from '../../config/messages'; +import { MENU_BUTTON_ID } from '../../config/selectors'; +import LIBRARY from '../../langs/constants'; +import { QueryClientContext } from '../QueryClientContext'; +import CollectionsGrid from '../collection/CollectionsGrid'; +import BackButton from '../common/BackButton'; +import Error from '../common/Error'; +import Seo from '../common/Seo'; +import useHeader from '../layout/useHeader'; + +interface Props { + id?: string; +} + +const Main = dynamic(() => import('@graasp/ui').then((mod) => mod.Main), { + ssr: false, +}); + +const Avatar = dynamic(() => import('@graasp/ui').then((mod) => mod.Avatar), { + ssr: false, +}); + +const Member = ({ id }: Props) => { + const { hooks } = useContext(QueryClientContext); + const { data, isLoading: isMemberInfoLoading, isError } = hooks.useMember(id); + const { data: memberPublishedItems, isLoading } = + hooks.usePublishedItemsForMember(id); + + const { leftContent, rightContent } = useHeader(); + const { t } = useLibraryTranslation(); + + if (isError) { + return ( +
+ + + +
+ ); + } + return ( + <> + +
+ + + + + + + {data?.name} + {/* Bio goes there */} + {/* */} + + + + + {t(LIBRARY.PUBLISHED_COLLECTIONS)} + + + + + +
+ + ); +}; + +export default Member; diff --git a/src/config/routes.ts b/src/config/routes.ts index bc0a4491..541618f5 100644 --- a/src/config/routes.ts +++ b/src/config/routes.ts @@ -4,3 +4,5 @@ export const HOME_ROUTE = '/'; export const ALL_COLLECTIONS_ROUTE = '/all-collections'; export const MY_LIKED_ITEMS_ROUTE = '/liked'; export const ERROR_ROUTE = '/error'; + +export const buildMemberRoute = (id = ':id') => `/members/${id}`; diff --git a/src/langs/constants.ts b/src/langs/constants.ts index 3f832a9e..f9697dd6 100644 --- a/src/langs/constants.ts +++ b/src/langs/constants.ts @@ -120,6 +120,7 @@ export const LIBRARY = { SEARCH_NO_RESULTS: 'SEARCH_NO_RESULTS', SEARCH_RESULTS_LOAD_MORE: 'SEARCH_RESULTS_LOAD_MORE', CONTENT_CHIP: 'CONTENT_CHIP', + PUBLISHED_COLLECTIONS: 'PUBLISHED_COLLECTIONS', LIKED_ITEMS: 'LIKED_ITEMS', SIGNIN_MESSAGE: 'SIGNIN_MESSAGE', }; diff --git a/src/langs/en.json b/src/langs/en.json index 28880077..3084378d 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -117,6 +117,7 @@ "SEARCH_NO_RESULTS": "Nothing corresponds to your search", "SEARCH_RESULTS_LOAD_MORE": "Load more", "CONTENT_CHIP": "Content", + "PUBLISHED_COLLECTIONS": "Published Collections", "LIKED_ITEMS": "Liked Items", "SIGNIN_MESSAGE": "You need to sign in First" }