From 12127a77633f0e92ae88cbafd49581296f559c33 Mon Sep 17 00:00:00 2001 From: sct Date: Tue, 22 Dec 2020 00:12:50 +0900 Subject: [PATCH] feat(frontend): add crew related movies/shows to person details page --- src/components/PersonDetails/index.tsx | 190 +++++++++++++++++-------- src/styles/globals.css | 13 +- tailwind.config.js | 3 + 3 files changed, 145 insertions(+), 61 deletions(-) diff --git a/src/components/PersonDetails/index.tsx b/src/components/PersonDetails/index.tsx index a03affb3e..c05829699 100644 --- a/src/components/PersonDetails/index.tsx +++ b/src/components/PersonDetails/index.tsx @@ -1,5 +1,5 @@ import { useRouter } from 'next/router'; -import React, { useContext } from 'react'; +import React, { useContext, useState } from 'react'; import useSWR from 'swr'; import type { PersonDetail } from '../../../server/models/Person'; import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces'; @@ -11,6 +11,7 @@ import { LanguageContext } from '../../context/LanguageContext'; const messages = defineMessages({ appearsin: 'Appears in', + crewmember: 'Crew Member', ascharacter: 'as {character}', nobiography: 'No biography available.', }); @@ -22,6 +23,7 @@ const PersonDetails: React.FC = () => { const { data, error } = useSWR( `/api/v1/person/${router.query.personId}` ); + const [showBio, setShowBio] = useState(false); const { data: combinedCredits, @@ -53,77 +55,151 @@ const PersonDetails: React.FC = () => { return 1; }); + const sortedCrew = combinedCredits?.crew.sort((a, b) => { + const aDate = + a.mediaType === 'movie' + ? a.releaseDate?.slice(0, 4) ?? 0 + : a.firstAirDate?.slice(0, 4) ?? 0; + const bDate = + b.mediaType === 'movie' + ? b.releaseDate?.slice(0, 4) ?? 0 + : b.firstAirDate?.slice(0, 4) ?? 0; + if (aDate > bDate) { + return -1; + } + return 1; + }); + const isLoading = !combinedCredits && !errorCombinedCredits; return ( <> -
+
{data.profilePath && (
)} -
-

{data.name}

-
- {data.biography - ? data.biography - : intl.formatMessage(messages.nobiography)} +
+

{data.name}

+
+ {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} +
setShowBio((show) => !show)} + role="button" + tabIndex={-1} + > +
+ {data.biography + ? data.biography + : intl.formatMessage(messages.nobiography)} +
+ {!showBio && ( +
+ )} +
-
-
-
- {intl.formatMessage(messages.appearsin)} + {(sortedCast ?? []).length > 0 && ( + <> +
+
+
+ {intl.formatMessage(messages.appearsin)} +
+
-
-
-
    - {sortedCast?.map((media) => { - return ( -
  • - - {media.character && ( -
    - {intl.formatMessage(messages.ascharacter, { - character: media.character, - })} -
    - )} -
  • - ); - })} - {isLoading && - [...Array(20)].map((_item, i) => ( -
  • - -
  • - ))} -
+
    + {sortedCast?.map((media, index) => { + return ( +
  • + + {media.character && ( +
    + {intl.formatMessage(messages.ascharacter, { + character: media.character, + })} +
    + )} +
  • + ); + })} +
+ + )} + {(sortedCrew ?? []).length > 0 && ( + <> +
+
+
+ {intl.formatMessage(messages.crewmember)} +
+
+
+
    + {sortedCrew?.map((media, index) => { + return ( +
  • + + {media.job && ( +
    + {media.job} +
    + )} +
  • + ); + })} +
+ + )} + {isLoading && } ); }; diff --git a/src/styles/globals.css b/src/styles/globals.css index 9df59f095..3517a6a62 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -7,7 +7,7 @@ body { } .plex-button { - @apply w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 transition ease-in-out duration-150 text-center disabled:opacity-50; + @apply flex justify-center w-full px-4 py-2 text-sm font-medium text-center text-white transition duration-150 ease-in-out bg-indigo-600 border border-transparent rounded-md disabled:opacity-50; background-color: #cc7b19; } @@ -16,7 +16,7 @@ body { } .titleCard { - @apply relative bg-cover rounded-lg bg-gray-800; + @apply relative bg-gray-800 bg-cover rounded-lg; padding-bottom: 150%; } @@ -34,7 +34,12 @@ body { } .error-message { - @apply flex items-center justify-center text-center text-gray-300 relative top-0 left-0 bottom-0 right-0 h-screen flex-col; + @apply relative top-0 bottom-0 left-0 right-0 flex flex-col items-center justify-center h-screen text-center text-gray-300; +} + +/* Used for animating height */ +.extra-max-height { + max-height: 100rem; } /* Hide scrollbar for Chrome, Safari and Opera */ @@ -49,5 +54,5 @@ body { } code { - @apply bg-gray-800 py-1 px-2 rounded-md; + @apply px-2 py-1 bg-gray-800 rounded-md; } diff --git a/tailwind.config.js b/tailwind.config.js index 01daf1bcb..94b25a79d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -5,6 +5,9 @@ module.exports = { purge: ['./src/pages/**/*.{ts,tsx}', './src/components/**/*.{ts,tsx}'], theme: { extend: { + transitionProperty: { + 'max-height': 'max-height', + }, fontFamily: { sans: ['Inter var', ...defaultTheme.fontFamily.sans], },