ActivityListItem.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { formatDistanceToNow } from 'date-fns';
  2. import { useTranslation } from 'next-i18next';
  3. import { type Locale } from 'date-fns/locale';
  4. import { getLocale } from '~/client/util/date-local';
  5. import type { ActivityHasUserId, SupportedActivityActionType } from '~/interfaces/activity';
  6. import { ActivityLogActions } from '~/interfaces/activity';
  7. export const ActivityActionTranslationMap: Record<
  8. SupportedActivityActionType,
  9. string
  10. > = {
  11. [ActivityLogActions.ACTION_PAGE_CREATE]: 'page_create',
  12. [ActivityLogActions.ACTION_PAGE_UPDATE]: 'page_update',
  13. [ActivityLogActions.ACTION_PAGE_DELETE]: 'page_delete',
  14. [ActivityLogActions.ACTION_PAGE_DELETE_COMPLETELY]: 'page_delete_completely',
  15. [ActivityLogActions.ACTION_PAGE_RENAME]: 'page_rename',
  16. [ActivityLogActions.ACTION_PAGE_REVERT]: 'page_revert',
  17. [ActivityLogActions.ACTION_PAGE_DUPLICATE]: 'page_duplicate',
  18. [ActivityLogActions.ACTION_PAGE_LIKE]: 'page_like',
  19. [ActivityLogActions.ACTION_COMMENT_CREATE]: 'comment_create',
  20. };
  21. export const IconActivityTranslationMap: Record<
  22. SupportedActivityActionType,
  23. string
  24. > = {
  25. [ActivityLogActions.ACTION_PAGE_CREATE]: 'add_box',
  26. [ActivityLogActions.ACTION_PAGE_UPDATE]: 'edit',
  27. [ActivityLogActions.ACTION_PAGE_DELETE]: 'delete',
  28. [ActivityLogActions.ACTION_PAGE_DELETE_COMPLETELY]: 'delete_forever',
  29. [ActivityLogActions.ACTION_PAGE_RENAME]: 'label',
  30. [ActivityLogActions.ACTION_PAGE_REVERT]: 'undo',
  31. [ActivityLogActions.ACTION_PAGE_DUPLICATE]: 'content_copy',
  32. [ActivityLogActions.ACTION_PAGE_LIKE]: 'favorite',
  33. [ActivityLogActions.ACTION_COMMENT_CREATE]: 'comment',
  34. };
  35. const translateAction = (action: SupportedActivityActionType): string => {
  36. return ActivityActionTranslationMap[action] || 'unknown_action';
  37. };
  38. const setIcon = (action: SupportedActivityActionType): string => {
  39. return IconActivityTranslationMap[action] || 'question_mark';
  40. };
  41. const calculateTimePassed = (date: Date, locale: Locale): string => {
  42. const timePassed = formatDistanceToNow(date, {
  43. addSuffix: true,
  44. locale,
  45. });
  46. return timePassed;
  47. };
  48. export const ActivityListItem = ({ activity }: { activity: ActivityHasUserId }): JSX.Element => {
  49. const { t, i18n } = useTranslation();
  50. const currentLangCode = i18n.language;
  51. const dateFnsLocale = getLocale(currentLangCode);
  52. const action = activity.action as SupportedActivityActionType;
  53. const keyToTranslate = translateAction(action);
  54. const fullKeyPath = `user_home_page.${keyToTranslate}`;
  55. return (
  56. <div className="activity-row">
  57. <p className="mb-1">
  58. <span className="material-symbols-outlined me-2">{setIcon(action)}</span>
  59. <span className="dark:text-white">
  60. {' '}{t(fullKeyPath)}
  61. </span>
  62. <span className="text-secondary small ms-3">
  63. {calculateTimePassed(activity.createdAt, dateFnsLocale)}
  64. </span>
  65. </p>
  66. </div>
  67. );
  68. };