skillbox/client/src/components/rooms/RoomEntry.vue

134 lines
2.8 KiB
Vue

<template>
<div
class="room-entry"
data-cy="room-entry"
>
<router-link
:to="{name: 'article', params: { slug: slug }}"
class="room-entry__router-link"
>
<div
class="room-entry__header"
v-if="image"
>
<img
:src="image"
:alt="title"
class="room-entry__image"
>
</div>
<div class="room-entry__content">
<h2 class="room-entry__title">
{{ title }}
</h2>
<!-- eslint-disable vue/no-v-html -->
<p class="room-entry__teaser" v-html="teaser" />
<div class="room-entry__footer">
<user-meta-widget v-bind="author" class="room-entry__author" />
<entry-count-widget :entry-count="comments" icon="speech-bubble" :verbose="false" />
</div>
</div>
</router-link>
<room-entry-actions data-cy="room-entry-actions" class="room-entry__more" :slug="slug" v-if="myEntry" />
</div>
</template>
<script>
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
import UserMetaWidget from '@/components/UserMetaWidget';
import teaser from '@/helpers/teaser';
import RoomEntryActions from '@/components/rooms/RoomEntryActions';
import EntryCountWidget from '@/components/rooms/EntryCountWidget';
export default {
props: ['title', 'author', 'contents', 'slug', 'id', 'comments'],
components: {
EntryCountWidget,
RoomEntryActions,
UserMetaWidget,
},
computed: {
image() {
if (this.contents) {
let found = this.contents.find((c) => c.type === 'image_url_block');
return found ? found.value.url : '';
}
return '';
},
teaser() {
return teaser(this.contents);
},
myEntry() {
const authorId = atob(this.author.id).split(':')[1];
const userId = atob(this.me.id).split(':')[1];
return authorId === userId;
},
},
apollo: {
me() {
return {
query: ME_QUERY,
};
},
},
};
</script>
<style scoped lang="scss">
@import '~styles/helpers';
.room-entry {
border-radius: 12px;
background-color: $color-white;
overflow: hidden;
-webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */
page-break-inside: avoid; /* Firefox */
break-inside: avoid; /* IE 10+ */
margin-bottom: 25px;
cursor: pointer;
position: relative;
&__image {
max-width: 100%;
}
&__content {
padding: 15px;
}
&__title {
font-size: toRem(21px);
margin-bottom: 10px;
}
&__teaser {
line-height: 1.5;
margin-bottom: 10px;
min-height: 50px;
}
&__more {
position: absolute;
top: 10px;
right: 10px;
display: none;
@include desktop {
display: block;
}
}
&__footer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
}
</style>