All files / src/components/CommentDateGroup index.tsx

100% Statements 67/67
100% Branches 3/3
100% Functions 3/3
100% Lines 67/67

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 1031x     1x           1x 1x     1x 1x 1x 1x     1x                               1x 29x 29x 29x 29x 29x 29x 29x 29x 29x 29x 29x 29x 29x   29x 29x   29x 29x 29x 29x 29x 29x 29x 29x 29x   29x 29x   29x 29x 29x 29x   29x 29x 29x 29x   29x 29x 29x 29x 29x 29x 29x 29x   29x 29x 29x 29x 29x 29x   29x 29x 29x 29x 29x 29x 29x 29x   29x  
import { useState } from 'react';
 
// Constants
import { FALLBACK_SRC } from '@shared/constants';
 
// Types
import { MealCommentDisplay } from '@/types';
 
// Utils
import { combineClasses } from '@shared/utils';
import { formatCommentGroupDate, pluralize } from '@/utils';
 
// Components
import { ImageFallback } from '@/components/common';
import { CommentList } from '@/components/CommentList';
import { CustomDialog } from '@shared/ui';
import { ImageIcon } from '../icons/reacts';
 
// Styles
import './styles/comment-date-group.css';
 
export interface CommentDateGroupProps {
  date: string;
  menuImageUrl: string;
  menuName?: string;
  totalComments: number;
  items: MealCommentDisplay[];
  selectedIds?: Set<string>;
  loadingIds?: Set<string>;
  disabled?: boolean;
  onToggleSelect?: (commentId: string) => void;
  emptyLabel?: string;
  className?: string;
}
 
export const CommentDateGroup = ({
  date,
  menuImageUrl,
  menuName = '',
  totalComments,
  items,
  selectedIds,
  loadingIds,
  disabled = false,
  onToggleSelect,
  emptyLabel,
  className = '',
}: CommentDateGroupProps) => {
  const [isImageOpen, setIsImageOpen] = useState(false);
 
  const handleOpenImage = () => setIsImageOpen(true);
  const handleCloseImage = () => setIsImageOpen(false);
 
  return (
    <div className={combineClasses('comment-date-group-root', className)}>
      <div className="comment-date-group-header">
        <div className="comment-date-group-header-left">
          <button
            type="button"
            aria-label="View meal image"
            onClick={handleOpenImage}
            className="comment-date-group-image-btn"
          >
            <ImageIcon />
          </button>
 
          <span className="comment-date-group-date">
            {formatCommentGroupDate(date)}
          </span>
        </div>
 
        <span className="comment-date-group-count">
          {`${totalComments} ${pluralize(totalComments, 'comment')}`}
        </span>
      </div>
 
      <CommentList
        items={items}
        selectedIds={selectedIds}
        loadingIds={loadingIds}
        disabled={disabled}
        onToggleSelect={onToggleSelect}
        emptyLabel={emptyLabel}
      />
 
      <CustomDialog
        open={isImageOpen}
        onOpenChange={handleCloseImage}
        headerClassName="hidden"
        hideCloseButton
        className="comment-date-group-image-dialog"
      >
        <ImageFallback
          src={menuImageUrl}
          alt={menuName}
          className="comment-date-group-image-full"
          fallbackSrc={FALLBACK_SRC.DEFAULT}
        />
      </CustomDialog>
    </div>
  );
};