diff --git a/src/components/EventForm.vue b/src/components/EventForm.vue
index aa8be1507ba48f67a0a5a007c6656874aeb673cb..c6e10a0224b7c0432f4f959c9d69b897a0a9037f 100644
--- a/src/components/EventForm.vue
+++ b/src/components/EventForm.vue
@@ -1,6 +1,6 @@
 <template lang="pug">
 q-card.full-width
-  //- Create Event Header
+  //- 'Create Event' Header
   q-card-section.bg-blue-grey-1(style='padding: 8px')
     span.text-subtitle1.text-weight-light.text-blue-grey-10.q-ml-sm Create your event
     q-chip.float-right(
@@ -11,12 +11,12 @@ q-card.full-width
       icon='done',
       style='margin-top: -1px'
     ) Submit Event
-  //- Create Event Form
+  //- 'Create Event' Form
   q-card-section
     //- Event name field
     .row.q-pb-md
       q-input.full-width(
-        v-model='name',
+        v-model='eventData.name',
         rounded,
         outlined,
         :dense='true',
@@ -28,9 +28,17 @@ q-card.full-width
     //- Date and Time field
     span.text-subtitle1.text-blue-grey-10.q-pt-sm Date and Time:
     .row.q-pb-md.no-wrap
-      q-input(v-model='date', rounded, outlined, type='date', :dense='true', hint='Date of Event', style='width: 60%')
+      q-input(
+        v-model='eventData.date',
+        rounded,
+        outlined,
+        type='date',
+        :dense='true',
+        hint='Date of Event',
+        style='width: 60%'
+      )
       q-input.q-ml-sm(
-        v-model='time',
+        v-model='eventData.time',
         rounded,
         outlined,
         type='time',
@@ -41,63 +49,207 @@ q-card.full-width
     //- Location of Event field
     .row.q-pb-md
       span.text-subtitle1.text-blue-grey-10 Where?:
-      q-input.full-width(rounded, outlined, v-model='places', label='Search places', :dense='true')
+      q-select.full-width(
+        v-model='location',
+        @input-value='setUserInput',
+        :options='placesOptions',
+        :dense='true',
+        label='Search places',
+        rounded,
+        outlined,
+        use-input,
+        input-debounce='0',
+        emit-value,
+        map-options
+      )
         template(v-slot:prepend)
           q-icon(name='place')
-        template(v-slot:append)
-          q-icon.cursor-pointer(name='search', @click='searchPlaces()')
+        template(v-slot:no-option)
+          q-item
+            q-item-section.text-grey No results
     //- Invite friends field
     .row.q-pb-md
       span.text-subtitle1.text-blue-grey-10 Invite your friends:
-      q-input.full-width(rounded, outlined, v-model='friends', label='Search friends', :dense='true')
+      q-select.full-width(
+        v-model='eventData.friends',
+        :dense='true',
+        :options='friendsOptions',
+        label='Select friends',
+        rounded,
+        outlined,
+        multiple,
+        use-chips,
+        emit-value,
+        map-options
+      )
         template(v-slot:prepend)
           q-icon(name='person_add')
-        template(v-slot:append)
-          q-icon.cursor-pointer(name='search', @click='searchFriends()')
-    //- Event icon field
+    //- Event choose icon field
     .text-subtitle1.text-blue-grey-10 Choose an icon for your Event:
     .row.q-pb-md.justify-around
-      img(src='https://img.icons8.com/dusk/50/000000/home.png')
-      img(src='https://img.icons8.com/dusk/50/000000/party-baloons.png')
-      img(src='https://img.icons8.com/dusk/50/000000/dancing-party.png')
-      img(src='https://img.icons8.com/dusk/50/000000/champagne.png')
-      img(src='https://img.icons8.com/dusk/50/000000/dj.png')
-      img(src='https://img.icons8.com/dusk/50/000000/gift.png')
-    //- Event details field
+      img.cursor-pointer.q-pa-xs(
+        v-for='eventType in ["Home", "Baloons", "Dancing", "Champagne", "Dj", "Gift"]',
+        @click='eventData.type = eventType',
+        :src='getEventIcon(eventType)',
+        :style='eventData.type == eventType ? "box-shadow: 0 0 1pt 2pt #03c6fc; border-radius: 30%" : ""'
+      )
+    //- Event insert details field
     .row
       span.text-subtitle1.text-blue-grey-10 Details:
       q-input.full-width(
         rounded,
         outlined,
         autogrow,
-        v-model='details',
+        v-model='eventData.details',
         placeholder='Dress code, specifications, directions etc.',
         :dense='true'
       )
 </template>
 
 <script>
+import { mapState, mapActions } from 'vuex'
+import axios from 'axios'
+
 export default {
   data() {
     return {
-      name: null,
-      date: null,
-      time: null,
-      places: null,
-      friends: null,
-      details: null
+      eventData: {
+        name: '',
+        date: null,
+        time: null,
+        friends: [],
+        type: '',
+        details: ''
+      },
+      location: '',
+      userInput: 'a',
+      service: null,
+      searchResults: []
     }
   },
+
   methods: {
-    searchPlaces() {
-      console.log('searching places')
+    async submitEvent() {
+      // Turn place name into coordinates to save in db
+      await this.geocodeLocation()
+      // Need to turn array into object before saving to db
+      this.eventData['friends'] = this.friendsObject
+      // Save eventData object under events node in db
+      this.firebaseSubmitEvent(this.eventData)
+    },
+
+    placesGetPredictions() {
+      this.service.getPlacePredictions(
+        {
+          input: this.userInput,
+          location: new google.maps.LatLng(this.center),
+          radius: 5000
+        },
+        this.savePredictions
+      )
     },
-    searchFriends() {
-      console.log('searching friends')
+
+    savePredictions(predictions, status) {
+      if (status !== window.google.maps.places.PlacesServiceStatus.OK) {
+        this.searchResults = []
+        return
+      }
+      this.searchResults = predictions
+    },
+
+    async geocodeLocation() {
+      const URL = `https://secret-ocean-49799.herokuapp.com/https://maps.googleapis.com/maps/api/place/details/json?place_id=${this.location}&fields=geometry&key=AIzaSyBPUdoB3wV6A9L-H1-J5POiQRmgqqcL9Bk`
+
+      await axios
+        .get(URL)
+        .then(response => {
+          let placeLocation = response.data.result.geometry.location
+
+          this.eventData['lat'] = placeLocation.lat
+          this.eventData['lng'] = placeLocation.lng
+        })
+        .catch(error => {
+          console.log(error)
+        })
     },
-    submitEvent() {
-      console.log('submit event')
+
+    getEventIcon(eventType) {
+      switch (eventType) {
+        case 'Home':
+          return 'https://img.icons8.com/dusk/50/000000/home.png'
+        case 'Baloons':
+          return 'https://img.icons8.com/dusk/50/000000/party-baloons.png'
+        case 'Dancing':
+          return 'https://img.icons8.com/dusk/50/000000/dancing-party.png'
+        case 'Champagne':
+          return 'https://img.icons8.com/dusk/50/000000/champagne.png'
+        case 'Dj':
+          return 'https://img.icons8.com/dusk/50/000000/dj.png'
+        case 'Gift':
+          return 'https://img.icons8.com/dusk/50/000000/gift.png'
+      }
+    },
+
+    setUserInput(val) {
+      this.userInput = val
+    },
+
+    ...mapActions('firebase', ['firebaseSubmitEvent'])
+  },
+
+  computed: {
+    friendsOptions() {
+      var optionsArray = []
+
+      for (const key in this.friends) {
+        let optionObject = {
+          label: this.friends[key].name,
+          value: key
+        }
+        optionsArray.push(optionObject)
+      }
+      return optionsArray
+    },
+
+    placesOptions() {
+      var optionsArray = []
+
+      for (const key in this.searchResults) {
+        let result = this.searchResults[key]
+
+        let optionObject = {
+          label: result.description,
+          value: result.place_id
+        }
+        optionsArray.push(optionObject)
+      }
+      return optionsArray
+    },
+
+    friendsObject() {
+      let friendsObj = {}
+
+      this.eventData.friends.forEach(friendKey => {
+        friendsObj[friendKey] = true
+      })
+
+      return friendsObj
+    },
+
+    ...mapState('firebase', ['friends', 'center'])
+  },
+
+  watch: {
+    userInput(newValue) {
+      if (newValue) {
+        this.placesGetPredictions()
+      }
     }
+  },
+
+  mounted() {
+    this.service = new window.google.maps.places.AutocompleteService()
+    this.placesGetPredictions() // Default predict with letter 'a' as input
   }
 }
 </script>
\ No newline at end of file
diff --git a/src/components/GoogleMap.vue b/src/components/GoogleMap.vue
index ea39366fd8bad77c449e413020957b99cd36b899..723e7659b67f5684d22fc53d3759a1709ab5dbd6 100644
--- a/src/components/GoogleMap.vue
+++ b/src/components/GoogleMap.vue
@@ -31,7 +31,8 @@ export default {
       map: null,
       heatmap: null,
       places: [],
-      crimes: []
+      crimes: [],
+      dataFetched: false
     }
   },
 
@@ -200,8 +201,7 @@ export default {
         map: map
       })
 
-      // Save heatmap and map instance for use in toggleHeatmap()
-      this.heatmap = heatmap
+      // Save map instance for global access in other methods
       this.map = map
 
       // Wait for google Places API to be finished fetching relevant data
@@ -209,12 +209,6 @@ export default {
       // Mark all relevant places on the map
       this.mapsInitPlaces()
 
-      // Add all signals saved in the store on the map
-      for (const i in this.signals) {
-        let signal = this.signals[i]
-        this.mapsAddSignal(signal)
-      }
-
       // Wait for police.uk API to return crime data
       await this.getCrimeData()
       // Create a heatmap based on crimes location
@@ -230,6 +224,23 @@ export default {
       })
       heatmap.set('radius', heatmap.get('radius') ? null : 80)
       heatmap.set('opacity', heatmap.get('opacity') ? null : 0.3)
+
+      // Save heatmap reference for user in toggleHeatmap()
+      this.heatmap = heatmap
+
+      // Add all signals saved in the store on the map
+      for (const i in this.signals) {
+        let signal = this.signals[i]
+        this.mapsAddSignal(signal)
+      }
+
+      // Add all event saved in the store on the map
+      for (const i in this.events) {
+        let event = this.events[i]
+        this.mapsAddEvent(event)
+      }
+
+      this.dataFetched = true
     },
 
     /* Creates markers and infoWindows for every relevant nightlife establishment in the area */
@@ -291,12 +302,50 @@ export default {
           return 'https://img.icons8.com/color/50/000000/car-rental.png'
       }
     },
+
+    /* Code snippet to add a marker and info window on the map for an event */
+    mapsAddEvent(event) {
+      var infoWindow = new google.maps.InfoWindow()
+
+      let marker = new google.maps.Marker({
+        position: new google.maps.LatLng(event.lat, event.lng),
+        map: this.map,
+        icon: this.getEventIcon(event.type)
+      })
+
+      google.maps.event.addListener(marker, 'click', () => {
+        infoWindow.setContent(
+          `<p class="text-subtitle1" style="margin-bottom:8px;">${event.name} (${event.date} ${event.time}) </p>
+            <p class="text-weight-light">${event.details}</p>`
+        )
+        infoWindow.open(this.map, marker)
+      })
+    },
+
+    /* Returns the image source for every type of event */
+    getEventIcon(eventType) {
+      switch (eventType) {
+        case 'Home':
+          return 'https://img.icons8.com/dusk/50/000000/home.png'
+        case 'Baloons':
+          return 'https://img.icons8.com/dusk/50/000000/party-baloons.png'
+        case 'Dancing':
+          return 'https://img.icons8.com/dusk/50/000000/dancing-party.png'
+        case 'Champagne':
+          return 'https://img.icons8.com/dusk/50/000000/champagne.png'
+        case 'Dj':
+          return 'https://img.icons8.com/dusk/50/000000/dj.png'
+        case 'Gift':
+          return 'https://img.icons8.com/dusk/50/000000/gift.png'
+      }
+    },
+
     ...mapActions('firebase', ['firebaseSavePosition'])
   },
 
   computed: {
     ...mapState(['mapStyles']),
-    ...mapState('firebase', ['center', 'signals', 'latestSignalKey'])
+    ...mapState('firebase', ['center', 'signals', 'latestSignalKey', 'events', 'latestEventKey'])
   },
 
   watch: {
@@ -305,8 +354,22 @@ export default {
       deep: true,
       // Whenever a new signal gets added, add it to the map
       handler() {
-        let signal = this.signals[this.latestSignalKey]
-        this.mapsAddSignal(signal)
+        // If db signals have been fetched start tracking new events
+        if (this.dataFetched === true) {
+          let signal = this.signals[this.latestSignalKey]
+          this.mapsAddSignal(signal)
+        }
+      }
+    },
+    events: {
+      deep: true,
+      // Whenever a new event gets added, add it to the map
+      handler() {
+        // If db events have been fetched start tracking new events
+        if (this.dataFetched === true) {
+          let event = this.events[this.latestEventKey]
+          this.mapsAddEvent(event)
+        }
       }
     }
   },
