2019-01-21 15:08:22 +01:00
< template >
2019-10-01 20:10:53 +02:00
< div class = "container" >
2019-04-03 17:29:03 +02:00
< b -loading :active.sync ="$apollo.loading" > < / b - l o a d i n g >
2019-10-08 22:27:14 +02:00
< transition appear name = "fade" mode = "out-in" >
< div v-if ="event" >
2019-10-10 14:50:44 +02:00
< div class = "header-picture" : style = "`background-image: url('${event.picture ? event.picture.url : 'https://picsum.photos/600/200/'}')`" >
<!-- < figure class = "image is-3by1" v-if ="event.picture" >
2019-10-08 22:27:14 +02:00
< img :src ="event.picture.url" >
< / figure >
< figure class = "image is-3by1" v-else >
< img src = "https://picsum.photos/600/200/" >
2019-10-10 14:50:44 +02:00
< / figure > -- >
2019-10-08 22:27:14 +02:00
< / div >
< section >
< div class = "title-and-participate-button" >
< div class = "title-wrapper" >
< div class = "date-component" >
< date -calendar -icon :date ="event.beginsOn" > < / d a t e - c a l e n d a r - i c o n >
2019-04-03 17:29:03 +02:00
< / div >
2019-10-08 22:27:14 +02:00
< h1 class = "title" > { { event . title } } < / h1 >
< / div >
< div class = "has-text-right" v-if ="new Date(endDate) > new Date()" >
< small v-if ="event.participantStats.approved > 0 && !actorIsParticipant" >
{ { $tc ( 'One person is going' , event . participantStats . approved , { approved : event . participantStats . approved } ) } }
< / small >
< small v -else -if = " event.participantStats.approved > 0 && actorIsParticipant " >
{ { $tc ( 'You and one other person are going to this event' , event . participantStats . approved - 1 , { approved : event . participantStats . approved - 1 } ) } }
< / small >
< participation -button
v - if = "currentActor.id && !actorIsOrganizer && !event.draft"
: participation = "participations[0]"
: current - actor = "currentActor"
@ joinEvent = "joinEvent"
@ joinModal = "isJoinModalActive = true"
@ confirmLeave = "confirmLeave"
/ >
< / div >
< div v-else >
< button class = "button is-primary" type = "button" slot = "trigger" disabled >
< template >
< span > { { $t ( 'Event already passed' ) } } < / span >
< / template >
< b -icon icon = "menu-down" > < / b - i c o n >
< / button >
2019-04-03 17:29:03 +02:00
< / div >
< / div >
2019-10-08 22:27:14 +02:00
< div class = "metadata columns" >
< div class = "column is-three-quarters-desktop" >
< p class = "tags" v-if ="event.category || event.tags.length > 0" >
< b -tag type = "is-warning" size = "is-medium" v-if ="event.draft" > {{ $ t ( ' Draft ' ) }} < / b -tag >
< b -tag type = "is-success" v-if ="event.tags" v-for="tag in event.tags" :key="tag.title" > {{ tag.title }} < / b -tag >
< span v-if ="event.tags > 0" > ⋅ < / span >
< span class = "visibility" v-if ="!event.draft" >
< b -tag type = "is-info" v-if ="event.visibility === EventVisibility.PUBLIC" > {{ $ t ( ' Public event ' ) }} < / b -tag >
< b -tag type = "is-info" v-if ="event.visibility === EventVisibility.UNLISTED" > {{ $ t ( ' Private event ' ) }} < / b -tag >
< / span >
2019-04-03 17:29:03 +02:00
< / p >
2019-10-08 22:27:14 +02:00
< div class = "date-and-add-to-calendar" >
< div class = "date-and-privacy" v-if ="event.beginsOn" >
< b -icon icon = "calendar-clock" / >
< event -full -date :beginsOn ="event.beginsOn" :endsOn ="event.endsOn" / >
< / div >
< a class = "add-to-calendar" @click ="downloadIcsEvent()" v-if ="!event.draft" >
< b -icon icon = "calendar-plus" / >
{ { $t ( 'Add to my calendar' ) } }
2019-09-09 09:31:08 +02:00
< / a >
2019-10-08 22:27:14 +02:00
< / div >
< p class = "slug" >
{ { event . slug } }
2019-09-09 09:31:08 +02:00
< / p >
2019-04-03 17:29:03 +02:00
< / div >
2019-10-08 22:27:14 +02:00
< div class = "column sidebar" >
< div class = "field has-addons" v-if ="currentActor.id" >
< p class = "control" v-if ="actorIsOrganizer || event.draft" >
< router -link
class = "button"
: to = "{ name: RouteName.EDIT_EVENT, params: {eventId: event.uuid}}"
>
{ { $t ( 'Edit' ) } }
< / r o u t e r - l i n k >
< / p >
< p class = "control" v-if ="actorIsOrganizer || event.draft" >
< a class = "button is-danger" @click ="openDeleteEventModalWrapper" >
{ { $t ( 'Delete' ) } }
< / a >
< / p >
< p class = "control" >
< a class = "button is-danger" @ click = "isReportModalActive = true" >
{ { $t ( 'Report' ) } }
< / a >
< / p >
2019-04-03 17:29:03 +02:00
< / div >
2019-10-08 22:27:14 +02:00
< div class = "address-wrapper" >
< b -icon icon = "map" / >
< span v-if ="!event.physicalAddress" > {{ $ t ( ' No address defined ' ) }} < / span >
< div class = "address" v-if ="event.physicalAddress" >
< address >
< span class = "addressDescription" :title ="event.physicalAddress.description" > { { event . physicalAddress . description } } < / span >
< span > { { event . physicalAddress . floor } } { { event . physicalAddress . street } } < / span >
< span > { { event . physicalAddress . postalCode } } { { event . physicalAddress . locality } } < / span >
< / address >
< span class = "map-show-button" @ click = "showMap = !showMap" v-if ="event.physicalAddress && event.physicalAddress.geom" >
{ { $t ( 'Show map' ) } }
< / span >
2019-04-03 17:29:03 +02:00
< / div >
2019-10-08 22:27:14 +02:00
< b -modal v-if ="event.physicalAddress && event.physicalAddress.geom" :active.sync="showMap" scroll="keep" >
< div class = "map" >
< map -leaflet
: coords = "event.physicalAddress.geom"
: popup = "event.physicalAddress.description"
/ >
< / div >
< / b - m o d a l >
< / div >
< div class = "organizer" >
< span >
< span v-if ="event.organizerActor" >
{ { $t ( 'By {name}' , { name : event . organizerActor . name ? event . organizerActor . name : event . organizerActor . preferredUsername } ) } }
< / span >
< figure v-if ="event.organizerActor.avatar" class="image is-48x48" >
< img
class = "is-rounded"
: src = "event.organizerActor.avatar.url"
: alt = "event.organizerActor.avatar.alt" / >
< / figure >
2019-09-12 11:34:01 +02:00
< / span >
2019-10-08 22:27:14 +02:00
< / div >
2019-04-03 17:29:03 +02:00
< / div >
< / div >
2019-10-08 22:27:14 +02:00
< / section >
< div class = "description" >
< div class = "description-container container" >
< h3 class = "title" >
{ { $t ( 'About this event' ) } }
< / h3 >
< p v-if ="!event.description" >
{ { $t ( "The event organizer didn't add any description." ) } }
< / p >
< div class = "columns" v-else >
2019-10-10 11:05:53 +02:00
< div class = "column is-half description-content" v-html ="event.description" >
2019-10-08 22:27:14 +02:00
< / div >
2019-04-03 17:29:03 +02:00
< / div >
< / div >
2019-01-21 15:08:22 +01:00
< / div >
2019-10-08 22:27:14 +02:00
< section class = "share" v-if ="!event.draft" >
< div class = "container" >
< div class = "columns" >
< div class = "column is-half has-text-centered" >
< h3 class = "title" > { { $t ( 'Share this event' ) } } < / h3 >
< div >
< b -icon icon = "mastodon" size = "is-large" type = "is-primary" / >
< a :href ="facebookShareUrl" target = "_blank" rel = "nofollow noopener" > < b -icon icon = "facebook" size = "is-large" type = "is-primary" / > < / a >
< a :href ="twitterShareUrl" target = "_blank" rel = "nofollow noopener" > < b -icon icon = "twitter" size = "is-large" type = "is-primary" / > < / a >
< a :href ="emailShareUrl" target = "_blank" rel = "nofollow noopener" > < b -icon icon = "email" size = "is-large" type = "is-primary" / > < / a >
<!-- TODO : mailto : links are not used anymore , we should provide a popup to redact a message instead -- >
< a :href ="linkedInShareUrl" target = "_blank" rel = "nofollow noopener" > < b -icon icon = "linkedin" size = "is-large" type = "is-primary" / > < / a >
< / div >
< / div >
< hr / >
< div class = "column is-half has-text-right add-to-calendar" >
< h3 @click ="downloadIcsEvent()" >
{ { $t ( 'Add to my calendar' ) } }
< / h3 >
2019-04-12 17:00:55 +02:00
< / div >
2019-04-03 17:29:03 +02:00
< / div >
< / div >
2019-10-08 22:27:14 +02:00
< / section >
< section class = "more-events container" v-if ="event.relatedEvents.length > 0" >
< h3 class = "title has-text-centered" > { { $t ( 'These events may interest you' ) } } < / h3 >
< div class = "columns" >
< div class = "column is-one-third-desktop" v-for ="relatedEvent in event.relatedEvents" :key="relatedEvent.uuid" >
< EventCard :event ="relatedEvent" / >
< / div >
2019-01-21 15:08:22 +01:00
< / div >
2019-10-08 22:27:14 +02:00
< / section >
< b -modal :active.sync ="isReportModalActive" has -modal -card ref = "reportModal" >
< report -modal :on-confirm ="reportEvent" : title = "$t('Report this event')" :outside-domain ="event.organizerActor.domain" @close ="$refs.reportModal.close()" / >
< / b - m o d a l >
< b -modal :active.sync ="isJoinModalActive" has -modal -card ref = "participationModal" >
< identity -picker v-model ="identity" >
< template v -slot : footer >
< footer class = "modal-card-foot" >
< button
class = "button"
ref = "cancelButton"
@ click = "isJoinModalActive = false" >
{ { $t ( 'Cancel' ) } }
< / button >
< button
class = "button is-primary"
ref = "confirmButton"
@ click = "joinEvent(identity)" >
{ { $t ( 'Confirm my particpation' ) } }
< / button >
< / footer >
< / template >
< / i d e n t i t y - p i c k e r >
< / b - m o d a l >
2019-01-21 15:08:22 +01:00
< / div >
2019-10-08 22:27:14 +02:00
< / transition >
< / div >
2019-01-21 15:08:22 +01:00
< / template >
< script lang = "ts" >
2019-09-26 16:38:58 +02:00
import { EVENT _PERSON _PARTICIPATION , FETCH _EVENT , JOIN _EVENT , LEAVE _EVENT } from '@/graphql/event' ;
import { Component , Prop } from 'vue-property-decorator' ;
2019-09-11 09:59:01 +02:00
import { CURRENT _ACTOR _CLIENT } from '@/graphql/actor' ;
2019-09-20 18:22:03 +02:00
import { EventVisibility , IEvent , IParticipant , ParticipantRole } from '@/types/event.model' ;
2019-09-26 16:38:58 +02:00
import { IPerson , Person } from '@/types/actor' ;
2019-03-21 20:23:42 +01:00
import { GRAPHQL _API _ENDPOINT } from '@/api/_entrypoint' ;
2019-04-03 17:29:03 +02:00
import DateCalendarIcon from '@/components/Event/DateCalendarIcon.vue' ;
import BIcon from 'buefy/src/components/icon/Icon.vue' ;
import EventCard from '@/components/Event/EventCard.vue' ;
import EventFullDate from '@/components/Event/EventFullDate.vue' ;
2019-08-09 11:32:14 +02:00
import ActorLink from '@/components/Account/ActorLink.vue' ;
2019-09-09 09:31:08 +02:00
import ReportModal from '@/components/Report/ReportModal.vue' ;
import { IReport } from '@/types/report.model' ;
import { CREATE _REPORT } from '@/graphql/report' ;
2019-09-18 17:32:37 +02:00
import EventMixin from '@/mixins/event' ;
2019-09-26 16:38:58 +02:00
import IdentityPicker from '@/views/Account/IdentityPicker.vue' ;
import ParticipationButton from '@/components/Event/ParticipationButton.vue' ;
2019-10-02 19:14:39 +02:00
import { GraphQLError } from 'graphql' ;
import { RouteName } from '@/router' ;
2019-01-21 15:08:22 +01:00
@ Component ( {
2019-03-22 17:35:07 +01:00
components : {
2019-08-09 11:32:14 +02:00
ActorLink ,
2019-04-03 17:29:03 +02:00
EventFullDate ,
EventCard ,
BIcon ,
DateCalendarIcon ,
2019-09-09 09:31:08 +02:00
ReportModal ,
2019-09-26 16:38:58 +02:00
IdentityPicker ,
ParticipationButton ,
2019-05-31 15:13:07 +02:00
// tslint:disable:space-in-parens
'map-leaflet' : ( ) => import ( /* webpackChunkName: "map" */ '@/components/Map.vue' ) ,
// tslint:enable
2019-03-22 17:35:07 +01:00
} ,
2019-01-21 15:08:22 +01:00
apollo : {
event : {
query : FETCH _EVENT ,
variables ( ) {
return {
2019-03-22 10:57:14 +01:00
uuid : this . uuid ,
2019-01-21 15:08:22 +01:00
} ;
2019-03-22 10:57:14 +01:00
} ,
2019-10-02 19:14:39 +02:00
error ( { graphQLErrors } ) {
this . handleErrors ( graphQLErrors ) ;
} ,
2019-01-21 15:08:22 +01:00
} ,
2019-09-11 09:59:01 +02:00
currentActor : {
query : CURRENT _ACTOR _CLIENT ,
2019-03-22 10:57:14 +01:00
} ,
2019-09-26 16:38:58 +02:00
participations : {
query : EVENT _PERSON _PARTICIPATION ,
variables ( ) {
return {
eventId : this . event . id ,
2019-10-04 18:28:25 +02:00
actorId : this . currentActor . id ,
2019-09-26 16:38:58 +02:00
} ;
} ,
update : ( data ) => {
if ( data && data . person ) return data . person . participations ;
return [ ] ;
} ,
2019-10-04 18:28:25 +02:00
skip ( ) {
2019-10-07 16:48:13 +02:00
return ! this . currentActor || ! this . event || ! this . event . id || ! this . currentActor . id ;
2019-10-04 18:28:25 +02:00
} ,
2019-09-26 16:38:58 +02:00
} ,
2019-03-22 10:57:14 +01:00
} ,
2019-01-21 15:08:22 +01:00
} )
2019-09-18 17:32:37 +02:00
export default class Event extends EventMixin {
2019-01-21 15:08:22 +01:00
@ Prop ( { type : String , required : true } ) uuid ! : string ;
event ! : IEvent ;
2019-09-11 09:59:01 +02:00
currentActor ! : IPerson ;
2019-09-26 16:38:58 +02:00
identity : IPerson = new Person ( ) ;
participations : IParticipant [ ] = [ ] ;
2019-04-03 17:29:03 +02:00
showMap : boolean = false ;
2019-09-09 09:31:08 +02:00
isReportModalActive : boolean = false ;
2019-09-11 09:59:01 +02:00
isJoinModalActive : boolean = false ;
2019-04-03 17:29:03 +02:00
EventVisibility = EventVisibility ;
2019-10-03 12:32:20 +02:00
RouteName = RouteName ;
2019-09-26 16:38:58 +02:00
mounted ( ) {
this . identity = this . currentActor ;
}
2019-01-21 15:08:22 +01:00
2019-09-18 17:32:37 +02:00
/ * *
* Delete the event , then redirect to home .
* /
async openDeleteEventModalWrapper ( ) {
await this . openDeleteEventModal ( this . event , this . currentActor ) ;
2019-01-21 15:08:22 +01:00
}
2019-09-09 09:31:08 +02:00
async reportEvent ( content : string , forward : boolean ) {
this . isReportModalActive = false ;
2019-09-11 09:59:01 +02:00
if ( ! this . event . organizerActor ) return ;
2019-09-09 09:31:08 +02:00
const eventTitle = this . event . title ;
try {
await this . $apollo . mutate < IReport > ( {
mutation : CREATE _REPORT ,
variables : {
eventId : this . event . id ,
2019-09-11 09:59:01 +02:00
reporterActorId : this . currentActor . id ,
2019-09-09 09:31:08 +02:00
reportedActorId : this . event . organizerActor . id ,
content ,
} ,
} ) ;
this . $buefy . notification . open ( {
2019-09-12 11:34:01 +02:00
message : this . $t ( 'Event {eventTitle} reported' , { eventTitle } ) as string ,
2019-09-09 09:31:08 +02:00
type : 'is-success' ,
position : 'is-bottom-right' ,
duration : 5000 ,
} ) ;
} catch ( error ) {
console . error ( error ) ;
}
}
2019-09-11 09:59:01 +02:00
async joinEvent ( identity : IPerson ) {
this . isJoinModalActive = false ;
2019-01-21 15:08:22 +01:00
try {
2019-09-02 18:52:23 +02:00
await this . $apollo . mutate < { joinEvent : IParticipant } > ( {
2019-02-22 11:24:41 +01:00
mutation : JOIN _EVENT ,
variables : {
2019-02-25 17:20:06 +01:00
eventId : this . event . id ,
2019-09-11 09:59:01 +02:00
actorId : identity . id ,
2019-02-22 11:24:41 +01:00
} ,
2019-09-02 18:52:23 +02:00
update : ( store , { data } ) => {
if ( data == null ) return ;
2019-09-26 16:38:58 +02:00
const participationCachedData = store . readQuery < { person : IPerson } > ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : this . event . id , name : identity . preferredUsername } ,
} ) ;
if ( participationCachedData == null ) return ;
const { person } = participationCachedData ;
if ( person === null ) {
console . error ( 'Cannot update participation cache, because of null value.' ) ;
return ;
}
person . participations . push ( data . joinEvent ) ;
store . writeQuery ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : this . event . id , name : identity . preferredUsername } ,
data : { person } ,
} ) ;
2019-09-02 18:52:23 +02:00
const cachedData = store . readQuery < { event : IEvent } > ( { query : FETCH _EVENT , variables : { uuid : this . event . uuid } } ) ;
if ( cachedData == null ) return ;
const { event } = cachedData ;
2019-02-22 11:24:41 +01:00
if ( event === null ) {
2019-02-25 17:20:06 +01:00
console . error ( 'Cannot update event participant cache, because of null value.' ) ;
2019-03-22 10:57:14 +01:00
return ;
2019-02-22 11:24:41 +01:00
}
2019-09-26 16:38:58 +02:00
if ( data . joinEvent . role === ParticipantRole . NOT _APPROVED ) {
event . participantStats . unapproved = event . participantStats . unapproved + 1 ;
} else {
event . participantStats . approved = event . participantStats . approved + 1 ;
}
2019-02-22 11:24:41 +01:00
2019-09-26 16:38:58 +02:00
store . writeQuery ( { query : FETCH _EVENT , variables : { uuid : this . uuid } , data : { event } } ) ;
2019-03-22 10:57:14 +01:00
} ,
2019-01-21 15:08:22 +01:00
} ) ;
} catch ( error ) {
console . error ( error ) ;
}
}
2019-09-11 09:59:01 +02:00
confirmLeave ( ) {
this . $buefy . dialog . confirm ( {
2019-09-20 18:22:03 +02:00
title : this . $t ( 'Leaving event "{title}"' , { title : this . event . title } ) as string ,
message : this . $t ( 'Are you sure you want to cancel your participation at event "{title}"?' , { title : this . event . title } ) as string ,
confirmText : this . $t ( 'Leave event' ) as string ,
cancelText : this . $t ( 'Cancel' ) as string ,
2019-09-11 09:59:01 +02:00
type : 'is-danger' ,
hasIcon : true ,
onConfirm : ( ) => this . leaveEvent ( ) ,
} ) ;
}
2019-02-22 11:24:41 +01:00
async leaveEvent ( ) {
try {
2019-09-02 18:52:23 +02:00
await this . $apollo . mutate < { leaveEvent : IParticipant } > ( {
2019-02-22 11:24:41 +01:00
mutation : LEAVE _EVENT ,
variables : {
2019-02-25 17:20:06 +01:00
eventId : this . event . id ,
2019-09-11 09:59:01 +02:00
actorId : this . currentActor . id ,
2019-02-22 11:24:41 +01:00
} ,
2019-09-02 18:52:23 +02:00
update : ( store , { data } ) => {
if ( data == null ) return ;
2019-09-26 16:38:58 +02:00
const participationCachedData = store . readQuery < { person : IPerson } > ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : this . event . id , name : this . currentActor . preferredUsername } ,
} ) ;
if ( participationCachedData == null ) return ;
const { person } = participationCachedData ;
if ( person === null ) {
console . error ( 'Cannot update participation cache, because of null value.' ) ;
2019-03-22 10:57:14 +01:00
return ;
2019-02-22 11:24:41 +01:00
}
2019-09-26 16:38:58 +02:00
const participation = person . participations [ 0 ] ;
person . participations = [ ] ;
store . writeQuery ( {
query : EVENT _PERSON _PARTICIPATION ,
variables : { eventId : this . event . id , name : this . currentActor . preferredUsername } ,
data : { person } ,
} ) ;
2019-02-22 11:24:41 +01:00
2019-09-26 16:38:58 +02:00
const eventCachedData = store . readQuery < { event : IEvent } > ( { query : FETCH _EVENT , variables : { uuid : this . event . uuid } } ) ;
if ( eventCachedData == null ) return ;
const { event } = eventCachedData ;
if ( event === null ) {
console . error ( 'Cannot update event cache, because of null value.' ) ;
return ;
}
if ( participation . role === ParticipantRole . NOT _APPROVED ) {
event . participantStats . unapproved = event . participantStats . unapproved - 1 ;
} else {
event . participantStats . approved = event . participantStats . approved - 1 ;
}
store . writeQuery ( { query : FETCH _EVENT , variables : { uuid : this . uuid } , data : { event } } ) ;
2019-03-22 10:57:14 +01:00
} ,
2019-02-22 11:24:41 +01:00
} ) ;
} catch ( error ) {
console . error ( error ) ;
}
2019-01-21 15:08:22 +01:00
}
2019-03-21 20:23:42 +01:00
async downloadIcsEvent ( ) {
const data = await ( await fetch ( ` ${ GRAPHQL _API _ENDPOINT } /events/ ${ this . uuid } /export/ics ` ) ) . text ( ) ;
const blob = new Blob ( [ data ] , { type : 'text/calendar' } ) ;
const link = document . createElement ( 'a' ) ;
link . href = window . URL . createObjectURL ( blob ) ;
link . download = ` ${ this . event . title } .ics ` ;
document . body . appendChild ( link ) ;
link . click ( ) ;
document . body . removeChild ( link ) ;
2019-01-21 15:08:22 +01:00
}
2019-10-02 19:14:39 +02:00
async handleErrors ( errors : GraphQLError ) {
if ( errors [ 0 ] . message . includes ( 'not found' ) ) {
await this . $router . push ( { name : RouteName . PAGE _NOT _FOUND } ) ;
}
}
2019-09-26 16:38:58 +02:00
get actorIsParticipant ( ) {
if ( this . actorIsOrganizer ) return true ;
2019-02-22 11:24:41 +01:00
2019-09-26 16:38:58 +02:00
return this . participations . length > 0 && this . participations [ 0 ] . role === ParticipantRole . PARTICIPANT ;
2019-01-21 15:08:22 +01:00
}
2019-02-22 11:24:41 +01:00
2019-09-26 16:38:58 +02:00
get actorIsOrganizer ( ) {
return this . participations . length > 0 && this . participations [ 0 ] . role === ParticipantRole . CREATOR ;
2019-01-21 15:08:22 +01:00
}
2019-04-03 17:29:03 +02:00
2019-10-02 17:59:07 +02:00
get endDate ( ) {
return this . event . endsOn !== null && this . event . endsOn > this . event . beginsOn ? this . event . endsOn : this . event . beginsOn ;
}
2019-04-03 17:29:03 +02:00
get twitterShareUrl ( ) : string {
return ` https://twitter.com/intent/tweet?url= ${ encodeURIComponent ( this . event . url ) } &text= ${ this . event . title } ` ;
}
get facebookShareUrl ( ) : string {
return ` https://www.facebook.com/sharer/sharer.php?u= ${ encodeURIComponent ( this . event . url ) } ` ;
}
get linkedInShareUrl ( ) : string {
return ` https://www.linkedin.com/shareArticle?mini=true&url= ${ encodeURIComponent ( this . event . url ) } &title= ${ this . event . title } ` ;
}
get emailShareUrl ( ) : string {
2019-10-10 12:25:32 +02:00
return ` mailto:?to=&body= ${ this . event . url } ${ encodeURIComponent ( '\n\n' ) } ${ this . textDescription } &subject= ${ this . event . title } ` ;
}
get textDescription ( ) : string {
const meta = document . querySelector ( "meta[property='og:description']" ) ;
if ( ! meta ) return '' ;
return meta . getAttribute ( 'content' ) || '' ;
2019-04-03 17:29:03 +02:00
}
2019-09-09 15:49:31 +02:00
2019-01-21 15:08:22 +01:00
}
< / script >
2019-04-03 17:29:03 +02:00
< style lang = "scss" scoped >
@ import "../../variables" ;
2019-10-08 22:27:14 +02:00
. fade - enter - active , . fade - leave - active {
transition : opacity .5 s ;
}
. fade - enter , . fade - leave - to {
opacity : 0 ;
}
2019-10-10 14:50:44 +02:00
. header - picture {
height : 400 px ;
background - size : cover ;
// background-position: center center;
background - attachment : fixed ;
background - repeat : no - repeat ;
}
2019-04-03 17:29:03 +02:00
div . sidebar {
display : flex ;
flex - wrap : wrap ;
flex - direction : column ;
position : relative ;
& : : before {
content : "" ;
background : # B3B3B2 ;
position : absolute ;
bottom : 30 px ;
top : 30 px ;
left : 0 ;
height : calc ( 100 % - 60 px ) ;
width : 1 px ;
}
div . address - wrapper {
display : flex ;
flex : 1 ;
flex - wrap : wrap ;
div . address {
flex : 1 ;
. map - show - button {
cursor : pointer ;
}
address {
font - style : normal ;
flex - wrap : wrap ;
display : flex ;
justify - content : flex - start ;
span . addressDescription {
text - overflow : ellipsis ;
white - space : nowrap ;
flex : 1 0 auto ;
min - width : 100 % ;
2019-09-20 19:43:29 +02:00
max - width : 4 rem ;
overflow : hidden ;
2019-04-03 17:29:03 +02:00
}
: not ( . addressDescription ) {
color : rgba ( 46 , 62 , 72 , .6 ) ;
flex : 1 ;
min - width : 100 % ;
}
}
}
div . map {
height : 900 px ;
width : 100 % ;
padding : 25 px 5 px 0 ;
}
}
div . organizer {
display : inline - flex ;
padding - top : 10 px ;
a {
color : # 4 a4a4a ;
span {
line - height : 2.7 rem ;
padding - right : 6 px ;
}
}
}
}
div . title - and - participate - button {
display : flex ;
flex - wrap : wrap ;
/*flex-flow: row wrap;*/
justify - content : space - between ;
/*align-self: center;*/
align - items : stretch ;
/*align-content: space-around;*/
padding : 15 px 10 px 0 ;
div . title - wrapper {
display : flex ;
flex : 1 1 auto ;
div . date - component {
margin - right : 16 px ;
}
h1 . title {
font - weight : normal ;
word - break : break - word ;
font - size : 1.7 em ;
}
}
. participate - button {
flex : 0 1 auto ;
display : inline - flex ;
a . button {
margin : 0 auto ;
}
}
}
div . metadata {
padding : 0 10 px ;
div . date - and - add - to - calendar {
display : flex ;
flex - wrap : wrap ;
span . icon {
margin - right : 5 px ;
}
div . date - and - privacy {
color : $primary ;
padding : 0.3 rem ;
background : $secondary ;
font - weight : bold ;
}
a . add - to - calendar {
flex : 0 0 auto ;
margin - left : 10 px ;
color : # 484849 ;
& : hover {
text - decoration : underline ;
}
}
}
}
p . tags {
span {
2019-10-02 17:59:07 +02:00
& . tag . is - success {
2019-04-03 17:29:03 +02:00
& : : before {
content : '#' ;
}
text - transform : uppercase ;
2019-10-02 17:59:07 +02:00
color : # 111111 ;
2019-04-03 17:29:03 +02:00
}
margin : auto 5 px ;
}
margin - bottom : 1 rem ;
}
h3 . title {
font - size : 3 rem ;
font - weight : 300 ;
}
. description {
padding - top : 10 px ;
min - height : 40 rem ;
background - repeat : no - repeat ;
background - size : 800 px ;
background - position : 95 % 101 % ;
background - image : url ( '../../assets/texting.svg' ) ;
border - top : solid 1 px # 111 ;
border - bottom : solid 1 px # 111 ;
2019-10-10 11:05:53 +02:00
. description - content {
/deep/ h1 {
font - size : 2 rem ;
}
2019-04-03 17:29:03 +02:00
2019-10-10 11:05:53 +02:00
/deep/ h2 {
font - size : 1.5 rem ;
}
/deep/ h3 {
font - size : 1.25 rem ;
}
/deep/ ul {
list - style - type : disc ;
}
/deep/ blockquote {
border - left : .2 em solid # 333 ;
display : block ;
padding - left : 1 em ;
}
/deep/ p {
margin : 10 px auto ;
a {
display : inline - block ;
padding : 0.3 rem ;
background : $secondary ;
color : # 111 ;
}
2019-04-03 17:29:03 +02:00
}
}
}
. share {
border - bottom : solid 1 px # 111 ;
. columns {
& > * {
padding : 10 rem 0 ;
}
. add - to - calendar {
background - repeat : no - repeat ;
background - size : 400 px ;
background - position : 10 % 50 % ;
background - image : url ( '../../assets/undraw_events.svg' ) ;
position : relative ;
& : : before {
content : "" ;
background : # B3B3B2 ;
position : absolute ;
bottom : 25 % ;
left : 0 ;
height : 40 % ;
width : 1 px ;
}
h3 {
display : block ;
color : $primary ;
font - size : 3 rem ;
text - decoration : underline ;
text - decoration - color : $secondary ;
cursor : pointer ;
max - width : 20 rem ;
margin - right : 0 ;
margin - left : auto ;
}
}
}
}
. more - events {
margin : 50 px auto ;
2019-03-22 17:35:07 +01:00
}
< / style >