dashpresshq/dashpress

View on GitHub
src/frontend/views/Dashboard/Widget/_render/Summary/Presentation.tsx

Summary

Maintainability
A
25 mins
Test Coverage
import type { Icon } from "react-feather";
import { ChevronsDown, ChevronsUp } from "react-feather";

import { SystemIcon } from "@/components/app/system-icons";
import type { SpectrumColorTypes } from "@/components/ui/spectrum";
import { spectrumVariants } from "@/components/ui/spectrum";
import { cn } from "@/components/utils";
import type { SystemIconsKeys } from "@/shared/constants/Icons";

const DirectionImplementation: Record<
  "up" | "down" | "side",
  {
    label: string;
    Icon: Icon;
  }
> = {
  down: {
    Icon: ChevronsDown,
    label: "Down",
  },
  up: {
    Icon: ChevronsUp,
    label: "Up",
  },
  side: {
    Icon: () => null,
    label: "Side",
  },
};

export interface IProps {
  title: string;
  color: SpectrumColorTypes;
  fullCount: string;
  relativeCount: string;
  icon: string;
  direction: "up" | "down" | "side";
}

export function SummaryWidgetPresentation({
  color,
  fullCount,
  relativeCount,
  title,
  direction,
  icon,
}: IProps) {
  const { Icon: DirectionIcon, label: directionLabel } =
    DirectionImplementation[direction];

  return (
    <div className="flex items-center gap-4">
      <SystemIcon
        icon={icon as SystemIconsKeys}
        className={cn(
          "size-10 min-w-10 rounded-full p-2",
          spectrumVariants({
            spectrum: color,
          })
        )}
        label={`${title} Icon`}
      />
      <div className="w-full pt-1">
        <div className="flex items-end justify-between">
          <p className="text-xl font-semibold" aria-label="Total Count">
            {fullCount}
          </p>
          {relativeCount ? (
            <div
              className={cn(
                "flex w-auto items-center gap-0.5 rounded-lg border px-1",
                spectrumVariants({
                  spectrum:
                    // eslint-disable-next-line no-nested-ternary
                    direction === "up"
                      ? "green"
                      : direction === "down"
                      ? "red"
                      : "gray",
                })
              )}
              aria-label="Relative Direction"
            >
              <span aria-label={directionLabel}>
                <DirectionIcon
                  size={20}
                  className={cn("align-sub", {
                    "text-green-600": direction === "up",
                    "text-red-600": direction === "down",
                  })}
                />
              </span>

              <p
                className={cn("text-xs font-semibold leading-5", {
                  "text-green-600": direction === "up",
                  "text-red-600": direction === "down",
                })}
                aria-label="Relative Count"
              >
                {relativeCount}
              </p>
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}