All files / src/components/Card index.tsx

100% Statements 10/10
77.77% Branches 7/9
100% Functions 3/3
100% Lines 10/10

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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                  4x                     41x   41x 32x                           9x 5x                               4x                             4x                                 41x                             105x                            
import React from "react";
import { Link, withPrefix } from "gatsby";
 
import Tag from "@/components/Tag";
 
import { parseImgur, SizeMapping } from "@/utils/images";
 
import * as style from "./index.module.scss";
 
const CardHeader = ({
  url,
  image,
  title,
  index,
}: {
  url: string;
  image: string;
  title: string;
  index: number;
}) => {
  const imageUrl = parseImgur(image, SizeMapping.large);
 
  if (index > 1) {
    return (
      <Link to={url}>
        <span className="visually-hidden">{title}</span>
        <div
          className={style.wrapper + " lozad"}
          data-background-image={imageUrl}
          aria-hidden="true"
          data-testid="card-header"
        />
      </Link>
    );
  }
 
  // For the first image (LCP), use img tag with eager loading and high priority
  if (index === 0) {
    return (
      <Link to={url} className={style.imageLink}>
        <span className="visually-hidden">{title}</span>
        <img
          src={imageUrl}
          alt=""
          className={style.wrapper}
          loading="eager"
          fetchPriority="high"
          data-testid="card-header"
        />
      </Link>
    );
  }
 
  // For other early images, keep the existing background-image approach
  return (
    <Link to={url}>
      <span className="visually-hidden">{title}</span>
      <div
        className={style.wrapper}
        style={{
          backgroundImage: ` url(${imageUrl})`,
        }}
        aria-hidden="true"
        data-testid="card-header"
      />
    </Link>
  );
};
 
const Card = ({
  title,
  date,
  url,
  headerImage,
  description,
  tags = [],
  index,
}: {
  title: string;
  date: string;
  url: string;
  headerImage?: string;
  description: string;
  tags: readonly (string | undefined)[];
  index: number;
}) => (
  <div className="col-sm-12 pb-4" data-testid="card">
    <div className={style.customCard}>
      {headerImage && (
        <CardHeader
          url={withPrefix(url)}
          image={headerImage}
          title={title}
          index={index}
        />
      )}
      <div className={style.data}>
        <div className={style.dataContent}>
          <div className={style.stats}>
            <span className={style.date}>{date?.split("T")[0]}</span>
            {tags.map((name, index) => (
              <Tag name={name || ""} key={`${name}-${index}`} />
            ))}
          </div>
          <Link to={withPrefix(url)}>
            <h3 className={style.title}>{title}</h3>
          </Link>
          <p>{description}</p>
        </div>
      </div>
    </div>
  </div>
);
 
export default Card;