All files / src/utils menuFeedback.ts

100% Statements 70/70
100% Branches 31/31
100% Functions 5/5
100% Lines 70/70

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 961x               1x 1x 1x           1x 13x 13x 13x 13x 13x   13x 4x 13x 3x 3x   13x 13x   1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x 6x 7x 7x   1x 31x 31x 31x 31x 31x 31x 31x 31x 31x 1x 30x 31x 31x   1x         3x 3x 3x 3x 3x 1x 2x 3x 3x 3x     1x 3x 3x 3x 3x 3x 3x   3x 1x 1x   2x 2x  
import {
  CommentListItemResponse,
  ExportFormat,
  FeedbackVisibility,
  MealCommentCardProps,
  MealCommentDisplay,
  MealMenuComment,
} from '@/types';
import { EXPORT_FILENAME_PREFIX } from '@/constants';
import { normalizeDateString } from './date';
import { sentimentStore } from '@/stores/sentiment';
 
/**
 * Builds the comments export filename, optionally tagged with the selected date(s).
 * Example: Feedback_Report_2026-06-01_to_2026-06-12.xlsx
 *  */
export const buildExportFilename = (
  format: ExportFormat,
  fromDate?: string,
  toDate?: string,
): string => {
  let dateRange = '';
 
  if (fromDate && toDate && fromDate !== toDate) {
    dateRange = `_${fromDate}_to_${toDate}`;
  } else if (fromDate || toDate) {
    dateRange = `_${fromDate ?? toDate}`;
  }
 
  return `${EXPORT_FILENAME_PREFIX}${dateRange}.${format}`;
};
 
export const mapMealCommentToCardProps = (
  comment: MealMenuComment,
  userName: string,
  avatarUrl: string,
): MealCommentDisplay => ({
  isComment: true,
  commentId: comment.id,
  feedback: comment.content,
  createdTime: normalizeDateString(comment.createdAt),
  authorName: userName,
  avatarUrl,
  visibility: comment.isAnonymous
    ? FeedbackVisibility.Anonymous
    : FeedbackVisibility.Public,
  feedbackSentiment: comment.sentiment ?? null,
});
 
export const mapCommentListItemToDisplay = (
  item: CommentListItemResponse,
): MealCommentDisplay => ({
  isComment: true,
  commentId: item.id,
  feedback: item.content,
  createdTime: normalizeDateString(item.createdAt),
  authorName: item.isAnonymous ? '' : (item.userInfo?.name ?? ''),
  avatarUrl: item.isAnonymous ? '' : (item.userInfo?.avatar ?? ''),
  visibility: item.isAnonymous
    ? FeedbackVisibility.Anonymous
    : FeedbackVisibility.Public,
  feedbackSentiment: item.sentiment,
});
 
export const syncCommentToDisplay = (comment: {
  id: string;
  content: string;
  isAnonymous: boolean;
  sentiment: string | null;
}) => {
  if (comment.sentiment) sentimentStore.setData(comment.id, comment.sentiment);
  return {
    feedback: comment.content,
    visibility: comment.isAnonymous
      ? FeedbackVisibility.Anonymous
      : FeedbackVisibility.Public,
    sentiment: comment.sentiment,
  };
};
 
/** Resolves Card comment props for a menu day from the fetched comments list. */
export const getMealCommentCardProps = (
  menuId: string,
  comments: MealMenuComment[],
  userName = '',
  avatarUrl = '',
): MealCommentCardProps => {
  const comment = comments.find((entry) => entry.menuId === menuId);
 
  if (!comment) {
    return { isComment: false };
  }
 
  return mapMealCommentToCardProps(comment, userName, avatarUrl);
};