src/app/components/RelatedContentSection/RelatedContentItem/index.tsx

Summary

Maintainability
A
35 mins
Test Coverage
A
100%
/** @jsx jsx */

import { jsx } from '@emotion/react';
import { forwardRef } from 'react';
import path from 'ramda/src/path';
import pathOr from 'ramda/src/pathOr';
import { createSrcsets } from '#lib/utilities/srcSet';
import buildIChefURL from '#app/lib/utilities/ichefURL';
import Promo from '#components/OptimoPromos';
import isEmpty from 'ramda/src/isEmpty';
import styles from './index.styles';
import { EventTrackingBlock } from '../../../models/types/eventTracking';

type RelatedContentItemProps = {
  item: object;
  ariaLabelledBy: string;
  eventTrackingData?: EventTrackingBlock;
};

const RelatedContentItem = forwardRef<HTMLDivElement, RelatedContentItemProps>(
  ({ item, ariaLabelledBy, eventTrackingData = null }, viewRef) => {
    if (!item || isEmpty(item)) return null;

    const headlineFirst = pathOr<string>(
      '',
      ['model', 'blocks', 0, 'model', 'blocks', 0, 'model', 'text'],
      item,
    );
    const headlineSecond = pathOr<string>(
      '',
      ['model', 'blocks', 1, 'model', 'blocks', 0, 'model', 'text'],
      item,
    );

    const headline = headlineFirst || headlineSecond;

    const assetUriFirst = pathOr<string>(
      '',
      [
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'locator',
      ],
      item,
    );

    const assetUriSecond = pathOr<string>(
      '',
      [
        'model',
        'blocks',
        1,
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'locator',
      ],
      item,
    );

    const assetUri = assetUriFirst || assetUriSecond;

    const DEFAULT_IMAGE_RES = 660;
    const imageResolutions = [70, 95, 144, 183, 240, 320, 660];
    const locatorDefault = path(
      ['model', 'blocks', 0, 'model', 'blocks', 1, 'model', 'locator'],
      item,
    );

    const locatorWithCaption = path(
      ['model', 'blocks', 0, 'model', 'blocks', 2, 'model', 'locator'],
      item,
    );

    const locator = locatorDefault || locatorWithCaption;

    const originCodeDefault = path(
      ['model', 'blocks', 0, 'model', 'blocks', 1, 'model', 'originCode'],
      item,
    );

    const originCodeWithCaption = path(
      ['model', 'blocks', 0, 'model', 'blocks', 2, 'model', 'originCode'],
      item,
    );

    const originCode = originCodeDefault || originCodeWithCaption;

    const altText = pathOr<string>(
      '',
      [
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'blocks',
        0,
        'model',
        'text',
      ],
      item,
    );

    const width = pathOr<number>(
      240,
      ['model', 'blocks', 0, 'model', 'blocks', 1, 'model', 'width'],
      item,
    );

    const height = pathOr<number>(
      0,
      ['model', 'blocks', 0, 'model', 'blocks', 1, 'model', 'height'],
      item,
    );

    const { primarySrcset, fallbackSrcset } = createSrcsets({
      originCode,
      locator,
      originalImageWidth: width,
      imageResolutions,
    });

    const src = buildIChefURL({
      originCode,
      locator,
      resolution: DEFAULT_IMAGE_RES,
    });

    const timestamp = pathOr<string>(
      '',
      ['model', 'blocks', 2, 'model', 'blocks', 0, 'model', 'timestamp'],
      item,
    );

    const titleTag = timestamp ? 'h3' : 'div';

    const titleHasContent = titleTag === 'h3';

    return (
      <div
        css={[styles.wrapper, headlineFirst && styles.promoFullWidth]}
        ref={viewRef}
      >
        <Promo
          to={assetUri}
          ariaLabelledBy={ariaLabelledBy}
          eventTrackingData={eventTrackingData}
        >
          {locator ? (
            <Promo.Image
              src={src}
              altText={altText}
              srcset={primarySrcset}
              fallbackSrcset={fallbackSrcset}
              width={width}
              height={height}
            />
          ) : null}
          <Promo.ContentWrapper>
            <Promo.Title
              css={titleHasContent ? styles.promoTitle : null}
              as={titleTag}
            >
              <Promo.Link>
                <Promo.Content headline={headline} />
              </Promo.Link>
            </Promo.Title>
            <Promo.Timestamp css={styles.promoTimestamp}>
              {timestamp}
            </Promo.Timestamp>
          </Promo.ContentWrapper>
        </Promo>
      </div>
    );
  },
);

export default RelatedContentItem;