diff --git a/src/api.js b/src/api.js
index de66b976355aff6b346246a3bf8819868ff2ce77..5f22e58803540389dcdd1322c4b551b1e146210d 100644
--- a/src/api.js
+++ b/src/api.js
@@ -116,6 +116,16 @@ export const api = {
       return null
     }
   },
+  async getUserLikedModels () {
+    const token = await localStorage.getItem('token')
+    const url = serverurl + 'vote/likedModels'
+    try {
+      const response = await fetch(url, { headers: { Authorization: 'Bearer ' + token } })
+      return await response.json()
+    } catch (error) {
+      return null
+    }
+  },
   async getModel (id) {
     const url = serverurl + 'models' + '?id=' + id
     const response = await fetch(url)
@@ -304,7 +314,7 @@ export const api = {
     }
   },
   async postModel (model) {
-    const url = this.$serverurl + 'models'
+    const url = serverurl + 'models'
     const token = await localStorage.getItem('token')
     try {
       const response = await fetch(url, {
@@ -321,7 +331,8 @@ export const api = {
           performance: model.performance,
           performanceUnit: model.performanceUnit,
           parameterCount: model.parameterCount,
-          tags: model.tags
+          tags: model.tags,
+          performanceLowerIsBetter: model.performanceLowerIsBetter
         })
       })
       return await response.json()
@@ -346,7 +357,8 @@ export const api = {
         performance: model.performance,
         performanceUnit: model.performanceUnit,
         parameterCount: model.parameterCount,
-        tags: model.tags
+        tags: model.tags,
+        performanceLowerIsBetter: model.performanceLowerIsBetter
       })
     })
     try {
@@ -390,5 +402,49 @@ export const api = {
     } catch (error) {
       return null
     }
+  },
+  async getVoteStatus (id) {
+    const url = serverurl + 'vote' + '?id=' + id
+    const token = await localStorage.getItem('token')
+    const response = await fetch(url, {
+      headers: {
+        Authorization: 'Bearer ' + token
+      }
+    })
+    try {
+      return await response.json()
+    } catch (error) {
+      return null
+    }
+  },
+  async addVote (id, isDown) {
+    const url = serverurl + 'vote' + '?id=' + id + '&isDown=' + isDown
+    const token = await localStorage.getItem('token')
+    const response = await fetch(url, {
+      method: 'PUT',
+      headers: {
+        Authorization: 'Bearer ' + token
+      }
+    })
+    try {
+      return await response.json()
+    } catch (error) {
+      return null
+    }
+  },
+  async removeVote (id, isDown) {
+    const url = serverurl + 'vote' + '?id=' + id + '&isDown=' + isDown
+    const token = await localStorage.getItem('token')
+    const response = await fetch(url, {
+      method: 'DELETE',
+      headers: {
+        Authorization: 'Bearer ' + token
+      }
+    })
+    try {
+      return await response.json()
+    } catch (error) {
+      return null
+    }
   }
 }
