|
6 | 6 | <div class="cd-event-form">
|
7 | 7 | <h3 class="cd-event-form__header">{{ `${$t('Create an event for')} ${dojo.name}` }}</h3>
|
8 | 8 | <form @submit="save">
|
| 9 | + |
| 10 | + <div v-if="submitError"> |
| 11 | + <h3 class="text-danger">{{ $t('There was an error processing this request. Please try again or contact support') }}</h3> |
| 12 | + </div> |
9 | 13 | <h4 class="cd-event__section-title">{{ $t('Event Title') }}</h4>
|
10 | 14 | <p class="text-danger" v-show="errors.has('name:required')">{{ $t('Title is required') }}</p>
|
11 | 15 | <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')">
|
12 | 16 |
|
13 | 17 | <div class="cd-event-form__location">
|
14 | 18 | <!-- is the text relevant when it's been modified? -->
|
15 | 19 | <!-- what about previous event information, default back to Dojo's or previous event ? -->
|
16 |
| - {{ $t('This event uses the Dojo address.') }} |
| 20 | + {{ $t('This event uses the address.') }}: |
17 | 21 | <span v-show="!addressIsVisible">{{ formattedAddress }}</span>
|
18 | 22 | <i class="fa fa-pencil" @click="addressIsVisible = true" v-show="!addressIsVisible"></i>
|
19 | 23 | <i class="fa fa-times" @click="addressIsVisible = false" v-show="addressIsVisible"></i>
|
20 | 24 | <div v-if="addressIsVisible">
|
21 |
| - <input type="text" name="city" v-model="city.name" class="form-control"> |
| 25 | + <input type="text" name="city" v-model="city.nameWithHierarchy" class="form-control"> |
22 | 26 | <textarea name="address" v-model="address" rows="3" class="form-control"></textarea>
|
23 | 27 | </div>
|
24 | 28 | </div>
|
25 | 29 |
|
26 | 30 | <div class="cd-event-form__description">
|
27 |
| - {{ $t('This event uses the previous event description') }} |
| 31 | + {{ $t('This event uses the description') }}: |
28 | 32 | <span v-show="!descriptionIsVisible">{{ truncatedDescription }}</span>
|
29 | 33 | <i class="fa fa-pencil" @click="descriptionIsVisible = true" v-show="!descriptionIsVisible"></i>
|
30 | 34 | <i class="fa fa-times" @click="descriptionIsVisible = false" v-show="descriptionIsVisible"></i>
|
| 35 | + |
| 36 | + <p class="text-danger" v-show="errors.has('description:required')">{{ $t('Description is required') }}</p> |
| 37 | + <input type="hidden" v-model="description" v-validate="'required'" name="description" /> |
31 | 38 | <div v-if="descriptionIsVisible">
|
32 |
| - <VueTrix v-model="description" /> |
| 39 | + <VueTrix v-model="description" ref="trixEditor" /> |
33 | 40 | </div>
|
34 | 41 | </div>
|
35 | 42 |
|
|
157 | 164 | city: {},
|
158 | 165 | address: '',
|
159 | 166 | dojo: {},
|
160 |
| - latestEvent: {}, |
| 167 | + latestEvent: undefined, |
161 | 168 | // state
|
162 | 169 | addressIsVisible: false,
|
163 | 170 | descriptionIsVisible: false,
|
164 | 171 | public: true,
|
165 |
| - // TODO: generate start/end based on previous event |
166 | 172 | startingTime: '09:00',
|
167 | 173 | finishTime: '11:00',
|
168 | 174 | // TODO: momentjs get month of current locale
|
169 |
| - eventDate: `${moment().year()}-${moment().month() + 1}-${moment().date()}`, |
| 175 | + eventDate: moment().format('YYYY-MM-DD'), |
170 | 176 | sendEmails: true,
|
| 177 | + submitError: false, |
171 | 178 | };
|
172 | 179 | },
|
173 | 180 | methods: {
|
174 | 181 | async populateForm() {
|
175 |
| - if (this.latestEvent !== undefined) { |
| 182 | + if (this.latestEvent) { |
| 183 | + await this.populateCityFromLatestEvent(); |
| 184 | + await this.populateDatesAndTimesFromLatestEvent(); |
| 185 | + await this.populateTicketQuantitiesFromLatestEvent(); |
| 186 | +
|
176 | 187 | this.description = this.latestEvent.description;
|
177 |
| - this.city = this.latestEvent.city; |
178 | 188 | this.address = this.latestEvent.address;
|
179 | 189 | } else {
|
180 |
| - // TODO: use dojo description? |
181 |
| - // this.description = 'standard desc'; |
| 190 | + this.description = this.dojo.notes; |
182 | 191 | this.address = this.dojo.address1;
|
183 |
| - this.city = this.dojo.city; |
| 192 | + this.city = { nameWithHierarchy: this.dojo.city.name }; |
| 193 | + } |
| 194 | + }, |
| 195 | + async populateCityFromLatestEvent() { |
| 196 | + // format the event city correctly :( |
| 197 | + const city = this.latestEvent.city; |
| 198 | + if (city && city.toponymName) { |
| 199 | + city.nameWithHierarchy = city.toponymName; |
| 200 | + delete city.toponymName; |
| 201 | + } |
| 202 | + this.city = city; |
| 203 | + }, |
| 204 | + async populateDatesAndTimesFromLatestEvent() { |
| 205 | + const startDate = moment.utc(this.latestEvent.startTime); |
| 206 | + let newDate = startDate.add(7, 'days'); |
| 207 | + const inPast = moment().diff(newDate, 'days') > 0; |
| 208 | +
|
| 209 | + if (inPast) { |
| 210 | + const neededDay = startDate.day(); |
| 211 | + newDate = (moment().isoWeekday() <= neededDay) ? |
| 212 | + moment().isoWeekday(neededDay) : |
| 213 | + moment().add(1, 'weeks').isoWeekday(neededDay); |
| 214 | + } |
| 215 | +
|
| 216 | + this.eventDate = newDate.format('YYYY-MM-DD'); |
| 217 | +
|
| 218 | + const endDate = moment.utc(this.latestEvent.endTime); |
| 219 | + this.startingTime = startDate.format('HH:mm'); |
| 220 | + this.finishTime = endDate.format('HH:mm'); |
| 221 | + }, |
| 222 | + async populateTicketQuantitiesFromLatestEvent() { |
| 223 | + if (this.latestEvent.sessions && this.latestEvent.sessions.length > 0) { |
| 224 | + // If there are any sessions for the last event just take the first one. |
| 225 | + // Any event that has more than one session was created using the old form |
| 226 | + // and it is unlikely to map to the new form structure |
| 227 | + const previousTickets = this.latestEvent.sessions[0].tickets; |
| 228 | + const youthTickets = previousTickets.find(ticket => ticket.name === 'Youth'); |
| 229 | + const mentorTickets = previousTickets.find(ticket => ticket.name === 'Mentor'); |
| 230 | +
|
| 231 | + if (youthTickets !== undefined) { |
| 232 | + this.$refs.youthTickets.setQuantity(youthTickets.quantity); |
| 233 | + } |
| 234 | + if (mentorTickets !== undefined) { |
| 235 | + this.$refs.mentorTickets.setQuantity(mentorTickets.quantity); |
| 236 | + } |
184 | 237 | }
|
185 | 238 | },
|
186 | 239 | async validateForm() {
|
|
191 | 244 | return false;
|
192 | 245 | }
|
193 | 246 | },
|
| 247 | +
|
194 | 248 | async save(e) {
|
195 | 249 | e.preventDefault();
|
196 | 250 | const valid = await this.validateForm();
|
197 | 251 | if (valid) {
|
198 |
| - await EventsService.v3.create({ |
199 |
| - name: this.name, |
200 |
| - description: this.description, |
201 |
| - city: this.city, |
202 |
| - address: this.address, |
203 |
| - dates: [{ startTime: this.startTime, endTime: this.endTime }], |
204 |
| - type: 'one-off', |
205 |
| - status: 'saved', |
206 |
| - public: this.public, |
207 |
| - useDojoAddress: false, |
208 |
| - ticketApproval: false, |
209 |
| - notifyOnApplicant: false, |
210 |
| - country: this.dojo.country, |
211 |
| - sessions: this.sessions, |
212 |
| - dojoId: this.dojo.id, |
213 |
| - }); |
| 252 | + try { |
| 253 | + const foo = await EventsService.v3.create({ |
| 254 | + name: this.name, |
| 255 | + description: this.description, |
| 256 | + city: this.city, |
| 257 | + address: this.address, |
| 258 | + dates: [{ startTime: this.startTime, endTime: this.endTime }], |
| 259 | + // type: 'one-off', |
| 260 | + status: 'published', |
| 261 | + public: this.public, |
| 262 | + useDojoAddress: false, |
| 263 | + ticketApproval: false, |
| 264 | + notifyOnApplicant: false, |
| 265 | + // country: this.dojo.country, |
| 266 | + // sessions: this.sessions, |
| 267 | + dojoId: this.dojo.id, |
| 268 | + }); |
| 269 | +
|
| 270 | + console.log(foo); |
| 271 | + this.$router.push({ name: 'DojoDetailsId', params: { id: this.dojo.id } }); |
| 272 | + } catch (err) { |
| 273 | + this.submitError = true; |
| 274 | + } |
214 | 275 | }
|
| 276 | +
|
| 277 | + // TODO: forward to event page |
215 | 278 | },
|
216 | 279 |
|
217 | 280 | toggle(field) { // eslint-disable-line no-unused-vars
|
|
221 | 284 | },
|
222 | 285 | computed: {
|
223 | 286 | truncatedDescription() {
|
224 |
| - return this.description.substring(0, 20); |
| 287 | + if (this.description) { |
| 288 | + const str = this.description.replace(/<[^<|>]+?>/gi, ' '); |
| 289 | + const words = str.split(' ').filter(word => word !== ''); |
| 290 | + return `${words.slice(0, 6).join(' ')}... `; |
| 291 | + } |
| 292 | + return ''; |
225 | 293 | },
|
226 | 294 | formattedAddress() {
|
227 |
| - return `${this.address.substring(0, 15)}... ${this.city.name}`; |
| 295 | + const str = this.address.replace(/<[^<|>]+?>/gi, ' '); |
| 296 | + const words = str.split(' ').filter(word => word !== ''); |
| 297 | + return `${words.slice(0, 5).join(' ')}... ${this.city.nameWithHierarchy}`; |
228 | 298 | },
|
229 | 299 | tickets() {
|
230 | 300 | return [this.$refs.youthTickets, this.$refs.mentorTickets];
|
231 | 301 | },
|
232 | 302 | startTime() {
|
233 |
| - const startDay = moment.utc(this.eventDate); |
| 303 | + const startDay = moment.utc(this.eventDate, 'YYYY-MM-DD'); |
234 | 304 | const startingTimeElements = this.startingTime.split(':');
|
235 | 305 | startDay.hours(startingTimeElements[0]);
|
236 | 306 | startDay.minutes(startingTimeElements[1]);
|
|
246 | 316 | sessions() {
|
247 | 317 | const tickets = this.tickets.map(t => t.createTicket());
|
248 | 318 | return [{
|
249 |
| - name: 'General', |
250 |
| - description: 'General Session', |
| 319 | + // TODO: this needs to be translated? |
| 320 | + name: 'Dojo', |
| 321 | + description: 'Dojo Session', |
251 | 322 | tickets,
|
252 | 323 | }];
|
253 | 324 | },
|
|
256 | 327 | // TODO: if eventId in params load event, otherwise populate defaults
|
257 | 328 |
|
258 | 329 | // TODO: get previous event, use that info to populate defaults
|
259 |
| -
|
260 |
| - // const query = { status: 'published' }; |
261 |
| - // query.afterDate = moment().unix(); |
262 |
| - // query.utcOffset = moment().utcOffset(); |
263 |
| - // query.pageSize = 1; |
264 | 330 | const { dojoId } = this.$route.params;
|
265 | 331 |
|
266 |
| - // const query = { pageSize: 1 }; |
267 | 332 | const latestEvent = await EventsService.v3.get(
|
268 | 333 | dojoId,
|
269 | 334 | {
|
|
273 | 338 | page: 1,
|
274 | 339 | orderBy: 'startTime',
|
275 | 340 | direction: 'desc',
|
| 341 | + related: 'sessions.tickets', |
276 | 342 | },
|
277 | 343 | });
|
278 | 344 |
|
279 |
| - // TODO: will this error when no events |
280 | 345 | this.latestEvent = latestEvent.body.results[0];
|
281 | 346 | this.dojo = (await DojosService.getDojoById(dojoId)).body;
|
282 | 347 | this.populateForm();
|
|
0 commit comments