All files / src/components/pages/notification/notification-card index.tsx

0% Statements 0/94
0% Branches 0/1
0% Functions 0/1
0% Lines 0/94

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                                                                                                                                                                                             
import { useRouter } from 'next/navigation';

import { Icon } from '@/components/icon';
import { useUpdateNotificationRead } from '@/hooks/use-notification/use-notification-update-read';
import { formatTimeAgo } from '@/lib/formatDateTime';
import { cn } from '@/lib/utils';
import { NotificationItem, NotificationType } from '@/types/service/notification';

interface Props {
  item: NotificationItem;
}

export const NotificationCard = ({ item }: Props) => {
  const router = useRouter();
  const { mutateAsync } = useUpdateNotificationRead();

  const NotificationIcon = IconMap[item.type];
  const title = getTitle(item);
  const description = getDescription(item);
  const timeAgo = getTimeAgo(item);

  const handleNotificationClick = () => {
    try {
      mutateAsync(item.id);

      router.push(`${item.redirectUrl}`);
    } catch {}
  };

  return (
    <article
      className={cn(
        'bg-mono-white flex cursor-pointer flex-row gap-3 px-5 py-6',
        !item.readAt && 'bg-mint-50',
      )}
      onClick={handleNotificationClick}
    >
      <div className={cn('flex-center mt-0.5 size-10 shrink-0 rounded-xl bg-gray-100')}>
        {NotificationIcon}
      </div>
      <div className='w-full'>
        <div className='flex flex-row justify-between'>
          <p className='text-text-md-bold mb-1 text-gray-800'>{title}</p>
          <span className='text-text-xs-medium text-gray-500'>{timeAgo}</span>
        </div>
        <p className='text-gray-600'>{description}</p>
      </div>
    </article>
  );
};

const IconMap: Record<NotificationType, React.ReactNode> = {
  FOLLOW: <Icon id='heart' className='text-mint-500 size-6' />,
  GROUP_CREATE: <Icon id='map-pin-2' className='size-6 text-[#FFBA1A]' />,
  GROUP_DELETE: <Icon id='x-2' className='size-6 text-gray-500' />,
  GROUP_JOIN: <Icon id='symbol' className='text-mint-500 size-6' />,
  EXIT: <Icon id='x-2' className='size-6 text-gray-500' />,
};

const getTitle = (data: NotificationItem) => {
  switch (data.type) {
    case 'FOLLOW':
      return `새 팔로워`;
    case 'GROUP_CREATE':
      return `모임 생성`;
    case 'GROUP_DELETE':
      return `모임 취소`;
    case 'GROUP_JOIN':
      return `모임 현황`;
    case 'EXIT':
      return `모임 현황`;
  }
};

const getDescription = (data: NotificationItem) => {
  // switch (data.type) {
  //   case 'FOLLOW':
  //     return `${data.actorNickname} 님이 팔로우 했습니다.`;
  //   case 'GROUP_CREATE':
  //     return `${data.actorNickname} 님이 "${data.actorNickname}" 모임을 생성했습니다.`;
  //   case 'CANCLE':
  //     return `${data.actorNickname} 님이 "${data.actorNickname}" 모임을 취소했습니다.`;
  //   case 'ENTER':
  //     return `${data.actorNickname} 님이 "${data.actorNickname}" 모임에 참가했습니다.`;
  //   case 'EXIT':
  //     return `${data.actorNickname} 님이 "${data.actorNickname}" 모임을 떠났습니다.`;
  // }
  return data.message;
};

const getTimeAgo = (data: NotificationItem) => {
  const { createdAt } = data;
  return formatTimeAgo(createdAt);
};