designtopack/src/components/comments/Comments.vue

211 lines
5.3 KiB
Vue
Raw Normal View History

2024-10-23 09:48:27 +02:00
<template>
<aside id="comments-container" aria-labelledby="comments-label">
<h2 id="comments-label" class="sr-only">Commentaires</h2>
<div class="comments | flow">
2024-10-29 16:13:07 +01:00
<template v-if="comments">
<template v-if="!openedComment">
<Comment
v-for="(comment, commentIndex) in sortedComments"
2024-10-29 16:13:07 +01:00
:comment="comment"
:commentIndex="comments.length - commentIndex"
2024-10-29 16:13:07 +01:00
:key="comment.id"
@click="openedComment = comment"
/>
</template>
<template v-else>
<button
class="btn | justify-start w-full | bg-white-10 text-white | px-8"
data-icon="chevron-single-left"
2024-10-29 16:51:31 +01:00
@click="
openedComment = null;
isAddOpen = false;
"
>
2024-10-29 16:13:07 +01:00
<span>Retour à la liste</span>
</button>
2024-10-29 16:51:31 +01:00
<Comment :comment="openedComment" data-opened="true" />
<div v-if="sortedReplies.length > 0" class="replies | flow">
2024-10-29 16:13:07 +01:00
<Comment
2024-10-30 13:29:26 +01:00
v-for="(reply, commentIndex) in sortedReplies"
2024-10-29 16:13:07 +01:00
:comment="reply"
2024-10-30 13:29:26 +01:00
:commentIndex="sortedReplies.length - commentIndex"
2024-10-29 16:13:07 +01:00
:key="reply.id"
/>
</div>
</template>
2024-10-29 11:18:17 +01:00
</template>
2024-10-29 16:13:07 +01:00
<template v-else> état aucun commentaire </template>
2024-10-23 09:48:27 +02:00
</div>
<button
2024-10-29 17:26:23 +01:00
v-if="!openedComment && !isAddOpen"
id="create-comment"
2024-10-23 09:48:27 +02:00
class="btn btn--white-20 | w-full"
@click="isAddOpen = true"
>
Ajouter un commentaire
</button>
<button
2024-10-29 16:51:31 +01:00
v-else-if="openedComment && !isAddOpen"
id="reply-comment"
class="btn btn--white-20 | justify-start w-full | text-white-50"
2024-10-29 16:51:31 +01:00
@click="isAddOpen = true"
>
Répondre
</button>
2024-10-23 09:48:27 +02:00
<form
v-if="isAddOpen"
action=""
method="post"
class="flow | bg-white-20 | p-12 | rounded-xl"
2024-10-29 16:51:31 +01:00
@submit="handleSubmit"
2024-10-23 09:48:27 +02:00
>
<label class="sr-only" for="comment">Votre commentaire</label>
<textarea
name="comment"
id="comment"
placeholder="Ajouter un commentaire…"
rows="5"
2024-10-23 09:48:27 +02:00
class="text-sm | rounded-lg bg-black p-12"
v-model="newCommentText"
></textarea>
<footer class="flex">
<input type="submit" class="btn btn--tranparent" />
2024-10-29 16:51:31 +01:00
<button class="btn btn--white-10" @click="isAddOpen = false">
Annuler
</button>
2024-10-23 09:48:27 +02:00
</footer>
</form>
</aside>
</template>
<script setup>
2024-10-23 11:32:51 +02:00
import dayjs from "dayjs";
import "dayjs/locale/fr";
import uniqid from "uniqid";
import { computed, ref } from "vue";
2024-10-23 09:48:27 +02:00
import { useUserStore } from "../../stores/user";
2024-10-23 11:32:51 +02:00
import { usePageStore } from "../../stores/page";
2024-10-28 17:50:40 +01:00
import { useApiStore } from "../../stores/api";
2024-10-29 16:13:07 +01:00
import Comment from "./Comment.vue";
2024-10-23 11:32:51 +02:00
dayjs.locale("fr");
2024-10-23 09:48:27 +02:00
2024-10-23 11:32:51 +02:00
const { currentPageIndex, file, comments } = defineProps({
currentPageIndex: Number,
file: Object,
comments: Array,
2024-10-23 09:48:27 +02:00
});
2024-10-29 11:18:17 +01:00
2024-10-23 09:48:27 +02:00
const { user } = useUserStore();
2024-10-23 11:32:51 +02:00
const { page } = usePageStore();
2024-10-28 17:50:40 +01:00
const api = useApiStore();
2024-10-23 09:48:27 +02:00
2024-10-29 11:18:17 +01:00
const openedComment = ref(null);
2024-10-23 09:48:27 +02:00
const newCommentText = ref("");
const isAddOpen = ref(false);
const emits = defineEmits(["update:file"]);
const sortedComments = computed(() => {
return comments.reverse();
});
2024-10-30 13:29:26 +01:00
const sortedReplies = computed(() => {
const sortedReplies =
openedComment.value && openedComment.value.replies
? openedComment.value.replies.slice().reverse()
: [];
return sortedReplies;
});
2024-10-23 09:48:27 +02:00
// Functions
2024-10-29 16:51:31 +01:00
function handleSubmit(event) {
2024-10-23 09:48:27 +02:00
event.preventDefault();
2024-10-23 11:32:51 +02:00
const date = dayjs().format();
2024-10-29 16:51:31 +01:00
const newComment = {
2024-10-23 11:32:51 +02:00
pageUri: page.uri + "/client-brief",
2024-10-29 16:13:07 +01:00
filePageIndex: currentPageIndex,
2024-10-23 11:32:51 +02:00
fileName: file.name,
2024-10-23 09:48:27 +02:00
userUuid: user.uuid,
text: newCommentText.value,
2024-10-23 11:32:51 +02:00
date,
id: uniqid(),
};
2024-10-29 16:51:31 +01:00
if (openedComment.value) {
replyComment(newComment);
} else {
addComment(newComment);
}
}
async function replyComment(newComment) {
newComment.parentId = openedComment.value.id;
const newFile = await api.replyComment(newComment);
newCommentText.value = "";
isAddOpen.value = false;
2024-10-30 13:29:26 +01:00
openedComment.value = newFile.comments.find(
(item) => item.id === openedComment.value.id
);
2024-10-29 16:51:31 +01:00
emits("update:file", newFile);
}
async function addComment(newComment) {
const newFile = await api.addComment(newComment);
2024-10-28 17:50:40 +01:00
newCommentText.value = "";
isAddOpen.value = false;
emits("update:file", newFile);
2024-10-23 11:32:51 +02:00
}
2024-10-23 09:48:27 +02:00
</script>
<style>
/* Comments */
#toggle-comments {
position: absolute;
right: var(--space-16);
bottom: var(--space-16);
padding: 0.625rem;
}
#comments-container {
background-color: black;
position: absolute;
top: 0;
right: 0;
bottom: 4.5rem;
width: var(--comments-w);
padding: var(--space-24) var(--space-32);
}
.comments {
overflow-y: auto;
height: calc(100% - 3.5rem);
margin-bottom: 1rem;
margin-right: -2rem;
padding-right: 2rem;
}
#comments-container form {
--flow-space: 0.5rem;
flex-direction: column;
position: -webkit-sticky;
position: sticky;
bottom: 5.5rem;
}
#comments-container textarea {
position: sticky;
bottom: 0;
margin: 0;
resize: none;
background: none;
padding: 0;
color: var(--color-white);
}
#comments-container textarea:focus {
outline: none;
}
::placeholder {
color: var(--color-white-50);
}
#comments-container form footer {
gap: var(--space-12);
}
#comments-container form footer > * {
flex-grow: 1;
}
</style>