mirror of
https://framagit.org/les/gancio.git
synced 2025-01-31 16:42:22 +01:00
Merge branch 'doc'
This commit is contained in:
commit
ac93505721
26 changed files with 739 additions and 120 deletions
|
@ -16,7 +16,7 @@
|
||||||
el-popover(
|
el-popover(
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
trigger="click")
|
trigger="click")
|
||||||
Search(past-filter)
|
Search(past-filter recurrent-filter)
|
||||||
el-menu-item(slot='reference' :title="$t('common.search')" icon='el-share-button')
|
el-menu-item(slot='reference' :title="$t('common.search')" icon='el-share-button')
|
||||||
v-icon(color='lightblue' name='search')
|
v-icon(color='lightblue' name='search')
|
||||||
el-badge(v-if='filters.tags.length+filters.places.length>0' is-dot type='warning')
|
el-badge(v-if='filters.tags.length+filters.places.length>0' is-dot type='warning')
|
||||||
|
|
|
@ -8,11 +8,18 @@
|
||||||
//- )
|
//- )
|
||||||
el-switch.mt-1.mb-1.ml-2.d-block(
|
el-switch.mt-1.mb-1.ml-2.d-block(
|
||||||
v-if='pastFilter'
|
v-if='pastFilter'
|
||||||
inactive-text='futuri'
|
inactive-text=''
|
||||||
|
active-text='anche appuntamenti fissi'
|
||||||
|
inactive-color='lightgreen'
|
||||||
|
v-model='showRecurrent'
|
||||||
|
)
|
||||||
|
el-switch.mt-1.mb-1.ml-2.d-block(
|
||||||
|
v-if='recurrentFilter'
|
||||||
|
inactive-text='solo futuri'
|
||||||
active-text='anche passati'
|
active-text='anche passati'
|
||||||
inactive-color='lightgreen'
|
inactive-color='lightgreen'
|
||||||
v-model='showPast'
|
v-model='showPast'
|
||||||
)
|
)
|
||||||
no-ssr
|
no-ssr
|
||||||
el-select.search(v-model='filter'
|
el-select.search(v-model='filter'
|
||||||
multiple
|
multiple
|
||||||
|
@ -33,24 +40,25 @@ export default {
|
||||||
},
|
},
|
||||||
name :'Search',
|
name :'Search',
|
||||||
props: {
|
props: {
|
||||||
pastFilter: Boolean
|
pastFilter: Boolean,
|
||||||
|
recurrentFilter: Boolean
|
||||||
},
|
},
|
||||||
methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents']),
|
methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents', 'showRecurrentEvents']),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['tags', 'places', 'filters', 'show_past_events']),
|
...mapState(['tags', 'places', 'filters']),
|
||||||
// TOFIX: optimize
|
// TOFIX: optimize
|
||||||
keywords () {
|
keywords () {
|
||||||
const tags = this.tags.map( t => ({ value: 't' + t.tag, label: t.tag, weigth: t.weigth }))
|
const tags = this.tags.map( t => ({ value: 't' + t.tag, label: t.tag, weigth: t.weigth }))
|
||||||
const places = this.places.map( p => ({ value: 'p' + p.id, label: p.name, weigth: p.weigth }))
|
const places = this.places.map( p => ({ value: 'p' + p.id, label: p.name, weigth: p.weigth }))
|
||||||
return tags.concat(places).sort((a, b) => b.weigth-a.weigth)
|
return tags.concat(places).sort((a, b) => b.weigth-a.weigth)
|
||||||
},
|
},
|
||||||
showPast : {
|
showPast: {
|
||||||
set (value) {
|
set (value) { this.showPastEvents(value) },
|
||||||
this.showPastEvents(value)
|
get () { return this.filters.show_past_events }
|
||||||
},
|
},
|
||||||
get () {
|
showRecurrent: {
|
||||||
return this.filters.show_past_events
|
set (value) { this.showRecurrentEvents(value) },
|
||||||
}
|
get () { return this.filters.show_recurrent_events }
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
set (filters) {
|
set (filters) {
|
||||||
|
|
3
docs/.gitignore
vendored
Normal file
3
docs/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
_site
|
||||||
|
.sass-cache
|
||||||
|
.jekyll-metadata
|
24
docs/404.html
Normal file
24
docs/404.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
.container {
|
||||||
|
margin: 10px auto;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 30px 0;
|
||||||
|
font-size: 4em;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h1>404</h1>
|
||||||
|
|
||||||
|
<p><strong>Page not found :(</strong></p>
|
||||||
|
<p>The requested page could not be found.</p>
|
||||||
|
</div>
|
36
docs/Gemfile
Normal file
36
docs/Gemfile
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
# Hello! This is where you manage which Jekyll version is used to run.
|
||||||
|
# When you want to use a different version, change it below, save the
|
||||||
|
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||||
|
#
|
||||||
|
# bundle exec jekyll serve
|
||||||
|
#
|
||||||
|
# This will help ensure the proper Jekyll version is running.
|
||||||
|
# Happy Jekylling!
|
||||||
|
gem "jekyll", "~> 3.8.6"
|
||||||
|
|
||||||
|
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||||
|
#gem "minima", "~> 2.0"
|
||||||
|
gem "just-the-docs"
|
||||||
|
gem "jemoji"
|
||||||
|
|
||||||
|
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||||
|
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||||
|
# gem "github-pages", group: :jekyll_plugins
|
||||||
|
|
||||||
|
# If you have any plugins, put them here!
|
||||||
|
group :jekyll_plugins do
|
||||||
|
gem "jekyll-feed", "~> 0.6"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||||
|
# and associated library.
|
||||||
|
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
|
||||||
|
gem "tzinfo", "~> 1.2"
|
||||||
|
gem "tzinfo-data"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performance-booster for watching directories on Windows
|
||||||
|
gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
|
||||||
|
|
101
docs/Gemfile.lock
Normal file
101
docs/Gemfile.lock
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
activesupport (5.2.3)
|
||||||
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
|
i18n (>= 0.7, < 2)
|
||||||
|
minitest (~> 5.1)
|
||||||
|
tzinfo (~> 1.1)
|
||||||
|
addressable (2.6.0)
|
||||||
|
public_suffix (>= 2.0.2, < 4.0)
|
||||||
|
colorator (1.1.0)
|
||||||
|
concurrent-ruby (1.1.5)
|
||||||
|
em-websocket (0.5.1)
|
||||||
|
eventmachine (>= 0.12.9)
|
||||||
|
http_parser.rb (~> 0.6.0)
|
||||||
|
eventmachine (1.2.7)
|
||||||
|
ffi (1.11.1)
|
||||||
|
forwardable-extended (2.6.0)
|
||||||
|
gemoji (3.0.1)
|
||||||
|
html-pipeline (2.11.0)
|
||||||
|
activesupport (>= 2)
|
||||||
|
nokogiri (>= 1.4)
|
||||||
|
http_parser.rb (0.6.0)
|
||||||
|
i18n (0.9.5)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
jekyll (3.8.6)
|
||||||
|
addressable (~> 2.4)
|
||||||
|
colorator (~> 1.0)
|
||||||
|
em-websocket (~> 0.5)
|
||||||
|
i18n (~> 0.7)
|
||||||
|
jekyll-sass-converter (~> 1.0)
|
||||||
|
jekyll-watch (~> 2.0)
|
||||||
|
kramdown (~> 1.14)
|
||||||
|
liquid (~> 4.0)
|
||||||
|
mercenary (~> 0.3.3)
|
||||||
|
pathutil (~> 0.9)
|
||||||
|
rouge (>= 1.7, < 4)
|
||||||
|
safe_yaml (~> 1.0)
|
||||||
|
jekyll-feed (0.12.1)
|
||||||
|
jekyll (>= 3.7, < 5.0)
|
||||||
|
jekyll-sass-converter (1.5.2)
|
||||||
|
sass (~> 3.4)
|
||||||
|
jekyll-seo-tag (2.6.1)
|
||||||
|
jekyll (>= 3.3, < 5.0)
|
||||||
|
jekyll-watch (2.2.1)
|
||||||
|
listen (~> 3.0)
|
||||||
|
jemoji (0.11.0)
|
||||||
|
gemoji (~> 3.0)
|
||||||
|
html-pipeline (~> 2.2)
|
||||||
|
jekyll (>= 3.0, < 5.0)
|
||||||
|
just-the-docs (0.2.5)
|
||||||
|
jekyll (~> 3.8.5)
|
||||||
|
jekyll-seo-tag (~> 2.0)
|
||||||
|
rake (~> 12.3.1)
|
||||||
|
kramdown (1.17.0)
|
||||||
|
liquid (4.0.3)
|
||||||
|
listen (3.1.5)
|
||||||
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
ruby_dep (~> 1.2)
|
||||||
|
mercenary (0.3.6)
|
||||||
|
mini_portile2 (2.4.0)
|
||||||
|
minitest (5.11.3)
|
||||||
|
nokogiri (1.10.3)
|
||||||
|
mini_portile2 (~> 2.4.0)
|
||||||
|
pathutil (0.16.2)
|
||||||
|
forwardable-extended (~> 2.6)
|
||||||
|
public_suffix (3.1.1)
|
||||||
|
rake (12.3.1)
|
||||||
|
rb-fsevent (0.10.3)
|
||||||
|
rb-inotify (0.10.0)
|
||||||
|
ffi (~> 1.0)
|
||||||
|
rouge (3.6.0)
|
||||||
|
ruby_dep (1.5.0)
|
||||||
|
safe_yaml (1.0.5)
|
||||||
|
sass (3.7.4)
|
||||||
|
sass-listen (~> 4.0.0)
|
||||||
|
sass-listen (4.0.0)
|
||||||
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
thread_safe (0.3.6)
|
||||||
|
tzinfo (1.2.5)
|
||||||
|
thread_safe (~> 0.1)
|
||||||
|
tzinfo-data (1.2019.2)
|
||||||
|
tzinfo (>= 1.0.0)
|
||||||
|
wdm (0.1.1)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
jekyll (~> 3.8.6)
|
||||||
|
jekyll-feed (~> 0.6)
|
||||||
|
jemoji
|
||||||
|
just-the-docs
|
||||||
|
tzinfo (~> 1.2)
|
||||||
|
tzinfo-data
|
||||||
|
wdm (~> 0.1.0)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.0.2
|
50
docs/_config.yml
Normal file
50
docs/_config.yml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Welcome to Jekyll!
|
||||||
|
#
|
||||||
|
# This config file is meant for settings that affect your whole blog, values
|
||||||
|
# which you are expected to set up once and rarely edit after that. If you find
|
||||||
|
# yourself editing this file very often, consider using Jekyll's data files
|
||||||
|
# feature for the data you need to update frequently.
|
||||||
|
#
|
||||||
|
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
||||||
|
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
|
||||||
|
|
||||||
|
# Site settings
|
||||||
|
# These are used to personalize your new site. If you look in the HTML files,
|
||||||
|
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
|
||||||
|
# You can create any custom variable you would like, and they will be accessible
|
||||||
|
# in the templates via {{ site.myvariable }}.
|
||||||
|
title: Gancio
|
||||||
|
email: gancio@cisti.org
|
||||||
|
description: >- # this means to ignore newlines until "baseurl:"
|
||||||
|
A shared agenda for local communities
|
||||||
|
baseurl: "" # the subpath of your site, e.g. /blog
|
||||||
|
url: "" # the base hostname & protocol for your site, e.g. http://example.com
|
||||||
|
#twitter_username: jekyllrb
|
||||||
|
#github_username: jekyll
|
||||||
|
|
||||||
|
# Build settings
|
||||||
|
markdown: kramdown
|
||||||
|
theme: "just-the-docs"
|
||||||
|
plugins:
|
||||||
|
- jekyll-feed
|
||||||
|
- jemoji
|
||||||
|
|
||||||
|
|
||||||
|
search_enabled: true
|
||||||
|
|
||||||
|
aux_links:
|
||||||
|
"Source":
|
||||||
|
- https://git.lattuga.net/cisti/gancio
|
||||||
|
|
||||||
|
|
||||||
|
#Exclude from processing.
|
||||||
|
# The following items will not be processed, by default. Create a custom list
|
||||||
|
# to override the default setting.
|
||||||
|
# exclude:
|
||||||
|
# - Gemfile
|
||||||
|
# - Gemfile.lock
|
||||||
|
# - node_modules
|
||||||
|
# - vendor/bundle/
|
||||||
|
# - vendor/cache/
|
||||||
|
# - vendor/gems/
|
||||||
|
# - vendor/ruby/
|
19
docs/admin.md
Normal file
19
docs/admin.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Admin
|
||||||
|
permalink: /admin
|
||||||
|
nav_order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
# Admin
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
1. TOC
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Basics
|
||||||
|
|
||||||
|
## Enable registration
|
||||||
|
## Confirm registration
|
||||||
|
## Confirm event
|
BIN
docs/assets/favicon.ico
Normal file
BIN
docs/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
18
docs/contribute.md
Normal file
18
docs/contribute.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Contribute
|
||||||
|
permalink: /contribute
|
||||||
|
nav_order: 6
|
||||||
|
---
|
||||||
|
# Contribute
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
|
||||||
|
1. TOC
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Code
|
||||||
|
## Translate
|
||||||
|
## Design
|
||||||
|
## Documentation
|
||||||
|
## Share
|
33
docs/dev.md
Normal file
33
docs/dev.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Develop
|
||||||
|
permalink: /dev
|
||||||
|
nav_order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
### Development Stack
|
||||||
|
|
||||||
|
**Gancio** is built with following technologies:
|
||||||
|
|
||||||
|
- [Nuxt.js](https://nuxtjs.org/)
|
||||||
|
- Vue.js
|
||||||
|
- Express
|
||||||
|
- Sequelize
|
||||||
|
- Element.ui
|
||||||
|
|
||||||
|
### Testing on your own machine
|
||||||
|
|
||||||
|
2. Download source
|
||||||
|
```bash
|
||||||
|
git clone https://git.lattuga.net/cisti/gancio
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install dependencies
|
||||||
|
```bash
|
||||||
|
yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Hacking
|
||||||
|
```bash
|
||||||
|
yarn dev
|
||||||
|
```
|
26
docs/index.md
Normal file
26
docs/index.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Home
|
||||||
|
nav_order: 1
|
||||||
|
description: "Gancio is a shared agenda for local communities."
|
||||||
|
permalink: /
|
||||||
|
---
|
||||||
|
|
||||||
|
# <img src='https://git.lattuga.net/repo-avatars/476' width="60px"/> Gancio
|
||||||
|
{: .fs-9 }
|
||||||
|
|
||||||
|
A shared agenda for local communities.
|
||||||
|
{: .fs-6 }
|
||||||
|
|
||||||
|
[Get started now](/setup){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } [Demo](https://gancio.cisti.org){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 }
|
||||||
|
[Source](https://git.lattuga.net/cisti/gancio){: .btn .fs-5 }
|
||||||
|
|
||||||
|
<iframe width="800" height="500" sandbox="allow-same-origin allow-scripts" src="https://spacepub.space/videos/embed/9745bffc-e1e8-416d-9b08-fbc5e4c803b3?muted=1&title=0" frameborder="0" allowfullscreen></iframe>
|
||||||
|
|
||||||
|
### About the project
|
||||||
|
|
||||||
|
Gancio is made with :heart: by [hacklab underscore](https://autistici.org/underscore)
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
Gancio is distributed by an [AGPL-3.0 Licence](https://www.gnu.org/licenses/agpl-3.0.en.html).
|
43
docs/settings.md
Normal file
43
docs/settings.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Settings
|
||||||
|
permalink: /settings
|
||||||
|
nav_order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
1. TOC
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Default settings
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "Gancio",
|
||||||
|
"description": "A shared agenda for local communities",
|
||||||
|
"baseurl": "http://localhost:13120",
|
||||||
|
"server": {
|
||||||
|
"host": "0.0.0.0",
|
||||||
|
"port": 13120
|
||||||
|
},
|
||||||
|
"db": {
|
||||||
|
"dialect": "sqlite",
|
||||||
|
"storage": "/tmp/db.sqlite"
|
||||||
|
},
|
||||||
|
"upload_path": "./",
|
||||||
|
"smtp": {
|
||||||
|
"auth": {
|
||||||
|
"user": "",
|
||||||
|
"pass": ""
|
||||||
|
},
|
||||||
|
"secure": true,
|
||||||
|
"host": ""
|
||||||
|
},
|
||||||
|
"admin": {
|
||||||
|
"email": "",
|
||||||
|
"password": ""
|
||||||
|
},
|
||||||
|
"secret": "notsosecret"
|
||||||
|
}
|
||||||
|
```
|
34
docs/setup/classic.md
Normal file
34
docs/setup/classic.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Classic
|
||||||
|
permalink: /setup/classic
|
||||||
|
parent: Setup
|
||||||
|
---
|
||||||
|
|
||||||
|
## Classic setup
|
||||||
|
|
||||||
|
1. Install Node.js
|
||||||
|
```bash
|
||||||
|
curl -sL https://deb.nodesource.com/setup_12.x | bash -
|
||||||
|
apt-get install -y nodejs
|
||||||
|
```
|
||||||
|
<small>[source](https://github.com/nodesource/distributions/blob/master/README.md)</small>
|
||||||
|
2. Install Gancio
|
||||||
|
```bash
|
||||||
|
npm install --global gancio
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Setup
|
||||||
|
```bash
|
||||||
|
gancio setup
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Start
|
||||||
|
```bash
|
||||||
|
gancio start
|
||||||
|
```
|
||||||
|
5. Enjoy :tada:
|
||||||
|
Point your web browser to [http://localhost:3000](http://localhost:3000)
|
||||||
|
|
||||||
|
|
||||||
|
|
10
docs/setup/docker.md
Normal file
10
docs/setup/docker.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Docker
|
||||||
|
permalink: /setup/docker
|
||||||
|
parent: Setup
|
||||||
|
---
|
||||||
|
|
||||||
|
## Install with docker
|
||||||
|
|
||||||
|
|
12
docs/setup/setup.md
Normal file
12
docs/setup/setup.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Setup
|
||||||
|
permalink: /setup
|
||||||
|
has_children: true
|
||||||
|
nav_order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
You would setup **Gancio** for different scenario
|
||||||
|
{: .fs-6 }
|
14
docs/usage.md
Normal file
14
docs/usage.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Usage
|
||||||
|
permalink: /usage
|
||||||
|
nav_order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
|
||||||
|
## Add event
|
||||||
|
### Normal
|
||||||
|
### Multidate
|
||||||
|
### Recurrent
|
|
@ -103,10 +103,7 @@ const it = {
|
||||||
tratta di un evento adatto a questo spazio, delegando questa scelta. Inoltre non sarà possibile modificarlo.<br/><br/>
|
tratta di un evento adatto a questo spazio, delegando questa scelta. Inoltre non sarà possibile modificarlo.<br/><br/>
|
||||||
Puoi invece fare il <a href='/login'>login</a> o <a href='/registrarti'>registrarti</a>,
|
Puoi invece fare il <a href='/login'>login</a> o <a href='/registrarti'>registrarti</a>,
|
||||||
altrimenti vai avanti e riceverai una risposta il prima possibile. `,
|
altrimenti vai avanti e riceverai una risposta il prima possibile. `,
|
||||||
multidate_description: 'tanti giorni',
|
same_day: 'Stesso giorno',
|
||||||
date_description: `Quand'è il gancio?`,
|
|
||||||
dates_description: 'Che giorni?',
|
|
||||||
same_day: 'stesso giorno',
|
|
||||||
what_description: 'Nome evento',
|
what_description: 'Nome evento',
|
||||||
description_description: 'Descrizione, dajene di copia/incolla',
|
description_description: 'Descrizione, dajene di copia/incolla',
|
||||||
tag_description: 'Tag...',
|
tag_description: 'Tag...',
|
||||||
|
@ -118,7 +115,21 @@ const it = {
|
||||||
where_description: `Dov'è il gancio? Se il posto non è presente, scrivilo e <b>premi invio</b>. `,
|
where_description: `Dov'è il gancio? Se il posto non è presente, scrivilo e <b>premi invio</b>. `,
|
||||||
confirmed: 'Evento confermato',
|
confirmed: 'Evento confermato',
|
||||||
not_found: 'Evento non trovato',
|
not_found: 'Evento non trovato',
|
||||||
remove_confirmation: `Sicura di voler eliminare questo evento?`
|
remove_confirmation: `Sicura di voler eliminare questo evento?`,
|
||||||
|
recurrent: `Ricorrente`,
|
||||||
|
recurrent_description: 'Scegli la frequenza e seleziona i giorni',
|
||||||
|
multidate_description: 'Un festival o una tre giorni? Scegli quando comincia e quando finisce.',
|
||||||
|
multidate: 'Più giorni',
|
||||||
|
normal: 'Normale',
|
||||||
|
normal_description: 'Scegli il giorno.',
|
||||||
|
recurrent_1w_days: 'Ogni {days}',
|
||||||
|
recurrent_2w_days: 'Un {days} ogni due',
|
||||||
|
recurrent_1m_days: '|Il giorno {days} di ogni mese|I giorni {days} di ogni mese',
|
||||||
|
recurrent_2m_days: '|Il giorno {days} ogni due mesi|I giorni {days} ogni due mesi',
|
||||||
|
recurrent_1m_ordinal: 'Il {n} {days} di ogni mese',
|
||||||
|
recurrent_2m_ordinal: 'Il {n} {days} un mese sì e uno no',
|
||||||
|
due: 'alle',
|
||||||
|
from: 'Dalle'
|
||||||
},
|
},
|
||||||
|
|
||||||
admin: {
|
admin: {
|
||||||
|
@ -132,7 +143,9 @@ const it = {
|
||||||
user_remove_ok: 'Utente eliminato',
|
user_remove_ok: 'Utente eliminato',
|
||||||
user_create_ok: 'Utente creato',
|
user_create_ok: 'Utente creato',
|
||||||
allow_registration_description : 'Vuoi abilitare la registrazione?',
|
allow_registration_description : 'Vuoi abilitare la registrazione?',
|
||||||
allow_anon_event: 'Si possono inserire eventi anonimi (previa conferma)?'
|
allow_anon_event: 'Si possono inserire eventi anonimi (previa conferma)?',
|
||||||
|
allow_comments: 'Abilita commenti',
|
||||||
|
allow_recurrent_event: 'Abilita eventi ricorrenti'
|
||||||
},
|
},
|
||||||
|
|
||||||
auth: {
|
auth: {
|
||||||
|
@ -152,6 +165,15 @@ const it = {
|
||||||
register_error: 'Errore nella registrazione'
|
register_error: 'Errore nella registrazione'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ordinal: {
|
||||||
|
1: 'primo',
|
||||||
|
2: 'secondo',
|
||||||
|
3: 'terzo',
|
||||||
|
4: 'quarto',
|
||||||
|
5: 'quinto',
|
||||||
|
[-1]: 'ultimo',
|
||||||
|
},
|
||||||
|
|
||||||
about: `
|
about: `
|
||||||
<p>
|
<p>
|
||||||
Gancio e' un progetto dell'<a href='https://autistici.org/underscore'>underscore hacklab</a> e uno dei
|
Gancio e' un progetto dell'<a href='https://autistici.org/underscore'>underscore hacklab</a> e uno dei
|
||||||
|
|
|
@ -14,6 +14,23 @@
|
||||||
p(v-html="$t('event.anon_description')")
|
p(v-html="$t('event.anon_description')")
|
||||||
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('common.next')}}
|
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('common.next')}}
|
||||||
|
|
||||||
|
//- WHAT
|
||||||
|
el-tab-pane
|
||||||
|
span(slot='label') {{$t('common.what')}} <v-icon name='file-alt'/>
|
||||||
|
span {{$t('event.what_description')}}
|
||||||
|
el-input.mb-3(v-model='event.title' ref='title')
|
||||||
|
span {{$t('event.description_description')}}
|
||||||
|
el-input.mb-3(v-model='event.description' type='textarea' :rows='9')
|
||||||
|
span {{$t('event.tag_description')}}
|
||||||
|
br
|
||||||
|
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.native='next' :disabled='!couldProceed') {{$t('common.next')}}
|
||||||
|
|
||||||
|
|
||||||
//- WHERE
|
//- WHERE
|
||||||
el-tab-pane
|
el-tab-pane
|
||||||
span(slot='label') <v-icon name='map-marker-alt'/> {{$t('common.where')}}
|
span(slot='label') <v-icon name='map-marker-alt'/> {{$t('common.where')}}
|
||||||
|
@ -34,49 +51,49 @@
|
||||||
//- WHEN
|
//- WHEN
|
||||||
el-tab-pane
|
el-tab-pane
|
||||||
span(slot='label') {{$t('common.when')}} <v-icon name='clock'/>
|
span(slot='label') {{$t('common.when')}} <v-icon name='clock'/>
|
||||||
span {{event.multidate ? $t('event.dates_description') : $t('event.date_description')}}
|
|
||||||
el-switch.float-right(v-model='event.multidate' :active-text="$t('event.multidate_description')")
|
|
||||||
//- el-switch.float-right(v-model='event.recurrent' :active-text="$t('event.recurrent_description')")
|
|
||||||
|
|
||||||
v-date-picker.mb-3(
|
.text-center
|
||||||
:mode='event.multidate ? "range" : "single"'
|
el-radio-group(v-model="event.type")
|
||||||
|
el-radio-button(label="normal") <v-icon name='calendar-day'/> {{$t('event.normal')}}
|
||||||
|
el-radio-button(label="multidate") <v-icon name='calendar-week'/> {{$t('event.multidate')}}
|
||||||
|
el-radio-button(label="recurrent") <v-icon name='calendar-alt'/> {{$t('event.recurrent')}}
|
||||||
|
br
|
||||||
|
span {{$t(`event.${event.type}_description`)}}
|
||||||
|
el-select.ml-2(v-if='event.type==="recurrent"' v-model='event.rec_frequency' placeholder='Frequenza')
|
||||||
|
el-option(label='Tutti i giorni' value='1d' key='1d')
|
||||||
|
el-option(label='Ogni settimana' value='1w' key='1w')
|
||||||
|
el-option(label='Ogni due settimane' value='2w' key='2w')
|
||||||
|
el-option(label='Ogni mese' value='1m' key='1m')
|
||||||
|
el-option(label='Ogni due mesi' value='2m' key='2m')
|
||||||
|
|
||||||
|
v-date-picker.mb-2.mt-3(
|
||||||
|
:mode='event.type === "multidate" ? "range" : event.type === "recurrent" ? "multiple" : "single"'
|
||||||
:attributes='attributes'
|
:attributes='attributes'
|
||||||
v-model='date'
|
v-model='date'
|
||||||
:locale='$i18n.locale'
|
:locale='$i18n.locale'
|
||||||
:from-page.sync='page'
|
:from-page.sync='page'
|
||||||
is-inline
|
is-inline
|
||||||
is-expanded
|
is-expanded
|
||||||
:min-date='new Date()'
|
:min-date='event.type !== "recurrent" && new Date()'
|
||||||
)
|
)
|
||||||
|
|
||||||
el-row
|
div.text-center.mb-2(v-if='event.type === "recurrent"')
|
||||||
el-col(:span='12')
|
span(v-if='event.rec_frequency !== "1m" && event.rec_frequency !== "2m"') {{whenPatterns}}
|
||||||
div {{$t('event.time_start_description')}}
|
el-radio-group(v-else v-model='event.rec_detail')
|
||||||
el-time-select.mb-3(ref='time_start'
|
el-radio-button(v-for='whenPattern in whenPatterns' :label='whenPattern.label' :key='whenPatterns.key')
|
||||||
|
span {{whenPattern.label}}
|
||||||
|
|
||||||
|
el-form.text-center(inline)
|
||||||
|
el-form-item(:label="$t('event.from')")
|
||||||
|
el-time-select.mr-2(ref='time_start'
|
||||||
v-model="time.start"
|
v-model="time.start"
|
||||||
:picker-options="{ start: '00:00', step: '00:30', end: '24:00'}")
|
:picker-options="{ start: '00:00', step: '00:30', end: '24:00'}")
|
||||||
div {{$t('event.time_end_description')}}
|
el-form-item(:label="$t('event.due')")
|
||||||
el-time-select(v-model='time.end'
|
el-time-select(v-model='time.end'
|
||||||
:picker-options="{start: '00:00', step: '00:30', end: '24:00'}")
|
:picker-options="{start: '00:00', step: '00:30', end: '24:00'}")
|
||||||
el-col(:span='12')
|
|
||||||
List(:events='todayEvents' :title='$t("event.same_day")')
|
List(v-if='event.type==="normal"' :events='todayEvents' :title='$t("event.same_day")')
|
||||||
el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('common.next')}}
|
el-button.float-right(@click='next' type='succes' :disabled='!couldProceed') {{$t('common.next')}}
|
||||||
|
|
||||||
//- WHAT
|
|
||||||
el-tab-pane
|
|
||||||
span(slot='label') {{$t('common.what')}} <v-icon name='file-alt'/>
|
|
||||||
span {{$t('event.what_description')}}
|
|
||||||
el-input.mb-3(v-model='event.title' ref='title')
|
|
||||||
span {{$t('event.description_description')}}
|
|
||||||
el-input.mb-3(v-model='event.description' type='textarea' :rows='9')
|
|
||||||
span {{$t('event.tag_description')}}
|
|
||||||
br
|
|
||||||
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.native='next' :disabled='!couldProceed') {{$t('common.next')}}
|
|
||||||
|
|
||||||
el-tab-pane
|
el-tab-pane
|
||||||
span(slot='label') {{$t('common.media')}} <v-icon name='image'/>
|
span(slot='label') {{$t('common.media')}} <v-icon name='image'/>
|
||||||
|
@ -96,6 +113,8 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapState, mapGetters } from 'vuex'
|
import { mapActions, mapState, mapGetters } from 'vuex'
|
||||||
|
import uniq from 'lodash/uniq'
|
||||||
|
import map from 'lodash/map'
|
||||||
import moment from 'dayjs'
|
import moment from 'dayjs'
|
||||||
import List from '@/components/List'
|
import List from '@/components/List'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
|
@ -111,10 +130,15 @@ export default {
|
||||||
const year = moment().year()
|
const year = moment().year()
|
||||||
return {
|
return {
|
||||||
event: {
|
event: {
|
||||||
|
type: 'normal',
|
||||||
place: { name: '', address: '' },
|
place: { name: '', address: '' },
|
||||||
title: '', description: '', tags: [],
|
title: '', description: '', tags: [],
|
||||||
multidate: false,
|
multidate: false,
|
||||||
image: false
|
image: false,
|
||||||
|
recurrent: false,
|
||||||
|
rec_frequency: '1w',
|
||||||
|
rec_when: null,
|
||||||
|
rec_ordinal: false,
|
||||||
},
|
},
|
||||||
page: { month, year},
|
page: { month, year},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
|
@ -129,6 +153,7 @@ export default {
|
||||||
name: 'newEvent',
|
name: 'newEvent',
|
||||||
watch: {
|
watch: {
|
||||||
'time.start' (value) {
|
'time.start' (value) {
|
||||||
|
if (!value) return
|
||||||
let [h, m] = value.split(':')
|
let [h, m] = value.split(':')
|
||||||
this.time.end = (Number(h)+1) + ':' + m
|
this.time.end = (Number(h)+1) + ':' + m
|
||||||
},
|
},
|
||||||
|
@ -186,8 +211,27 @@ export default {
|
||||||
places_name: state => state.places.map(p => p.name ).sort((a, b) => b.weigth-a.weigth),
|
places_name: state => state.places.map(p => p.name ).sort((a, b) => b.weigth-a.weigth),
|
||||||
places: state => state.places,
|
places: state => state.places,
|
||||||
user: state => state.user,
|
user: state => state.user,
|
||||||
events: state => state.events
|
events: state => state.events,
|
||||||
}),
|
}),
|
||||||
|
whenPatterns () {
|
||||||
|
const dates = this.date
|
||||||
|
if (!dates || !dates.length) return
|
||||||
|
|
||||||
|
const freq = this.event.rec_frequency
|
||||||
|
const weekDays = uniq(map(dates, date => moment(date).format('dddd')))
|
||||||
|
if (freq === '1w' || freq === '2w') {
|
||||||
|
return this.$t(`event.recurrent_${freq}_days`, {days: weekDays.join(', ')})
|
||||||
|
}
|
||||||
|
if (freq === '1m' || freq === '2m') {
|
||||||
|
const days = uniq(map(dates, date => moment(date).date()))
|
||||||
|
const n = Math.floor((days[0]-1)/7)+1
|
||||||
|
return [
|
||||||
|
{ label: this.$tc(`event.recurrent_${freq}_days`, days.length, {days}) },
|
||||||
|
{ label: this.$tc(`event.recurrent_${freq}_ordinal`, days.length, {n: this.$t(`ordinal.${n}`), days: weekDays.join(', ')}) }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
todayEvents () {
|
todayEvents () {
|
||||||
if (this.event.multidate) {
|
if (this.event.multidate) {
|
||||||
if (!this.date || !this.date.start) return
|
if (!this.date || !this.date.start) return
|
||||||
|
@ -222,6 +266,29 @@ export default {
|
||||||
.filter(e => e.multidate)
|
.filter(e => e.multidate)
|
||||||
.map( e => ({ key: e.id, highlight: {}, dates: {
|
.map( e => ({ key: e.id, highlight: {}, dates: {
|
||||||
start: new Date(e.start_datetime*1000), end: new Date(e.end_datetime*1000) }})))
|
start: new Date(e.start_datetime*1000), end: new Date(e.end_datetime*1000) }})))
|
||||||
|
|
||||||
|
if (this.event.type==='recurrent' && this.event.rec_frequency && Array.isArray(this.date)) {
|
||||||
|
const recurrent = {}
|
||||||
|
if (this.event.rec_frequency === '1w') {
|
||||||
|
recurrent.weekdays = this.date.map(d => moment(d).day()+1)
|
||||||
|
recurrent.weeklyInterval = 1
|
||||||
|
}
|
||||||
|
if (this.event.rec_frequency === '2w') {
|
||||||
|
recurrent.weekdays = this.date.map(d => moment(d).day()+1)
|
||||||
|
recurrent.weeklyInterval = 2
|
||||||
|
recurrent.start = new Date(this.date[0])
|
||||||
|
}
|
||||||
|
if (this.event.rec_frequency === '1m') {
|
||||||
|
// recurrent.weeks = 1
|
||||||
|
// recurrent.ordinalWeekdays = { 1: this.date.map(d => moment(d).day()+1) }
|
||||||
|
recurrent.days = this.date.map(d => moment(d).date())
|
||||||
|
recurrent.monthlyInterval = 1
|
||||||
|
recurrent.start = new Date(this.date[0])
|
||||||
|
}
|
||||||
|
if (this.event.rec_frequency === '2m') {
|
||||||
|
}
|
||||||
|
attributes.push({name: 'recurrent', dates: recurrent, dot: { color: 'red'}})
|
||||||
|
}
|
||||||
return attributes
|
return attributes
|
||||||
},
|
},
|
||||||
disableAddress () {
|
disableAddress () {
|
||||||
|
@ -233,12 +300,12 @@ export default {
|
||||||
case 0+t:
|
case 0+t:
|
||||||
return true
|
return true
|
||||||
case 1+t:
|
case 1+t:
|
||||||
|
return this.event.title.length>0
|
||||||
|
case 2+t:
|
||||||
return this.event.place.name.length>0 &&
|
return this.event.place.name.length>0 &&
|
||||||
this.event.place.address.length>0
|
this.event.place.address.length>0
|
||||||
case 2+t:
|
|
||||||
if (this.date && this.time.start) return true
|
|
||||||
case 3+t:
|
case 3+t:
|
||||||
return this.event.title.length>0
|
if (this.date && this.time.start) return true
|
||||||
case 4+t:
|
case 4+t:
|
||||||
return this.event.place.name.length>0 &&
|
return this.event.place.name.length>0 &&
|
||||||
this.event.place.address.length>0 &&
|
this.event.place.address.length>0 &&
|
||||||
|
@ -302,6 +369,16 @@ export default {
|
||||||
formData.append('multidate', this.event.multidate)
|
formData.append('multidate', this.event.multidate)
|
||||||
formData.append('start_datetime', start_datetime.unix())
|
formData.append('start_datetime', start_datetime.unix())
|
||||||
formData.append('end_datetime', end_datetime.unix())
|
formData.append('end_datetime', end_datetime.unix())
|
||||||
|
|
||||||
|
if (this.event.type === 'recurrent') {
|
||||||
|
const recurrent = {
|
||||||
|
frequency: this.rec_frequency,
|
||||||
|
days: this.rec_when,
|
||||||
|
ordinal: this.rec_ordinal,
|
||||||
|
}
|
||||||
|
formData.append('recurrent', JSON.stringify(recurrent))
|
||||||
|
}
|
||||||
|
|
||||||
if (this.edit) {
|
if (this.edit) {
|
||||||
formData.append('id', this.event.id)
|
formData.append('id', this.event.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,20 +89,28 @@
|
||||||
v-icon(name='cog')
|
v-icon(name='cog')
|
||||||
span {{$t('common.settings')}}
|
span {{$t('common.settings')}}
|
||||||
|
|
||||||
el-form(inline @submit.native.prevent='associate_mastondon_instance' label-width='140px')
|
el-form(inline label-width="400px")
|
||||||
|
|
||||||
|
//- allow open registration
|
||||||
|
el-form-item(:label="$t('admin.allow_registration_description')")
|
||||||
|
el-switch(name='reg' v-model='allow_registration')
|
||||||
|
|
||||||
|
//- allow anon event
|
||||||
|
el-form-item(:label="$t('admin.allow_anon_event')")
|
||||||
|
el-switch(v-model='allow_anon_event')
|
||||||
|
|
||||||
|
el-form-item(:label="$t('admin.allow_recurrent_event')")
|
||||||
|
el-switch(v-model='allow_recurrent_event')
|
||||||
|
|
||||||
|
el-divider {{$t('admin.federation')}}
|
||||||
|
el-form(inline @submit.native.prevent='associate_mastondon_instance' label-width='240px')
|
||||||
p {{$t('admin.mastodon_description')}}
|
p {{$t('admin.mastodon_description')}}
|
||||||
el-form-item(:label='$t("admin.mastodon_instance")')
|
el-form-item(:label='$t("admin.mastodon_instance")')
|
||||||
el-input(v-model="mastodon_instance")
|
el-input(v-model="mastodon_instance")
|
||||||
el-form-item
|
el-form-item
|
||||||
el-button(native-type='submit' type='success' :disabled='!mastodon_instance') {{$t('common.associate')}}
|
el-button(native-type='submit' type='success' :disabled='!mastodon_instance') {{$t('common.associate')}}
|
||||||
hr
|
el-form-item(:label="$t('admin.allow_comments')")
|
||||||
p {{$t('admin.allow_registration_description')}}
|
el-switch(v-model='allow_comments')
|
||||||
el-form-item(:label="allow_registration?$t('common.disable'):$t('common.enable')")
|
|
||||||
el-switch(v-model='allow_registration')
|
|
||||||
p {{$t('admin.allow_anon_event')}}
|
|
||||||
el-form-item(:label="allow_anon_event?$t('common.disable'):$t('common.enable')")
|
|
||||||
el-switch(v-model='allow_anon_event')
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -73,7 +73,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// TODO
|
copy (msg) {
|
||||||
|
this.$copyText(msg).then(e => console.error('ok ', e)).catch(e => console.error('err ',e))
|
||||||
|
},
|
||||||
async add_notification () {
|
async add_notification () {
|
||||||
if (!this.notification.email){
|
if (!this.notification.email){
|
||||||
Message({message:'Inserisci una mail', showClose: true, type: 'error'})
|
Message({message:'Inserisci una mail', showClose: true, type: 'error'})
|
||||||
|
|
|
@ -25,6 +25,9 @@ import 'vue-awesome/icons/chevron-right'
|
||||||
import 'vue-awesome/icons/chevron-left'
|
import 'vue-awesome/icons/chevron-left'
|
||||||
import 'vue-awesome/icons/search'
|
import 'vue-awesome/icons/search'
|
||||||
import 'vue-awesome/icons/times'
|
import 'vue-awesome/icons/times'
|
||||||
|
import 'vue-awesome/icons/calendar-day'
|
||||||
|
import 'vue-awesome/icons/calendar-week'
|
||||||
|
import 'vue-awesome/icons/calendar-alt'
|
||||||
|
|
||||||
import Icon from 'vue-awesome/components/Icon'
|
import Icon from 'vue-awesome/components/Icon'
|
||||||
|
|
||||||
|
|
|
@ -177,13 +177,22 @@ const eventController = {
|
||||||
|
|
||||||
async getAll(req, res) {
|
async getAll(req, res) {
|
||||||
// this is due how v-calendar shows dates
|
// this is due how v-calendar shows dates
|
||||||
const start = moment().year(req.params.year).month(req.params.month)
|
const start = moment()
|
||||||
.startOf('month').startOf('isoWeek')
|
.year(req.params.year)
|
||||||
let end = moment().utc().year(req.params.year).month(req.params.month).endOf('month')
|
.month(req.params.month)
|
||||||
|
.startOf('month')
|
||||||
|
.startOf('isoWeek')
|
||||||
|
|
||||||
|
let end = moment()
|
||||||
|
.year(req.params.year)
|
||||||
|
.month(req.params.month)
|
||||||
|
.endOf('month')
|
||||||
|
|
||||||
const shownDays = end.diff(start, 'days')
|
const shownDays = end.diff(start, 'days')
|
||||||
if (shownDays <= 35) end = end.add(1, 'week')
|
if (shownDays <= 35) end = end.add(1, 'week')
|
||||||
end = end.endOf('isoWeek')
|
end = end.endOf('isoWeek')
|
||||||
const events = await Event.findAll({
|
|
||||||
|
let events = await Event.findAll({
|
||||||
where: {
|
where: {
|
||||||
is_visible: true,
|
is_visible: true,
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
|
@ -200,7 +209,50 @@ const eventController = {
|
||||||
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
res.json(events)
|
|
||||||
|
events = events.map(e => {
|
||||||
|
e.start_datetime = e.start_datetime*1000
|
||||||
|
e.end_datetime = e.end_datetime*1000
|
||||||
|
e.tags = e.tags.map(t => t.tag)
|
||||||
|
return e
|
||||||
|
})
|
||||||
|
|
||||||
|
// build singular events from a recurrent pattern from today due to
|
||||||
|
// specified parameters
|
||||||
|
function createEventsFromRecurrent(e, dueTo=null, maxEvents=20) {
|
||||||
|
const events = []
|
||||||
|
const cursor = moment()
|
||||||
|
const start_date = moment(e.start_datetime)
|
||||||
|
const frequency = e.recurrent.frequency
|
||||||
|
const days = e.recurrent.days
|
||||||
|
const ordinal = e.recurrent.ordinal
|
||||||
|
|
||||||
|
// EACH WEEK
|
||||||
|
if (frequency === '1w') {
|
||||||
|
while(true) {
|
||||||
|
const found = days.indexOf(cursor.day())
|
||||||
|
if (found) break
|
||||||
|
cursor.add(1, 'day')
|
||||||
|
}
|
||||||
|
|
||||||
|
e.start_datetime = cursor.set('hour', e.start_datetime.hour()).set('minute', e.start_datetime.minutes())
|
||||||
|
while (true) {
|
||||||
|
if ((dueTo && cursor.isAfter(dueTo)) || events.length>maxEvents) break
|
||||||
|
e.start_datetime = cursor.unix()
|
||||||
|
events.push(e)
|
||||||
|
cursors.add(1, 'week')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EACH TWO WEEKS
|
||||||
|
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalEvents = events.filter(e => !e.recurrent)
|
||||||
|
const recurrentEvents = events.filter(e => e.recurrent).map(createEventsFromRecurrent)
|
||||||
|
|
||||||
|
res.json(normalEvents.concat(recurrentEvents))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
'use strict'
|
|
||||||
module.exports = (sequelize, DataTypes) => {
|
module.exports = (sequelize, DataTypes) => {
|
||||||
const event = sequelize.define('event', {
|
const event = sequelize.define('event', {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
title: DataTypes.STRING,
|
title: DataTypes.STRING,
|
||||||
slug: DataTypes.STRING,
|
slug: DataTypes.STRING,
|
||||||
description: DataTypes.TEXT,
|
description: DataTypes.TEXT,
|
||||||
|
@ -19,6 +23,8 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
type: DataTypes.STRING(18),
|
type: DataTypes.STRING(18),
|
||||||
index: true
|
index: true
|
||||||
},
|
},
|
||||||
|
recurrent: DataTypes.JSON,
|
||||||
|
// parent: DataTypes.INTEGER
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
event.associate = function (models) {
|
event.associate = function (models) {
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
p= t('email.confirm')
|
<!DOCTYPE html>
|
||||||
|
html(lang="en")
|
||||||
|
head
|
||||||
|
meta(charset="UTF-8")
|
||||||
|
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
||||||
|
meta(http-equiv="X-UA-Compatible", content="ie=edge")
|
||||||
|
title #{config.title}
|
||||||
|
body
|
||||||
|
p= t('email.confirm')
|
||||||
|
|
||||||
hr
|
hr
|
||||||
<a href="#{config.baseurl}"> #{config.title} - #{config.description}</a>
|
<a href="#{config.baseurl}"> #{config.title} - #{config.description}</a>
|
104
store/index.js
104
store/index.js
|
@ -1,16 +1,15 @@
|
||||||
import moment from 'dayjs'
|
import moment from 'dayjs'
|
||||||
import intersection from 'lodash/intersection'
|
import intersection from 'lodash/intersection'
|
||||||
import map from 'lodash/map'
|
import map from 'lodash/map'
|
||||||
|
import filter from 'lodash/filter'
|
||||||
|
import find from 'lodash/find'
|
||||||
|
|
||||||
export const state = () => ({
|
export const state = () => ({
|
||||||
// config: {},
|
|
||||||
locale: '',
|
locale: '',
|
||||||
events: [],
|
events: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
places: [],
|
places: [],
|
||||||
settings: {
|
settings: {},
|
||||||
|
|
||||||
},
|
|
||||||
filters: {
|
filters: {
|
||||||
tags: [],
|
tags: [],
|
||||||
places: [],
|
places: [],
|
||||||
|
@ -23,55 +22,60 @@ export const state = () => ({
|
||||||
export const getters = {
|
export const getters = {
|
||||||
|
|
||||||
// filter matches search tag/place
|
// filter matches search tag/place
|
||||||
filteredEvents: state => {
|
filteredEvents: state => {
|
||||||
let events = state.events
|
|
||||||
|
|
||||||
// TOFIX: use lodash
|
const search_for_tags = !!state.filters.tags.length
|
||||||
if (state.filters.tags.length || state.filters.places.length) {
|
const search_for_places = !!state.filters.places.length
|
||||||
events = events.filter((e) => {
|
|
||||||
if (state.filters.tags.length) {
|
|
||||||
const m = intersection(e.tags.map(t => t.tag), state.filters.tags)
|
|
||||||
if (m.length > 0) return true
|
|
||||||
}
|
|
||||||
if (state.filters.places.length) {
|
|
||||||
if (state.filters.places.find(p => p === e.place.id)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state.filters.show_past_events) {
|
return state.events.filter(e => {
|
||||||
events = events.filter(e => !e.past)
|
|
||||||
}
|
|
||||||
|
|
||||||
return events
|
// filter past events
|
||||||
|
if (!state.filters.show_past_events && e.past) return false
|
||||||
|
|
||||||
|
// filter recurrent events
|
||||||
|
if (!state.filters.show_recurrent_events && e.recurrent) return false
|
||||||
|
|
||||||
|
if (search_for_places) {
|
||||||
|
if (find(state.filters.places, p => p === e.place.id)) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search_for_tags) {
|
||||||
|
const common_tags = intersection(map(e.tags, t => t.tag), state.filters.tags);
|
||||||
|
if (common_tags.length > 0) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!search_for_places && !search_for_tags) return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
// filter matches search tag/place
|
|
||||||
filteredEventsWithPast: state => {
|
|
||||||
let events = state.events
|
|
||||||
|
|
||||||
// TOFIX: use lodash
|
// filter matches search tag/place including past events
|
||||||
if (state.filters.tags.length || state.filters.places.length) {
|
filteredEventsWithPast: state => {
|
||||||
events = events.filter((e) => {
|
|
||||||
if (state.filters.tags.length) {
|
|
||||||
const m = intersection(e.tags.map(t => t.tag), state.filters.tags)
|
|
||||||
if (m.length > 0) return true
|
|
||||||
}
|
|
||||||
if (state.filters.places.length) {
|
|
||||||
if (state.filters.places.find(p => p === e.place.id)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return events
|
const search_for_tags = !!state.filters.tags.length
|
||||||
|
const search_for_places = !!state.filters.places.length
|
||||||
|
|
||||||
|
return state.events.filter(e => {
|
||||||
|
const match = false
|
||||||
|
|
||||||
|
// filter recurrent events
|
||||||
|
if (!state.filters.show_recurrent_events && e.recurrent) return false
|
||||||
|
|
||||||
|
if (!match && search_for_places) {
|
||||||
|
if (find(state.filters.places, p => p === e.place.id)) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search_for_tags) {
|
||||||
|
const common_tags = intersection(map(e.tags, t => t.tag), state.filters.tags);
|
||||||
|
if (common_tags.length > 0) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!search_for_places && !search_for_tags) return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
@ -115,6 +119,9 @@ export const mutations = {
|
||||||
showPastEvents(state, show) {
|
showPastEvents(state, show) {
|
||||||
state.filters.show_past_events = show
|
state.filters.show_past_events = show
|
||||||
},
|
},
|
||||||
|
showRecurrentEvents(state, show) {
|
||||||
|
state.filters.show_recurrent_events = show
|
||||||
|
},
|
||||||
setSettings(state, settings) {
|
setSettings(state, settings) {
|
||||||
state.settings = settings
|
state.settings = settings
|
||||||
},
|
},
|
||||||
|
@ -128,7 +135,7 @@ export const mutations = {
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
// this method is called server side only for each request
|
// this method is called server side only for each request
|
||||||
// we use it to get configuration from db
|
// we use it to get configuration from db, setting locale, etc...
|
||||||
async nuxtServerInit ({ commit }, { app, req } ) {
|
async nuxtServerInit ({ commit }, { app, req } ) {
|
||||||
const settings = await app.$axios.$get('/settings')
|
const settings = await app.$axios.$get('/settings')
|
||||||
commit('setSettings', settings)
|
commit('setSettings', settings)
|
||||||
|
@ -168,6 +175,9 @@ export const actions = {
|
||||||
showPastEvents({ commit }, show) {
|
showPastEvents({ commit }, show) {
|
||||||
commit('showPastEvents', show)
|
commit('showPastEvents', show)
|
||||||
},
|
},
|
||||||
|
showRecurrentEvents({ commit }, show ) {
|
||||||
|
commit('showRecurrentEvents', show)
|
||||||
|
},
|
||||||
async setSetting({ commit }, setting) {
|
async setSetting({ commit }, setting) {
|
||||||
await this.$axios.$post('/settings', setting )
|
await this.$axios.$post('/settings', setting )
|
||||||
commit('setSetting', setting)
|
commit('setSetting', setting)
|
||||||
|
|
Loading…
Reference in a new issue