|
|
@@ -1,9 +1,10 @@
|
|
|
import { formatDistanceToNow } from 'date-fns';
|
|
|
-import { useTranslation } from 'next-i18next';
|
|
|
import { type Locale } from 'date-fns/locale';
|
|
|
-import { getLocale } from '~/server/util/locale-utils';
|
|
|
-import type { ActivityHasUserId, SupportedActivityActionType } from '~/interfaces/activity';
|
|
|
+import { useTranslation } from 'next-i18next';
|
|
|
+
|
|
|
+import type { SupportedActivityActionType, ActivityHasTargetPage } from '~/interfaces/activity';
|
|
|
import { ActivityLogActions } from '~/interfaces/activity';
|
|
|
+import { getLocale } from '~/server/util/locale-utils';
|
|
|
|
|
|
|
|
|
export const ActivityActionTranslationMap: Record<
|
|
|
@@ -36,6 +37,18 @@ export const IconActivityTranslationMap: Record<
|
|
|
[ActivityLogActions.ACTION_COMMENT_CREATE]: 'comment',
|
|
|
};
|
|
|
|
|
|
+type ActivityListItemProps = {
|
|
|
+ activity: ActivityHasTargetPage,
|
|
|
+}
|
|
|
+
|
|
|
+type AllowPageDisplayPayload = {
|
|
|
+ grant: number | undefined,
|
|
|
+ status: string,
|
|
|
+ wip: boolean,
|
|
|
+ deletedAt?: Date,
|
|
|
+ path: string,
|
|
|
+}
|
|
|
+
|
|
|
const translateAction = (action: SupportedActivityActionType): string => {
|
|
|
return ActivityActionTranslationMap[action] || 'unknown_action';
|
|
|
};
|
|
|
@@ -53,29 +66,85 @@ const calculateTimePassed = (date: Date, locale: Locale): string => {
|
|
|
return timePassed;
|
|
|
};
|
|
|
|
|
|
+const pageAllowedForDisplay = (allowDisplayPayload: AllowPageDisplayPayload): boolean => {
|
|
|
+ const {
|
|
|
+ grant, status, wip, deletedAt,
|
|
|
+ } = allowDisplayPayload;
|
|
|
+ if (grant !== 1) return false;
|
|
|
+
|
|
|
+ if (status !== 'published') return false;
|
|
|
+
|
|
|
+ if (wip) return false;
|
|
|
+
|
|
|
+ if (deletedAt) return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+const setPath = (path: string, allowed: boolean): string => {
|
|
|
+ if (allowed) return path;
|
|
|
|
|
|
-export const ActivityListItem = ({ activity }: { activity: ActivityHasUserId }): JSX.Element => {
|
|
|
+ return '';
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+export const ActivityListItem = ({ props }: { props: ActivityListItemProps }): JSX.Element => {
|
|
|
const { t, i18n } = useTranslation();
|
|
|
const currentLangCode = i18n.language;
|
|
|
const dateFnsLocale = getLocale(currentLangCode);
|
|
|
|
|
|
+ const { activity } = props;
|
|
|
+
|
|
|
+ const {
|
|
|
+ path, grant, status, wip, deletedAt,
|
|
|
+ } = activity.target;
|
|
|
+
|
|
|
+
|
|
|
+ const allowDisplayPayload: AllowPageDisplayPayload = {
|
|
|
+ grant,
|
|
|
+ status,
|
|
|
+ wip,
|
|
|
+ deletedAt,
|
|
|
+ path,
|
|
|
+ };
|
|
|
+
|
|
|
+ const isPageAllowed = pageAllowedForDisplay(allowDisplayPayload);
|
|
|
+
|
|
|
const action = activity.action as SupportedActivityActionType;
|
|
|
const keyToTranslate = translateAction(action);
|
|
|
const fullKeyPath = `user_home_page.${keyToTranslate}`;
|
|
|
|
|
|
return (
|
|
|
<div className="activity-row">
|
|
|
- <p className="mb-1">
|
|
|
- <span className="material-symbols-outlined me-2">{setIcon(action)}</span>
|
|
|
-
|
|
|
- <span className="dark:text-white">
|
|
|
- {' '}{t(fullKeyPath)}
|
|
|
+ <div className="d-flex align-items-center">
|
|
|
+ <span className="material-symbols-outlined me-2 flex-shrink-0">
|
|
|
+ {setIcon(action)}
|
|
|
</span>
|
|
|
|
|
|
- <span className="text-secondary small ms-3">
|
|
|
- {calculateTimePassed(activity.createdAt, dateFnsLocale)}
|
|
|
- </span>
|
|
|
- </p>
|
|
|
+ <div className="flex-grow-1 ms-2">
|
|
|
+ <div className="activity-path-line mb-0">
|
|
|
+ <a
|
|
|
+ href={setPath(path, isPageAllowed)}
|
|
|
+ className="activity-target-link fw-bold text-wrap d-block"
|
|
|
+ >
|
|
|
+ <span>
|
|
|
+ {setPath(path, isPageAllowed)}
|
|
|
+ </span>
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="activity-details-line d-flex">
|
|
|
+ <span>
|
|
|
+ {t(fullKeyPath)}
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <span className="text-secondary small ms-3 align-self-center">
|
|
|
+ {calculateTimePassed(activity.createdAt, dateFnsLocale)}
|
|
|
+ </span>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
);
|
|
|
};
|