All files / src/view/pages/MainPage/DetailPage DetailPage.tsx

0% Statements 0/51
0% Branches 0/1
0% Functions 0/1
0% Lines 0/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64                                                                                                                               
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { ICharacter, IEpisode } from '@/shared/types/character';
import { getCharacterById, getCharactersByUrls, getEpisodesByUrls, getLocationByUrl } from './DetailPage.service';
import CharacterInfo from './CharacterInfo/CharacterInfo';
import EpisodesTimeline from './EpisodesTimeline/EpisodesTimeline';
import RelatedCharacters from './RelatedCharacters/RelatedCharacters';
import CharacterHero from './CharacterHero/CharacterHero';
import { forkJoin, of, switchMap, tap } from 'rxjs';
import './DetailPage.scss';
 
const DetailPage = () => {
  const { id } = useParams();
  const [character, setCharacter] = useState<ICharacter | null>(null);
  const [episodes, setEpisodes] = useState<IEpisode[]>([]);
  const [related, setRelated] = useState<ICharacter[]>([]);
 
  useEffect(() => {
    if (!id) return;
 
    const subscription = getCharacterById(id)
      .pipe(
        tap((char) => setCharacter(char)),
        switchMap((char) => {
          const episode$ = getEpisodesByUrls(char.episode);
          const related$ = char.location?.url
            ? getLocationByUrl(char.location.url).pipe(
                switchMap((loc) => {
                  const urls = loc.residents.filter((url) => url !== char.url).slice(0, 6);
                  return urls.length ? getCharactersByUrls(urls) : of([]);
                })
              )
            : of([]);
 
          return forkJoin([episode$, related$]);
        })
      )
      .subscribe({
        next: ([ep, relatedChars]) => {
          setEpisodes(ep);
          setRelated(relatedChars);
        },
        error: (err) => console.error('DetailPage error', err),
      });
 
    return () => subscription.unsubscribe();
  }, [id]);
  if (!character) return <div className="loading">Loading...</div>;
 
  return (
    <div className="detail-page">
      <CharacterHero character={character ?? {}} />
 
      <CharacterInfo character={character ?? {}} />
 
      <EpisodesTimeline episodes={episodes ?? []} />
 
      <RelatedCharacters characters={related ?? []} />
    </div>
  );
};
 
export default DetailPage;