vbv/client/src/components/notifications/NotificationList.vue

99 lines
2.7 KiB
Vue

<script setup lang="ts">
import router from "@/router";
import { useNotificationsStore } from "@/stores/notifications";
import type { Notification } from "@/types";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { onMounted, ref, watch } from "vue";
dayjs.extend(relativeTime);
const notificationsStore = useNotificationsStore();
const props = defineProps<{
numNotificationsToShow: number;
}>();
const state = ref({ notifications: [] as Notification[] });
async function loadNotifications() {
state.value.notifications = await notificationsStore.loadNotifications(
props.numNotificationsToShow
);
}
onMounted(async () => {
await loadNotifications();
});
watch(
() => props.numNotificationsToShow,
async () => {
await loadNotifications();
}
);
function onNotificationClick(notification: Notification) {
if (notification.target_url) {
router.push(notification.target_url);
}
}
</script>
<template>
<div
v-if="0 === state.notifications.length"
class="mt-14 mb-14 text-center text-black"
data-cy="no-notifications"
>
{{ $t("notifications.no_notifications") }}
</div>
<li
v-for="(notification, index) in state.notifications"
:key="notification.id"
:data-cy="`notification-idx-${index}`"
class="flex flex-row justify-between border-b border-gray-500 py-4 leading-[45px] last:border-0"
>
<div class="flex flex-row">
<img
v-if="notification.notification_type === 'USER_INTERACTION'"
alt="Notification icon"
class="mr-2 h-[45px] min-w-[45px] rounded-full"
:src="notification.actor_avatar_url ?? undefined"
/>
<it-icon-vbv
v-else
class="it-icon mr-2 h-[45px] min-w-[45px] rounded-full bg-blue-900"
/>
<button
:to="notification.target_url"
class="mr-2 flex flex-col lg:mr-10"
:disabled="null === notification.target_url"
:data-cy="`notification-target-idx-${index}`"
@click="() => onNotificationClick(notification)"
>
<span
class="text-left text-sm leading-6 text-black lg:text-base"
style="hyphens: none"
>
{{ notification.verb }}
</span>
<span class="flex flex-wrap text-sm leading-6 text-gray-500 lg:text-base">
<span v-if="notification.course">{{ notification.course }} -&nbsp;</span>
<span>
{{ dayjs(notification.timestamp).fromNow() }}
</span>
</span>
</button>
</div>
<div v-if="notification.unread" class="leading-[45px]">
<div class="flex h-[45px] flex-row items-center pl-3" data-cy="unread">
<div class="h-[10px] w-[10px] rounded-full bg-blue-500" />
</div>
</div>
</li>
</template>
<style scoped></style>