start with nuxt
This commit is contained in:
94
components/Calendar.vue
Normal file
94
components/Calendar.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template lang="pug">
|
||||
v-calendar#calendar.card(
|
||||
show-caps
|
||||
:popover-expanded='true'
|
||||
: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'
|
||||
// import filters from '@/filters'
|
||||
import moment from 'dayjs'
|
||||
import { intersection } from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Calendar',
|
||||
// filters,
|
||||
data () {
|
||||
const month = moment().month()+1
|
||||
const year = moment().year()
|
||||
return {
|
||||
page: { month, year},
|
||||
}
|
||||
},
|
||||
|
||||
// async mounted () {
|
||||
// await this.updateEvents(this.page)
|
||||
// },
|
||||
watch: {
|
||||
page () {
|
||||
this.updateEvents(this.page)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['updateEvents']),
|
||||
eventToAttribute(event) {
|
||||
let e = {
|
||||
key: event.id,
|
||||
customData: event,
|
||||
order: event.start_datetime,
|
||||
popover: {
|
||||
slot: 'popover',
|
||||
visibility: 'hover'
|
||||
}
|
||||
}
|
||||
|
||||
let color = event.tags && event.tags.length && event.tags[0].color ? event.tags[0].color : 'rgba(170,170,250,0.7)'
|
||||
if (event.past) color = 'rgba(200,200,200,0.5)'
|
||||
if (event.multidate) {
|
||||
e.dates = {
|
||||
start: event.start_datetime, end: event.end_datetime
|
||||
}
|
||||
e.highlight = { backgroundColor: color,
|
||||
borderColor: 'transparent',
|
||||
borderWidth: '4px' }
|
||||
} else {
|
||||
e.dates = event.start_datetime
|
||||
e.dot = { backgroundColor: color, borderColor: color, borderWidth: '3px' }
|
||||
}
|
||||
return e
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredEvents () {
|
||||
return this.$store.getters.filteredEvents
|
||||
},
|
||||
...mapState(['events', 'filters', 'user', 'logged']),
|
||||
attributes () {
|
||||
return [
|
||||
{ key: 'todaly', dates: new Date(),
|
||||
highlight: {
|
||||
backgroundColor: '#aaffaa'
|
||||
},
|
||||
popover: {label: this.$t('Today')}
|
||||
},
|
||||
...this.filteredEvents.map(this.eventToAttribute)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#calendar {
|
||||
margin-bottom: 0em;
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
#calendar a {
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
64
components/Event.vue
Normal file
64
components/Event.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template lang="pug">
|
||||
b-card(bg-variant='dark' text-variant='white' :class="{ withImg: event.image_path ? true : false }"
|
||||
@click='$router.push("/event/" + event.id)'
|
||||
:img-src='imgPath')
|
||||
strong {{event.title}}
|
||||
div <v-icon name='clock'/> {{event.start_datetime|datetime}}
|
||||
//- span <v-icon name='map-marker-alt'/> {{event.place.name}}
|
||||
br
|
||||
el-tag.mr-1(:color='tag.color || "grey"' v-for='tag in event.tags' :key='tag.tag'
|
||||
size='small' @click.stop='addSearchTag(tag)') {{tag.tag}}
|
||||
</template>
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex'
|
||||
// import api from '@/server/api'
|
||||
// import filters from '@/filters'
|
||||
|
||||
export default {
|
||||
props: ['event'],
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
imgPath() {
|
||||
return this.event.image_path && '/uploads/thumb/' + this.event.image_path
|
||||
},
|
||||
mine() {
|
||||
return this.event.userId === this.user.id
|
||||
}
|
||||
},
|
||||
// filters: {
|
||||
// datetime: this.datetime
|
||||
// },
|
||||
methods: {
|
||||
...mapActions(['delEvent', 'addSearchTag']),
|
||||
async remove() {
|
||||
// await api.delEvent(this.event.id)
|
||||
// this.delEvent(this.event.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
/* .card::before {
|
||||
border-top: 4px solid black;
|
||||
content: ''
|
||||
} */
|
||||
|
||||
.el-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-card img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-columns .card {
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
.card-img {
|
||||
height: 180px;
|
||||
|
||||
object-fit: cover;
|
||||
}
|
||||
</style>
|
||||
100
components/Home.vue
Normal file
100
components/Home.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template lang="pug">
|
||||
div
|
||||
magic-grid(:animate="false" useMin :gap=5 :maxCols=4
|
||||
:maxColWidth='400' ref='magicgrid')
|
||||
div.mt-1.item
|
||||
//- Search#search
|
||||
no-ssr
|
||||
Calendar
|
||||
Event.item.mt-1(v-for='event in events'
|
||||
:key='event.id'
|
||||
:event='event')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import axios from 'axios'
|
||||
// import filters from '@/filters.js'
|
||||
import Event from '@/components/Event'
|
||||
import Calendar from '@/components/Calendar'
|
||||
// import { intersection } from 'lodash'
|
||||
// import moment from 'dayjs'
|
||||
// import Search from '@/components/Search'
|
||||
|
||||
export default {
|
||||
name: 'Home',
|
||||
// async asyncData ({req}) {
|
||||
// console.log('dentro asyncData')
|
||||
// const { data } = await axios.get('http://localhost:3000/api/event/2019/2')
|
||||
// return { events: data }
|
||||
// },
|
||||
components: { Event, Calendar }, // , Calendar, Search },
|
||||
computed: {
|
||||
...mapState(['events', 'filters']),
|
||||
filteredEvents() {
|
||||
return this.events
|
||||
// return this.$store.getters.filteredEvents
|
||||
.filter(e => !e.past)
|
||||
.sort((a, b) => a.start_datetime > b.start_datetime)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filteredEvents() {
|
||||
// this.$nextTick(this.$refs.magicgrid.positionItems) TOFIX
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#search {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin-top: 4px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card-columns {
|
||||
column-count: 1;
|
||||
column-gap: 0.2em;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.container {
|
||||
max-width: none;
|
||||
}
|
||||
.card-columns {
|
||||
column-count: 2;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 950px) {
|
||||
.container {
|
||||
max-width: 1400px;
|
||||
}
|
||||
.card-columns {
|
||||
column-count: 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* .item {
|
||||
transition: all .2s;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
} */
|
||||
/* .list-enter, .list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
.list-leave-active {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 0px;
|
||||
left: 0px;
|
||||
height: 0px;
|
||||
z-index: -10;
|
||||
} */
|
||||
</style>
|
||||
79
components/Logo.vue
Normal file
79
components/Logo.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="VueToNuxtLogo">
|
||||
<div class="Triangle Triangle--two" />
|
||||
<div class="Triangle Triangle--one" />
|
||||
<div class="Triangle Triangle--three" />
|
||||
<div class="Triangle Triangle--four" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.VueToNuxtLogo {
|
||||
display: inline-block;
|
||||
animation: turn 2s linear forwards 1s;
|
||||
transform: rotateX(180deg);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 180px;
|
||||
width: 245px;
|
||||
}
|
||||
|
||||
.Triangle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.Triangle--one {
|
||||
border-left: 105px solid transparent;
|
||||
border-right: 105px solid transparent;
|
||||
border-bottom: 180px solid #41b883;
|
||||
}
|
||||
|
||||
.Triangle--two {
|
||||
top: 30px;
|
||||
left: 35px;
|
||||
animation: goright 0.5s linear forwards 3.5s;
|
||||
border-left: 87.5px solid transparent;
|
||||
border-right: 87.5px solid transparent;
|
||||
border-bottom: 150px solid #3b8070;
|
||||
}
|
||||
|
||||
.Triangle--three {
|
||||
top: 60px;
|
||||
left: 35px;
|
||||
animation: goright 0.5s linear forwards 3.5s;
|
||||
border-left: 70px solid transparent;
|
||||
border-right: 70px solid transparent;
|
||||
border-bottom: 120px solid #35495e;
|
||||
}
|
||||
|
||||
.Triangle--four {
|
||||
top: 120px;
|
||||
left: 70px;
|
||||
animation: godown 0.5s linear forwards 3s;
|
||||
border-left: 35px solid transparent;
|
||||
border-right: 35px solid transparent;
|
||||
border-bottom: 60px solid #fff;
|
||||
}
|
||||
|
||||
@keyframes turn {
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes godown {
|
||||
100% {
|
||||
top: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes goright {
|
||||
100% {
|
||||
left: 70px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
50
components/Nav.vue
Normal file
50
components/Nav.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<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(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' @click='logout' v-b-tooltip :title='$t("Logout")') <v-icon color='red' name='sign-out-alt'/>
|
||||
span.d-md-none {{$t('Logout')}}
|
||||
b-navbar-nav.ml-auto
|
||||
b-nav-item(to='/about')
|
||||
span {{$t('Info')}} <v-icon color='#ff9fc4' name='question-circle'/>
|
||||
|
||||
</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>
|
||||
|
||||
7
components/README.md
Normal file
7
components/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# COMPONENTS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
The components directory contains your Vue.js Components.
|
||||
|
||||
_Nuxt.js doesn't supercharge these components._
|
||||
39
components/Search.vue
Normal file
39
components/Search.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user