Skip to content
Snippets Groups Projects
editEvent.js 11.5 KiB
Newer Older
Hermann's avatar
Hermann committed
import m from 'mithril';
import { RaisedButton, RadioGroup, Switch } from 'polythene-mithril';
import { fileInput } from 'amiv-web-ui-components';
aneff's avatar
aneff committed
import { styler } from 'polythene-core-css';
// eslint-disable-next-line import/extensions
import { apiUrl } from 'networkConfig';
Hermann's avatar
Hermann committed
import EditView from '../views/editView';
// import { colors } from '../style';
aneff's avatar
aneff committed

const style = [
  {
    '.mywrapper': {
      padding: '10px',
    },
  },
];
styler.add('event-add', style);

Hermann's avatar
Hermann committed
export default class newEvent extends EditView {
  constructor(vnode) {
Hermann's avatar
Hermann committed
    super(vnode);
aneff's avatar
aneff committed
    this.currentpage = 1;
    if (!this.form.data.priority) this.form.data.priority = 1;

    // read additional_fields to make it editable
    if (this.form.data.additional_fields) {
      const copy = JSON.parse(this.form.data.additional_fields);
      this.form.data.add_fields_sbb = 'SBB_Abo' in copy.properties;
      this.form.data.add_fields_food = 'Food' in copy.properties;
      this.form.data.additional_fields = {};
    // price can either not be set or set to null
    // if it is 0 however, that would mean that there actually is a price that
    // you can edit
    this.hasprice = 'price' in this.form.data && this.form.data.price !== null;
    this.hasregistration = 'spots' in this.form.data || 'time_registration_start' in this.form.data;
Hermann's avatar
Hermann committed
  beforeSubmit() {
    // Collect images seperate from everything else
    const images = {};
Hermann's avatar
Hermann committed
    ['thumbnail', 'banner', 'infoscreen', 'poster'].forEach((key) => {
      if (this.form.data[`new_${key}`]) {
        images[`img_${key}`] = this.form.data[`new_${key}`];
        delete this.form.data[`new_${key}`];
      if (this.form.data[`img_${key}`]) {
        delete this.form.data[`img_${key}`];
Hermann's avatar
Hermann committed
      }
    });

    // Merge Options for additional fields
    const additionalFields = {
      $schema: 'http://json-schema.org/draft-04/schema#',
Hermann's avatar
Hermann committed
      additionalProperties: false,
      title: 'Additional Fields',
      type: 'object',
      properties: {},
      required: [],
    };
    if (this.form.data.add_fields_sbb) {
Hermann's avatar
Hermann committed
      additionalFields.properties.SBB_Abo = {
        type: 'string',
        enum: ['None', 'GA', 'Halbtax', 'Gleis 7'],
      };
      additionalFields.required.push('SBB_Abo');
    }

    if (this.form.data.add_fields_food) {
Hermann's avatar
Hermann committed
      additionalFields.properties.Food = {
        type: 'string',
        enum: ['Omnivor', 'Vegi', 'Vegan', 'Other'],
      };
      additionalFields.properties['Special Food Requirements'] = {
        type: 'string',
Hermann's avatar
Hermann committed
      };
      additionalFields.required.push('Food');
    }
    if ('add_fields_sbb' in this.form.data) delete this.form.data.add_fields_sbb;
    if ('add_fields_food' in this.form.data) delete this.form.data.add_fields_food;

    // if the properties are empty, we null the whole field, otherwise we send a json string
    // of the additional fields object
    if (Object.keys(additionalFields.properties).length > 0) {
      this.form.data.additional_fields = JSON.stringify(additionalFields);
      this.form.data.additional_fields = null;
Hermann's avatar
Hermann committed
    }
Hermann's avatar
Hermann committed
    // if spots is not set, also remove 'allow_email_signup'
    if (!('spots' in this.form.data) && 'allow_email_signup' in this.form.data
        && !this.form.data.allow_email_signup) {
      delete this.form.data.allow_email_signup;
    console.log(this.form.data);
    if (Object.keys(images).length > 0) {
      images._id = this.form.data._id;
      images._etag = this.form.data._etag;
      // first upload the images as formData, then the rest as JSON
      this.controller.handler.patch(images, true).then(({ _etag }) => {
        this.form.data._etag = _etag;
        this.submit();
      });
    } else {
      this.submit();
    }
Hermann's avatar
Hermann committed
  }

  view() {
    const buttonRight = m(RaisedButton, {
      label: 'next',
      disabled: this.currentpage === 5,
          this.currentpage = Math.min(this.currentpage + 1, 5);
    const buttonLeft = m(RaisedButton, {
      label: 'previous',
      disabled: this.currentpage === 1,
      events: {
        onclick: () => {
          this.currentpage = Math.max(1, this.currentpage - 1);
aneff's avatar
aneff committed

    const radioButtonSelectionMode = m(RadioGroup, {
      name: 'Selection Mode',
      buttons: [
        {
          value: 'fcfs',
          label: 'First come, first serve',
        },
        {
          value: 'manual',
          label: 'Selection made by organizer',
        },
      ],
      onChange: (state) => {
        this.selection_strategy = state.value;
        this.form.data.selection_strategy = state.value;
        console.log(this.form.data); // Temp proof of concept.
    const keysPages = [[
      'title_en',
      'catchphrase_en',
      'description_en',
      'title_de',
      'catchphrase_de',
      'description_de',
    ],
    ['time_start', 'time_end', 'location'],
    ['price', 'spots', 'time_register_start', 'time_register_end'],
    ['time_advertising_start', 'time_advertising_end'],
    [],
    ];
    const errorPages = keysPages.map(keysOfOnePage => keysOfOnePage.map((key) => {
      if (this.form.errors && key in this.form.errors) return this.form.errors[key].length > 0;
      return false;
    }).includes(true));
    const titles = [
Hermann's avatar
Hermann committed
      'Event Description', 'When and Where?', 'Signups', 'Advertisement', 'Images',
aneff's avatar
aneff committed
    // checks currentPage and selects the fitting page
Hermann's avatar
Hermann committed
    return this.layout([
      // navigation bar
      // all pages are displayed, current is highlighted,
      // validation errors are shown per page by red icon-background
      m('div', {
        style: { display: 'flex', 'justify-content': 'space-around', 'flex-wrap': 'wrap' },
      }, [...titles.entries()].map(numAndTitle => m('div', m('div', {
        style: {
          border: (this.currentpage === numAndTitle[0] + 1) ?
            '2px solid black' :
            '2px solid #888888',
          color: (this.currentpage === numAndTitle[0] + 1) ? 'black' : '#888888',
          'background-color': errorPages[numAndTitle[0]] ? '#ff7a56' : 'white',
          'border-radius': '20px',
          height: '40px',
          'margin-bottom': '7px',
          padding: '12px',
          'font-size': '20px',
          'line-height': '11px',
        },
        onclick: () => { this.currentpage = numAndTitle[0] + 1; },
      }, numAndTitle[1])))),
      // page 1: title & description
Hermann's avatar
Hermann committed
      m('div', {
        style: { display: (this.currentpage === 1) ? 'block' : 'none' },
        title_en: { type: 'text', label: 'English Event Title' },
        catchphrase_en: { type: 'text', label: 'English Catchphrase' },
        description_en: {
          type: 'text',
          label: 'English Description',
          multiLine: true,
          rows: 5,
        },
        title_de: { type: 'text', label: 'German Event Title' },
        catchphrase_de: { type: 'text', label: 'German Catchphrase' },
        description_de: {
          type: 'text',
          label: 'German Description',
          multiLine: true,
          rows: 5,
        },
Hermann's avatar
Hermann committed
      })),
      // page 2: when & where
Hermann's avatar
Hermann committed
      m('div', {
        style: { display: (this.currentpage === 2) ? 'block' : 'none' },
        time_start: { type: 'datetime', label: 'Event Start Time' },
        time_end: { type: 'datetime', label: 'Event End Time' },
        location: { type: 'text', label: 'Location' },
      })),
      // page 3: registration
Hermann's avatar
Hermann committed
      m('div', {
        style: { display: (this.currentpage === 3) ? 'block' : 'none' },
        m(Switch, {
          label: 'people have to pay something to attend this event',
          style: { 'margin-bottom': '5px' },
          checked: this.hasprice,
          onChange: ({ checked }) => {
            this.hasprice = checked;
            if (!checked) {
              // if it originally had a price, set to null, otherwise delete
              if (this.controller.data.price) this.form.data.price = null;
              else delete this.form.data.price;
        ...this.hasprice && this.form.renderPage({
          price: { type: 'number', label: 'Price', min: 0, step: 0.01 },
        }),
        m('br'),
        m(Switch, {
          label: 'people have to register to attend this event',
          checked: this.hasregistration,
          onChange: ({ checked }) => {
            this.hasregistration = checked;
            if (!checked) {
              delete this.form.data.spots;
              delete this.form.data.time_register_start;
              delete this.form.data.time_register_end;
              delete this.form.data.add_fields_sbb;
              delete this.form.data.add_fields_food;
              delete this.form.data.allow_email_signup;
              delete this.form.data.selection_strategy;
        ...this.hasregistration && this.form.renderPage({
          spots: {
            label: 'Number of Spots',
            help: '0 for open event',
            focusHelp: true,
          time_register_start: { type: 'datetime', label: 'Start of Registration' },
          time_register_end: { type: 'datetime', label: 'End of Registration' },
          add_fields_food: { type: 'checkbox', label: 'Food limitations' },
Hermann's avatar
Hermann committed
          add_fields_sbb: { type: 'checkbox', label: 'SBB Abbonement' },
        m('br'),
        ...this.hasregistration && this.form.renderPage({
          allow_email_signup: { type: 'checkbox', label: 'Allow Email Signup' },
        this.hasregistration && radioButtonSelectionMode,
      // page 4: advertisement
Hermann's avatar
Hermann committed
      m('div', {
        style: { display: (this.currentpage === 4) ? 'block' : 'none' },
          time_advertising_start: {
            type: 'datetime',
            label: 'Start of Advertisement',
            required: true,
          },
          time_advertising_end: {
            type: 'datetime',
            label: 'End of Advertisement',
            required: true,
          },
        /*
        m.trust('Priority<br>'),
        m(Slider, {
          min: 1,
          max: 10,
          stepSize: 1,
          // value: this.data.priority || 1,
          // onChange: ({ value }) => { this.data.priority = value; },
          show_website: { type: 'checkbox', label: 'Advertise on Website' },
          show_announce: { type: 'checkbox', label: 'Advertise in Announce' },
          show_infoscreen: {
            type: 'checkbox',
            label: 'Advertise on Infoscreen',
          },
      m('div', {
        style: { display: (this.currentpage === 5) ? 'block' : 'none' },
      }, [
Hermann's avatar
Hermann committed
        ['thumbnail', 'banner', 'poster', 'infoscreen'].map(key => [
          this.form.data[`img_${key}`] ? m('img', {
            src: `${apiUrl}${this.form.data[`img_${key}`].file}`,
Hermann's avatar
Hermann committed
            style: { 'max-height': '50px', 'max-width': '100px' },
          }) : m('div', `currently no ${key} image set`),
          m(fileInput, this.form.bind({
Hermann's avatar
Hermann committed
            name: `new_${key}`,
            label: `New ${key} Image`,
            accept: 'image/png, image/jpeg',
          })),
        ]),
      // bottom back & forth
      m('div', {
        style: { display: 'flex', 'justify-content': 'space-between', padding: '35px', 'padding-top': '20px'}
      },
      [buttonLeft, buttonRight],
      ),
Hermann's avatar
Hermann committed
    ]);