Encore des commits degeu
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
90de5a105b
commit
63b63d9ee2
5416
js/package-lock.json
generated
5416
js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@
|
|||
"test:e2e": "vue-cli-service test:e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"material-design-icons-iconfont": "^3.0.3",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"moment": "^2.22.1",
|
||||
"ngeohash": "^0.6.0",
|
||||
"register-service-worker": "^1.0.0",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>eventos</title>
|
||||
<title>eventos</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<v-avatar size="125px">
|
||||
<img v-if="!account.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
src="https://picsum.photos/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
|
@ -84,7 +84,7 @@
|
|||
<v-card-media
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="http://lorempixel.com/400/200/"
|
||||
src="https://picsum.photos/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
|
@ -125,7 +125,7 @@
|
|||
<v-card-media
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="http://lorempixel.com/400/200/"
|
||||
src="https://picsum.photos/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
|
|
|
@ -28,54 +28,63 @@
|
|||
</v-list>
|
||||
</v-menu>
|
||||
</v-card-title>
|
||||
<v-container grid-list-md text-xs-center>
|
||||
<v-card-media
|
||||
src="https://picsum.photos/600/400/"
|
||||
height="200px"
|
||||
>
|
||||
|
||||
</v-card-media>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs6>
|
||||
<v-spacer></v-spacer>
|
||||
<div class="text-xs-center">
|
||||
<v-card-title class="pl-5 pt-5">
|
||||
<div class="display-1 pl-5 pt-5">{{ event.title }}</div>
|
||||
</v-card-title>
|
||||
<span class="subheading grey--text">{{ event.begins_on | formatDay }}</span>
|
||||
<h1 class="display-2">{{ event.title }}</h1>
|
||||
<div>
|
||||
<router-link :to="{name: 'Account', params: { name: event.organizer.username } }">
|
||||
<v-avatar size="25px">
|
||||
<img class="img-circle elevation-7 mb-1"
|
||||
:src="event.organizer.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
<span v-if="event.organizer">Organisé par {{ event.organizer.display_name }}</span>
|
||||
</div>
|
||||
<p>
|
||||
<vue-markdown :source="event.description" />
|
||||
</p>
|
||||
<!--<p><router-link :to="{ name: 'Account', params: {id: event.organizer.id} }"><span class="grey--text">{{ event.organizer.username }}</span></router-link> organises {{ event.title }} <span v-if="event.address.addressLocality">in {{ event.address.addressLocality }}</span> on the {{ event.startDate | formatDate }}.</p>
|
||||
<v-card-text v-if="event.description"><vue-markdown :source="event.description"></vue-markdown></v-card-text>-->
|
||||
</div>
|
||||
</v-flex>
|
||||
<v-flex xs6>
|
||||
<v-card-actions>
|
||||
<v-btn color="success" v-if="!event.participants.map(participant => participant.id).includes($store.state.user.actor.id)" @click="joinEvent" class="btn btn-primary"><v-icon>check</v-icon> Join</v-btn>
|
||||
<v-btn v-if="event.participants.map(participant => participant.id).includes($store.state.user.actor.id)" @click="leaveEvent" class="btn btn-primary">Leave</v-btn>
|
||||
</v-card-actions>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<v-container fluid grid-list-md>
|
||||
<v-subheader>Membres</v-subheader>
|
||||
<v-layout row>
|
||||
<v-flex xs2>
|
||||
<router-link :to="{name: 'Account', params: {'id': event.organizer.id}}">
|
||||
<v-flex xs2 v-for="actor in event.participants" :key="actor.uuid">
|
||||
<router-link :to="{name: 'Account', params: { name: actor.username }}">
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!event.organizer.avatar_url"
|
||||
<img v-if="!actor.avatar"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
src="https://picsum.photos/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="event.organizer.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
Organisateur <span>{{ event.organizer.username }}</span>
|
||||
</v-flex>
|
||||
<v-flex xs2 v-for="actor in event.participants" :key="actor.id">
|
||||
<router-link :to="{name: 'Account', params: {'id': actor.id}}">
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!account.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="account.avatar_url"
|
||||
:src="actor.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
<span>{{ actor.username }}</span>
|
||||
</v-flex>
|
||||
<span v-if="event.participants.length === 0">No participants yet.</span>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<v-card-actions>
|
||||
<button v-if="!event.participants.map(participant => participant.id).includes($store.state.user.actor.id)" @click="joinEvent" class="btn btn-primary">Join</button>
|
||||
<button v-if="event.participants.map(participant => participant.id).includes($store.state.user.actor.id)" @click="leaveEvent" class="btn btn-primary">Leave</button>
|
||||
<button @click="deleteEvent" class="btn btn-danger">Delete</button>
|
||||
</v-card-actions>
|
||||
</v-layout>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
|
@ -97,9 +106,10 @@
|
|||
loading: true,
|
||||
error: false,
|
||||
event: {
|
||||
name: this.name,
|
||||
slug: this.slug,
|
||||
name: '',
|
||||
slug: '',
|
||||
title: '',
|
||||
uuid: this.uuid,
|
||||
description: '',
|
||||
organizer: {
|
||||
id: null,
|
||||
|
@ -112,11 +122,11 @@
|
|||
methods: {
|
||||
deleteEvent() {
|
||||
const router = this.$router;
|
||||
eventFetch(`/events/${this.name}/${this.slug}`, this.$store, { method: 'DELETE' })
|
||||
eventFetch(`/events/${this.uuid}`, this.$store, { method: 'DELETE' })
|
||||
.then(() => router.push({'name': 'EventList'}));
|
||||
},
|
||||
fetchData() {
|
||||
eventFetch(`/events/${this.name}/${this.slug}`, this.$store)
|
||||
eventFetch(`/events/${this.uuid}`, this.$store)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
this.loading = false;
|
||||
|
@ -130,21 +140,21 @@
|
|||
});
|
||||
},
|
||||
joinEvent() {
|
||||
eventFetch(`/events/${this.name}/${this.slug}/join`, this.$store)
|
||||
eventFetch(`/events/${this.uuid}/join`, this.$store)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
},
|
||||
leaveEvent() {
|
||||
eventFetch(`/events/${this.name}/${this.slug}/leave`, this.$store)
|
||||
eventFetch(`/events/${this.uuid}/leave`, this.$store)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
},
|
||||
downloadIcsEvent() {
|
||||
eventFetch(`/events/${this.name}/${this.slug}/ics`, this.$store, {responseType: 'arraybuffer'})
|
||||
eventFetch(`/events/${this.uuid}/ics`, this.$store, {responseType: 'arraybuffer'})
|
||||
.then((response) => response.text())
|
||||
.then(response => {
|
||||
const blob = new Blob([response],{type: 'text/calendar'});
|
||||
|
@ -158,14 +168,10 @@
|
|||
},
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
uuid: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
slug: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchData();
|
||||
|
|
|
@ -1,35 +1,43 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<v-layout>
|
||||
<v-flex xs12 sm8 offset-sm2>
|
||||
<v-card>
|
||||
<h1>{{ $t("event.list.title") }}</h1>
|
||||
|
||||
<v-progress-circular v-if="loading" indeterminate color="primary"></v-progress-circular>
|
||||
<v-chip close v-model="locationChip" label color="pink" text-color="white" v-if="$router.currentRoute.params.location">
|
||||
<v-icon left>location_city</v-icon>{{ locationText }}
|
||||
</v-chip>
|
||||
<v-layout row wrap justify-space-around>
|
||||
<v-flex xs12 md3 v-for="event in events" :key="event.id">
|
||||
<v-container grid-list-sm fluid>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs4 v-for="event in events" :key="event.id">
|
||||
<v-card>
|
||||
<v-card-media v-if="event.image"
|
||||
<v-card-media v-if="!event.image"
|
||||
class="white--text"
|
||||
height="200px"
|
||||
src="http://lorempixel.com/400/200/"
|
||||
src="https://picsum.photos/g/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
<v-flex xs12 align-end flexbox>
|
||||
<span class="headline">{{ event.title }}</span>
|
||||
<span class="headline black--text">{{ event.title }}</span>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-card-media>
|
||||
<v-card-title v-else primary-title>
|
||||
<div class="headline">{{ event.title }}</div>
|
||||
</v-card-title>
|
||||
<v-container>
|
||||
<!--<span class="grey--text">{{ event.startDate | formatDate }} à <router-link :to="{name: 'EventList', params: {location: geocode(event.address.geo.latitude, event.address.geo.longitude, 10) }}">{{ event.address.addressLocality }}</router-link></span><br>-->
|
||||
<p><vue-markdown>{{ event.description }}</vue-markdown></p>
|
||||
<p v-if="event.organizer">Organisé par <router-link :to="{name: 'Account', params: {'name': event.organizer.username}}">{{ event.organizer.username }}</router-link></p>
|
||||
</v-container>
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<span class="grey--text">{{ event.begins_on | formatDate }}</span><br>
|
||||
<router-link :to="{name: 'Account', params: { name: event.organizer.username } }">
|
||||
<v-avatar size="25px">
|
||||
<img class="img-circle elevation-7 mb-1"
|
||||
:src="event.organizer.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
<span v-if="event.organizer">Organisé par <router-link :to="{name: 'Account', params: {'name': event.organizer.username}}">{{ event.organizer.username }}</router-link></span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-actions>
|
||||
<v-btn flat color="orange" @click="downloadIcsEvent(event)">Share</v-btn>
|
||||
<v-btn flat color="orange" @click="viewEvent(event)">Explore</v-btn>
|
||||
|
@ -38,8 +46,11 @@
|
|||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<router-link :to="{ name: 'CreateEvent' }" class="btn btn-default">Create</router-link>
|
||||
</v-container>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -96,18 +107,19 @@
|
|||
.then((response) => {
|
||||
this.loading = false;
|
||||
this.events = response.data;
|
||||
console.log(this.events);
|
||||
});
|
||||
},
|
||||
deleteEvent(event) {
|
||||
const router = this.$router;
|
||||
eventFetch(`/events/${event.organizer.username}/${event.slug}`, this.$store, {'method': 'DELETE'})
|
||||
eventFetch(`/events/${event.uuid}`, this.$store, {'method': 'DELETE'})
|
||||
.then(() => router.push('/events'));
|
||||
},
|
||||
viewEvent(event) {
|
||||
this.$router.push({ name: 'Event', params: { name: event.organizer.username, slug: event.slug } })
|
||||
this.$router.push({ name: 'Event', params: { uuid: event.uuid } })
|
||||
},
|
||||
downloadIcsEvent(event) {
|
||||
eventFetch(`/events/${event.organizer.username}/${event.slug}/export`, this.$store, {responseType: 'arraybuffer'})
|
||||
eventFetch(`/events/${event.uuid}/ics`, this.$store, {responseType: 'arraybuffer'})
|
||||
.then((response) => response.text())
|
||||
.then(response => {
|
||||
const blob = new Blob([response],{type: 'text/calendar'});
|
||||
|
|
|
@ -4,37 +4,57 @@
|
|||
<v-flex xs12 sm6 offset-sm3>
|
||||
<v-progress-circular v-if="loading" indeterminate color="primary"></v-progress-circular>
|
||||
<v-card v-if="!loading">
|
||||
<v-layout column class="media">
|
||||
<v-card-title>
|
||||
<v-btn icon @click="$router.go(-1)">
|
||||
<v-icon>chevron_left</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon class="mr-3" v-if="$store.state.user">
|
||||
<v-icon>edit</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-spacer></v-spacer>
|
||||
<div class="text-xs-center">
|
||||
<v-avatar size="125px">
|
||||
<img v-if="!group.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="group.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
<v-card-title class="pl-5 pt-5">
|
||||
<div class="display-1 pl-5 pt-5">{{ group.title }}<span v-if="group.server">@{{ group.server.address }}</span></div>
|
||||
<v-card-media :src="group.banner" height="400px">
|
||||
<v-layout column class="media">
|
||||
<v-card-title>
|
||||
<v-btn icon @click="$router.go(-1)">
|
||||
<v-icon>chevron_left</v-icon>
|
||||
</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<!--<v-btn icon class="mr-3" v-if="$store.state.user && $store.state.user.actor.id === actor.id">-->
|
||||
<!--<v-icon>edit</v-icon>-->
|
||||
<!--</v-btn>-->
|
||||
<v-btn icon>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text v-html="group.description"></v-card-text>
|
||||
</div>
|
||||
</v-layout>
|
||||
<v-spacer></v-spacer>
|
||||
<div class="text-xs-center">
|
||||
<v-avatar size="125px">
|
||||
<img v-if="!group.avatar"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="https://picsum.photos/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="group.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</div>
|
||||
<v-container fluid grid-list-lg>
|
||||
<v-layout row>
|
||||
<v-flex xs7>
|
||||
<div class="headline">{{ group.display_name }}</div>
|
||||
<div>
|
||||
<span class="subheading">
|
||||
~{{ group.username }}
|
||||
<span v-if="group.domain">
|
||||
@{{ group.domain }}
|
||||
</span>
|
||||
</span>
|
||||
<v-chip color="indigo" text-color="white">
|
||||
<v-avatar>
|
||||
<v-icon>group</v-icon>
|
||||
</v-avatar>
|
||||
Group
|
||||
</v-chip>
|
||||
</div>
|
||||
<v-card-text v-if="group.description" v-html="group.description"></v-card-text>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-layout>
|
||||
</v-card-media>
|
||||
<v-list three-line>
|
||||
<v-list-tile>
|
||||
<v-list-tile-action>
|
||||
|
@ -59,48 +79,90 @@
|
|||
</v-list-tile-content>
|
||||
</v-list-tile>
|
||||
<v-divider inset></v-divider>
|
||||
<v-list-tile v-if="group.address">
|
||||
<v-list-tile>
|
||||
<v-list-tile-action>
|
||||
<v-icon color="indigo">location_on</v-icon>
|
||||
</v-list-tile-action>
|
||||
<v-list-tile-content>
|
||||
<v-list-tile-title>{{ group.address.streetAddress }}</v-list-tile-title>
|
||||
<v-list-tile-sub-title>{{ group.address.postalCode }} {{ group.address.locality }}</v-list-tile-sub-title>
|
||||
<v-list-tile-title>1400 Main Street</v-list-tile-title>
|
||||
<v-list-tile-sub-title>Orlando, FL 79938</v-list-tile-sub-title>
|
||||
</v-list-tile-content>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
<v-container fluid grid-list-md v-if="group.members.length > 0">
|
||||
<v-subheader>Membres</v-subheader>
|
||||
<v-layout row>
|
||||
<v-flex xs2 v-for="member in group.members" :key="member.id">
|
||||
<router-link :to="{name: 'Account', params: {'id': member.actor.id}}">
|
||||
<v-flex xs2 v-for="member in group.members" :key="member.actor.username">
|
||||
<router-link :to="{name: 'Account', params: { name: member.actor.username } }">
|
||||
<v-badge overlap>
|
||||
<span slot="badge" v-if="member.role == 3"><v-icon>stars</v-icon></span>
|
||||
<span slot="badge" v-if="member.role === 1"><v-icon>star_half</v-icon></span>
|
||||
<span slot="badge" v-if="member.role === 2"><v-icon>star</v-icon></span>
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!member.account.avatar_url"
|
||||
<img v-if="!member.actor.avatar"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
src="https://picsum.photos/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="member.account.avatar_url"
|
||||
:src="member.actor.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</v-badge>
|
||||
</router-link>
|
||||
<span>{{ groupAccount.actor.username }}</span>
|
||||
<span>{{ member.actor.username }}</span>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<v-container fluid grid-list-md v-if="group.events.length > 0">
|
||||
<v-container fluid grid-list-md v-if="group.participatingEvents && group.participatingEvents.length > 0">
|
||||
<v-subheader>Participated at</v-subheader>
|
||||
<v-layout row wrap>
|
||||
<v-flex v-for="event in group.events" :key="event.id">
|
||||
<v-flex v-for="event in group.participatingEvents" :key="event.id">
|
||||
<v-card>
|
||||
<v-card-media
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="http://lorempixel.com/400/200/"
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="https://picsum.photos/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
<v-flex xs12 align-end flexbox>
|
||||
<span class="headline">{{ event.title }}</span>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-card-media>
|
||||
<v-card-title>
|
||||
<div>
|
||||
<span class="grey--text">{{ event.startDate | formatDate }} à {{ event.location }}</span><br>
|
||||
<p>{{ event.description }}</p>
|
||||
<p v-if="event.organizer">Organisé par <router-link :to="{name: 'Account', params: {'id': event.organizer.id}}">{{ event.organizer.username }}</router-link></p>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon>
|
||||
<v-icon>favorite</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon>
|
||||
<v-icon>bookmark</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon>
|
||||
<v-icon>share</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<v-container fluid grid-list-md v-if="group.organizingEvents && group.organizingEvents.length > 0">
|
||||
<v-subheader>Organized events</v-subheader>
|
||||
<v-layout row wrap>
|
||||
<v-flex v-for="event in group.organizingEvents" :key="event.id">
|
||||
<v-card>
|
||||
<v-card-media
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="https://picsum.photos/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
|
@ -140,40 +202,39 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import eventFetch from '@/api/eventFetch';
|
||||
|
||||
import eventFetch from '@/api/eventFetch';
|
||||
|
||||
export default {
|
||||
name: 'Group',
|
||||
props: ['id'],
|
||||
data() {
|
||||
return {
|
||||
group: {
|
||||
id: this.id,
|
||||
title: '',
|
||||
description: '',
|
||||
export default {
|
||||
name: 'Group',
|
||||
data() {
|
||||
return {
|
||||
group: null,
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
eventFetch(`/groups/${this.id}`, this.$store)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
this.loading = false;
|
||||
this.group = data.data;
|
||||
});
|
||||
},
|
||||
deleteGroup() {
|
||||
const router = this.$router;
|
||||
eventFetch(`/groups/${this.id}`, this.$store, { method: 'DELETE' })
|
||||
.then(response => response.json())
|
||||
.then(() => router.push('/groups'));
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchData();
|
||||
},
|
||||
}
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData();
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
eventFetch(`/actors/${this.name}`, this.$store)
|
||||
.then(response => response.json())
|
||||
.then((response) => {
|
||||
this.group = response.data;
|
||||
this.loading = false;
|
||||
console.log(this.group);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<v-card-media
|
||||
class="black--text"
|
||||
height="200px"
|
||||
src="http://lorempixel.com/400/200/"
|
||||
src="https://picsum.photos/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
|
@ -26,9 +26,9 @@
|
|||
</div>
|
||||
</v-card-title>
|
||||
<v-card-actions>
|
||||
<v-btn flat color="green" @click="joinGroup(group.id)"><v-icon v-if="group.locked">lock</v-icon>Join</v-btn>
|
||||
<v-btn flat color="green" @click="joinGroup(group)"><v-icon v-if="group.locked">lock</v-icon>Join</v-btn>
|
||||
<v-btn flat color="orange" @click="viewActor(group)">Explore</v-btn>
|
||||
<v-btn flat color="red" @click="deleteEvent(group.id)">Delete</v-btn>
|
||||
<v-btn flat color="red" @click="deleteGroup(group)">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
|
@ -64,20 +64,20 @@
|
|||
this.groups = data.data;
|
||||
});
|
||||
},
|
||||
deleteEvent(id) {
|
||||
deleteGroup(group) {
|
||||
const router = this.$router;
|
||||
eventFetch('/groups/' + id, this.$store, {'method': 'DELETE'})
|
||||
eventFetch(`/groups/${this.username_with_domain(group)}`, this.$store, {'method': 'DELETE'})
|
||||
.then(response => response.json())
|
||||
.then(() => router.push('/groups'));
|
||||
},
|
||||
viewActor(actor) {
|
||||
this.$router.push({ name: 'Account', params: { name: this.username_with_domain(actor) } })
|
||||
this.$router.push({ name: 'Group', params: { name: this.username_with_domain(actor) } })
|
||||
},
|
||||
joinGroup(id) {
|
||||
joinGroup(group) {
|
||||
const router = this.$router;
|
||||
eventFetch('/groups/' + id + '/join', this.$store)
|
||||
eventFetch(`/groups/${this.username_with_domain(group)}/join`, this.$store, { method: 'POST' })
|
||||
.then(response => response.json())
|
||||
.then(() => router.push('/group/' + id))
|
||||
.then(() => router.push({ name: 'Group', params: { name: this.username_with_domain(group) } }));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,10 +1,59 @@
|
|||
<template>
|
||||
<v-container>
|
||||
<h1 class="welcome" v-if="$store.state.user">{{ $t("home.welcome", { 'username': this.displayed_name }) }}</h1>
|
||||
<h1 class="welcome" v-else>{{ $t("home.welcome_off", { 'username': $store.state.user.username}) }}</h1>
|
||||
<router-link :to="{ name: 'EventList' }">{{ $t('home.events') }}</router-link>
|
||||
<router-link v-if="$store.state.user === false" :to="{ name: 'Login' }">{{ $t('home.login') }}</router-link>
|
||||
<router-link v-if="$store.state.user === false" :to="{ name: 'Register' }">{{ $t('home.register') }}</router-link>
|
||||
<v-jumbotron
|
||||
:gradient="gradient"
|
||||
src="https://picsum.photos/1200/900"
|
||||
dark
|
||||
v-if="$store.state.user === false"
|
||||
>
|
||||
<v-container fill-height>
|
||||
<v-layout align-center>
|
||||
<v-flex text-xs-center>
|
||||
<h1 class="display-3">Find events you like</h1>
|
||||
<h2>Share it with Eventos</h2>
|
||||
<v-btn>{{ $t("home.register") }}</v-btn>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-jumbotron>
|
||||
<v-layout>
|
||||
<v-flex xs12 sm8 offset-sm2>
|
||||
<v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs4 v-for="event in events" :key="event.uuid">
|
||||
<v-card :to="{ name: 'Event', params:{ uuid: event.uuid } }">
|
||||
<v-card-media v-if="!event.image"
|
||||
class="white--text"
|
||||
height="200px"
|
||||
src="https://picsum.photos/g/400/200/"
|
||||
>
|
||||
<v-container fill-height fluid>
|
||||
<v-layout fill-height>
|
||||
<v-flex xs12 align-end flexbox>
|
||||
<span class="headline black--text">{{ event.title }}</span>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-card-media>
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<span class="grey--text">{{ event.begins_on | formatDate }}</span><br>
|
||||
<router-link :to="{name: 'Account', params: { name: event.organizer.username } }">
|
||||
<v-avatar size="25px">
|
||||
<img class="img-circle elevation-7 mb-1"
|
||||
:src="event.organizer.avatar"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
<span v-if="event.organizer">Organisé par {{ event.organizer.display_name }}</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
<v-layout row>
|
||||
<v-flex xs6>
|
||||
<v-btn large @click="geoLocalize"><v-icon>my_location</v-icon>Me géolocaliser</v-btn>
|
||||
|
@ -36,6 +85,7 @@ export default {
|
|||
name: 'Home',
|
||||
data() {
|
||||
return {
|
||||
gradient: 'to top right, rgba(63,81,181, .7), rgba(25,32,72, .7)',
|
||||
user: null,
|
||||
searchTerm: null,
|
||||
location_field: {
|
||||
|
@ -43,10 +93,11 @@ export default {
|
|||
search: null,
|
||||
},
|
||||
locations: [],
|
||||
events: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// this.fetchLocations();
|
||||
created() {
|
||||
this.fetchData();
|
||||
},
|
||||
computed: {
|
||||
displayed_name: function() {
|
||||
|
@ -61,6 +112,14 @@ export default {
|
|||
this.locations = response;
|
||||
});
|
||||
},
|
||||
fetchData() {
|
||||
eventFetch('/events', this.$store)
|
||||
.then(response => response.json())
|
||||
.then((response) => {
|
||||
this.loading = false;
|
||||
this.events = response.data;
|
||||
});
|
||||
},
|
||||
geoLocalize() {
|
||||
const router = this.$router;
|
||||
if (sessionStorage.getItem('City')) {
|
||||
|
@ -85,6 +144,9 @@ export default {
|
|||
sessionStorage.setItem('City', geohash);
|
||||
this.$router.push({name: 'EventList', params: {location: geohash}});
|
||||
},
|
||||
viewEvent(event) {
|
||||
this.$router.push({ name: 'Event', params: { uuid: event.uuid } })
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<v-toolbar-title style="width: 300px" class="ml-0 pl-3">
|
||||
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
|
||||
<router-link :to="{ name: 'Home' }">
|
||||
Libre-Event
|
||||
Eventos
|
||||
</router-link>
|
||||
</v-toolbar-title>
|
||||
<v-select
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default {
|
||||
home: {
|
||||
welcome: 'Welcome on Libre-Event, {username}',
|
||||
welcome_off: 'Welcome on Libre-Event',
|
||||
welcome: 'Welcome on Eventos, {username}',
|
||||
welcome_off: 'Welcome on Eventos',
|
||||
events: 'Events',
|
||||
groups: 'Groups',
|
||||
login: 'Login',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default {
|
||||
home: {
|
||||
welcome: 'Bienvenue sur Libre-Event, {username}!',
|
||||
welcome_off: 'Bienvenue sur Libre-Event',
|
||||
welcome: 'Bienvenue sur Eventos, {username}!',
|
||||
welcome_off: 'Bienvenue sur Eventos',
|
||||
events: 'Événements',
|
||||
groups: 'Groupes',
|
||||
login: 'Se connecter',
|
||||
|
|
|
@ -8,8 +8,8 @@ import Vuetify from 'vuetify';
|
|||
import Vuex from 'vuex';
|
||||
import moment from 'moment';
|
||||
import VuexI18n from 'vuex-i18n';
|
||||
import 'material-design-icons/iconfont/material-icons.css';
|
||||
import 'vuetify/dist/vuetify.min.css';
|
||||
import 'material-design-icons-iconfont/dist/material-design-icons.css';
|
||||
import App from '@/App';
|
||||
import router from '@/router';
|
||||
import storeData from '@/store/index';
|
||||
|
@ -37,6 +37,7 @@ let language = window.navigator.userLanguage || window.navigator.language;
|
|||
moment.locale(language);
|
||||
|
||||
Vue.filter('formatDate', value => (value ? moment(String(value)).format('LLLL') : null));
|
||||
Vue.filter('formatDay', value => (value ? moment(String(value)).format('LL') : null));
|
||||
|
||||
if (!(language in translations)) {
|
||||
[language] = language.split('-', 1);
|
||||
|
|
|
@ -103,7 +103,7 @@ const router = new Router({
|
|||
meta: { requiredAuth: false },
|
||||
},
|
||||
{
|
||||
path: '/@:name/:slug',
|
||||
path: '/events/:uuid',
|
||||
name: 'Event',
|
||||
component: Event,
|
||||
props: true,
|
||||
|
|
|
@ -133,6 +133,15 @@ defmodule Eventos.Actors do
|
|||
Repo.all(from a in Actor, where: a.type == "Group")
|
||||
end
|
||||
|
||||
def get_group_by_name(name) do
|
||||
actor = case String.split(name, "@") do
|
||||
[name] ->
|
||||
Repo.get_by(Actor, preferred_username: name, type: :Group)
|
||||
[name, domain] ->
|
||||
Repo.get_by(Actor, preferred_username: name, domain: domain, type: :Group)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a group.
|
||||
|
||||
|
@ -176,7 +185,7 @@ defmodule Eventos.Actors do
|
|||
|
||||
def insert_or_update_actor(data) do
|
||||
cs = Actor.remote_actor_creation(data)
|
||||
Repo.insert(cs, on_conflict: [set: [public_key: data.public_key, avatar_url: data.avatar_url, banner: data.banner_url, name: data.name]], conflict_target: [:preferred_username, :domain])
|
||||
Repo.insert(cs, on_conflict: [set: [public_key: data.public_key, avatar_url: data.avatar_url, banner_url: data.banner_url, name: data.name]], conflict_target: [:preferred_username, :domain])
|
||||
end
|
||||
|
||||
# def increase_event_count(%Actor{} = actor) do
|
||||
|
@ -494,7 +503,8 @@ defmodule Eventos.Actors do
|
|||
def create_member(attrs \\ %{}) do
|
||||
%Member{}
|
||||
|> Member.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
|> Repo.insert!()
|
||||
|> Repo.preload([:actor, :parent])
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -544,6 +554,22 @@ defmodule Eventos.Actors do
|
|||
Member.changeset(member, %{})
|
||||
end
|
||||
|
||||
def groups_for_actor(%Actor{id: id} = _actor) do
|
||||
Repo.all(
|
||||
from m in Member,
|
||||
where: m.actor_id == ^id,
|
||||
preload: [:parent]
|
||||
)
|
||||
end
|
||||
|
||||
def members_for_group(%Actor{type: :Group, id: id} = _group) do
|
||||
Repo.all(
|
||||
from m in Member,
|
||||
where: m.parent_id == ^id,
|
||||
preload: [:parent, :actor]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
alias Eventos.Actors.Bot
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ defmodule Eventos.Actors.Member do
|
|||
alias Eventos.Actors.Member
|
||||
alias Eventos.Actors.Actor
|
||||
|
||||
|
||||
@primary_key false
|
||||
schema "members" do
|
||||
field :approved, :boolean
|
||||
field :role, :integer
|
||||
field :approved, :boolean, default: true
|
||||
field :role, :integer, default: 0 # 0 : Member, 1 : Moderator, 2 : Admin
|
||||
belongs_to :parent, Actor
|
||||
belongs_to :actor, Actor
|
||||
|
||||
|
@ -20,7 +20,7 @@ defmodule Eventos.Actors.Member do
|
|||
@doc false
|
||||
def changeset(%Member{} = member, attrs) do
|
||||
member
|
||||
|> cast(attrs, [:role])
|
||||
|> validate_required([:role])
|
||||
|> cast(attrs, [:role, :approved, :parent_id, :actor_id])
|
||||
|> validate_required([:parent_id, :actor_id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,6 +26,5 @@ defmodule Eventos.Addresses.Address do
|
|||
def changeset(%Address{} = address, attrs) do
|
||||
address
|
||||
|> cast(attrs, [:description, :floor, :geom, :addressCountry, :addressLocality, :addressRegion, :postalCode, :streetAddress])
|
||||
|> validate_required([:geom])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,7 @@ defmodule Eventos.Events.Event do
|
|||
field :thumbnail, :string
|
||||
field :large_image, :string
|
||||
field :publish_at, Timex.Ecto.DateTimeWithTimezone
|
||||
field :uuid, Ecto.UUID, default: Ecto.UUID.generate()
|
||||
belongs_to :organizer_actor, Actor, [foreign_key: :organizer_actor_id]
|
||||
many_to_many :tags, Tag, join_through: "events_tags"
|
||||
belongs_to :category, Category
|
||||
|
@ -64,12 +65,17 @@ defmodule Eventos.Events.Event do
|
|||
|
||||
@doc false
|
||||
def changeset(%Event{} = event, attrs) do
|
||||
event
|
||||
changeset = event
|
||||
|> cast(attrs, [:title, :description, :url, :begins_on, :ends_on, :organizer_actor_id, :category_id, :state, :status, :public, :thumbnail, :large_image, :publish_at])
|
||||
|> cast_assoc(:tags)
|
||||
|> cast_assoc(:address)
|
||||
|> validate_required([:title, :description, :begins_on, :ends_on, :organizer_actor_id, :category_id])
|
||||
|> TitleSlug.maybe_generate_slug()
|
||||
|> TitleSlug.unique_constraint()
|
||||
|> put_change(:uuid, Ecto.UUID.generate())
|
||||
|
||||
import Logger
|
||||
Logger.debug(inspect changeset)
|
||||
changeset
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,6 +77,13 @@ defmodule Eventos.Events do
|
|||
Repo.get_by(Event, url: url)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets an event by it's UUID
|
||||
"""
|
||||
def get_event_by_uuid(uuid) do
|
||||
Repo.get_by(Event, uuid: uuid)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single event, with all associations loaded.
|
||||
"""
|
||||
|
@ -93,6 +100,14 @@ defmodule Eventos.Events do
|
|||
Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :address])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a full event by it's UUID
|
||||
"""
|
||||
def get_event_full_by_uuid(uuid) do
|
||||
event = Repo.get_by(Event, uuid: uuid)
|
||||
Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :address])
|
||||
end
|
||||
|
||||
@spec get_event_full_by_name_and_slug!(String.t, String.t) :: Event.t
|
||||
def get_event_full_by_name_and_slug!(name, slug) do
|
||||
query = case String.split(name, "@") do
|
||||
|
@ -139,7 +154,8 @@ defmodule Eventos.Events do
|
|||
def create_event(attrs \\ %{}) do
|
||||
%Event{}
|
||||
|> Event.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
|> Repo.insert!()
|
||||
|> Repo.preload([:organizer_actor])
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule Eventos.Events.Participant do
|
|||
|
||||
@primary_key false
|
||||
schema "participants" do
|
||||
field :role, :integer
|
||||
field :role, :integer, default: 0 # 0 : participant, 1 : moderator, 2 : administrator, 3 : creator
|
||||
field :approved, :boolean
|
||||
belongs_to :event, Event, primary_key: true
|
||||
belongs_to :actor, Actor, primary_key: true
|
||||
|
|
|
@ -11,7 +11,8 @@ defmodule Eventos.Export.ICalendar do
|
|||
summary: event.title,
|
||||
dtstart: event.begins_on,
|
||||
dtend: event.ends_on,
|
||||
description: event.description
|
||||
description: event.description,
|
||||
uid: event.uuid
|
||||
}]
|
||||
%ICalendar{events: events}
|
||||
|> ICalendar.to_ics()
|
||||
|
|
|
@ -27,6 +27,27 @@ defmodule EventosWeb.AddressController do
|
|||
end
|
||||
end
|
||||
|
||||
def process_geom(%{"type" => type, "data" => data}) do
|
||||
import Logger
|
||||
Logger.debug("Process geom")
|
||||
Logger.debug(inspect data)
|
||||
Logger.debug(inspect type)
|
||||
types = [:point]
|
||||
unless is_atom(type) do
|
||||
type = String.to_existing_atom(type)
|
||||
end
|
||||
case type do
|
||||
:point ->
|
||||
%Geo.Point{coordinates: {data["latitude"], data["longitude"]}, srid: 4326}
|
||||
nil ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def process_geom(nil) do
|
||||
nil
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
address = Addresses.get_address!(id)
|
||||
render(conn, "show.json", address: address)
|
||||
|
|
|
@ -17,18 +17,30 @@ defmodule EventosWeb.EventController do
|
|||
end
|
||||
|
||||
def create(conn, %{"event" => event_params}) do
|
||||
event_params = %{event_params | "address" => process_address(event_params["address"])}
|
||||
address = process_address(event_params["address"])
|
||||
event_params = if is_nil address do
|
||||
event_params
|
||||
else
|
||||
%{event_params | "address" => address}
|
||||
end
|
||||
with {:ok, %Event{} = event} <- Events.create_event(event_params) do
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> put_resp_header("location", event_path(conn, :show, event))
|
||||
|> put_resp_header("location", event_path(conn, :show, event.uuid))
|
||||
|> render("show_simple.json", event: event)
|
||||
end
|
||||
end
|
||||
|
||||
defp process_address(address) do
|
||||
case Addresses.process_geom(address["geom"]) do
|
||||
{:ok, geom} ->
|
||||
import Logger
|
||||
Logger.debug("process address")
|
||||
Logger.debug(inspect address)
|
||||
geom = EventosWeb.AddressController.process_geom(address["geom"])
|
||||
Logger.debug(inspect geom)
|
||||
case geom do
|
||||
nil ->
|
||||
address
|
||||
_ ->
|
||||
%{address | "geom" => geom}
|
||||
_ ->
|
||||
address
|
||||
|
@ -40,27 +52,26 @@ defmodule EventosWeb.EventController do
|
|||
render(conn, "index.json", events: events)
|
||||
end
|
||||
|
||||
def show(conn, %{"username" => username, "slug" => slug}) do
|
||||
event = Events.get_event_full_by_name_and_slug!(username, slug)
|
||||
def show(conn, %{"uuid" => uuid}) do
|
||||
event = Events.get_event_full_by_uuid(uuid)
|
||||
render(conn, "show.json", event: event)
|
||||
end
|
||||
|
||||
def export_to_ics(conn, %{"username" => username, "slug" => slug}) do
|
||||
event = Events.get_event_full_by_name_and_slug!(username, slug)
|
||||
|> ICalendar.export_event()
|
||||
def export_to_ics(conn, %{"uuid" => uuid}) do
|
||||
event = Events.get_event_full_by_uuid(uuid) |> ICalendar.export_event()
|
||||
send_resp(conn, 200, event)
|
||||
end
|
||||
|
||||
def update(conn, %{"username" => username, "slug" => slug, "event" => event_params}) do
|
||||
event = Events.get_event_full_by_name_and_slug!(username, slug)
|
||||
def update(conn, %{"uuid" => uuid, "event" => event_params}) do
|
||||
event = Events.get_event_full_by_uuid(uuid)
|
||||
|
||||
with {:ok, %Event{} = event} <- Events.update_event(event, event_params) do
|
||||
render(conn, "show_simple.json", event: event)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"username" => username, "slug" => slug}) do
|
||||
event = Events.get_event_full_by_name_and_slug!(username, slug)
|
||||
def delete(conn, %{"uuid" => uuid}) do
|
||||
event = Events.get_event_by_uuid(uuid)
|
||||
with {:ok, %Event{}} <- Events.delete_event(event) do
|
||||
send_resp(conn, :no_content, "")
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule EventosWeb.GroupController do
|
|||
use EventosWeb, :controller
|
||||
|
||||
alias Eventos.Actors
|
||||
alias Eventos.Actors.Actor
|
||||
alias Eventos.Actors.{Actor, Member}
|
||||
|
||||
action_fallback EventosWeb.FallbackController
|
||||
|
||||
|
@ -23,4 +23,18 @@ defmodule EventosWeb.GroupController do
|
|||
|> render(EventosWeb.ActorView, "acccount_basic.json", actor: group)
|
||||
end
|
||||
end
|
||||
|
||||
def join(conn, %{"name" => group_name}) do
|
||||
with actor = Guardian.Plug.current_resource(conn).actor,
|
||||
group <- Actors.get_group_by_name(group_name),
|
||||
%Member{} = member <- Actors.create_member(%{"parent_id" => group.id, "actor_id" => actor.id}) do
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> render(EventosWeb.MemberView, "member.json", member: member)
|
||||
else
|
||||
err ->
|
||||
import Logger
|
||||
Logger.debug(inspect err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,10 +40,10 @@ defmodule EventosWeb.Router do
|
|||
get "/groups", GroupController, :index
|
||||
get "/events", EventController, :index
|
||||
get "/events/search/:name", EventController, :search
|
||||
get "/events/:username/:slug", EventController, :show
|
||||
get "/events/:username/:slug/ics", EventController, :export_to_ics
|
||||
get "/events/:username/:slug/tracks", TrackController, :show_tracks_for_event
|
||||
get "/events/:username/:slug/sessions", SessionController, :show_sessions_for_event
|
||||
get "/events/:uuid/ics", EventController, :export_to_ics
|
||||
get "/events/:uuid/tracks", TrackController, :show_tracks_for_event
|
||||
get "/events/:uuid/sessions", SessionController, :show_sessions_for_event
|
||||
get "/events/:uuid", EventController, :show
|
||||
resources "/comments", CommentController, only: [:show]
|
||||
get "/bots/:id", BotController, :view
|
||||
|
||||
|
@ -71,18 +71,17 @@ defmodule EventosWeb.Router do
|
|||
resources "/users", UserController, except: [:new, :edit, :show]
|
||||
patch "/actors/:name", ActorController, :update
|
||||
post "/events", EventController, :create
|
||||
patch "/events/:username/:slug", EventController, :update
|
||||
put "/events/:username/:slug", EventController, :update
|
||||
delete "/events/:username/:slug", EventController, :delete
|
||||
patch "/events/:uuid", EventController, :update
|
||||
put "/events/:uuid", EventController, :update
|
||||
delete "/events/:uuid", EventController, :delete
|
||||
resources "/comments", CommentController, except: [:new, :edit, :show]
|
||||
#post "/events/:id/request", EventRequestController, :create_for_event
|
||||
resources "/participant", ParticipantController
|
||||
resources "/bots", BotController, except: [:new, :edit, :show]
|
||||
#resources "/requests", EventRequestController
|
||||
post "/groups", GroupController, :create
|
||||
#post "/groups/:id/request", GroupRequestController, :create_for_group
|
||||
post "/groups/:name/join", GroupController, :join
|
||||
resources "/members", MemberController
|
||||
#resources "/requests", GroupRequestController
|
||||
resources "/sessions", SessionController, except: [:index, :show]
|
||||
resources "/tracks", TrackController, except: [:index, :show]
|
||||
get "/tracks/:id/sessions", SessionController, :show_sessions_for_track
|
||||
|
|
|
@ -3,7 +3,8 @@ defmodule EventosWeb.ActorView do
|
|||
View for Actors
|
||||
"""
|
||||
use EventosWeb, :view
|
||||
alias EventosWeb.{ActorView, EventView}
|
||||
alias EventosWeb.{ActorView, EventView, MemberView}
|
||||
alias Eventos.Actors
|
||||
|
||||
def render("index.json", %{actors: actors}) do
|
||||
%{data: render_many(actors, ActorView, "acccount_basic.json")}
|
||||
|
@ -32,7 +33,7 @@ defmodule EventosWeb.ActorView do
|
|||
end
|
||||
|
||||
def render("actor.json", %{actor: actor}) do
|
||||
%{id: actor.id,
|
||||
output = %{id: actor.id,
|
||||
username: actor.preferred_username,
|
||||
domain: actor.domain,
|
||||
display_name: actor.name,
|
||||
|
@ -45,5 +46,14 @@ defmodule EventosWeb.ActorView do
|
|||
banner: actor.banner_url,
|
||||
organized_events: render_many(actor.organized_events, EventView, "event_for_actor.json")
|
||||
}
|
||||
import Logger
|
||||
Logger.debug(inspect actor.type)
|
||||
if actor.type == :Group do
|
||||
Logger.debug("I'm a group !")
|
||||
Map.put(output, :members, render_many(Actors.members_for_group(actor), MemberView, "member.json"))
|
||||
else
|
||||
Logger.debug("not a group")
|
||||
output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,8 @@ defmodule EventosWeb.EventView do
|
|||
def render("event_for_actor.json", %{event: event}) do
|
||||
%{id: event.id,
|
||||
title: event.title,
|
||||
slug: event.slug
|
||||
slug: event.slug,
|
||||
uuid: event.uuid,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -31,8 +32,11 @@ defmodule EventosWeb.EventView do
|
|||
description: event.description,
|
||||
begins_on: event.begins_on,
|
||||
ends_on: event.ends_on,
|
||||
uuid: event.uuid,
|
||||
organizer: %{
|
||||
username: event.organizer_actor.preferred_username
|
||||
username: event.organizer_actor.preferred_username,
|
||||
display_name: event.organizer_actor.name,
|
||||
avatar: event.organizer_actor.avatar_url,
|
||||
},
|
||||
type: "Event",
|
||||
}
|
||||
|
@ -44,6 +48,7 @@ defmodule EventosWeb.EventView do
|
|||
description: event.description,
|
||||
begins_on: event.begins_on,
|
||||
ends_on: event.ends_on,
|
||||
uuid: event.uuid,
|
||||
organizer: render_one(event.organizer_actor, ActorView, "acccount_basic.json"),
|
||||
participants: render_many(event.participants, ActorView, "show_basic.json"),
|
||||
address: render_one(event.address, AddressView, "address.json"),
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule EventosWeb.MemberView do
|
|||
View for Members
|
||||
"""
|
||||
use EventosWeb, :view
|
||||
alias EventosWeb.MemberView
|
||||
alias EventosWeb.{MemberView, ActorView}
|
||||
|
||||
def render("index.json", %{members: members}) do
|
||||
%{data: render_many(members, MemberView, "member.json")}
|
||||
|
@ -14,7 +14,10 @@ defmodule EventosWeb.MemberView do
|
|||
end
|
||||
|
||||
def render("member.json", %{member: member}) do
|
||||
%{id: member.id,
|
||||
role: member.role}
|
||||
%{
|
||||
role: member.role,
|
||||
actor: render_one(member.actor, ActorView, "acccount_basic.json"),
|
||||
group: render_one(member.parent, ActorView, "acccount_basic.json")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
defmodule EventosWeb.RequestView do
|
||||
@moduledoc """
|
||||
View for event request
|
||||
"""
|
||||
use EventosWeb, :view
|
||||
alias EventosWeb.RequestView
|
||||
|
||||
def render("index.json", %{requests: requests}) do
|
||||
%{data: render_many(requests, RequestView, "request.json")}
|
||||
end
|
||||
|
||||
def render("show.json", %{request: request}) do
|
||||
%{data: render_one(request, RequestView, "request.json")}
|
||||
end
|
||||
|
||||
def render("request.json", %{request: request}) do
|
||||
%{id: request.id,
|
||||
state: request.state}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Eventos.Repo.Migrations.AddUUIDIdToEvents do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:events) do
|
||||
add :uuid, :uuid
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:events) do
|
||||
remove :uuid
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Eventos.Repo.Migrations.AddApprovedStatusToMember do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:members) do
|
||||
add :approved, :boolean, default: true
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:members) do
|
||||
remove :approved
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue