Nav and Search components

This commit is contained in:
lesion 2019-03-05 15:18:46 +01:00
parent ae5dd27603
commit eba37eb934
11 changed files with 207 additions and 159 deletions

View file

@ -1,28 +1,6 @@
<template lang='pug'>
#app
b-navbar(type="dark" variant="dark" toggleable='lg')
b-navbar-toggle(target='nav_collapse')
b-navbar-brand(to='/') <img id='logo' src='gancio_logo.svg'/>
b-collapse#nav_collapse(is-nav)
b-navbar-nav
b-nav-item(v-if='!logged' to='/login' v-b-tooltip :title='$t("Login")') <v-icon color='lightgreen' name='lock' /> {{$t('User')}}
//- b-nav-item(v-if='!logged' to='/register' v-b-tooltip :title='$t("Register")' ) <v-icon color='orange' name='user' scale='2'/>
b-nav-item(v-if='logged' to='/new_event' v-b-tooltip :title='$t("Add Event")' ) <v-icon color='lightgreen' name='plus'/>
b-nav-item(v-if='logged' to='/settings' v-b-tooltip :title='$t("Settings")') <v-icon color='orange' name='cog'/>
b-nav-item(v-if='user.is_admin' to='/admin' v-b-tooltip :title='$t("Admin")') <v-icon color='lightblue' name='tools'/>
b-nav-item(to='/export' v-b-tooltip :title='$t("Export")') <v-icon name='file-export' color='yellow'/>
b-nav-item(v-if='logged' variant='danger' @click='logout' v-b-tooltip :title='$t("Logout")') <v-icon color='red' name='sign-out-alt'/>
b-navbar-nav#search.ml-auto
b-nav-item <v-icon name='search' color='orange' />
b-nav-form
el-select.mr-1(v-model='filters_places' multiple filterable collapse-tags
default-first-option :placeholder='$t("Where")')
el-option(v-for='place in places' :value='place.name'
:label='place.name' :key='place.id')
el-select(v-model='filters_tags' multiple filterable collapse-tags
default-first-option :placeholder='$t("Tags")')
el-option(v-for='tag in tags' :key='tag.tag'
:label='tag.tag' :value='tag.tag')
Nav
Home
transition(name="fade" mode="out-in")
router-view(name='modal')
@ -30,7 +8,7 @@
<script>
import moment from 'moment'
import api from '@/api'
import { mapActions, mapState } from 'vuex';
import { mapActions } from 'vuex';
import Register from '@/components/Register'
import Login from '@/components/Login'
import Settings from '@/components/Settings'
@ -38,34 +16,15 @@ import newEvent from '@/components/newEvent'
import eventDetail from '@/components/EventDetail'
import Timeline from '@/components/Timeline'
import Home from '@/components/Home'
import Nav from '@/components/Nav'
export default {
name: 'App',
mounted () {
this.updateMeta()
},
components: { Register, Login, Home, Settings, newEvent, eventDetail },
computed: {
...mapState(['logged', 'user', 'filters', 'tags', 'places']),
filters_tags: {
set (value) {
this.setSearchTags(value)
},
get () {
return this.filters.tags
}
},
filters_places: {
set (value) {
this.setSearchPlaces(value)
},
get () {
return this.filters.places
}
}
},
methods: mapActions(['logout', 'updateMeta', 'addSearchTag',
'setSearchTags', 'setSearchPlaces', 'addSearchPlace']),
methods: mapActions(['updateMeta']),
components: { Nav, Register, Login, Home, Settings, newEvent, eventDetail },
}
</script>

View file

@ -1,5 +1,5 @@
<template lang="pug">
el-dialog(@close='$router.replace("/")' :title='$t("Admin")' center width='900px' :visible='true')
b-modal(@hidden='$router.replace("/")' :title='$t("Admin")' :visible='true' size='lg')
el-tabs
el-tab-pane.pt-1
template(slot='label')

View file

