Skip to content
This repository was archived by the owner on Dec 14, 2023. It is now read-only.

Commit 6c462a6

Browse files
committed
Add timepicker and validations
1 parent 83fdec4 commit 6c462a6

File tree

6 files changed

+242
-90
lines changed

6 files changed

+242
-90
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"vue": "^2.2.6",
3535
"vue-analytics": "^4.1.3",
3636
"vue-awesome": "^2.3.1",
37+
"vue-ctk-date-time-picker": "^2.1.1",
3738
"vue-dob-picker": "^1.0.9",
3839
"vue-i18n": "^7.0.3",
3940
"vue-multiselect": "^2.1.0",

src/events/cd-event-form.vue

Lines changed: 191 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,112 @@
11
<template>
22
<div class="cd-event-form">
3-
<div class="cd-event-form__left-column">
4-
<h1 class="cd-event-form__header">{{ $t('Create an event') }}</h1>
5-
<form @submit="save">
6-
<input type="text" name="title" v-model="title" class="form-control" :placeholder="$t('e.g. October Dojo')">
7-
<div class="cd-event-form__location">
8-
<!-- is the text relevant when it's been modified? -->
9-
<!-- what about previous event information, default back to Dojo's or previous event ? -->
10-
{{ $t('This event uses the Dojo address.') }}
11-
<span v-show="!addressIsVisible">{{ formattedAddress }}</span>
12-
<i class="fa fa-pencil" @click="addressIsVisible = true" v-show="!addressIsVisible"></i>
13-
<i class="fa fa-times" @click="addressIsVisible = false" v-show="addressIsVisible"></i>
14-
<div v-if="addressIsVisible">
15-
<input type="text" name="city" v-model="city" class="form-control">
16-
<textarea name="address" v-model="address" rows="3" class="form-control"></textarea>
17-
</div>
18-
</div>
19-
<div class="cd-event-form__description">
20-
{{ $t('This event uses the previous event description') }}
21-
<span v-show="!descriptionIsVisible">{{ truncatedDescription }}</span>
22-
<i class="fa fa-pencil" @click="descriptionIsVisible = true" v-show="!descriptionIsVisible"></i>
23-
<i class="fa fa-times" @click="descriptionIsVisible = false" v-show="descriptionIsVisible"></i>
24-
<div v-if="descriptionIsVisible">
25-
<VueTrix v-model="description" />
26-
</div>
27-
</div>
28-
<div class="cd-event-form__date form-group">
29-
<input list="days" type="number" name="day" v-model="day" class="form-control">
30-
<datalist id="days" v-model="day">
31-
<option v-for="day in 31" :key="index" :value="day">{{ day }} </option>
32-
</datalist>
33-
<select name="month" v-model="month">
34-
<option v-for="(month, index) in months" :value="index">{{ month }}</option>
35-
</select>
36-
<input list="years" type="number" name="year" v-model="year" class="form-control">
37-
<datalist id="years" v-model="year">
38-
<option v-for="year in 3" :key="index">{{ year + today.year() -1 }} </option>
39-
</datalist>
40-
</div>
41-
<div class="cd-event-form__date form-group">
42-
<input type="datetime-local" name="day" :value="today" :min="today">
3+
<h1 class="cd-event-form__header">{{ $t('Create an event') }}</h1>
4+
<form @submit="save">
5+
6+
<p class="text-danger" v-show="errors.has('name:required')">{{ $t('Name is required') }}</p>
7+
<input type="text" name="name" v-model="name" class="form-control" data-vv-name="name" v-validate="'required'" data-vv-validate-on="blur" :placeholder="$t('e.g. October Dojo')">
8+
9+
<div class="cd-event-form__location">
10+
<!-- is the text relevant when it's been modified? -->
11+
<!-- what about previous event information, default back to Dojo's or previous event ? -->
12+
{{ $t('This event uses the Dojo address.') }}
13+
<span v-show="!addressIsVisible">{{ formattedAddress }}</span>
14+
<i class="fa fa-pencil" @click="addressIsVisible = true" v-show="!addressIsVisible"></i>
15+
<i class="fa fa-times" @click="addressIsVisible = false" v-show="addressIsVisible"></i>
16+
<div v-if="addressIsVisible">
17+
<input type="text" name="city" v-model="city" class="form-control">
18+
<textarea name="address" v-model="address" rows="3" class="form-control"></textarea>
4319
</div>
44-
<div class="cd-event-form__tickets">
45-
<form-tickets label="Youth tickets" ref="youthTickets" :default-quantity="20" class="cd-event-form__youth-tickets">
46-
</form-tickets>
47-
<form-tickets label="Mentor tickets" ref="mentorTickets" :default-quantity="5" class="cd-event-form__mentor-tickets">
48-
</form-tickets>
20+
</div>
21+
22+
<div class="cd-event-form__description">
23+
{{ $t('This event uses the previous event description') }}
24+
<span v-show="!descriptionIsVisible">{{ truncatedDescription }}</span>
25+
<i class="fa fa-pencil" @click="descriptionIsVisible = true" v-show="!descriptionIsVisible"></i>
26+
<i class="fa fa-times" @click="descriptionIsVisible = false" v-show="descriptionIsVisible"></i>
27+
<div v-if="descriptionIsVisible">
28+
<VueTrix v-model="description" />
4929
</div>
50-
<dropdown type="primary" display="splitted" class="cd-event-form__button">
51-
<button slot="submit" type="submit" class="btn btn-primary cd-event-form__button-default-submit">
52-
{{ $t('Publish and email members') }}
53-
</button>
54-
<li><a href="#">Publish only</a></li>
55-
<li><a href="#">Save as draft</a></li>
56-
</dropdown>
57-
</form>
58-
</div>
59-
<div class="cd-event-form__right-column">
60-
<div class="cd-event-form__info-box">
61-
<h3 class="cd-event-form__info-box-header">Say "Hi" to our new events!</h3>
62-
<p>We simplified our events experience, read <a href="TODO">about it here</a>. To use the old more complicated interface, click <a href="TODO">Advanced Events</a></p>
63-
<p>If you need any help, <a href="mailto:[email protected]">email support</a>.</p>
6430
</div>
65-
</div>
31+
32+
<div class="cd-event-form__date form-group">
33+
<input list="days" type="number" name="day" v-model="day" class="form-control">
34+
<datalist id="days" v-model="day">
35+
<option v-for="day in 31" :key="index" :value="day">{{ day }} </option>
36+
</datalist>
37+
<select name="month" v-model="month">
38+
<option v-for="(month, index) in months" :value="index">{{ month }}</option>
39+
</select>
40+
<input list="years" type="number" name="year" v-model="year" class="form-control">
41+
<datalist id="years" v-model="year">
42+
<option v-for="year in 3" :key="index">{{ year + today.year() -1 }} </option>
43+
</datalist>
44+
</div>
45+
46+
<p class="text-danger" v-show="errors.has('startingTime:required')">{{ $t('Start time is required') }}</p>
47+
<p class="text-danger" v-show="errors.has('finishTime:required')">{{ $t('Finish time is required') }}</p>
48+
<p class="text-danger" v-show="errors.has('finishTime:after')">{{ $t('Finish time must be after start time') }}</p>
49+
<div class="cd-event-form__date form-group">
50+
<VueCtkDateTimePicker v-model="startingTime"
51+
name="startingTime"
52+
v-validate="'required'"
53+
:only-time="true"
54+
:input-size="'sm'"
55+
:format="'HH:mm'"
56+
:formatted="'llll'"
57+
:minute-interval=10
58+
:no-label=true
59+
/>
60+
<span>
61+
to:
62+
</span>
63+
<VueCtkDateTimePicker v-model="finishTime"
64+
name="finishTime"
65+
v-on:input="finishTimeChanged"
66+
:only-time="true"
67+
:input-size="'sm'"
68+
:format="'HH:mm'"
69+
:formatted="'llll'"
70+
:minute-interval=10
71+
:no-label=true
72+
/>
73+
</div>
74+
75+
<div class="cd-event-form__tickets">
76+
<p class="text-danger" v-show="errors.has('Youth tickets:required')">{{ $t('Number of Youth tickets is required') }}</p>
77+
<p class="text-danger" v-show="errors.has('Youth tickets:min_value')">{{ $t('Must be greater than 0') }}</p>
78+
<form-tickets label="Youth tickets"
79+
v-validate="'required|min_value:1'"
80+
ref="youthTickets"
81+
:default-quantity="20"
82+
class="cd-event-form__youth-tickets">
83+
</form-tickets>
84+
<p class="text-danger" v-show="errors.has('Mentor tickets:required')">{{ $t('Number of Mentor tickets is required') }}</p>
85+
<p class="text-danger" v-show="errors.has('Mentor tickets:min_value')">{{ $t('Must be greater than 0') }}</p>
86+
<form-tickets label="Mentor tickets"
87+
v-validate="'required|min_value:1'"
88+
ref="mentorTickets"
89+
:default-quantity="5"
90+
class="cd-event-form__mentor-tickets">
91+
</form-tickets>
92+
</div>
93+
<button slot="submit" type="submit" class="btn btn-primary cd-event-form__button-default-submit">
94+
{{ $t('Publish') }}
95+
</button>
96+
</form>
97+
<p>We simplified our events experience, read <a href="TODO">about it here</a>.
98+
<br/>
99+
If you need to customise your event further you can still use the <a href="TODO">advanced events form</a></p>
66100
</div>
67101
</template>
68102
<script>
69103
import moment from 'moment';
70104
import VueTrix from 'vue-trix';
105+
import VueCtkDateTimePicker from 'vue-ctk-date-time-picker';
106+
import 'vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css';
71107
import DojoService from '@/dojos/service';
72108
import Dropdown from '@/common/cd-dropdown';
109+
import EventService from '@/events/service';
73110
import EventTile from './cd-event-tile';
74111
import FormTickets from './form/form-tickets';
75112
@@ -80,12 +117,13 @@
80117
dropdown: Dropdown,
81118
formTickets: FormTickets,
82119
VueTrix,
120+
VueCtkDateTimePicker,
83121
},
84122
data() {
85123
return {
86-
title: '',
124+
name: '',
87125
description: '',
88-
city: '',
126+
city: {},
89127
address: '',
90128
day: moment().date(),
91129
// TODO: momentjs get month of current locale
@@ -96,21 +134,78 @@
96134
// state
97135
addressIsVisible: false,
98136
descriptionIsVisible: false,
137+
public: true,
138+
// TODO: generate start/end based on previous event
139+
startingTime: '9:00',
140+
finishTime: '10:00',
99141
};
100142
},
101143
methods: {
144+
async validateForm() {
145+
try {
146+
const res = await this.$validator.validateAll();
147+
console.log(res);
148+
return res;
149+
} catch (err) {
150+
return false;
151+
}
152+
},
102153
async save(e) {
103154
e.preventDefault();
104-
await Promise.all(this.tickets.map(t => t.createTicket()));
155+
console.log('something');
156+
const ready = await this.validateForm();
157+
console.log(ready);
158+
if (ready) {
159+
await Promise.all(this.tickets.map(t => t.createTicket()));
160+
await EventService.v3.create({
161+
name: this.name,
162+
description: this.description,
163+
city: this.city,
164+
address: this.address,
165+
dates: [{ startTime: this.startTime, endTime: this.endTime }],
166+
type: 'one-off',
167+
status: 'saved',
168+
public: this.public,
169+
useDojoAddress: false,
170+
ticketApproval: false,
171+
notifyOnApplicant: false,
172+
country: {
173+
countryName: 'Ireland',
174+
countryNumber: 372,
175+
continent: 'Europe',
176+
alpha2: 'IE',
177+
alpha3: 'IRL',
178+
},
179+
sessions: this.sessions,
180+
dojoId: 'a6796f63-db6b-429b-b2bd-612e0f107c84',
181+
});
182+
}
105183
},
184+
106185
toggle(field) { // eslint-disable-line no-unused-vars
107186
// eslint-disable-next-line no-param-reassign
108187
field = !field;
109188
},
189+
finishTimeChanged() {
190+
console.log(this.startTime);
191+
console.log(this.endTime);
192+
const isAfter = this.endTime.isAfter(this.startTime);
193+
console.log('Is it after:', isAfter);
194+
if (!isAfter) {
195+
console.log('It is before lets add error');
196+
this.errors.add(
197+
{
198+
field: 'finishTime',
199+
msg: 'Finish time is after start time',
200+
rule: 'after',
201+
});
202+
console.log(this.errors);
203+
}
204+
},
110205
},
111206
computed: {
112207
eventDay() {
113-
return moment.utc(this.day, this.month, this.year);
208+
return moment.utc([this.year, this.month, this.day]);
114209
},
115210
truncatedDescription() {
116211
return this.description.substring(0, 20);
@@ -124,41 +219,51 @@
124219
tickets() {
125220
return [this.$refs.youthTickets, this.$refs.mentorTickets];
126221
},
222+
startTime() {
223+
console.log('Getting start time');
224+
const startDay = moment.utc([this.year, this.month, this.day]);
225+
// const startDay = this.eventDay;
226+
const startingTimeElements = this.startingTime.split(':');
227+
console.log('st el:', startingTimeElements);
228+
startDay.hours(startingTimeElements[0]);
229+
startDay.minutes(startingTimeElements[1]);
230+
return startDay;
231+
},
232+
endTime() {
233+
console.log('Getting end time');
234+
const endDay = moment.utc([this.year, this.month, this.day]);
235+
// const day = this.eventDay;
236+
const finishTimeElements = this.finishTime.split(':');
237+
console.log('ft el:', finishTimeElements);
238+
endDay.hours(finishTimeElements[0]);
239+
endDay.minutes(finishTimeElements[1]);
240+
return endDay;
241+
},
242+
sessions() {
243+
return [{
244+
name: 'A session',
245+
description: 'Some session or other',
246+
tickets: [{
247+
name: 'tickets',
248+
type: 'ninja',
249+
quantity: 3,
250+
}],
251+
}];
252+
},
127253
},
128254
async created() {
129255
const { dojoId } = this.$route.params;
130256
this.dojo = (await DojoService.getDojoById(dojoId)).body;
131257
this.address = this.dojo.address1;
132-
this.city = this.dojo.city.name;
258+
this.city = this.dojo.city;
133259
},
134260
};
135261
</script>
136262
<style scoped lang="less">
137263
@import "../common/variables";
138264
139265
.cd-event-form {
140-
display: flex;
141-
flex-direction: row;
142266
padding-bottom: 5em;
143-
&__left-column {
144-
flex: 2;
145-
display: flex;
146-
flex-direction: column;
147-
padding: @margin;
148-
}
149-
&__right-column {
150-
flex: 1;
151-
display: flex;
152-
flex-direction: column;
153-
justify-content: space-around;
154-
}
155-
&__info-box {
156-
background-color: @side-column-grey;
157-
padding: @margin;
158-
&-header {
159-
margin-top: 10px;
160-
}
161-
}
162267
&__header {
163268
.title;
164269
}

src/events/form/form-tickets.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
<template>
22
<div>
3+
34
<label for="quantity">{{ $t(label) }}</label>
4-
<input type="number" v-model="quantity" name="quantity" />
5+
<input type="number"
6+
v-model="quantity"
7+
name="quantity" />
58
</div>
69

710
</template>
811
<script>
912
export default {
13+
$_veeValidate: {
14+
name() {
15+
return this.label;
16+
},
17+
value() {
18+
return this.quantity;
19+
},
20+
},
1021
name: 'form-ticket',
1122
props: [
1223
'label',

src/events/service.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const EventsService = {
3535
getOrder(userId, options) {
3636
return Vue.http.get(`${Vue.config.apiServer}/api/3.0/users/${userId}/orders`, options);
3737
},
38+
create(event) {
39+
return Vue.http.post(`${Vue.config.apiServer}/api/3.0/events`, event);
40+
},
3841
},
3942
};
4043

0 commit comments

Comments
 (0)