diff --git a/src/store/firebase.js b/src/store/firebase.js
index d8d82adbdfd6c70982df919c29ca051334f0b9cc..4b4ad20ff418b403edada6c7bb556477d58068b0 100644
--- a/src/store/firebase.js
+++ b/src/store/firebase.js
@@ -9,7 +9,9 @@ const state = {
   friends: {},
   pending: {},
   signals: {},
-  latestSignalKey: null
+  latestSignalKey: null,
+  events: {},
+  latestEventKey: null
 }
 
 const mutations = {
@@ -59,6 +61,13 @@ const mutations = {
     let signalId = Object.keys(payload)[0]
     state.signals[signalId] = payload[signalId]    
     state.latestSignalKey = signalId
+  },
+
+  // Adds an event in 'events' object
+  addEvent(state, payload) {
+    let eventId = Object.keys(payload)[0]
+    state.events[eventId] = payload[eventId]    
+    state.latestEventKey = eventId
   }
 }
 
@@ -124,6 +133,8 @@ const actions = {
         dispatch('firebaseGetFriends', userId)
         // Get all signals in db and save them in the store
         dispatch('firebaseGetSignals')
+        // Get all signals in db and save them in the store
+        dispatch('firebaseGetEvents')
         
         // Handle online status
         firebaseDb.ref('.info/connected').on('value', (snap) => {
@@ -241,7 +252,7 @@ const actions = {
       })
   },
 
-  /* Add signal under signals node in firebase's sb */
+  /* Add signal under signals node in firebase's db */
   firebaseSendSignal({ state, commit }, payload) {
     let signal = payload
     signal['lat'] = state.center.lat
@@ -256,6 +267,30 @@ const actions = {
     commit('addSignal', newSignal)
   },
 
+  /***********************
+          EVENTS
+  ************************/
+  /* Fetch from db all events and save them to the store while adding
+   a listener to automatically add new recorded events */
+  firebaseGetEvents({ commit }) {
+    firebaseDb.ref('events/').on('child_added', snapshot => {
+      let event = {}
+      event[snapshot.key] = snapshot.val()
+      commit('addEvent', event)
+      })
+  },
+
+  /* Add an event under events node in firebase's db */
+  firebaseSubmitEvent({ commit }, payload) {
+    let event = payload
+    // Add event to db
+    let eventRef = firebaseDb.ref('events/').push(event)
+
+    let newEvent = {}
+    newEvent[eventRef.key] =  event // {eventKey: eventContent}
+    // Add event to the store's 'event' object
+    commit('addEvent', newEvent)
+  },
   /***********************
           POSITION
   ************************/