From c3902a6d642f34c2df1418291e9759444c0112e5 Mon Sep 17 00:00:00 2001 From: lesion Date: Thu, 11 Jul 2019 23:31:37 +0200 Subject: [PATCH 1/3] start with recurrent events --- components/Nav.vue | 2 +- components/Search.vue | 32 ++++--- locales/it.js | 34 ++++++-- pages/add/_edit.vue | 147 +++++++++++++++++++++++++-------- pages/admin.vue | 26 ++++-- pages/export.vue | 4 +- plugins/vue-awesome.js | 3 + server/api/controller/event.js | 62 ++++++++++++-- server/api/models/event.js | 8 +- server/emails/confirm/html.pug | 14 +++- store/index.js | 104 ++++++++++++----------- 11 files changed, 316 insertions(+), 120 deletions(-) diff --git a/components/Nav.vue b/components/Nav.vue index 2bf70267..ef459187 100644 --- a/components/Nav.vue +++ b/components/Nav.vue @@ -16,7 +16,7 @@ el-popover( placement="bottom" trigger="click") - Search(past-filter) + Search(past-filter recurrent-filter) el-menu-item(slot='reference' :title="$t('common.search')" icon='el-share-button') v-icon(color='lightblue' name='search') el-badge(v-if='filters.tags.length+filters.places.length>0' is-dot type='warning') diff --git a/components/Search.vue b/components/Search.vue index 64466774..76400d0d 100644 --- a/components/Search.vue +++ b/components/Search.vue @@ -8,11 +8,18 @@ //- ) el-switch.mt-1.mb-1.ml-2.d-block( 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' inactive-color='lightgreen' v-model='showPast' - ) + ) no-ssr el-select.search(v-model='filter' multiple @@ -33,24 +40,25 @@ export default { }, name :'Search', props: { - pastFilter: Boolean + pastFilter: Boolean, + recurrentFilter: Boolean }, - methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents']), + methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents', 'showRecurrentEvents']), computed: { - ...mapState(['tags', 'places', 'filters', 'show_past_events']), + ...mapState(['tags', 'places', 'filters']), // TOFIX: optimize keywords () { 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 })) return tags.concat(places).sort((a, b) => b.weigth-a.weigth) }, - showPast : { - set (value) { - this.showPastEvents(value) - }, - get () { - return this.filters.show_past_events - } + showPast: { + set (value) { this.showPastEvents(value) }, + get () { return this.filters.show_past_events } + }, + showRecurrent: { + set (value) { this.showRecurrentEvents(value) }, + get () { return this.filters.show_recurrent_events } }, filter: { set (filters) { diff --git a/locales/it.js b/locales/it.js index f4dfe16e..b7fc1bce 100644 --- a/locales/it.js +++ b/locales/it.js @@ -103,10 +103,7 @@ const it = { tratta di un evento adatto a questo spazio, delegando questa scelta. Inoltre non sarà possibile modificarlo.

Puoi invece fare il login o registrarti, altrimenti vai avanti e riceverai una risposta il prima possibile. `, - multidate_description: 'tanti giorni', - date_description: `Quand'è il gancio?`, - dates_description: 'Che giorni?', - same_day: 'stesso giorno', + same_day: 'Stesso giorno', what_description: 'Nome evento', description_description: 'Descrizione, dajene di copia/incolla', tag_description: 'Tag...', @@ -118,7 +115,21 @@ const it = { where_description: `Dov'è il gancio? Se il posto non è presente, scrivilo e premi invio. `, confirmed: 'Evento confermato', 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: { @@ -132,7 +143,9 @@ const it = { user_remove_ok: 'Utente eliminato', user_create_ok: 'Utente creato', 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: { @@ -152,6 +165,15 @@ const it = { register_error: 'Errore nella registrazione' }, + ordinal: { + 1: 'primo', + 2: 'secondo', + 3: 'terzo', + 4: 'quarto', + 5: 'quinto', + [-1]: 'ultimo', + }, + about: `

Gancio e' un progetto dell'underscore hacklab e uno dei diff --git a/pages/add/_edit.vue b/pages/add/_edit.vue index ab13f6ad..9a06769a 100644 --- a/pages/add/_edit.vue +++ b/pages/add/_edit.vue @@ -14,6 +14,23 @@ p(v-html="$t('event.anon_description')") el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('common.next')}} + //- WHAT + el-tab-pane + span(slot='label') {{$t('common.what')}} + 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 el-tab-pane span(slot='label') {{$t('common.where')}} @@ -34,49 +51,49 @@ //- WHEN el-tab-pane span(slot='label') {{$t('common.when')}} - 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( - :mode='event.multidate ? "range" : "single"' + .text-center + el-radio-group(v-model="event.type") + el-radio-button(label="normal") {{$t('event.normal')}} + el-radio-button(label="multidate") {{$t('event.multidate')}} + el-radio-button(label="recurrent") {{$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' v-model='date' :locale='$i18n.locale' :from-page.sync='page' is-inline is-expanded - :min-date='new Date()' + :min-date='event.type !== "recurrent" && new Date()' ) - el-row - el-col(:span='12') - div {{$t('event.time_start_description')}} - el-time-select.mb-3(ref='time_start' + div.text-center.mb-2(v-if='event.type === "recurrent"') + span(v-if='event.rec_frequency !== "1m" && event.rec_frequency !== "2m"') {{whenPatterns}} + el-radio-group(v-else v-model='event.rec_detail') + 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" :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' :picker-options="{start: '00:00', step: '00:30', end: '24:00'}") - el-col(:span='12') - List(:events='todayEvents' :title='$t("event.same_day")') - el-button.float-right(@click='next' :disabled='!couldProceed') {{$t('common.next')}} - - //- WHAT - el-tab-pane - span(slot='label') {{$t('common.what')}} - 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')}} + + List(v-if='event.type==="normal"' :events='todayEvents' :title='$t("event.same_day")') + el-button.float-right(@click='next' type='succes' :disabled='!couldProceed') {{$t('common.next')}} el-tab-pane span(slot='label') {{$t('common.media')}} @@ -96,6 +113,8 @@