From 287313f1fd7b903d5efee48c5bab2dfca5d12d5b Mon Sep 17 00:00:00 2001
From: Sandro Lutz <code@temparus.ch>
Date: Sun, 18 Feb 2018 09:41:49 +0100
Subject: [PATCH] Refactoring events model

---
 src/models/events.js      |  94 +++++++++++++++-------------
 src/views/eventDetails.js | 127 +++++++++++++++++++-------------------
 2 files changed, 115 insertions(+), 106 deletions(-)

diff --git a/src/models/events.js b/src/models/events.js
index 5c4fadbe..54f1810f 100644
--- a/src/models/events.js
+++ b/src/models/events.js
@@ -1,7 +1,6 @@
 import m from 'mithril';
 import { apiUrl } from './config';
 import { getToken, getUserId, isLoggedIn } from './auth';
-import { log } from './log';
 
 const lang = 'de';
 const date = `${new Date().toISOString().split('.')[0]}Z`;
@@ -15,23 +14,23 @@ export function getList() {
   return this.list;
 }
 
-export function getCurrent() {
-  return this.current;
+export function getSelectedEvent() {
+  return this.selectedEvent;
 }
 
-export function getCurrentSignup() {
-  return this.currentSignup;
+export function getSignupForSelectedEvent() {
+  return this.selectedEventSignup;
 }
 
-export function currentSignupHasLoaded() {
-  return this.currentSignupLoaded;
+export function signupForSelectedEventHasLoaded() {
+  return this.selectedEventSignupLoaded;
 }
 
-export function checkCurrentSignup() {
+export function loadSignupForSelectedEvent() {
   const queryString = m.buildQueryString({
     where: JSON.stringify({
       user: getUserId(),
-      event: this.getCurrent()._id,
+      event: this.getSelectedEvent()._id,
     }),
   });
 
@@ -42,14 +41,44 @@ export function checkCurrentSignup() {
       Authorization: `Token ${getToken()}`,
     } : {},
   }).then((result) => {
-    [this.currentSignup] = result._items;
-    this.currentSignupLoaded = true;
+    [this.selectedEventSignup] = result._items;
+    this.selectedEventSignupLoaded = true;
   });
 }
 
-export function signupCurrent(additionalFields, email = '') {
+export function _signupUserForSelectedEvent(additionalFieldsString) {
+  return m.request({
+    method: 'POST',
+    url: `${apiUrl}/eventsignups`,
+    data: {
+      event: this.selectedEvent._id,
+      additional_fields: additionalFieldsString,
+      user: getUserId(),
+    },
+    headers: getToken() ? {
+      Authorization: `Token ${getToken()}`,
+    } : {},
+  }).then(() => { this.loadSignupForSelectedEvent(); });
+}
+
+export function _signupEmailForSelectedEvent(additionalFieldsString, email) {
+  return m.request({
+    method: 'POST',
+    url: `${apiUrl}/eventsignups`,
+    data: {
+      event: this.selectedEvent._id,
+      additional_fields: additionalFieldsString,
+      email,
+    },
+    headers: getToken() ? {
+      Authorization: `Token ${getToken()}`,
+    } : {},
+  }).then(() => { this.loadSignupForSelectedEvent(); });
+}
+
+export function signupForSelectedEvent(additionalFields, email = '') {
   let additionalFieldsString;
-  if (this.current.additional_fields === undefined ||
+  if (this.selectedEvent.additional_fields === undefined ||
     additionalFields === null || typeof additionalFields !== 'object') {
     additionalFieldsString = undefined;
   } else {
@@ -57,34 +86,11 @@ export function signupCurrent(additionalFields, email = '') {
   }
 
   if (isLoggedIn()) {
-    log(`UserId: ${getUserId()}`);
-    m.request({
-      method: 'POST',
-      url: `${apiUrl}/eventsignups`,
-      data: {
-        event: this.current._id,
-        additional_fields: additionalFieldsString,
-        user: getUserId(),
-      },
-      headers: getToken() ? {
-        Authorization: `Token ${getToken()}`,
-      } : {},
-    }).then(() => { this.checkCurrentSignup(); });
-  } else if (this.current.allow_email_signup) {
-    log(`Email: ${email}`);
-    m.request({
-      method: 'POST',
-      url: `${apiUrl}/eventsignups`,
-      data: {
-        event: this.current._id,
-        additional_fields: additionalFieldsString,
-        email,
-      },
-      headers: getToken() ? {
-        Authorization: `Token ${getToken()}`,
-      } : {},
-    }).then(() => { this.checkCurrentSignup(); });
+    return this._signupUserForSelectedEvent(additionalFieldsString);
+  } else if (this.selectedEvent.allow_email_signup) {
+    return this._signupEmailForSelectedEvent(additionalFieldsString, email);
   }
+  return Promise.reject(new Error('Signup not allowed'));
 }
 
 export function load(query = {}) {
@@ -113,9 +119,9 @@ export function load(query = {}) {
   });
 }
 
-export function loadCurrent(eventId) {
-  this.current = this.getList().find(item => item._id === eventId);
-  if (typeof this.current === 'undefined') {
+export function selectEvent(eventId) {
+  this.selectedEvent = this.getList().find(item => item._id === eventId);
+  if (typeof this.selectedEvent === 'undefined') {
     this.load({
       where: {
         time_advertising_start: { $lte: date },
@@ -124,7 +130,7 @@ export function loadCurrent(eventId) {
       },
       sort: ['-priority', 'time_advertising_start'],
     }).then(() => {
-      this.current = this.getList().find(item => item._id === eventId);
+      this.selectedEvent = this.getList().find(item => item._id === eventId);
     });
   }
 }
diff --git a/src/views/eventDetails.js b/src/views/eventDetails.js
index c24297f3..7c209999 100644
--- a/src/views/eventDetails.js
+++ b/src/views/eventDetails.js
@@ -13,96 +13,99 @@ class EventSignupForm extends JSONSchemaForm {
     this.emailErrors = [];
     this.emailValid = false;
     if (isLoggedIn()) {
-      events.checkCurrentSignup();
+      events.loadSignupForSelectedEvent();
     }
   }
 
-  submit() {
-    if (isLoggedIn()) {
-      events.signupCurrent(super.getValue());
-    } else {
-      events.signupCurrent(super.getValue(), this.email);
-    }
+  signup() {
+    events.signupForSelectedEvent(super.getValue(), this.email)
+      .then(() => log('Successfully signed up for the event!'))
+      .catch(() => log('Could not sign up of the event!'));
   }
 
   view() {
     // do not render anything if there is no data yet
-    if (typeof events.getCurrent() === 'undefined') return m();
+    if (typeof events.getSelectedEvent() === 'undefined') return m();
 
     if (isLoggedIn()) {
       // do not render form if there is no signup data of the current user
-      if (!events.currentSignupHasLoaded()) return m('span', 'Loading...');
-      if (typeof events.getCurrentSignup() === 'undefined') {
+      if (!events.signupForSelectedEventHasLoaded()) return m('span', 'Loading...');
+      if (typeof events.getSignupForSelectedEvent() === 'undefined') {
         const elements = this.renderFormElements();
-        elements.push(m(submitButton, {
-          active: super.isValid(),
-          args: {
-            onclick: () => this.submit(),
-          },
-          text: 'Signup',
-        }));
+        elements.push(this._renderSignupButton());
         return m('form', elements);
       }
       return m('div', 'You have already signed up for this event.');
-    } else if (events.getCurrent().allow_email_signup) {
+    } else if (events.getSelectedEvent().allow_email_signup) {
       const elements = this.renderFormElements();
-      elements.push(m(inputGroup, {
-        name: 'email',
-        title: 'Email',
-        args: {
-          type: 'text',
-        },
-        oninput: (e) => {
-          // bind changed data
-          this.email = e.target.value;
-
-          // validate if email address has the right structure
-          if (EmailValidator.validate(this.email)) {
-            this.emailValid = true;
-            this.emailErrors = [];
-          } else {
-            this.emailValid = false;
-            this.emailErrors = ['Not a valid email address'];
-          }
-        },
-        getErrors: () => this.emailErrors,
-        value: this.email,
-      }));
-      elements.push(m(submitButton, {
-        active: this.emailValid && super.isValid(),
-        args: {
-          onclick: () => this.submit(),
-        },
-        text: 'Signup',
-      }));
+      elements.push(this._renderEmailField());
+      elements.push(this._renderSignupButton());
       return m('form', elements);
     }
     return m('div', 'This event is for AMIV members only.');
   }
+
+  isValid() {
+    if (!isLoggedIn()) {
+      return super.isValid() && this.emailValid;
+    }
+    return super.isValid();
+  }
+
+  _renderEmailField() {
+    return m(inputGroup, {
+      name: 'email',
+      title: 'Email',
+      args: {
+        type: 'text',
+      },
+      oninput: (e) => {
+        // bind changed data
+        this.email = e.target.value;
+
+        // validate if email address has the right structure
+        if (EmailValidator.validate(this.email)) {
+          this.emailValid = true;
+          this.emailErrors = [];
+        } else {
+          this.emailValid = false;
+          this.emailErrors = ['Not a valid email address'];
+        }
+      },
+      getErrors: () => this.emailErrors,
+      value: this.email,
+    });
+  }
+
+  _renderSignupButton() {
+    return m(submitButton, {
+      active: super.isValid(),
+      args: {
+        onclick: () => this.signup(),
+      },
+      text: 'Signup',
+    });
+  }
 }
 
 export default class EventDetails {
   static oninit(vnode) {
-    events.loadCurrent(vnode.attrs.eventId);
+    events.selectEvent(vnode.attrs.eventId);
   }
 
   static view() {
-    if (typeof events.getCurrent() === 'undefined') {
+    if (typeof events.getSelectedEvent() === 'undefined') {
       return m();
     }
-    log(events.getCurrent());
     let eventSignupForm;
     const now = new Date();
-    const registerStart = new Date(events.getCurrent().time_register_start);
-    const registerEnd = new Date(events.getCurrent().time_register_end);
-    log(`Now: ${now}`);
-    log(`Start: ${registerStart}`);
-    log(`End: ${registerEnd}`);
+    const registerStart = new Date(events.getSelectedEvent().time_register_start);
+    const registerEnd = new Date(events.getSelectedEvent().time_register_end);
     if (registerStart <= now) {
       if (registerEnd >= now) {
         eventSignupForm = m(EventSignupForm, {
-          schema: events.getCurrent().additional_fields === undefined ?
-            undefined : JSON.parse(events.getCurrent().additional_fields),
+          schema: events.getSelectedEvent().additional_fields === undefined ?
+            undefined : JSON.parse(events.getSelectedEvent().additional_fields),
         });
       } else {
         eventSignupForm = m('div', 'The registration period is over.');
@@ -111,11 +114,11 @@ export default class EventDetails {
       eventSignupForm = m('div', `The registration starts at ${registerStart}`);
     }
     return m('div', [
-      m('h1', events.getCurrent().title_de),
-      m('span', events.getCurrent().time_start),
-      m('span', events.getCurrent().signup_count),
-      m('span', events.getCurrent().spots),
-      m('p', events.getCurrent().description_de),
+      m('h1', events.getSelectedEvent().title_de),
+      m('span', events.getSelectedEvent().time_start),
+      m('span', events.getSelectedEvent().signup_count),
+      m('span', events.getSelectedEvent().spots),
+      m('p', events.getSelectedEvent().description_de),
       eventSignupForm,
     ]);
   }
-- 
GitLab