Update Cards UI

This commit is contained in:
PascalMarchesseault
2024-08-19 18:48:54 -04:00
parent f9e814d989
commit d03a9d24e1
7 changed files with 542 additions and 15 deletions

View File

@@ -0,0 +1,265 @@
<template>
<div class="shadow-md bg-gray-50">
<div>
<v-card-title>
<div class="flex flex-row justify-between items-center">
<div class="flex items-center">
<img
:src="props.content.createdByPortraitUrl"
alt="Profile Image"
class="rounded-full"
width="32px"
height="32px">
<div class="capitalize px-2">
{{ props.content.createdByName }}
</div>
<span class="text-subtitle-2">
{{ time_ago(props.content.createdAt) }}
</span>
</div>
<v-menu>
<template v-slot:activator="{ props }">
<v-btn variant="plain" v-bind="props">
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item v-if="creatorIsCurrentUser" @click="editContent">
<v-list-item-title>Modifier le contenu</v-list-item-title>
</v-list-item>
<v-list-item v-if="creatorIsCurrentUser" @click="openDeleteConfirmationDialog">
<v-list-item-title>Effacer le contenu</v-list-item-title>
</v-list-item>
<v-list-item @click="reportContent">
<v-list-item-title>Reporter le contenu</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
<div class="uppercase">
{{ props.content.title }}
</div>
<div>
{{ props.content.description }}
</div>
</v-card-title>
<v-carousel
hide-delimiters
v-if="hasUrls"
:show-arrows="props.content.urls.length > 1"
:show-indicators="props.content.urls.length > 1"
>
<v-carousel-item
v-for="url in props.content.urls"
:key="url"
class="image-container"
@click="redirectToContent"
>
<component :is="getComponent(url)" :src="url"></component>
</v-carousel-item>
</v-carousel>
</div>
<div class="px-1">
<div class="flex justify-around ">
<v-btn variant="plain" icon @click="likeContent">
<v-icon>mdi-thumb-up-outline</v-icon>
</v-btn>
<v-btn variant="plain" icon @click="dislikeContent">
<v-icon>mdi-thumb-down-outline</v-icon>
</v-btn>
<v-btn
:class="{'comment-active': hasMessages}"
variant="plain"
icon
@click="toggleComments">
<v-icon>mdi-comment-outline</v-icon>
</v-btn>
<donation-button :color-border="colorMenu"
:color-accent="colorAccent"
:creator-id="creatorId"
:creator-name="creatorName"
:creator-logo="creatorLogo"
iconColorClass="text-black"
></donation-button>
</div>
<div :class="{'hidden': !messagesVisible}">
<h2 class="font-sans font-semibold ">Commentaires</h2>
<message-list
:subject-id="props.content.id"
:messages="messages"
></message-list>
</div>
<div class="py-1">
<post-message :subject-id="props.content.id"
@message-posted="addMessage"
></post-message>
</div>
</div>
</div>
<v-dialog v-model="openDeleteConfirmationModal" max-width="500">
<v-form>
<v-card class="text-center rounded-xl"
:style="{
border: `2px solid `
}">
<div class="flex items-center justify-between py-4 text-2xl font-bold border-b mb-2">
<div class="flex-1 text-center">
Supprimer ce contenu ?
</div>
<v-btn icon @click="openDeleteConfirmationModal = false" class="ml-auto mr-2" variant="text">
<v-icon>mdi-close</v-icon>
</v-btn>
</div>
<div class=" mr-2">
Êtes-vous sûr de vouloir supprimer le contenu ?
</div>
<div class="py-2 space-x-3">
<v-btn variant="flat"
@click="deleteContent()" class=" mt-5">
Oui
</v-btn>
<v-btn variant="outlined"
@click="openDeleteConfirmationModal = false" class=" mt-5">
Non
</v-btn>
</div>
</v-card>
</v-form>
</v-dialog>
</template>
<script setup>
import {computed, ref} from 'vue';
import {time_ago} from "@/internal_time_ago.js";
import MessageList from "@/views/messages/MessageList.vue";
import PostMessage from "@/views/messages/PostMessage.vue";
import DonationButton from "@/views/creators/DonationButton.vue";
import YoutubePlayer from '../YoutubePlayer.vue';
import ImageViewer from '../ImageViewer.vue';
import {useClient} from "@/plugins/api.js";
import {useAuthStore} from "@/stores/authStore.js";
const props = defineProps({
content: {
type: Object,
required: true,
}
});
const openDeleteConfirmationModal = ref(false);
const emits = defineEmits(['content-deleted'])
const contentId = computed(() => props.content.id)
const creatorId = computed(() => props.content.createdBy)
const creatorName = computed(() => props.content.createdByName)
const creatorLogo = computed(() => props.content.createdByPortraitUrl)
const colorMenu = computed(() => props.content.colorMenu)
const colorAccent = computed(() => props.content.colorAccent)
const authStore = useAuthStore()
const creatorIsCurrentUser = computed(() => authStore.isAuthenticated && authStore.userId === creatorId.value)
const hasUrls = computed(() => !!props.content.urls && props.content.urls.length > 0);
const messagesVisible = ref(false);
const messages = ref([]);
const hasMessages = computed(() => messages.value.length > 0)
function openDeleteConfirmationDialog() {
openDeleteConfirmationModal.value = true;
}
function addMessage(newMessage) {
messages.value.unshift(newMessage);
messagesVisible.value = true;
}
function toggleComments() {
messagesVisible.value = !messagesVisible.value;
}
function likeContent() {
console.log('Content liked');
}
function dislikeContent() {
console.log('Content disliked');
}
function getComponent(url) {
if (url.includes('youtube.com') || url.includes('youtu.be')) {
return YoutubePlayer;
} else if (url.match(/\.(jpeg|jpg|gif|png)$/)) {
return ImageViewer;
}
}
function editContent() {
console.log('Modifier le contenu');
}
async function deleteContent() {
const client = useClient()
const response = await client.delete(`/api/contents/${contentId.value}`)
if (response.status >= 200 && response.status < 300) {
emits('content-deleted', contentId.value)
}
}
function reportContent() {
console.log('Reporter le contenu');
}
function redirectToContent() {
window.location.href = `/content/${props.content.id}`;
}
</script>
<style>
.image-container {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
cursor: pointer;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.custom-border {
border-color: #EAEBEC;
}
.hidden {
display: none;
}
.v-carousel-item {
padding: 0; /* Supprime tout padding interne */
margin: 0; /* Supprime toute marge interne */
width: 100vw; /* Assure que chaque item occupe toute la largeur de l'écran */
}
.comment-active .v-icon {
color: #D63DAB;
}
</style>