2019-09-18 17:32:37 +02:00
< template >
2022-08-12 16:46:44 +02:00
< div class = "container mx-auto px-1" >
< h1 >
2022-07-12 10:55:28 +02:00
{ { t ( "My events" ) } }
2020-02-18 08:57:00 +01:00
< / h1 >
2020-12-09 19:09:31 +01:00
< p >
{ {
2022-07-12 10:55:28 +02:00
t (
2021-11-22 09:39:50 +01:00
"You will find here all the events you have created or of which you are a participant, as well as events organized by groups you follow or are a member of."
2020-12-09 19:09:31 +01:00
)
} }
< / p >
2022-07-12 10:55:28 +02:00
< div class = "my-2" v-if ="!hideCreateEventButton" >
< o -button
tag = "router-link"
variant = "primary"
2020-12-09 19:09:31 +01:00
: to = "{ name: RouteName.CREATE_EVENT }"
2022-07-12 10:55:28 +02:00
> { { t ( "Create event" ) } } < / o - b u t t o n
2020-12-09 19:09:31 +01:00
>
< / div >
2022-07-12 10:55:28 +02:00
<!-- < o -loading v -model :active ="$apollo.loading" > < / o - l o a d i n g > - - >
< div class = "wrapper flex flex-wrap gap-4 items-start" >
< div class = "event-filter text-violet-1 flex-auto md:flex-none" >
< o -field >
< o -switch v-model ="showUpcoming" > {{
showUpcoming ? t ( "Upcoming events" ) : t ( "Past events" )
} } < / o - s w i t c h >
< / o - f i e l d >
< o -field v-if ="showUpcoming" >
< o -checkbox v-model ="showDrafts" > {{ t ( " Drafts " ) }} < / o -checkbox >
< / o - f i e l d >
< o -field v-if ="showUpcoming" >
< o -checkbox v-model ="showAttending" > {{ t ( " Attending " ) }} < / o -checkbox >
< / o - f i e l d >
< o -field v-if ="showUpcoming" >
< o -checkbox v-model ="showMyGroups" > {{
t ( "From my groups" )
} } < / o - c h e c k b o x >
< / o - f i e l d >
< p v-if ="!showUpcoming" >
{ {
t (
"You have attended {count} events in the past." ,
{
count : pastParticipations . total ,
} ,
pastParticipations . total
)
} }
< / p >
< o -field
class = "date-filter"
expanded
: label = "
showUpcoming
? t ( 'Showing events starting on' )
: t ( 'Showing events before' )
"
>
< o -datepicker
v - model = "dateFilter"
: first - day - of - week = "firstDayOfWeek"
/ >
< o -button
@ click = "dateFilter = new Date()"
class = "reset-area"
icon - left = "close"
: title = "t('Clear date filter field')"
/ >
< / o - f i e l d >
2021-11-02 19:47:54 +01:00
< / div >
2022-07-12 10:55:28 +02:00
< div class = "my-events flex-1" >
2021-11-02 19:47:54 +01:00
< section
class = "py-4"
v - if = "showUpcoming && showDrafts && drafts.length > 0"
>
< multi -event -minimalist -card :events ="drafts" :showOrganizer ="true" / >
< / section >
< section
class = "py-4"
2020-11-30 10:24:11 +01:00
v - if = "
2022-07-12 10:55:28 +02:00
showUpcoming &&
monthlyFutureEvents &&
monthlyFutureEvents . length > 0
2020-11-30 10:24:11 +01:00
"
2020-02-18 08:57:00 +01:00
>
2021-11-02 19:47:54 +01:00
< transition -group name = "list" tag = "p" >
< div
class = "mb-5"
2022-07-12 10:55:28 +02:00
v - for = "month of monthlyFutureEvents()"
2021-11-02 19:47:54 +01:00
: key = "month[0]"
>
< span class = "upcoming-month" > { { month [ 0 ] } } < / span >
< div v-for ="element in month[1]" :key="element.id" >
< event -participation -card
v - if = "'role' in element"
: participation = "element"
: options = "{ hideDate: false }"
@ event - deleted = "eventDeleted"
class = "participation"
/ >
< event -minimalist -card
v - else - if = "
2022-07-12 10:55:28 +02:00
element . id &&
! monthParticipationsIds ( month [ 1 ] ) . includes ( element ? . id )
2021-11-02 19:47:54 +01:00
"
: event = "element"
class = "participation"
/ >
< / div >
< / div >
< / t r a n s i t i o n - g r o u p >
< div class = "columns is-centered" >
2022-07-12 10:55:28 +02:00
< o -button
2021-11-02 19:47:54 +01:00
class = "column is-narrow"
v - if = "
hasMoreFutureParticipations &&
futureParticipations &&
futureParticipations . length === limit
"
@ click = "loadMoreFutureParticipations"
2022-07-12 10:55:28 +02:00
size = "large"
variant = "primary"
> { { t ( "Load more" ) } } < / o - b u t t o n
2021-11-02 19:47:54 +01:00
>
< / div >
< / section >
< section
2022-08-12 16:46:44 +02:00
class = "text-center not-found"
2020-11-30 10:24:11 +01:00
v - if = "
2021-11-02 19:47:54 +01:00
showUpcoming &&
monthlyFutureEvents &&
2022-07-12 10:55:28 +02:00
monthlyFutureEvents . length === 0 &&
true // !$apollo.loading
2020-11-30 10:24:11 +01:00
"
2020-02-18 08:57:00 +01:00
>
2022-07-12 10:55:28 +02:00
< div class = "img-container h-64" / >
2022-08-12 16:46:44 +02:00
< div class = "text-center prose dark:prose-invert" >
2020-12-09 19:09:31 +01:00
< p >
2021-11-02 19:47:54 +01:00
{ {
2022-07-12 10:55:28 +02:00
t (
2021-11-02 19:47:54 +01:00
"You don't have any upcoming events. Maybe try another filter?"
)
} }
2020-12-09 19:09:31 +01:00
< / p >
2022-07-12 10:55:28 +02:00
< i18n -t
keypath = "Do you wish to {create_event} or {explore_events}?"
2021-11-02 19:47:54 +01:00
tag = "p"
>
2022-08-12 16:42:40 +02:00
< template # create_event >
2022-07-12 10:55:28 +02:00
< router -link : to = "{ name: RouteName.CREATE_EVENT }" > { {
t ( "create an event" )
} } < / r o u t e r - l i n k >
< / template >
2022-08-12 16:42:40 +02:00
< template # explore_events >
2022-07-12 10:55:28 +02:00
< router -link : to = "{ name: RouteName.SEARCH }" > { {
t ( "explore the events" )
} } < / r o u t e r - l i n k >
< / template >
< / i 1 8 n - t >
2020-12-09 19:09:31 +01:00
< / div >
2021-11-02 19:47:54 +01:00
< / section >
< section v-if ="!showUpcoming && pastParticipations.elements.length > 0" >
< transition -group name = "list" tag = "p" >
< div v-for ="month in monthlyPastParticipations" :key="month[0]" >
< span class = "past-month" > { { month [ 0 ] } } < / span >
< event -participation -card
v - for = "participation in month[1]"
: key = "participation.id"
2022-07-12 10:55:28 +02:00
: participation = "(participation as IParticipant)"
2021-11-02 19:47:54 +01:00
: options = "{ hideDate: false }"
@ event - deleted = "eventDeleted"
class = "participation"
/ >
< / div >
< / t r a n s i t i o n - g r o u p >
< div class = "columns is-centered" >
2022-07-12 10:55:28 +02:00
< o -button
2021-11-02 19:47:54 +01:00
class = "column is-narrow"
v - if = "
hasMorePastParticipations &&
pastParticipations . elements . length === limit
"
@ click = "loadMorePastParticipations"
2022-07-12 10:55:28 +02:00
size = "large"
variant = "primary"
> { { t ( "Load more" ) } } < / o - b u t t o n
2021-11-02 19:47:54 +01:00
>
< / div >
< / section >
2020-12-08 10:39:59 +01:00
< / div >
2021-11-02 19:47:54 +01:00
< / div >
2020-12-09 19:09:31 +01:00
< / div >
2019-09-18 17:32:37 +02:00
< / template >
2022-07-12 10:55:28 +02:00
< script lang = "ts" setup >
2020-11-27 19:27:44 +01:00
import { ParticipantRole } from "@/types/enums" ;
2020-12-09 19:09:31 +01:00
import RouteName from "@/router/name" ;
2022-07-12 10:55:28 +02:00
import { IParticipant } from "../../types/participant.model" ;
2021-11-02 19:47:54 +01:00
import { LOGGED _USER _DRAFTS } from "../../graphql/actor" ;
2022-07-12 10:55:28 +02:00
import { IEvent } from "../../types/event.model" ;
2021-11-02 19:47:54 +01:00
import EventParticipationCard from "../../components/Event/EventParticipationCard.vue" ;
import MultiEventMinimalistCard from "../../components/Event/MultiEventMinimalistCard.vue" ;
import EventMinimalistCard from "../../components/Event/EventMinimalistCard.vue" ;
import {
LOGGED _USER _PARTICIPATIONS ,
LOGGED _USER _UPCOMING _EVENTS ,
} from "@/graphql/participant" ;
2022-07-12 10:55:28 +02:00
import { useQuery } from "@vue/apollo-composable" ;
import { computed , inject , ref } from "vue" ;
import { IUser } from "@/types/current-user.model" ;
import { booleanTransformer , useRouteQuery } from "vue-use-route-query" ;
import { Locale } from "date-fns" ;
import { useI18n } from "vue-i18n" ;
import { useRestrictions } from "@/composition/apollo/config" ;
2021-11-02 19:47:54 +01:00
type Eventable = IParticipant | IEvent ;
2019-09-18 17:32:37 +02:00
2022-07-12 10:55:28 +02:00
const { t } = useI18n ( { useScope : "global" } ) ;
2021-11-02 19:47:54 +01:00
2022-07-12 10:55:28 +02:00
const futurePage = ref ( 1 ) ;
const pastPage = ref ( 1 ) ;
const limit = ref ( 10 ) ;
2021-11-02 19:47:54 +01:00
2022-07-12 10:55:28 +02:00
const showUpcoming = useRouteQuery ( "showUpcoming" , true , booleanTransformer ) ;
const showDrafts = useRouteQuery ( "showDrafts" , true , booleanTransformer ) ;
const showAttending = useRouteQuery ( "showAttending" , true , booleanTransformer ) ;
const showMyGroups = useRouteQuery ( "showMyGroups" , false , booleanTransformer ) ;
const dateFilter = useRouteQuery ( "dateFilter" , new Date ( ) , {
fromQuery ( query ) {
2021-11-02 19:47:54 +01:00
if ( query && /(\d{4}-\d{2}-\d{2})/ . test ( query ) ) {
return new Date ( ` ${ query } T00:00:00Z ` ) ;
}
return new Date ( ) ;
2022-07-12 10:55:28 +02:00
} ,
toQuery ( value : Date ) {
2021-11-02 19:47:54 +01:00
const pad = ( number : number ) => {
if ( number < 10 ) {
return "0" + number ;
}
return number ;
} ;
2022-07-12 10:55:28 +02:00
return ` ${ value . getFullYear ( ) } - ${ pad ( value . getMonth ( ) + 1 ) } - ${ pad (
value . getDate ( )
) } ` ;
} ,
} ) ;
const hasMoreFutureParticipations = ref ( true ) ;
const hasMorePastParticipations = ref ( true ) ;
// config: CONFIG
const {
result : loggedUserUpcomingEventsResult ,
fetchMore : fetchMoreUpcomingEvents ,
} = useQuery < {
loggedUser : IUser ;
} > ( LOGGED _USER _UPCOMING _EVENTS , ( ) => ( {
page : 1 ,
limit : 10 ,
afterDateTime : dateFilter . value ,
} ) ) ;
const futureParticipations = computed (
( ) =>
loggedUserUpcomingEventsResult . value ? . loggedUser . participations . elements ? ?
[ ]
) ;
const groupEvents = computed (
( ) =>
loggedUserUpcomingEventsResult . value ? . loggedUser . followedGroupEvents
. elements ? ? [ ]
) ;
const { result : draftsResult } = useQuery < {
loggedUser : Pick < IUser , " drafts " > ;
} > ( LOGGED _USER _DRAFTS , ( ) => ( { page : 1 , limit : 10 } ) ) ;
const drafts = computed ( ( ) => draftsResult . value ? . loggedUser . drafts ? ? [ ] ) ;
const { result : participationsResult , fetchMore : fetchMoreParticipations } =
useQuery < {
loggedUser : Pick < IUser , " participations " > ;
} > ( LOGGED _USER _PARTICIPATIONS , ( ) => ( { page : 1 , limit : 10 } ) ) ;
const pastParticipations = computed (
( ) =>
participationsResult . value ? . loggedUser . participations ? ? {
elements : [ ] ,
total : 0 ,
2021-11-02 19:47:54 +01:00
}
2022-07-12 10:55:28 +02:00
) ;
// metaInfo() {
// return {
// title: this.t("My events") as string,
// };
// },
const monthlyEvents = (
elements : Eventable [ ] ,
revertSort = false
) : Map < string , Eventable [ ] > => {
const res = elements . filter ( ( element : Eventable ) => {
if ( "role" in element ) {
return (
element . event . beginsOn != null &&
element . role !== ParticipantRole . REJECTED
) ;
2020-07-06 17:35:03 +02:00
}
2022-07-12 10:55:28 +02:00
return element . beginsOn != null ;
} ) ;
if ( revertSort ) {
res . sort ( ( a : Eventable , b : Eventable ) => {
const aTime = "role" in a ? a . event . beginsOn : a . beginsOn ;
const bTime = "role" in b ? b . event . beginsOn : b . beginsOn ;
return new Date ( bTime ) . getTime ( ) - new Date ( aTime ) . getTime ( ) ;
} ) ;
} else {
res . sort ( ( a : Eventable , b : Eventable ) => {
const aTime = "role" in a ? a . event . beginsOn : a . beginsOn ;
const bTime = "role" in b ? b . event . beginsOn : b . beginsOn ;
return new Date ( aTime ) . getTime ( ) - new Date ( bTime ) . getTime ( ) ;
} ) ;
2019-09-18 17:32:37 +02:00
}
2022-07-12 10:55:28 +02:00
return res . reduce ( ( acc : Map < string , Eventable [ ] > , element : Eventable ) => {
const month = new Date (
"role" in element ? element . event . beginsOn : element . beginsOn
) . toLocaleDateString ( undefined , {
year : "numeric" ,
month : "long" ,
} ) ;
const filteredElements : Eventable [ ] = acc . get ( month ) || [ ] ;
filteredElements . push ( element ) ;
acc . set ( month , filteredElements ) ;
return acc ;
} , new Map ( ) ) ;
} ;
const monthlyFutureEvents = ( ) : Map < string , Eventable [ ] > => {
let eventable = [ ] as Eventable [ ] ;
if ( showAttending . value ) {
eventable = [ ... eventable , ... futureParticipations . value ] ;
2019-09-18 17:32:37 +02:00
}
2022-07-12 10:55:28 +02:00
if ( showMyGroups . value ) {
eventable = [ ... eventable , ... groupEvents . value ] ;
2021-11-02 19:47:54 +01:00
}
2022-07-12 10:55:28 +02:00
return monthlyEvents ( eventable ) ;
} ;
const monthlyPastParticipations = computed ( ( ) : Map < string , Eventable [ ] > => {
return monthlyEvents ( pastParticipations . value . elements , true ) ;
} ) ;
const monthParticipationsIds = ( elements : Eventable [ ] ) : string [ ] => {
const res = elements . filter ( ( element : Eventable ) => {
return "role" in element ;
} ) as IParticipant [ ] ;
return res . map ( ( { event } : { event : IEvent } ) => {
return event . id as string ;
} ) ;
} ;
const loadMoreFutureParticipations = ( ) : void => {
futurePage . value += 1 ;
if ( fetchMoreUpcomingEvents ) {
fetchMoreUpcomingEvents ( {
// New variables
variables : {
page : futurePage . value ,
limit : limit . value ,
} ,
2021-11-02 19:47:54 +01:00
} ) ;
2019-09-18 17:32:37 +02:00
}
2022-07-12 10:55:28 +02:00
} ;
2019-09-18 17:32:37 +02:00
2022-07-12 10:55:28 +02:00
const loadMorePastParticipations = ( ) : void => {
pastPage . value += 1 ;
if ( fetchMoreParticipations ) {
fetchMoreParticipations ( {
// New variables
variables : {
page : pastPage . value ,
limit : limit . value ,
} ,
} ) ;
2019-09-18 17:32:37 +02:00
}
2022-07-12 10:55:28 +02:00
} ;
const eventDeleted = ( eventid : string ) : void => {
futureParticipations . value = futureParticipations . value . filter (
( participation ) => participation . event . id !== eventid
) ;
pastParticipations . value = {
elements : pastParticipations . value . elements . filter (
( participation ) => participation . event . id !== eventid
) ,
total : pastParticipations . value . total - 1 ,
} ;
} ;
2019-09-18 17:32:37 +02:00
2022-07-12 10:55:28 +02:00
const { restrictions } = useRestrictions ( ) ;
2019-09-18 17:32:37 +02:00
2022-07-12 10:55:28 +02:00
const hideCreateEventButton = computed ( ( ) : boolean => {
return restrictions . value ? . onlyGroupsCanCreateEvents === true ;
} ) ;
2021-10-06 18:00:50 +02:00
2022-07-12 10:55:28 +02:00
const dateFnsLocale = inject < Locale > ( "dateFnsLocale" ) ;
2021-12-13 17:20:33 +01:00
2022-07-12 10:55:28 +02:00
const firstDayOfWeek = computed ( ( ) : number => {
return dateFnsLocale ? . options ? . weekStartsOn ? ? 0 ;
} ) ;
2019-09-18 17:32:37 +02:00
< / script >
< style lang = "scss" scoped >
2020-02-18 08:57:00 +01:00
. participation {
margin : 1 rem auto ;
}
2019-09-18 17:32:37 +02:00
2020-02-18 08:57:00 +01:00
section {
2021-06-11 18:31:24 +02:00
. upcoming - month ,
. past - month {
2020-02-18 08:57:00 +01:00
text - transform : capitalize ;
2021-06-11 18:31:24 +02:00
display : inline - block ;
position : relative ;
font - size : 1.3 rem ;
& : : after {
position : absolute ;
left : 0 ;
right : 0 ;
top : 100 % ;
content : "" ;
width : calc ( 100 % + 30 px ) ;
height : 3 px ;
max - width : 150 px ;
}
2020-02-18 08:57:00 +01:00
}
}
2020-12-09 19:09:31 +01:00
. not - found {
2021-11-02 19:47:54 +01:00
margin - top : 2 rem ;
2020-12-09 19:09:31 +01:00
. img - container {
2022-07-12 10:55:28 +02:00
background - image : url ( "/img/pics/event_creation-480w.webp" ) ;
2020-12-11 15:27:04 +01:00
@ media ( min - resolution : 2 dppx ) {
& {
2022-07-12 10:55:28 +02:00
background - image : url ( "/img/pics/event_creation-1024w.webp" ) ;
2020-12-11 15:27:04 +01:00
}
}
2020-12-09 19:09:31 +01:00
max - width : 450 px ;
height : 300 px ;
box - shadow : 0 0 8 px 8 px white inset ;
2022-07-12 10:55:28 +02:00
@ media ( prefers - color - scheme : dark ) {
box - shadow : 0 0 8 px 8 px # 374151 inset ;
}
2020-12-09 19:09:31 +01:00
background - size : cover ;
border - radius : 10 px ;
margin : auto auto 1 rem ;
}
}
2021-11-02 19:47:54 +01:00
. wrapper {
2022-07-12 10:55:28 +02:00
// display: grid;
// grid-template-areas: "filter" "events";
// align-items: start;
// // @include desktop {
// gap: 2rem;
// grid-template-columns: 1fr 3fr;
// grid-template-areas: "filter events";
// // }
2021-11-02 19:47:54 +01:00
. event - filter {
grid - area : filter ;
background : lightgray ;
border - radius : 5 px ;
padding : 0.75 rem 1.25 rem 0.25 rem ;
2022-07-12 10:55:28 +02:00
// @include desktop {
// padding: 2rem 1.25rem;
// :deep(.field.is-grouped) {
// display: block;
// }
// }
2021-11-02 19:47:54 +01:00
2022-07-12 10:55:28 +02:00
: deep ( . field > . field ) {
2021-11-02 19:47:54 +01:00
margin : 0 auto 1.25 rem ! important ;
}
2022-07-12 10:55:28 +02:00
. date - filter : deep ( . field - body ) {
2021-11-02 19:47:54 +01:00
display : block ;
}
}
. my - events {
grid - area : events ;
}
}
2019-09-18 17:32:37 +02:00
< / style >