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 117 118 119                  5x                     51x   51x 40x                             11x 6x                               5x                               5x                                 51x                             141x                              
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}
          title={title}
          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})`,
        }}
        title={title}
        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>
          <Link to={withPrefix(url)}>....Read more....</Link>
        </div>
      </div>
    </div>
  </div>
);
 
export default Card;