192 lines
4.6 KiB
Vue
192 lines
4.6 KiB
Vue
<template>
|
|
<article
|
|
:id="`comment-${comment.id}`"
|
|
class="comment | flow"
|
|
:data-status="status"
|
|
@click="read()"
|
|
>
|
|
<header>
|
|
<p>
|
|
<strong>{{ comment.author.name ?? comment.author.email }}</strong>
|
|
<template v-if="commentIndex">
|
|
<span class="comment__id">#{{ commentIndex }}</span>
|
|
•
|
|
</template>
|
|
<span class="comment__page">Page {{ comment.position.pageIndex }}</span>
|
|
<time
|
|
class="comment__date"
|
|
:datetime="dayjs(comment.date).format('YYYY-MM-DD')"
|
|
>{{ formatDate() }}</time
|
|
>
|
|
</p>
|
|
</header>
|
|
<p class="comment__body">
|
|
{{ comment.text }}
|
|
</p>
|
|
<footer class="comment__replies">
|
|
<p v-if="comment.replies?.length > 0">
|
|
{{ comment.replies.length }} réponse{{
|
|
comment.replies.length > 1 ? "s" : ""
|
|
}}
|
|
</p>
|
|
<div
|
|
v-if="comment.author.uuid === userStore.user.uuid"
|
|
class="comment__ctas | mt-8"
|
|
>
|
|
<button class="btn btn--transparent btn--icon btn--sm" data-icon="edit">
|
|
<span class="sr-only">Éditer</span>
|
|
</button>
|
|
<button
|
|
class="btn btn--transparent btn--icon btn--sm"
|
|
data-icon="delete"
|
|
@click="deleteComment($event)"
|
|
>
|
|
<span class="sr-only">Supprimer</span>
|
|
</button>
|
|
</div>
|
|
</footer>
|
|
</article>
|
|
</template>
|
|
|
|
<script setup>
|
|
import dayjs from "dayjs";
|
|
import "dayjs/locale/fr";
|
|
import { useUserStore } from "../../stores/user";
|
|
import { useApiStore } from "../../stores/api";
|
|
import { useDialogStore } from "../../stores/dialog";
|
|
import { computed } from "vue";
|
|
|
|
dayjs.locale("fr");
|
|
|
|
const { comment, commentIndex } = defineProps({
|
|
comment: Object,
|
|
commentIndex: Number,
|
|
});
|
|
|
|
const emits = defineEmits(["update:file", "close:comment"]);
|
|
|
|
const userStore = useUserStore();
|
|
const api = useApiStore();
|
|
const dialog = useDialogStore();
|
|
|
|
// Functions
|
|
const status = computed(() => {
|
|
const correspondingNotification = userStore.notifications.find(
|
|
(notification) => notification.id === comment.id
|
|
);
|
|
if (correspondingNotification && !correspondingNotification.isRead) {
|
|
return "unread";
|
|
}
|
|
return undefined;
|
|
});
|
|
|
|
function formatDate() {
|
|
const todayNumber = parseInt(dayjs().format("YYMMD"));
|
|
const dateNumber = parseInt(dayjs(comment.date).format("YYMMD"));
|
|
|
|
if (dateNumber === todayNumber) {
|
|
return "Aujourd'hui";
|
|
}
|
|
|
|
if (dateNumber === todayNumber - 1) {
|
|
return "hier";
|
|
}
|
|
|
|
return dayjs(date).format("D MMM YY");
|
|
}
|
|
|
|
function closeAddField() {
|
|
isAddOpen.value = false;
|
|
newCommentText.value = "";
|
|
}
|
|
|
|
async function read() {
|
|
if (status.value !== "unread") return;
|
|
try {
|
|
const newNotification = await api.readNotification(comment.id);
|
|
userStore.readNotification(comment.id);
|
|
} catch (error) {
|
|
console.log("Erreur lors de la lecture de la notification : ", error);
|
|
}
|
|
}
|
|
|
|
async function deleteComment(event) {
|
|
event.stopPropagation();
|
|
const newFile = await api.deleteComment(comment);
|
|
dialog.updateFile(newFile);
|
|
if (comment.parentId) {
|
|
emits("close:comment");
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.comments > .comment:not([data-opened="true"]) {
|
|
cursor: pointer;
|
|
}
|
|
.comment {
|
|
--flow-space: var(--space-12);
|
|
font-size: var(--text-sm);
|
|
border: var(--border);
|
|
border-width: 2px;
|
|
border-radius: var(--rounded-lg);
|
|
padding: var(--space-12);
|
|
color: var(--color-grey-400);
|
|
transition: border-color 0.1s ease-in-out;
|
|
}
|
|
.comment.highlight {
|
|
border-color: #fff;
|
|
}
|
|
|
|
.comment header p {
|
|
display: flex;
|
|
gap: var(--space-8);
|
|
}
|
|
.comment header strong,
|
|
.comment footer {
|
|
font-weight: 500;
|
|
color: var(--color-white);
|
|
}
|
|
.comment header time {
|
|
color: var(--color-primary);
|
|
font-weight: 500;
|
|
margin-left: auto;
|
|
}
|
|
.comment[data-status="unread"] {
|
|
background: var(--color-white);
|
|
border-color: var(--color-white);
|
|
color: var(--color-grey-700);
|
|
}
|
|
.comment[data-status="unread"] header p > :first-child::before {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 0.375rem;
|
|
height: 0.375rem;
|
|
border-radius: 50%;
|
|
background: var(--color-primary);
|
|
margin-right: var(--space-8);
|
|
margin-bottom: 0.075em;
|
|
}
|
|
.comment[data-status="unread"] header strong,
|
|
.comment[data-status="unread"] footer {
|
|
color: var(--color-black);
|
|
}
|
|
.comment[data-status="unread"] header time {
|
|
color: var(--color-primary);
|
|
}
|
|
.comment[data-opened="true"] {
|
|
border-color: transparent;
|
|
}
|
|
.comment[data-opened="true"] .comment__replies {
|
|
color: var(--color-primary);
|
|
}
|
|
.comment__id,
|
|
.comment__page,
|
|
.comment__date {
|
|
flex-shrink: 0;
|
|
}
|
|
.comment__ctas > * {
|
|
--border-color: transparent;
|
|
margin-right: var(--space-4);
|
|
}
|
|
</style>
|