@ -1,10 +1,10 @@
<template lang="pug">
v-calendar#calendar.card(
:attributes='attributes'
:from-page.sync='page'
is-expanded is-inline)
div(slot='popover', slot-scope='{ customData }')
router-link(:to="`/event/${customData.id}`") {{customData.start_datetime|hour}} - {{customData.title}} @{{customData.place.name}}
v-calendar#calendar.card(
:attributes='attributes'
:from-page.sync='page'
is-expanded is-inline)
div(slot='popover', slot-scope='{ customData }')
router-link(:to="`/event/${customData.id}`") {{customData.start_datetime|hour}} - {{customData.title}} @{{customData.place.name}}
</template>
<script>
import { mapState, mapActions } from 'vuex'
@ -62,20 +62,8 @@ export default {
computed: {
filteredEvents () {
return this.$store.getters.filteredEvents
// if (!this.filters.tags.length && !this.filters.places.length) return this.events
// return this.events.filter(e => {
// if (this.filters.tags.length) {
// const m = intersection(e.tags.map(t => t.tag), this.filters.tags)
// if (m.length>0) return true
// }
// if (this.filters.places.length) {
// if (this.filters.places.find(p => p === e.place.name))
// return true
// }
// return 0
// })
},
...mapState(['events', 'tags', 'filters']),
...mapState(['events', 'filters', 'user', 'logged']),
attributes () {
return [
{ key: 'todaly', dates: new Date(),

View file

@ -1,18 +1,24 @@
<template lang="pug">
el-dialog#eventDetail(@close='$router.replace("/")' :visible='true' top='4vh')
img(:src='imgPath')
el-card(v-loading='loading')
h4 {{event.title}}
h6 <v-icon name='clock' /> {{event.start_datetime|datetime}}
h6 <v-icon name='map-marker-alt' /> {{event.place.name}} - {{event.place.address}}
el-card(v-if='event.description || event.tags && event.tags.length')
pre.mb-2 {{event.description}}
el-tag.mr-1(:color='tag.color' v-for='tag in event.tags'
size='mini') {{tag.tag}}
.ml-auto(v-if='mine')
hr
el-button(plain type='danger' @click.prevent='remove' icon='el-icon-remove') {{$t('Remove')}}
el-button(plain type='primary' @click='$router.replace("/edit/"+event.id)') <v-icon color='orange' name='edit'/> {{$t('Edit')}}
b-modal#eventDetail(hide-body hide-header hide-footer @hidden='$router.replace("/")' size='lg' :visible='true')
b-card(bg-variant='dark' href='#' text-variant='white'
no-body, :img-src='imgPath')
b-card-header
h3 {{event.title}}
v-icon(name='clock')
span {{event.start_datetime|datetime}}
br
v-icon(name='map-marker-alt')
span {{event.place.name}} - {{event.place.address}}
br
b-card-body(v-if='event.description || event.tags')
pre {{event.description}}
br
el-tag.mr-1(:color='tag.color' v-for='tag in event.tags'
size='mini') {{tag.tag}}
.ml-auto(v-if='mine')
hr
el-button(plain type='danger' @click.prevent='remove' icon='el-icon-remove') {{$t('Remove')}}
el-button(plain type='primary' @click='$router.replace("/edit/"+event.id)') <v-icon color='orange' name='edit'/> {{$t('Edit')}}
//- b-navbar(type="dark" variant="dark" toggleable='lg')
//- template(slot='footer')
//- b-navbar-nav
@ -69,20 +75,8 @@ export default {
}
</script>
<style>
#eventDetail .el-dialog {
min-width: 800px;
}
#eventDetail .el-dialog__header {
display: none;
}
#eventDetail .el-dialog__body {
#eventDetail .modal-body {
padding: 0px;
font-size: 17px;
}
#eventDetail img {
width: 100%;
}
</style>

View file

@ -1,5 +1,5 @@
<template lang="pug">
el-dialog(@close='$router.replace("/")' :title='$t("Export")' :visible='true' center width='600px')
b-modal(@hidden='$router.replace("/")' :title='$t("Export")' :visible='true' size='lg' hide-footer)
p {{$t('export_intro')}}
li(v-if='filters.tags.length') {{$t('Tags')}}:
@ -7,16 +7,7 @@
li(v-if='filters.places.length') {{$t('Places')}}:
el-tag.ml-1(color='#409EFF' size='mini' v-for='place in filters.places') {{place}}
el-tabs.mt-2(tabPosition='left' v-model='type')
el-tab-pane.pt-1(label='feed rss' name='feed')
span(v-html='$t(`export_feed_explanation`)')
el-input(v-model='link')
el-button(slot='append' plain type="primary" icon='el-icon-document' v-clipboard:copy="link") {{$t("Copy")}}
el-tab-pane.pt-1(label='ics/ical' name='ics')
p(v-html='$t(`export_ical_explanation`)')
el-input(v-model='link')
el-button(slot='append' plain type="primary" icon='el-icon-document' v-clipboard:copy="link") {{$t("Copy")}}
el-tab-pane.pt-1(label='email' name='email')
p(v-html='$t(`export_email_explanation`)')
b-form
@ -26,6 +17,16 @@
el-input.mt-2(v-model='mail.mail' :placeholder="$t('Insert your address')")
el-button.mt-2.float-right(type='success' @click='activate_email') {{$t('Send')}}
el-tab-pane.pt-1(label='feed rss' name='feed')
span(v-html='$t(`export_feed_explanation`)')
el-input(v-model='link')
el-button(slot='append' plain type="primary" icon='el-icon-document' v-clipboard:copy="link") {{$t("Copy")}}
el-tab-pane.pt-1(label='ics/ical' name='ics')
p(v-html='$t(`export_ical_explanation`)')
el-input(v-model='link')
el-button(slot='append' plain type="primary" icon='el-icon-document' v-clipboard:copy="link") {{$t("Copy")}}
el-tab-pane.pt-1(label='list' name='list')
p(v-html='$t(`export_list_explanation`)')
b-card.mb-1(no-body header='Eventi')
@ -33,7 +34,7 @@
b-list-group-item.flex-column.align-items-start(v-for="event in filteredEvents"
:to='`/event/${event.id}`')
//- b-media
img(v-if='event.image_path' slot="aside" :src="imgPath(event)" alt="Media Aside" style='max-height: 60px')
img(v-if='event.image_path' slot="aside" :src="imgPath(event)" alt="Meia Aside" style='max-height: 60px')
small.float-right {{event.start_datetime|datetime}}
strong.mb-1 {{event.title}}
br

View file

@ -1,7 +1,9 @@
<template lang="pug">
b-container
b-card-group(columns)
Calendar
b-card-group.card-horiz
b-form-group.mt-1
Search#search
Calendar
Event.item(v-for='event in filteredEvents'
:key='event.id'
:event='event')
@ -13,10 +15,11 @@ import Event from '@/components/Event'
import Calendar from '@/components/Calendar'
import {intersection} from 'lodash'
import moment from 'moment'
import Search from '@/components/Search'
export default {
name: 'Home',
components: { Event, Calendar },
components: { Event, Calendar, Search },
computed: {
...mapState(['events', 'filters']),
filteredEvents () {
@ -27,6 +30,19 @@ export default {
</script>
<style>
#search {
display: inline-flex;
}
/*
.card-horiz {
flex-flow: row wrap;
display: flex;
/*! margin-left: -8px; */
}
.card-horiz .card {
width: 400px !important;
} */
.card-columns {
column-count: 1;
column-gap: 0.2em;

View file

@ -1,15 +1,15 @@
<template lang='pug'>
el-dialog(@show="$refs.email.focus()" :title='$t("Login")' center width='400px'
@close='$router.replace("/")' :visible='true')
b-modal(@show="$refs.email.focus()" :title='$t("Login")' hide-footer
@hidden='$router.replace("/")' :visible='true')
el-form
span {{$t('login_explanation')}}
el-input.mb-2(v-model='email' type='email' :placeholder='$t("Email")' autocomplete='email' ref='email')
v-icon(name='user' slot='prepend')
el-input.mb-2(v-model='password' type='password' :placeholder='$t("Password")')
v-icon(name="lock" slot='prepend')
router-link(to='/register')
el-button(plain type="success" icon='el-icon-arrow-right' @click='submit') {{$t('Login')}}
router-link.float-right(to='/register')
a {{$t('Not registered?')}}
el-button.float-right(plain type="success" icon='el-icon-arrow-right' @click='submit') {{$t('Login')}}
</template>
<script>

View file

@ -0,0 +1,46 @@
<template lang="pug">
b-navbar(type="dark" variant="dark" toggleable='md')
b-navbar-toggle(target='nav_collapse')
b-navbar-brand(to='/') <img id='logo' src='gancio_logo.svg'/>
b-collapse#nav_collapse(is-nav)
b-navbar-nav
b-nav-item(v-if='!logged' to='/login' v-b-tooltip :title='$t("Login")') <v-icon color='lightgreen' name='lock' />
span.d-md-none {{$t('User')}}
b-nav-item(v-if='logged' to='/new_event' v-b-tooltip :title='$t("Add Event")' ) <v-icon color='lightgreen' name='plus'/>
span.d-md-none {{$t('Add Event')}}
b-nav-item(v-if='logged' to='/settings' v-b-tooltip :title='$t("Settings")') <v-icon color='orange' name='cog'/>
span.d-md-none {{$t('Settings')}}
b-nav-item(v-if='user.is_admin' to='/admin' v-b-tooltip :title='$t("Admin")') <v-icon color='lightblue' name='tools'/>
span.d-md-none {{$t('Admin')}}
b-nav-item(to='/export' v-b-tooltip :title='$t("Export")') <v-icon name='file-export' color='yellow'/>
span.d-md-none {{$t('Export')}}
b-nav-item(v-if='logged' variant='danger' @click='logout' v-b-tooltip :title='$t("Logout")') <v-icon color='red' name='sign-out-alt'/>
span.d-md-none {{$t('Logout')}}
</template>
<script>
import {mapState, mapActions} from 'vuex'
export default {
name: 'Nav',
computed: {
...mapState(['logged', 'user','filters']),
filters_tags: {
set (value) {
this.setSearchTags(value)
},
get () {
return this.filters.tags
}
},
filters_places: {
set (value) {
this.setSearchPlaces(value)
},
get () {
return this.filters.places
}
},
},
methods: mapActions(['logout']),
}
</script>

View file

@ -0,0 +1,38 @@
<template lang="pug">
div
el-select.mr-1(v-model='filters_places' multiple filterable collapse-tags
default-first-option :placeholder='$t("Where")')
el-option(v-for='place in places' :value='place.name'
:label='place.name' :key='place.id')
el-select(v-model='filters_tags' multiple filterable collapse-tags
default-first-option :placeholder='$t("Tags")')
el-option(v-for='tag in tags' :key='tag.tag'
:label='tag.tag' :value='tag.tag')
</template>
<script>
import {mapState, mapActions} from 'vuex'
export default {
name :'Search',
methods: mapActions(['setSearchPlaces', 'setSearchTags']),
computed: {
...mapState(['tags', 'places', 'filters']),
filters_tags: {
set (value) {
this.setSearchTags(value)
},
get () {
return this.filters.tags
}
},
filters_places: {
set (value) {
this.setSearchPlaces(value)
},
get () {
return this.filters.places
}
},
}
}
</script>

View file

@ -1,55 +1,57 @@
<template lang="pug">
el-dialog(@close='$router.replace("/")' :title="edit?$t('Edit event'):$t('New event')" center :close-on-press-escape='false' :visible='true')
el-tabs.mb-2(v-model='activeTab' v-loading='sending')
//- el-dialog(@close='$router.replace("/")' :title="edit?$t('Edit event'):$t('New event')" center :close-on-press-escape='false' :visible='true')
b-modal(@hidden='$router.replace("/")' :title="edit?$t('Edit event'):$t('New event')" size='md' :visible='true' hide-footer)
b-container
el-tabs.mb-2(v-model='activeTab' v-loading='sending')
el-tab-pane
span(slot='label') {{$t('Where')}} <v-icon name='map-marker-alt'/>
p {{$t('where_explanation')}}
el-form(label-width='120px')
el-form-item(:label='$t("Where")')
el-select(v-model='event.place.name' @change='placeChoosed' filterable allow-create default-first-option)
el-option(v-for='place in places_name' :label='place' :value='place')
el-form-item(:label='$t("Address")')
el-input(ref='address' v-model='event.place.address' @keydown.native.enter='next')
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('Next')}}
el-tab-pane
span(slot='label') {{$t('When')}} <v-icon name='clock'/>
el-form(label-width='120px')
span {{event.multidate ? $t('dates_explanation') : $t('date_explanation')}}
el-switch.float-right(v-model='event.multidate' :active-text="$t('multidate_explanation')")
v-date-picker.mb-3(:mode='event.multidate ? "range" : "single"' v-model='date' is-inline
is-expanded :min-date='new Date()' @input='date ? $refs.time_start.focus() : false')
el-form-item(:label="$t('time_start_explanation')")
el-time-select(ref='time_start'
v-model="time.start"
:picker-options="{ start: '00:00', step: '00:30', end: '24:00'}")
el-form-item(:label="$t('time_end_explanation')")
el-time-select(v-model='time.end'
:picker-options="{start: '00:00', step: '00:30', end: '24:00'}")
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('Next')}}
el-tab-pane
span(slot='label') {{$t('What')}} <v-icon name='file-alt'/>
span {{$t('what_explanation')}}
el-input.mb-3(v-model='event.title')
span {{$t('description_explanation')}}
el-input.mb-3(v-model='event.description' type='textarea' :rows='3')
span {{$t('tag_explanation')}}
br
//- typeahead(v-model="event.tags" :data='tags' multiple)
el-select(v-model='event.tags' multiple filterable allow-create
default-first-option placeholder='Tag')
el-option(v-for='tag in tags' :key='tag'
:label='tag' :value='tag')
el-tab-pane
span(slot='label') {{$t('Where')}} <v-icon name='map-marker-alt'/>
p {{$t('where_explanation')}}
el-form(label-width='120px')
el-form-item(:label='$t("Where")')
el-select(v-model='event.place.name' @change='placeChoosed' filterable allow-create default-first-option)
el-option(v-for='place in places_name' :label='place' :value='place')
el-form-item(:label='$t("Address")')
el-input(ref='address' v-model='event.place.address' @keydown.native.enter='next')
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('Next')}}
el-tab-pane
span(slot='label') {{$t('When')}} <v-icon name='clock'/>
el-form(label-width='120px')
span {{event.multidate ? $t('dates_explanation') : $t('date_explanation')}}
el-switch.float-right(v-model='event.multidate' :active-text="$t('multidate_explanation')")
v-date-picker.mb-3(:mode='event.multidate ? "range" : "single"' v-model='date' is-inline
is-expanded :min-date='new Date()' @input='date ? $refs.time_start.focus() : false')
el-form-item(:label="$t('time_start_explanation')")
el-time-select(ref='time_start'
v-model="time.start"
:picker-options="{ start: '00:00', step: '00:30', end: '24:00'}")
el-form-item(:label="$t('time_end_explanation')")
el-time-select(v-model='time.end'
:picker-options="{start: '00:00', step: '00:30', end: '24:00'}")
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('Next')}}
el-tab-pane
span(slot='label') {{$t('What')}} <v-icon name='file-alt'/>
span {{$t('what_explanation')}}
el-input.mb-3(v-model='event.title')
span {{$t('description_explanation')}}
el-input.mb-3(v-model='event.description' type='textarea' :rows='3')
span {{$t('tag_explanation')}}
br
//- typeahead(v-model="event.tags" :data='tags' multiple)
el-select(v-model='event.tags' multiple filterable allow-create
default-first-option placeholder='Tag')
el-option(v-for='tag in tags' :key='tag'
:label='tag' :value='tag')
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('Next')}}
el-tab-pane
span(slot='label') {{$t('Media')}} <v-icon name='image'/>
span {{$t('media_explanation')}}
b-form-file.mb-2(v-model='event.image', :placeholder='$t("Poster")' accept='image/*')
el-button.float-right(@click='done') {{edit?$t('Edit'):$t('Send')}}
el-tab-pane
span(slot='label') {{$t('Media')}} <v-icon name='image'/>
span {{$t('media_explanation')}}
b-form-file.mb-2(v-model='event.image', :placeholder='$t("Poster")' accept='image/*')
el-button.float-right(@click='done') {{edit?$t('Edit'):$t('Send')}}

View file

@ -56,6 +56,9 @@ const it = {
Save: 'Salva',
Address: 'Indirizzo',
Remove: 'Elimina',
Password: 'Password',
Email: 'Email',
User: 'Utente',
Edit: 'Modifica',
Admin: 'Amministra',
Today: 'Oggi',
@ -70,6 +73,7 @@ const it = {
register_explanation: `I movimenti hanno bisogno di organizzarsi e autofinanziarsi. <br/>Questo è un dono per voi, non possiamo più vedervi usare le piattaforme del capitalismo. Solo eventi non commerciali e ovviamente antifascisti, antisessisti, antirazzisti.
<br/>Prima di poter pubblicare <strong>dobbiamo approvare l'account</strong>, considera che <strong>dietro questo sito ci sono delle persone</strong> di
carne e sangue, scrivici quindi due righe per farci capire che eventi vorresti pubblicare.`,
'Not registered?': `Non sei registrata?`,
login_explanation: ``
}