diff --git a/src/components/AspectRatio/Loading/index.tsx b/src/components/AspectRatio/Loading/index.tsx new file mode 100644 index 0000000..d8bdc60 --- /dev/null +++ b/src/components/AspectRatio/Loading/index.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + +import { SkeletonContainer } from './styles'; + +const AspectRatioLoading: React.FC = () => { + return ; +}; + +export default AspectRatioLoading; diff --git a/src/components/AspectRatio/Loading/styles.ts b/src/components/AspectRatio/Loading/styles.ts new file mode 100644 index 0000000..b3c93be --- /dev/null +++ b/src/components/AspectRatio/Loading/styles.ts @@ -0,0 +1,8 @@ +import styled from 'styled-components'; + +import { Skeleton } from 'components'; + +export const SkeletonContainer = styled(Skeleton)` + width: 100%; + padding-top: 100%; +`; diff --git a/src/components/AspectRatio/index.tsx b/src/components/AspectRatio/index.tsx new file mode 100644 index 0000000..7c0acc8 --- /dev/null +++ b/src/components/AspectRatio/index.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import Props from './types'; +import { Container } from './styles'; + +const AspectRatio: React.FC = ({ + width = 1, + height = 1, + borderRadius = '0', + children, +}) => { + return ( + + {children} + + ); +}; + +export default AspectRatio; diff --git a/src/components/AspectRatio/styles.ts b/src/components/AspectRatio/styles.ts new file mode 100644 index 0000000..aedaaf9 --- /dev/null +++ b/src/components/AspectRatio/styles.ts @@ -0,0 +1,21 @@ +import styled from 'styled-components'; +import Props from './types'; + +export const Container = styled.div` + position: relative; + width: 100%; + padding-top: calc( + (${props => props.height} / ${props => props.width}) * 100% + ); + + overflow: hidden; + border-radius: ${props => props.borderRadius}; + + & > * { + position: absolute; + top: 0; + width: 100%; + height: 100%; + object-fit: cover; + } +`; diff --git a/src/components/AspectRatio/types/index.ts b/src/components/AspectRatio/types/index.ts new file mode 100644 index 0000000..8375eb8 --- /dev/null +++ b/src/components/AspectRatio/types/index.ts @@ -0,0 +1,5 @@ +export default interface Props { + width?: number; + height?: number; + borderRadius?: string; +} diff --git a/src/components/Media/helpers/checkImageMedia.ts b/src/components/Media/helpers/checkImageMedia.ts new file mode 100644 index 0000000..c573a7f --- /dev/null +++ b/src/components/Media/helpers/checkImageMedia.ts @@ -0,0 +1,9 @@ +const checkImageMedia = (media: string): boolean => { + const imageExtensions = ['jpg', 'jpe', 'jpeg', 'png', 'gif']; + + return imageExtensions.some(extension => + media.toUpperCase().endsWith(extension.toUpperCase()), + ); +}; + +export default checkImageMedia; diff --git a/src/components/Media/helpers/index.ts b/src/components/Media/helpers/index.ts new file mode 100644 index 0000000..ae9656a --- /dev/null +++ b/src/components/Media/helpers/index.ts @@ -0,0 +1 @@ +export { default as checkImageMedia } from './checkImageMedia'; diff --git a/src/components/Media/index.tsx b/src/components/Media/index.tsx new file mode 100644 index 0000000..7dd79b9 --- /dev/null +++ b/src/components/Media/index.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +import { checkImageMedia } from 'components/Media/helpers'; +import { AspectRatio, AspectRatioLoading } from 'components'; +import Props from './types'; + +import { LoadingContainer } from './styles'; + +const Media: React.FC = ({ src, ...rest }) => { + return ( + + {checkImageMedia(src) ? ( + media + ) : ( + + ); +}; + +export default Media; diff --git a/src/components/Media/styles.ts b/src/components/Media/styles.ts new file mode 100644 index 0000000..c435cf8 --- /dev/null +++ b/src/components/Media/styles.ts @@ -0,0 +1,10 @@ +import styled from 'styled-components'; + +export const LoadingContainer = styled.div` + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + z-index: -1; +`; diff --git a/src/components/Media/types/index.ts b/src/components/Media/types/index.ts new file mode 100644 index 0000000..c2642a1 --- /dev/null +++ b/src/components/Media/types/index.ts @@ -0,0 +1,5 @@ +import AspectRatioProps from 'components/AspectRatio/types'; + +export default interface MediaProps extends AspectRatioProps { + src: string; +} diff --git a/src/components/Modal/hooks.tsx b/src/components/Modal/hooks.tsx index a4bc2e6..4c981f5 100644 --- a/src/components/Modal/hooks.tsx +++ b/src/components/Modal/hooks.tsx @@ -6,7 +6,8 @@ import React, { useState, } from 'react'; -import ModalContent from 'components/Modal/types/ModalContent'; +import StyleProps from 'components/Modal/types/StyleProps'; +import ModalContent from 'components/Modal/types/ModalProps'; import ContextData from './types/ContextData'; // import Modal from './dtos'; @@ -14,27 +15,34 @@ const ModalContext = createContext({} as ContextData); const ModalProvider: React.FC = ({ children }) => { const [data, setData] = useState(null as any); + const [propsData, setPropsData] = useState({} as StyleProps); const [callbackFunction, setCallbackFunction] = useState(null as any); const [isCallback, setIsCallback] = useState(false); - const setModalContent = useCallback(({ value, callback }: ModalContent) => { - setData(value); + const setModalContent = useCallback( + ({ value, callback, props }: ModalContent) => { + setData(value); + setPropsData(props || ({} as StyleProps)); - if (callback) { - setCallbackFunction(() => callback); - } - }, []); + if (callback) { + setCallbackFunction(() => callback); + } + }, + [], + ); // Dismiss modal and run callback const successCloseModal = useCallback(() => { setIsCallback(true); setData(null as any); + setPropsData({} as StyleProps); }, []); // Dismiss modal without callback const dismissModal = useCallback(() => { setIsCallback(false); setData(null as any); + setPropsData({} as StyleProps); }, []); // Run callback when close modal and reset state @@ -54,6 +62,7 @@ const ModalProvider: React.FC = ({ children }) => { = ({ +const Modal: React.FC = ({ onClose, show, - hideCloseButton = true, + hideCloseButton, children, + fullscreen, + borderRadius, + background, + center, + height, + width, + shadow, }) => { const { modalContent, dismissModal } = useModal(); + const location = useLocation(); const handleDismiss = useCallback(() => { if (onClose) { @@ -29,6 +39,10 @@ const Modal: React.FC = ({ dismissModal(); }, [dismissModal, onClose]); + useEffect(() => { + handleDismiss(); + }, [location]); // eslint-disable-line + if (!modalContent && !children && !show) { return null; } @@ -36,7 +50,7 @@ const Modal: React.FC = ({ return ( - + {!hideCloseButton && ( diff --git a/src/components/Modal/styles.ts b/src/components/Modal/styles.ts index 72c5c1e..276f8be 100644 --- a/src/components/Modal/styles.ts +++ b/src/components/Modal/styles.ts @@ -1,6 +1,7 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import { Color, Size } from 'shared/enums'; +import StyleProps from 'components/Modal/types/StyleProps'; export const Container = styled.div` display: flex; @@ -11,9 +12,9 @@ export const Container = styled.div` left: 0; z-index: 10; - * { + /* * { box-sizing: border-box; - } + } */ `; export const Backdrop = styled.div` @@ -21,26 +22,44 @@ export const Backdrop = styled.div` background-color: rgba(0, 0, 0, 0.4); `; -export const ModalContainer = styled.div` - position: fixed; - width: 1280px; - min-height: 100px; - max-height: calc(min(700px, 100%) - 100px - ${Size.Medium}); +export const ModalContainer = styled.div` + position: absolute; top: 100px; - right: 0; - left: 0; - margin-right: auto; - margin-left: auto; + left: 50%; + transform: translateX(-50%); + + z-index: 15; display: flex; flex-direction: column; align-items: center; - @media (max-width: 1280px) { + max-height: 100%; + overflow: hidden; + + /* height: 100%; */ + + ${props => + props.center && + css` + top: 50% !important; + transform: translate(-50%, -50%); + `} + + ${props => + props.height && + css` + height: ${props.height}; + `} + + + + + /* @media (max-width: 1280px) { width: calc(100% - ${Size.Medium} * 2); - } + } */ @media (max-width: 715px) { /* top: 0; @@ -48,26 +67,25 @@ export const ModalContainer = styled.div` width: 100%; height: 100%; */ } + + `; export const ModalContent = styled.div` display: flex; flex-direction: column; - width: 100%; - min-height: 100px; - max-height: calc(min(700px, 100%) - 100px - ${Size.Medium}); box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); - /* padding: ${Size.Small}; */ background-color: ${Color.Fill}; border-radius: ${Size.Small}; - @media (max-width: 715px) { - top: 0; - left: 0; - width: 100%; - height: 100%; - } + top: 0; + left: 0; + /* width: 100%; */ + /* height: 100%; */ + + max-height: 100%; + overflow: hidden; `; export const CloseContainer = styled.div` @@ -85,8 +103,12 @@ export const CloseButton = styled.img` export const ContentContainer = styled.div` display: flex; - flex: 1; - width: 100%; + align-items: center; + justify-content: center; + /* flex: 1; */ + /* width: 100%; */ overflow: auto; - padding: 10px; + + max-height: 100%; + overflow: hidden; `; diff --git a/src/components/Modal/types/ContextData.ts b/src/components/Modal/types/ContextData.ts index 9331db9..ec87bec 100644 --- a/src/components/Modal/types/ContextData.ts +++ b/src/components/Modal/types/ContextData.ts @@ -1,8 +1,10 @@ -import ModalContent from 'components/Modal/types/ModalContent'; +import ModalProps from 'components/Modal/types/ModalProps'; +import StyleProps from 'components/Modal/types/StyleProps'; export default interface ContextData { modalContent: any; - setModalContent(params: ModalContent): void; + modalProps: StyleProps; + setModalContent(params: ModalProps): void; successCloseModal(): void; dismissModal(): void; } diff --git a/src/components/Modal/types/ModalContent.ts b/src/components/Modal/types/ModalContent.ts deleted file mode 100644 index 1d3d785..0000000 --- a/src/components/Modal/types/ModalContent.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface ModalContent { - value: any; - callback?: any; - dismissCallback?: any; - props?: any; -} diff --git a/src/components/Modal/types/ModalProps.ts b/src/components/Modal/types/ModalProps.ts new file mode 100644 index 0000000..f49912d --- /dev/null +++ b/src/components/Modal/types/ModalProps.ts @@ -0,0 +1,8 @@ +import StyleProps from 'components/Modal/types/StyleProps'; + +export default interface ModalProps { + value: any; + callback?: any; + dismissCallback?: any; + props?: StyleProps; +} diff --git a/src/components/Modal/types/StyleProps.ts b/src/components/Modal/types/StyleProps.ts new file mode 100644 index 0000000..e03186a --- /dev/null +++ b/src/components/Modal/types/StyleProps.ts @@ -0,0 +1,13 @@ +export default interface StyleProps { + fullscreen?: boolean; + borderRadius?: string; + background?: string; + center?: boolean; + height?: string; + width?: string; + shadow?: string; + + hideCloseButton?: boolean; + onClose?: any; + show?: boolean; +} diff --git a/src/components/index.ts b/src/components/index.ts index a3b7b03..47aeebb 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,9 +1,13 @@ export { ColumnLayout, RowLayout, Wrapper, Container } from 'components/Layout'; export { Skeleton } from './Skeleton'; +export { default as AspectRatio } from './AspectRatio'; +export { default as AspectRatioLoading } from './AspectRatio/Loading'; + export { default as Button } from './Button'; export { default as EnvironmentLabel } from './EnvironmentLabel'; export { default as Input } from './Input'; +export { default as Media } from './Media'; export { default as Modal } from './Modal'; export { default as MovieHighlight } from './MovieHighlight'; diff --git a/src/containers/EntityImage/index.tsx b/src/containers/EntityImage/index.tsx index e07c507..585f470 100644 --- a/src/containers/EntityImage/index.tsx +++ b/src/containers/EntityImage/index.tsx @@ -4,9 +4,11 @@ import { BsHeartFill } from 'react-icons/bs'; import { getEntityRoute } from 'shared/helpers'; import { useAuth } from 'domains/Auth/hooks'; +import { useModal } from 'components/Modal/hooks'; import { useFavorite } from 'domains/Favorites/hooks'; import { Color } from 'shared/enums'; +import { Media } from 'components'; import { EntityImageLoading } from 'containers'; import { Container, @@ -16,6 +18,7 @@ import { InfoContainer, InfoTitle, InfoSubtitle, + MediaContainer, } from './styles'; import Props from './types'; @@ -29,10 +32,13 @@ const EntityImage: React.FC = ({ hideSubtitle, showEmpty, isLoading, + showModal, ...entity }) => { const history = useHistory(); + const { setModalContent, successCloseModal } = useModal(); const { user } = useAuth(); + const { favoriteList = [], UpdateFavorite } = useFavorite(); const [isFavorite, setIsFavorite] = useState(entity.favorite); @@ -53,8 +59,29 @@ const EntityImage: React.FC = ({ if (!disabled) { const entityRoute = getEntityRoute(entity.mediaType); history.push(`${entityRoute}/${entity.id}`); + successCloseModal(); } - }, [disabled, history, entity.id, entity.mediaType]); + }, [disabled, history, entity.id, entity.mediaType, successCloseModal]); + + const handleShowModal = useCallback(() => { + setModalContent({ + value: ( + + + + ), + props: { hideCloseButton: true, center: true }, + }); + }, [entity.featuredImage, setModalContent]); + + const handleClick = useCallback(() => { + if (showModal) { + handleShowModal(); + return; + } + + handleRedirect(); + }, [showModal, handleShowModal, handleRedirect]); // Check if entity is in favorite list and change status useEffect(() => { @@ -95,7 +122,7 @@ const EntityImage: React.FC = ({ size={size} showInfo={showInfo} disabled={disabled} - onClick={handleRedirect} + onClick={handleClick} > = ({ disabled, showInfo, hideSubtitle, + showModal, }) => { const itemsContainer = createRef(); const [showPreviousButton, setShowPreviousButton] = useState(false); @@ -112,6 +113,7 @@ const EntityImageList: React.FC = ({ disabled={disabled} showInfo={showInfo} hideSubtitle={hideSubtitle} + showModal={showModal} {...entity} /> ))} diff --git a/src/containers/GlobalComponents/index.tsx b/src/containers/GlobalComponents/index.tsx index 9ad6daf..0a4adde 100644 --- a/src/containers/GlobalComponents/index.tsx +++ b/src/containers/GlobalComponents/index.tsx @@ -4,12 +4,12 @@ import { useModal } from 'components/Modal/hooks'; import { EnvironmentLabel, Modal } from 'components'; const GlobalComponents: React.FC = () => { - const { modalContent } = useModal(); + const { modalContent, modalProps } = useModal(); return ( <> - {modalContent} + {modalContent} ); }; diff --git a/src/containers/Header/index.tsx b/src/containers/Header/index.tsx index 0bb57e9..292e65d 100644 --- a/src/containers/Header/index.tsx +++ b/src/containers/Header/index.tsx @@ -31,6 +31,7 @@ const Header: React.FC = ({ const handleSearch = useCallback(() => { setModalContent({ value: , + props: { hideCloseButton: true }, }); }, [setModalContent]); @@ -53,7 +54,6 @@ const Header: React.FC = ({ variant="icon" theme={theme} color={color} - // onClick={() => setIsSearch(true)} onClick={handleSearch} > @@ -68,8 +68,6 @@ const Header: React.FC = ({ - - {/* setIsSearch(false)} /> */} ); }; diff --git a/src/containers/SearchModal/styles.ts b/src/containers/SearchModal/styles.ts index ebca188..529ae73 100644 --- a/src/containers/SearchModal/styles.ts +++ b/src/containers/SearchModal/styles.ts @@ -5,6 +5,11 @@ export const Container = styled.div` display: flex; flex-direction: column; flex: 1; + padding: ${Size.Small}; + + width: min(1280px, calc(100vw - ${Size.Medium} * 2)); + min-height: 100px; + max-height: calc(min(700px, 100%) - 100px - ${Size.Medium}); `; export const ResultsContainer = styled.div` @@ -12,9 +17,9 @@ export const ResultsContainer = styled.div` flex-direction: column; border-top: 1px solid ${Color.Placeholder}; - max-height: 100%; overflow-y: auto; border-radius: 0 0 ${Size.Small} ${Size.Small}; + max-height: min(600px, 60vh); `; export const LoadingContainer = styled.div` diff --git a/src/domains/Movie/api/Details/index.ts b/src/domains/Movie/api/Details/index.ts index e185c1b..95912be 100644 --- a/src/domains/Movie/api/Details/index.ts +++ b/src/domains/Movie/api/Details/index.ts @@ -31,7 +31,10 @@ export const rawPopular = async ( params?: Params, ): Promise => { const response = await tmdb.get(`/movie/${movieId}`, { - params: { append_to_response: params?.appendToResponse }, + params: { + append_to_response: params?.appendToResponse, + include_image_language: params?.includeImageLanguage || 'pt,en,null', + }, }); return response.data; diff --git a/src/domains/Movie/api/Details/types/Params.ts b/src/domains/Movie/api/Details/types/Params.ts index e1d07a0..105454f 100644 --- a/src/domains/Movie/api/Details/types/Params.ts +++ b/src/domains/Movie/api/Details/types/Params.ts @@ -1,3 +1,4 @@ export default interface Params { appendToResponse?: string; + includeImageLanguage?: string; } diff --git a/src/domains/Person/api/Details/index.ts b/src/domains/Person/api/Details/index.ts index 3127c77..8b0c597 100644 --- a/src/domains/Person/api/Details/index.ts +++ b/src/domains/Person/api/Details/index.ts @@ -97,7 +97,16 @@ const parseResponse = (person: RawResponse): Response => { Date.parse(a.originalDate) < Date.parse(b.originalDate) ? 1 : -1, ); - parsedPerson = { ...parsedPerson, knownFor, filmography }; + const images = person.images?.profiles.map(image => ({ + aspectRatio: image.aspect_ratio, + featuredImage: getFeaturedImage(image) || undefined, + height: image.height, + voteAverage: image.vote_average, + voteCount: image.vote_count, + width: image.width, + })); + + parsedPerson = { ...parsedPerson, knownFor, filmography, images }; return parsedPerson; }; diff --git a/src/domains/Person/api/Details/types/RawResponse.ts b/src/domains/Person/api/Details/types/RawResponse.ts index 493a171..c9896cc 100644 --- a/src/domains/Person/api/Details/types/RawResponse.ts +++ b/src/domains/Person/api/Details/types/RawResponse.ts @@ -20,5 +20,16 @@ export default interface RawResponse { imdb_id: string; homepage?: string; + images?: { + profiles: Array<{ + aspect_ratio: number; + file_path: string; + height: number; + vote_average: number; + vote_count: number; + width: number; + }>; + }; + combined_credits?: { cast: RawMovie[] }; } diff --git a/src/domains/Person/api/Details/types/Response.ts b/src/domains/Person/api/Details/types/Response.ts index 03b48fa..591d3bc 100644 --- a/src/domains/Person/api/Details/types/Response.ts +++ b/src/domains/Person/api/Details/types/Response.ts @@ -21,6 +21,15 @@ export default interface Response { knownFor?: Movie[]; filmography?: Movie[]; + images?: Array<{ + aspectRatio: number; + featuredImage?: string; + height: number; + voteAverage: number; + voteCount: number; + width: number; + }>; + favorite: boolean; mediaType: number; featuredImage?: string; diff --git a/src/domains/Tv/api/Details/index.ts b/src/domains/Tv/api/Details/index.ts index b6dd10c..86a1f78 100644 --- a/src/domains/Tv/api/Details/index.ts +++ b/src/domains/Tv/api/Details/index.ts @@ -31,7 +31,10 @@ export const rawPopular = async ( params?: Params, ): Promise => { const response = await tmdb.get(`/tv/${tvId}`, { - params: { append_to_response: params?.appendToResponse }, + params: { + append_to_response: params?.appendToResponse, + include_image_language: params?.includeImageLanguage || 'pt,en,null', + }, }); return response.data; @@ -47,11 +50,10 @@ const parseResponse = (tv: RawResponse): Response => { popularity: tv.popularity, voteCount: tv.vote_count, voteAverage: tv.vote_average, + tagline: tv.tagline, runtime: `${tv.episode_run_time} min`, - directorName: tv.credits?.crew.find( - person => person.job.toUpperCase() === 'DIRECTOR', - )?.name, + creatorName: tv.created_by[0]?.name, releaseDate: getReleaseDate(tv), backdrop: getBackdrop(tv), diff --git a/src/domains/Tv/api/Details/types/Params.ts b/src/domains/Tv/api/Details/types/Params.ts index e1d07a0..105454f 100644 --- a/src/domains/Tv/api/Details/types/Params.ts +++ b/src/domains/Tv/api/Details/types/Params.ts @@ -1,3 +1,4 @@ export default interface Params { appendToResponse?: string; + includeImageLanguage?: string; } diff --git a/src/domains/Tv/api/Details/types/RawResponse.ts b/src/domains/Tv/api/Details/types/RawResponse.ts index 98ec1a9..69892cd 100644 --- a/src/domains/Tv/api/Details/types/RawResponse.ts +++ b/src/domains/Tv/api/Details/types/RawResponse.ts @@ -18,9 +18,12 @@ export default interface RawResponse { name: string; backdrop_path?: string; popularity: number; + tagline: string; episode_run_time: number; vote_count: number; vote_average: number; + created_by: any[]; + recommendations?: { results: Recommendations[]; }; diff --git a/src/domains/Tv/api/Details/types/Response.ts b/src/domains/Tv/api/Details/types/Response.ts index c4d61ed..446f53e 100644 --- a/src/domains/Tv/api/Details/types/Response.ts +++ b/src/domains/Tv/api/Details/types/Response.ts @@ -17,9 +17,11 @@ export default interface Response { id: number; originalTitle: string; popularity: number; + tagline: string; runtime: string; voteCount: number; voteAverage: number; + creatorName: string; recommendations?: Recommendations[]; credits?: Credits; diff --git a/src/pages/Movie/styles.ts b/src/pages/Movie/styles.ts index 31259ab..5feffad 100644 --- a/src/pages/Movie/styles.ts +++ b/src/pages/Movie/styles.ts @@ -49,10 +49,10 @@ export const MovieDetailsContainer = styled.div` display: flex; flex: 1; flex-direction: column; - justify-content: space-between; color: ${Color.Text}; margin-top: ${Size.Large}; - /* padding: ${Size.Medium}; */ + width: 100%; + justify-content: space-between; @media (min-width: 715px) { height: 50rem; diff --git a/src/pages/Person/index.tsx b/src/pages/Person/index.tsx index 6eb257c..3a980f7 100644 --- a/src/pages/Person/index.tsx +++ b/src/pages/Person/index.tsx @@ -119,6 +119,16 @@ const Person: React.FC = () => { message="Recomendações indisponíveis." /> + {person?.images && ( + + )} + = () => { const { id } = useParams(); - const [tv, setMovie] = useState({} as MovieDetails); + const [tv, setTv] = useState({} as TvDetails); const [isLoading, setIsLoading] = useState(false); const { user } = useAuth(); const { Favorites, favoriteList } = useFavorite(); - const getMovie = useCallback(async () => { + const getTv = useCallback(async () => { try { setIsLoading(true); const params = { @@ -51,10 +52,10 @@ const Tv: React.FC = () => { const response = await Details(+id, params); - setMovie(response); + setTv(response); return response; } catch (error) { - console.log('getMovie -> error', error); + console.log('getTv -> error', error); } finally { setIsLoading(false); } @@ -62,8 +63,8 @@ const Tv: React.FC = () => { useEffect(() => { window.scrollTo(0, 0); - getMovie(); - }, [getMovie]); + getTv(); + }, [getTv]); useEffect(() => { if (user) { @@ -82,7 +83,7 @@ const Tv: React.FC = () => { - + = () => { {isLoading && } {!isLoading && ( - + {tv.title} {tv.releaseDate} | {tv.genresNames} | {tv.runtime} + {tv.tagline && {`"${tv.tagline}"`}} Sinopse {tv.overview} @@ -112,13 +114,13 @@ const Tv: React.FC = () => { Votação do público:{' '} {tv.voteAverage} - - Diretor: - {tv.directorName} - - + + Criador: + {tv.creatorName} + + )} - + { return formatTmdbImage({ - value: value.poster_path || value.profile_path, + value: value.poster_path || value.profile_path || value.file_path, }); };