import { groupBy } from 'lodash'; import { useRouter } from 'next/router'; import React, { useMemo, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import TruncateMarkup from 'react-truncate-markup'; import useSWR from 'swr'; import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces'; import type { PersonDetail } from '../../../server/models/Person'; import Ellipsis from '../../assets/ellipsis.svg'; import globalMessages from '../../i18n/globalMessages'; import Error from '../../pages/_error'; import CachedImage from '../Common/CachedImage'; import ImageFader from '../Common/ImageFader'; import LoadingSpinner from '../Common/LoadingSpinner'; import PageTitle from '../Common/PageTitle'; import TitleCard from '../TitleCard'; const messages = defineMessages({ birthdate: 'Born {birthdate}', lifespan: '{birthdate} – {deathdate}', alsoknownas: 'Also Known As: {names}', appearsin: 'Appearances', crewmember: 'Crew', ascharacter: 'as {character}', }); const PersonDetails: React.FC = () => { const intl = useIntl(); const router = useRouter(); const { data, error } = useSWR( `/api/v1/person/${router.query.personId}` ); const [showBio, setShowBio] = useState(false); const { data: combinedCredits, error: errorCombinedCredits } = useSWR( `/api/v1/person/${router.query.personId}/combined_credits` ); const sortedCast = useMemo(() => { const grouped = groupBy(combinedCredits?.cast ?? [], 'id'); const reduced = Object.values(grouped).map((objs) => ({ ...objs[0], character: objs.map((pos) => pos.character).join(', '), })); return reduced.sort((a, b) => { const aVotes = a.voteCount ?? 0; const bVotes = b.voteCount ?? 0; if (aVotes > bVotes) { return -1; } return 1; }); }, [combinedCredits]); const sortedCrew = useMemo(() => { const grouped = groupBy(combinedCredits?.crew ?? [], 'id'); const reduced = Object.values(grouped).map((objs) => ({ ...objs[0], job: objs.map((pos) => pos.job).join(', '), })); return reduced.sort((a, b) => { const aVotes = a.voteCount ?? 0; const bVotes = b.voteCount ?? 0; if (aVotes > bVotes) { return -1; } return 1; }); }, [combinedCredits]); if (!data && !error) { return ; } if (!data) { return ; } const personAttributes: string[] = []; if (data.birthday) { if (data.deathday) { personAttributes.push( intl.formatMessage(messages.lifespan, { birthdate: intl.formatDate(data.birthday, { year: 'numeric', month: 'long', day: 'numeric', }), deathdate: intl.formatDate(data.deathday, { year: 'numeric', month: 'long', day: 'numeric', }), }) ); } else { personAttributes.push( intl.formatMessage(messages.birthdate, { birthdate: intl.formatDate(data.birthday, { year: 'numeric', month: 'long', day: 'numeric', }), }) ); } } if (data.placeOfBirth) { personAttributes.push(data.placeOfBirth); } const isLoading = !combinedCredits && !errorCombinedCredits; const cast = (sortedCast ?? []).length > 0 && ( <>
{intl.formatMessage(messages.appearsin)}
    {sortedCast?.map((media, index) => { return (
  • {media.character && (
    {intl.formatMessage(messages.ascharacter, { character: media.character, })}
    )}
  • ); })}
); const crew = (sortedCrew ?? []).length > 0 && ( <>
{intl.formatMessage(messages.crewmember)}
    {sortedCrew?.map((media, index) => { return (
  • {media.job && (
    {media.job}
    )}
  • ); })}
); return ( <> {(sortedCrew || sortedCast) && (
media.backdropPath) .map( (media) => `https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${media.backdropPath}` ) .slice(0, 6)} />
)}
{data.profilePath && (
)}

{data.name}

{personAttributes.join(' | ')}
{(data.alsoKnownAs ?? []).length > 0 && (
{intl.formatMessage(messages.alsoknownas, { names: (data.alsoKnownAs ?? []).reduce((prev, curr) => intl.formatMessage(globalMessages.delimitedlist, { a: prev, b: curr, }) ), })}
)}
{data.biography && (
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
setShowBio((show) => !show)} role="button" tabIndex={-1} > } >

{data.biography}

)}
{data.knownForDepartment === 'Acting' ? [cast, crew] : [crew, cast]} {isLoading && } ); }; export default PersonDetails;