All files / components/chat file-preview-card.tsx

100% Statements 4/4
100% Branches 2/2
100% Functions 1/1
100% Lines 4/4

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 484x                   4x             13x 13x                                                          
import { XMarkIcon } from "@/components/icons/XMark";
import type { FilePreviewType } from "@/utils/file-type";
 
type FilePreviewCardProps = {
  fileName: string;
  fileType?: FilePreviewType;
  onRemove?: () => void;
  onPreview: () => void;
};
 
const FILE_TYPE_CONFIG: Record<FilePreviewType, { label: string; bg: string }> = {
  pdf:   { label: "PDF",   bg: "bg-red-500 hover:bg-red-400" },
  image: { label: "IMG",   bg: "bg-violet-500 hover:bg-violet-400" },
  video: { label: "VID",   bg: "bg-blue-500 hover:bg-blue-400" },
  audio: { label: "AUD",   bg: "bg-amber-500 hover:bg-amber-400" },
};
 
export function FilePreviewCard({ fileName, fileType = "pdf", onPreview, onRemove }: FilePreviewCardProps) {
  const { label, bg } = FILE_TYPE_CONFIG[fileType];
 
  return (
    <div className="flex w-fit max-w-xs items-center gap-3 rounded-xl border border-white/10 bg-white/6 px-3 py-2.5 light:border-slate-200 light:bg-slate-50">
      <button
        type="button"
        aria-label="Preview file"
        onClick={onPreview}
        className={`inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-[10px] font-bold text-white transition ${bg}`}
      >
        {label}
      </button>
      <div className="min-w-0 flex-1 cursor-pointer" onClick={onPreview}>
        <p className="truncate text-sm font-medium text-white/85 light:text-slate-800">{fileName}</p>
        <p className="text-xs text-white/40 light:text-slate-400">{label}</p>
      </div>
      {onRemove && (
        <button
          type="button"
          aria-label="Remove file"
          onClick={onRemove}
          className="grid h-5 w-5 shrink-0 place-items-center rounded-full bg-white/20 text-white/70 transition hover:bg-white/30 hover:text-white light:bg-slate-200 light:text-slate-500 light:hover:bg-slate-300"
        >
          <XMarkIcon className="size-3" />
        </button>
      )}
    </div>
  );
}