99 lines
2.7 KiB
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 }} - </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>
|