All files / src/utils commentGrouping.ts

100% Statements 39/39
100% Branches 12/12
100% Functions 2/2
100% Lines 39/39

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    1x 1x             1x 47x 47x 47x 47x   47x 21x 21x 21x 2x 21x 19x 19x 21x   47x 47x 47x 19x     19x 19x 19x 19x 47x 47x       1x 4x 4x   4x   5x     5x   5x 5x 5x 5x 5x 5x 5x  
import { CommentDateGroupProps } from '@/components/CommentDateGroup';
import { CommentListItemResponse, Meal } from '@/types';
import { formatDateToISODateString } from './date';
import { mapCommentListItemToDisplay } from './menuFeedback';
 
/**
 * Builds a `CommentDateGroupProps[]` from a flat comment list returned by the
 * date-range API. Comments are grouped by their `date` field; groups are sorted
 * chronologically. Menu images are resolved from `menuImageByMenuId`.
 */
export const groupCommentsByDate = (
  comments: CommentListItemResponse[],
  menuImageByMenuId: Record<string, string>,
): CommentDateGroupProps[] => {
  const groupMap = new Map<string, CommentListItemResponse[]>();
 
  for (const comment of comments) {
    const key = formatDateToISODateString(comment.date as string | Date);
    const existing = groupMap.get(key);
    if (existing) {
      existing.push(comment);
    } else {
      groupMap.set(key, [comment]);
    }
  }
 
  return Array.from(groupMap.entries())
    .sort(([a], [b]) => b.localeCompare(a))
    .map(([date, items]) => ({
      date,
      // Prefer the image carried inline on each list item (correct for any
      // selected range); fall back to the current-week menu map for safety.
      menuImageUrl:
        items[0]?.image || menuImageByMenuId[items[0]?.menuId ?? ''] || '',
      totalComments: items.length,
      items: items.map(mapCommentListItemToDisplay),
    }));
};
 
export type CommentsByMenuId = Record<string, CommentListItemResponse[]>;
 
export const groupCommentsByMenu = (
  meals: Meal[],
  commentsByMenuId: CommentsByMenuId,
): CommentDateGroupProps[] =>
  meals.map((meal) => {
    // Raw API items for this menu, defaulting to empty when not yet loaded.
    const rawItems = commentsByMenuId[meal.id] ?? [];
 
    // Convert each API item to the display model consumed by CommentList.
    const items = rawItems.map(mapCommentListItemToDisplay);
 
    return {
      date: meal.date,
      menuImageUrl: meal.image,
      totalComments: items.length,
      items,
    };
  });