Merge pull request #6385 from Ocelot-Social-Community/6379-fix-event-teaser-date-from-start-to-end

fix(webapp): fix event teaser date from start to end by new components
This commit is contained in:
Wolfgang Huß 2023-06-08 21:04:50 +02:00 committed by GitHub
commit 2b7cdaabf6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 205 additions and 89 deletions

View File

@ -0,0 +1,101 @@
<template>
<ds-text class="date-time-range" align="left" color="soft" :size="size">
<div>
<div>
<base-icon name="calendar" data-test="calendar" />
{{ getStartDateString }}
</div>
<div>
<base-icon name="clock" data-test="calendar" />
{{
getStartTimeString +
(this.endDateAsDate && isSameDayLocal ? '&mdash;' + getEndTimeString : '')
}}
</div>
</div>
<template v-if="!isSameDayLocal">
&nbsp;&mdash;&nbsp;
<div>
<div>
<base-icon name="calendar" data-test="calendar" />
{{ getEndDateString }}
</div>
<div>
<base-icon name="clock" data-test="calendar" />
{{ getEndTimeString }}
</div>
</div>
</template>
</ds-text>
</template>
<script>
import { format, isSameDay, isSameYear } from 'date-fns'
export default {
name: 'DateTimeRange',
props: {
/**
* The size used for the text.
* @options small|base|large|x-large|xx-large|xxx-large
*/
size: {
type: String,
default: null,
validator: (value) => {
return value.match(/(small|base|large|x-large|xx-large|xxx-large)/)
},
},
startDate: {
type: String,
require: true,
},
endDate: {
type: String,
default: null,
},
},
computed: {
startDateAsDate() {
return new Date(this.startDate)
},
endDateAsDate() {
return this.endDate ? new Date(this.endDate) : null
},
isSameDayLocal() {
return !this.endDateAsDate || isSameDay(this.endDateAsDate, this.startDateAsDate)
},
isSameYearLocal() {
return !this.endDateAsDate || isSameYear(this.endDateAsDate, this.startDateAsDate)
},
getStartDateString() {
let startDateFormat = this.$t('components.dateTimeRange.yearMonthDay')
if (!this.isSameDayLocal && this.isSameYearLocal) {
startDateFormat = this.$t('components.dateTimeRange.monthDay')
}
return format(this.startDateAsDate, startDateFormat)
},
getStartTimeString() {
return format(new Date(this.startDate), this.$t('components.dateTimeRange.hourMinute'))
},
getEndDateString() {
return this.endDate
? format(new Date(this.endDate), this.$t('components.dateTimeRange.yearMonthDay'))
: ''
},
getEndTimeString() {
return this.endDate
? format(new Date(this.endDate), this.$t('components.dateTimeRange.hourMinute'))
: ''
},
},
}
</script>
<style lang="scss">
.date-time-range {
display: flex;
align-items: center;
gap: 2px;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<ds-text class="location-teaser" align="left" color="soft" :size="size">
<base-icon name="map-marker" data-test="map-marker" />
<span v-if="venue">{{ venue }}</span>
<span v-if="venue">&nbsp;&mdash;&nbsp;</span>
<span v-if="!isOnline">
{{ locationName }}
</span>
<span v-else>
{{ $t('post.viewEvent.eventIsOnline') }}
</span>
</ds-text>
</template>
<script>
export default {
name: 'LocationTeaser',
props: {
/**
* The size used for the text.
* @options small|base|large|x-large|xx-large|xxx-large
*/
size: {
type: String,
default: null,
validator: (value) => {
return value.match(/(small|base|large|x-large|xx-large|xxx-large)/)
},
},
venue: {
type: String,
default: null,
},
locationName: {
type: String,
default: null,
},
isOnline: {
type: Boolean,
default: false,
},
},
}
</script>
<style lang="scss">
.location-teaser {
display: flex;
align-items: center;
gap: 2px;
}
</style>

View File

@ -11,7 +11,6 @@
}" }"
:highlight="isPinned" :highlight="isPinned"
> >
<!-- {{ post }} -->
<template v-if="post.image" #heroImage> <template v-if="post.image" #heroImage>
<img :src="post.image | proxyApiUrl" class="image" /> <img :src="post.image | proxyApiUrl" class="image" />
</template> </template>
@ -31,25 +30,19 @@
margin-bottom="small" margin-bottom="small"
style="padding: 5px" style="padding: 5px"
> >
<ds-flex> <location-teaser
<ds-flex-item> class="event-info"
<ds-text align="left" size="small" color="soft" class="event-info"> size="small"
<base-icon name="map-marker" data-test="map-marker" /> :venue="post.eventVenue"
<span v-if="post.eventIsOnline"> :locationName="post.eventLocationName"
{{ $t('post.viewEvent.eventIsOnline') }} :isOnline="post.eventIsOnline"
</span> />
<span v-else-if="post.eventLocationName"> <date-time-range
{{ post.eventLocationName }} class="event-info"
</span> size="small"
</ds-text> :startDate="post.eventStart"
</ds-flex-item> :endDate="post.eventEnd"
<ds-flex-item> />
<ds-text align="left" color="soft" size="small" class="event-info">
<base-icon name="calendar" data-test="calendar" />
<span>{{ getEventDateString }}</span>
</ds-text>
</ds-flex-item>
</ds-flex>
</ds-space> </ds-space>
<!-- TODO: replace editor content with tiptap render view --> <!-- TODO: replace editor content with tiptap render view -->
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
@ -113,12 +106,13 @@
import Category from '~/components/Category' import Category from '~/components/Category'
import ContentMenu from '~/components/ContentMenu/ContentMenu' import ContentMenu from '~/components/ContentMenu/ContentMenu'
import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon' import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon'
import DateTimeRange from '~/components/DateTimeRange/DateTimeRange'
import HcRibbon from '~/components/Ribbon' import HcRibbon from '~/components/Ribbon'
import LocationTeaser from '~/components/LocationTeaser/LocationTeaser'
import UserTeaser from '~/components/UserTeaser/UserTeaser' import UserTeaser from '~/components/UserTeaser/UserTeaser'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import PostMutations from '~/graphql/PostMutations' import PostMutations from '~/graphql/PostMutations'
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers' import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
import { format } from 'date-fns'
export default { export default {
name: 'PostTeaser', name: 'PostTeaser',
@ -126,7 +120,9 @@ export default {
Category, Category,
ContentMenu, ContentMenu,
CounterIcon, CounterIcon,
DateTimeRange,
HcRibbon, HcRibbon,
LocationTeaser,
UserTeaser, UserTeaser,
}, },
props: { props: {
@ -185,15 +181,6 @@ export default {
if (this.post.postType[0] === 'Event') return this.$t('post.event') if (this.post.postType[0] === 'Event') return this.$t('post.event')
return this.$t('post.name') return this.$t('post.name')
}, },
getEventDateString() {
if (this.post.eventEnd) {
const eventStart = format(new Date(this.post.eventStart), 'dd.MM.')
const eventEnd = format(new Date(this.post.eventEnd), 'dd.MM.yyyy')
return `${eventStart} - ${eventEnd}`
} else {
return format(new Date(this.post.eventStart), 'dd.MM.yyyy')
}
},
}, },
methods: { methods: {
async deletePostCallback() { async deletePostCallback() {
@ -228,6 +215,7 @@ export default {
}, },
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.post-teaser, .post-teaser,
.post-teaser:hover, .post-teaser:hover,

View File

@ -124,6 +124,11 @@
"versus": "Versus" "versus": "Versus"
}, },
"components": { "components": {
"dateTimeRange": {
"hourMinute": "HH:mm",
"monthDay": "dd.MM.",
"yearMonthDay": "dd.MM.yyyy"
},
"password-reset": { "password-reset": {
"change-password": { "change-password": {
"error": "Passwort Änderung fehlgeschlagen. Möglicherweise falscher Sicherheitscode?", "error": "Passwort Änderung fehlgeschlagen. Möglicherweise falscher Sicherheitscode?",
@ -752,7 +757,7 @@
}, },
"viewEvent": { "viewEvent": {
"eventEnd": "Ende", "eventEnd": "Ende",
"eventIsOnline": "Online Veranstaltung", "eventIsOnline": "Online",
"eventLocationName": "Stadt", "eventLocationName": "Stadt",
"eventStart": "Beginn", "eventStart": "Beginn",
"eventVenue": "Veranstaltungsort", "eventVenue": "Veranstaltungsort",

View File

@ -124,6 +124,11 @@
"versus": "Versus" "versus": "Versus"
}, },
"components": { "components": {
"dateTimeRange": {
"hourMinute": "HH:mm",
"monthDay": "MM/dd/",
"yearMonthDay": "MM/dd/yyyy"
},
"password-reset": { "password-reset": {
"change-password": { "change-password": {
"error": "Changing your password failed. Maybe the security code was not correct?", "error": "Changing your password failed. Maybe the security code was not correct?",
@ -752,7 +757,7 @@
}, },
"viewEvent": { "viewEvent": {
"eventEnd": "End", "eventEnd": "End",
"eventIsOnline": "Online Event", "eventIsOnline": "Online",
"eventLocationName": "City", "eventLocationName": "City",
"eventStart": "Start", "eventStart": "Start",
"eventVenue": "Venue", "eventVenue": "Venue",

View File

@ -54,55 +54,28 @@
</section> </section>
<ds-space margin-bottom="small" /> <ds-space margin-bottom="small" />
<h2 class="title hyphenate-text">{{ post.title }}</h2> <h2 class="title hyphenate-text">{{ post.title }}</h2>
<!-- Eventdata --> <!-- event data -->
<ds-space <ds-space
v-if="post && post.postType[0] === 'Event'" v-if="post && post.postType[0] === 'Event'"
margin-bottom="small" margin-bottom="small"
style="padding: 10px" style="padding: 10px"
> >
<ds-text align="left" color="soft"> <location-teaser
<base-icon name="map-marker" data-test="map-marker" /> class="event-info"
<span v-if="post.eventVenue">{{ post.eventVenue }}</span> :venue="post.eventVenue"
<span v-if="!post.eventIsOnline"> :locationName="post.eventLocationName"
<span v-if="post.eventVenue">&mdash;</span> :isOnline="post.eventIsOnline"
{{ post.eventLocationName }} />
</span> <date-time-range
<span v-else> class="event-info"
<span v-if="post.eventVenue">&mdash;</span> :startDate="post.eventStart"
{{ $t('post.viewEvent.eventIsOnline') }} :endDate="post.eventEnd"
</span> />
</ds-text>
<ds-text align="left" color="soft" class="event-info">
<div>
<div>
<base-icon name="calendar" data-test="calendar" />
<span>{{ getEventStartDateString }}</span>
</div>
<div>
<base-icon name="clock" data-test="calendar" />
<span>{{ getEventStartTimeString }}</span>
</div>
</div>
<div v-if="getEventEndDateString">&nbsp;&mdash;&nbsp;</div>
<div v-if="getEventEndDateString">
<div>
<base-icon name="calendar" data-test="calendar" />
<span>{{ getEventEndDateString }}</span>
</div>
<div>
<base-icon name="clock" data-test="calendar" />
<span>{{ getEventEndTimeString }}</span>
</div>
</div>
</ds-text>
<!--ds-text v-if="getEventTimeString" align="left" color="soft" class="event-info">
<base-icon name="clock" data-test="calendar" />
<span>{{ getEventTimeString }}</span>
</ds-text-->
</ds-space> </ds-space>
<ds-space margin-bottom="small" /> <ds-space margin-bottom="small" />
<!-- content -->
<content-viewer class="content hyphenate-text" :content="post.content" /> <content-viewer class="content hyphenate-text" :content="post.content" />
<!-- Categories --> <!-- categories -->
<div v-if="categoriesActive" class="categories"> <div v-if="categoriesActive" class="categories">
<ds-space margin="xx-large" /> <ds-space margin="xx-large" />
<ds-space margin="xx-small" /> <ds-space margin="xx-small" />
@ -177,11 +150,13 @@
import ContentViewer from '~/components/Editor/ContentViewer' import ContentViewer from '~/components/Editor/ContentViewer'
import HcCategory from '~/components/Category' import HcCategory from '~/components/Category'
import HcHashtag from '~/components/Hashtag/Hashtag' import HcHashtag from '~/components/Hashtag/Hashtag'
import ContentMenu from '~/components/ContentMenu/ContentMenu'
import UserTeaser from '~/components/UserTeaser/UserTeaser'
import HcShoutButton from '~/components/ShoutButton.vue'
import CommentForm from '~/components/CommentForm/CommentForm' import CommentForm from '~/components/CommentForm/CommentForm'
import CommentList from '~/components/CommentList/CommentList' import CommentList from '~/components/CommentList/CommentList'
import ContentMenu from '~/components/ContentMenu/ContentMenu'
import DateTimeRange from '~/components/DateTimeRange/DateTimeRange'
import UserTeaser from '~/components/UserTeaser/UserTeaser'
import HcShoutButton from '~/components/ShoutButton.vue'
import LocationTeaser from '~/components/LocationTeaser/LocationTeaser'
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue' import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
import { import {
postMenuModalsData, postMenuModalsData,
@ -193,7 +168,6 @@ import { groupQuery } from '~/graphql/groups'
import PostMutations from '~/graphql/PostMutations' import PostMutations from '~/graphql/PostMutations'
import links from '~/constants/links.js' import links from '~/constants/links.js'
import SortCategories from '~/mixins/sortCategoriesMixin.js' import SortCategories from '~/mixins/sortCategoriesMixin.js'
import { format } from 'date-fns'
export default { export default {
name: 'PostSlug', name: 'PostSlug',
@ -206,9 +180,11 @@ export default {
CommentForm, CommentForm,
CommentList, CommentList,
ContentViewer, ContentViewer,
DateTimeRange,
HcCategory, HcCategory,
HcHashtag, HcHashtag,
HcShoutButton, HcShoutButton,
LocationTeaser,
PageParamsLink, PageParamsLink,
UserTeaser, UserTeaser,
}, },
@ -310,18 +286,6 @@ export default {
!this.post.group || (this.group && ['usual', 'admin', 'owner'].includes(this.group.myRole)) !this.post.group || (this.group && ['usual', 'admin', 'owner'].includes(this.group.myRole))
) )
}, },
getEventStartDateString() {
return format(new Date(this.post.eventStart), 'dd.MM.yyyy')
},
getEventStartTimeString() {
return format(new Date(this.post.eventStart), 'HH:mm')
},
getEventEndDateString() {
return this.post.eventEnd ? format(new Date(this.post.eventEnd), 'dd.MM.yyyy') : ''
},
getEventEndTimeString() {
return this.post.eventEnd ? format(new Date(this.post.eventEnd), 'HH:mm') : ''
},
}, },
methods: { methods: {
reply(message) { reply(message) {
@ -403,6 +367,7 @@ export default {
}, },
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.post-side-navigation { .post-side-navigation {
position: sticky; position: sticky;