diff --git a/src/components/Vote.vue b/src/components/Vote.vue
new file mode 100644
index 0000000000000000000000000000000000000000..79a910d933596111a570070c5333490febaf8d10
--- /dev/null
+++ b/src/components/Vote.vue
@@ -0,0 +1,68 @@
+<template>
+  <div class="vote" :key="voteStatus.status">
+    <h1 class="title is-4">{{localVoteCount}} votes</h1>
+    <div v-if="voteStatus.status === 'none'">
+      <b-button size="is-small" icon-left="thumb-down-outline" style="top:-2px" @click="addDownVote"/>
+      <b-button size="is-small" icon-left="thumb-up-outline" style="top:-2px" @click="addUpVote"/>
+    </div>
+    <div v-else-if="voteStatus.status === 'up'">
+      <b-button size="is-small" icon-left="thumb-down-outline" style="top:-2px" disabled/>
+      <b-button size="is-small" icon-left="thumb-up" style="top:-2px" @click="removeUpVote" type="is-success"/>
+    </div>
+    <div v-else-if="voteStatus.status === 'down'">
+      <b-button size="is-small" icon-left="thumb-down" style="top:-2px" @click="removeDownVote" type="is-danger"/>
+      <b-button size="is-small" icon-left="thumb-up-outline" style="top:-2px" disabled/>
+    </div>
+  </div>
+</template>
+
+<script>
+import { api } from '@/api.js'
+
+export default {
+  name: 'vote',
+  props: ['modelId', 'voteCount'],
+  data () {
+    return {
+      voteStatus: {
+        status: 'none'
+      },
+      localVoteCount: 0
+    }
+  },
+  async mounted () {
+    this.localVoteCount = this.voteCount
+    this.voteStatus = await api.getVoteStatus(this.modelId)
+  },
+  methods: {
+    async addUpVote () {
+      var response = await api.addVote(this.modelId, false)
+      if (response.error) return
+      this.localVoteCount += 1
+      this.voteStatus = await api.getVoteStatus(this.modelId)
+    },
+    async addDownVote () {
+      var response = await api.addVote(this.modelId, true)
+      if (response.error) return
+      this.localVoteCount -= 1
+      this.voteStatus = await api.getVoteStatus(this.modelId)
+    },
+    async removeUpVote () {
+      var response = await api.removeVote(this.modelId, false)
+      if (response.error) return
+      this.localVoteCount -= 1
+      this.voteStatus = await api.getVoteStatus(this.modelId)
+    },
+    async removeDownVote () {
+      var response = await api.removeVote(this.modelId, true)
+      if (response.error) return
+      this.localVoteCount += 1
+      this.voteStatus = await api.getVoteStatus(this.modelId)
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>
diff --git a/src/views/Account.vue b/src/views/Account.vue
index 95cd4146f4b1828112193e3e274bc6520db6acc0..a5e6e57b9b7db5dc54a3ed1dcc662b153782b234 100644
--- a/src/views/Account.vue
+++ b/src/views/Account.vue
@@ -33,46 +33,97 @@
     </div>
     <div class="box">
       <h1 class="title is-4">My models</h1>
-      <ModelTable/>
+      <b-table :data="models" :loading="isLoading" striped hoverable>
+        <template slot-scope="props">
+          <b-table-column field="name" label="Model name" searchable sortable>
+            {{ props.row.name }} <b-icon v-if="props.row.isVerified" icon="check"/>
+          </b-table-column>
+
+          <b-table-column field="vote" label="Votes" sortable>
+            {{ props.row.votes }}
+          </b-table-column>
+
+          <b-table-column field="date" label="Last modification" centered sortable>
+            {{ new Date(props.row.lastModified).toLocaleDateString() }}
+          </b-table-column>
+
+          <b-table-column field="date" label="Added" centered sortable>
+            {{ new Date(props.row.added).toLocaleDateString() }}
+          </b-table-column>
+
+          <b-table-column label="" centered>
+            <b-button class="actionButton" icon-left="eye" type="is-info" tag="router-link" :to="{ name: 'Model', query: { id: props.row.id } }" outlined/>
+            <b-button class="actionButton" icon-left="pencil" type="is-warning" tag="router-link" :to="{ name: 'ModelEdit', params: {model: props.row} }" outlined/>
+            <b-button class="actionButton" icon-left="delete" type="is-danger" @click="removePrompt(props.row.id, props.row.name)" outlined/>
+          </b-table-column>
+        </template>
+      </b-table>
     </div>
 
     <div class="box">
       <h1 class="title is-4">Liked models</h1>
+      <b-table :data="likedModels" :loading="isLoading" striped hoverable>
+        <template slot-scope="props">
+          <b-table-column field="name" label="Model name" searchable sortable>
+            {{ props.row.name }} <b-icon v-if="props.row.isVerified" icon="check"/>
+          </b-table-column>
+
+          <b-table-column field="vote" label="Votes" sortable>
+            {{ props.row.votes }}
+          </b-table-column>
+
+          <b-table-column field="date" label="Last modification" centered sortable>
+            {{ new Date(props.row.lastModified).toLocaleDateString() }}
+          </b-table-column>
+
+          <b-table-column field="date" label="Added" centered sortable>
+            {{ new Date(props.row.added).toLocaleDateString() }}
+          </b-table-column>
+
+          <b-table-column label="" centered>
+            <b-button class="actionButton" icon-left="eye" type="is-info" tag="router-link" :to="{ name: 'Model', query: { id: props.row.id } }" outlined/>
+          </b-table-column>
+        </template>
+      </b-table>
     </div>
   </div>
 </template>
 
 <script>
-import ModelTable from '@/components/ModelTable.vue'
 import { api } from '@/api.js'
 
 export default {
   name: 'Account',
-  components: {
-    ModelTable
-  },
   data () {
     return {
+      isLoading: true,
       account: {},
-      models: []
+      models: [],
+      likedModels: []
     }
   },
   async mounted () {
     this.account = await api.getUser()
     this.models = await api.getUserModels()
+    this.likedModels = await api.getUserLikedModels()
     await localStorage.setItem('user_role', this.account.role)
     await localStorage.setItem('user_id', this.account.id)
+    this.isLoading = false
   },
   methods: {
-    async getAccount () {
-      const token = await localStorage.getItem('token')
-      const url = this.$serverurl + 'user'
-      try {
-        const response = await fetch(url, { headers: { Authorization: 'Bearer ' + token } })
-        return await response.json()
-      } catch (error) {
-        return null
-      }
+    removePrompt (id, name) {
+      this.$buefy.dialog.confirm({
+        message: 'Delete ' + name + ' ?',
+        cancelText: 'Abort',
+        confirmText: 'Delete',
+        type: 'is-danger',
+        hasIcon: true,
+        onConfirm: async () => {
+          await api.removeModel(id)
+          this.$buefy.toast.open(name + ' deleted')
+          this.models = await api.getUserModels()
+        }
+      })
     }
   }
 }
@@ -82,4 +133,8 @@ export default {
 .account{
   margin-top: 20px;
 }
+
+.actionButton {
+  margin-left:8px;
+}
 </style>
diff --git a/src/views/Model.vue b/src/views/Model.vue
index bdd18397791c6b91bac9ad9c3a45ed280a35185d..b21cd698fc83d685684e676f51b1182b15a568fc 100644
--- a/src/views/Model.vue
+++ b/src/views/Model.vue
@@ -4,7 +4,7 @@
       <h1 class="title is-1">Error</h1>
       <h2 class="subtitle">Cant find model</h2>
     </div>
-    <div v-else>
+    <div v-else-if="model">
       <div class="columns box">
         <div class="column is-two-thirds">
           <h1 class="title is-1">{{model.name}} <b-tag v-if="model.isVerified" type="is-success" size="is-large">Verified</b-tag></h1>
@@ -19,7 +19,7 @@
             <br>
             <br>
           </div>
-          <h1 class="title is-4">{{model.votes}} votes <b-button size="is-small" icon-left="heart-outline" style="top:-2px"/></h1>
+          <Vote v-bind:modelId="model.id" v-bind:voteCount="model.votes"/>
           <small>Author: </small><strong>{{model.author.username}}</strong>
           <br>
           <small>Added: </small><strong>{{new Date(model.added).toLocaleDateString()}}</strong>
@@ -73,17 +73,19 @@
 
 <script>
 import Comments from '@/components/Comments.vue'
+import Vote from '@/components/Vote.vue'
 import marked from 'marked'
 import { api } from '@/api.js'
 
 export default {
   name: 'Model',
   components: {
-    Comments
+    Comments,
+    Vote
   },
   data () {
     return {
-      model: '',
+      model: null,
       isError: false,
       isLoading: true,
       isAuthor: false,
diff --git a/src/views/ModelAdd.vue b/src/views/ModelAdd.vue
index ea3716f577354bec04993295da213e6e49d3b52f..922ee8a636df54bd90f91e6f3766497d765f2211 100644
--- a/src/views/ModelAdd.vue
+++ b/src/views/ModelAdd.vue
@@ -18,6 +18,7 @@
           <b-field>
             <b-input type="number" placeholder="98" max="10000000" step="0.01" v-model="model.performance"/>
             <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit" maxlength="50"/>
+            <b-checkbox v-model="model.performanceLowerIsBetter">Lower is better</b-checkbox>
           </b-field>
         </b-field>
 
diff --git a/src/views/ModelEdit.vue b/src/views/ModelEdit.vue
index 5b1f89af37a11d122cdfe464ed0484e9cb349343..8ca5831aefbb5341ca2b548a66d6805ea561e847 100644
--- a/src/views/ModelEdit.vue
+++ b/src/views/ModelEdit.vue
@@ -20,6 +20,7 @@
             <b-field>
               <b-input type="number" placeholder="98" max="10000000" step="0.01" v-model="model.performance"/>
               <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit" maxlength="50"/>
+              <b-checkbox v-model="model.performanceLowerIsBetter">Lower is better</b-checkbox>
             </b-field>
           </b-field>