diff --git a/src/components/Filters.vue b/src/components/Filters.vue
index 76954fa729a82716a00624c0ce1fbec5b1c64426..c9e4c2d040dce593d55c60afe92e523706f576f4 100644
--- a/src/components/Filters.vue
+++ b/src/components/Filters.vue
@@ -16,12 +16,12 @@
           <b-slider-tick :value="3">10000</b-slider-tick>
         </b-slider>
       </b-menu-list>
-      <b-menu-list v-for="tag in tags" v-bind:key="tag.name" :label="tag.name">
-        <div v-for="type in tag.types" v-bind:key="type" class="field">
+      <b-menu-list v-for="category in tags" v-bind:key="category.name" :label="category.name">
+        <div v-for="tag in category.tags" v-bind:key="tag" class="field">
           <b-checkbox
-          :native-value="type"
+          :native-value="tag.name"
           v-model="checkboxGroup"
-          @input="changeTag">{{type}}</b-checkbox>
+          @input="changeTag">{{tag.name}}</b-checkbox>
         </div>
       </b-menu-list>
     </div>
diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue
index 8c9093325dc76ac32690a1a85a1e6498712d7252..b3dc08df24c9b135bbe1db6b50faaf91205cf5fc 100644
--- a/src/components/LoginForm.vue
+++ b/src/components/LoginForm.vue
@@ -7,8 +7,8 @@
       <section class="modal-card-body">
         <h2 class="subtitle has-text-danger">{{errorMessage}}</h2>
 
-        <b-field label="Email">
-          <b-input type="email" v-model="email" placeholder="email" required/>
+        <b-field label="Username">
+          <b-input v-model="username" placeholder="username" required/>
         </b-field>
 
         <b-field label="Password">
@@ -30,24 +30,26 @@ export default {
   name: 'LoginForm',
   data () {
     return {
-      email: '',
+      username: '',
       password: '',
       errorMessage: null
     }
   },
   methods: {
     async onLogin () {
-      var response = await this.login(this.email, this.password)
-      if (response.token !== null) {
-        await localStorage.setItem('token', response.token)
+      var response = await this.login(this.username, this.password)
+      console.log('LOGIN RESPONSE ' + response)
+      if (response !== null) {
+        console.log('LOGIN TOKEN OK')
+        await localStorage.setItem('token', response.message)
         this.$parent.close()
         this.$router.go()
       } else {
-        this.errorMessage = 'Email or password incorect'
+        this.errorMessage = 'Username or password incorect'
       }
     },
-    async login (email, password) {
-      const url = this.$serverurl + 'auth'
+    async login (username, password) {
+      const url = this.$serverurl + 'login'
       try {
         const response = await fetch(
           url, {
@@ -57,7 +59,7 @@ export default {
               'Content-Type': 'application/json'
             },
             body: JSON.stringify({
-              email: email,
+              username: username,
               password: password
             })
           }
diff --git a/src/components/ModelCard.vue b/src/components/ModelCard.vue
index 2c56fec228b7d183d5b75a7187665d2cc65f02af..6202d5a29e8e0b0eab8978a197d0bb51ef2fc9d3 100644
--- a/src/components/ModelCard.vue
+++ b/src/components/ModelCard.vue
@@ -8,13 +8,12 @@
         <p>
           <strong>{{model.name}}</strong>
           <br>
-          <small>{{model.author}}</small> - <small>{{new Date(model.modificationDate).toLocaleDateString()}}</small>
+          <small>{{model.author.username}}</small> - <small>{{new Date(model.modificationDate).toLocaleDateString()}}</small>
           <br>
           {{model.shortDescription}}
         </p>
         <b-taglist>
-          <b-tag v-for="tag in model.tags" v-bind:key="tag.type" type="is-info">{{tag.type}}</b-tag>
-          <b-tag type="is-info">{{model.performance}}%</b-tag>
+          <b-tag v-for="tag in model.tags" v-bind:key="tag.name" type="is-info">{{tag.name}}</b-tag>
         </b-taglist>
       </div>
     </div>
diff --git a/src/components/ModelUpload.vue b/src/components/ModelUpload.vue
index 83a4aa84666ac9a73bfa5fda129b839e69c043eb..e535dc5dd8b15b8c7104c188b2fd1663048ab2b7 100644
--- a/src/components/ModelUpload.vue
+++ b/src/components/ModelUpload.vue
@@ -77,7 +77,7 @@ export default {
         this.setError(response.message)
         return
       } else {
-        this.modelId = response.id
+        this.modelId = response.message
       }
 
       if (this.model.file !== undefined) {
diff --git a/src/components/RegisterForm.vue b/src/components/RegisterForm.vue
index ddf95544b790aec1898724dd3abcbe87d86f4195..b553034e610834591ceac1ad85a989e58612cd26 100644
--- a/src/components/RegisterForm.vue
+++ b/src/components/RegisterForm.vue
@@ -52,13 +52,13 @@ export default {
       if (response.error) {
         this.errorMessage = response.message
       } else {
-        await localStorage.setItem('token', response.token)
+        await localStorage.setItem('token', response.message)
         this.$parent.close()
         this.$router.go()
       }
     },
     async register (username, email, password) {
-      const url = this.$serverurl + 'user'
+      const url = this.$serverurl + 'user/signup'
       try {
         const response = await fetch(
           url, {
diff --git a/src/components/TagEditor.vue b/src/components/TagEditor.vue
index 7a565b4d6505124e7024ffced9f484128f99bd05..f78f2898426cfcf72950fb0fe858eafaa5222e16 100644
--- a/src/components/TagEditor.vue
+++ b/src/components/TagEditor.vue
@@ -1,38 +1,59 @@
 <template>
   <div class="tagEditor">
-    <b-field position="is-centered" has-addons>
-      <b-autocomplete
-        v-model="tagName"
-        :open-on-focus="true"
-        :data="filteredTags"
-        icon-right="close-circle"
-        icon-right-clickable>
-        <template slot="header">
-          <a @click="addNewTagDialog">
-            <span> Add new... </span>
-          </a>
-        </template>
-      </b-autocomplete>
-      <p class="control">
-        <b-select placeholder="Select a category" v-model="selectedCategory">
-          <option v-for="tag in tagList" v-bind:key="tag.type" :value="tag.name">{{tag.name}}</option>
-        </b-select>
-      </p>
-      <p class="control">
-        <b-button class="control is-primary" @click="addTagToModel">Add</b-button>
-      </p>
-    </b-field>
-
     <b-taglist>
       <b-tag
-        v-for="tag in tags"
-        v-bind:key="tag.type"
+        v-for="tag in modelTags"
+        v-bind:key="tag"
         type="is-info"
         @close="removeTagFromModel(tag)"
         closable>
-      {{tag.type}}
+
+        {{tag}}
       </b-tag>
     </b-taglist>
+
+    <b-collapse
+      class="card"
+      animation="slide"
+      v-for="(category, index) of aviablesTags"
+      :key="index"
+      :open="isOpen == index"
+      @open="isOpen = index">
+
+      <div
+        slot="trigger"
+        slot-scope="props"
+        class="card-header"
+        role="button">
+
+        <p class="card-header-title">
+          {{category.name}}
+        </p>
+        <a class="card-header-icon">
+          <b-icon :icon="props.open ? 'menu-down' : 'menu-up'"/>
+        </a>
+      </div>
+
+      <div class="card-content">
+        <div class="buttons">
+          <b-button
+            v-for="tag in category.tags"
+            v-bind:key="tag.name"
+            @click="addTagToModel(tag.name)"
+            type="is-info"
+            rounded>
+
+            {{tag.name}}
+          </b-button>
+
+          <b-button
+            @click="addNewTagDialog(category.id)"
+            type="is-warning"
+            icon-right="plus"
+            rounded/>
+        </div>
+      </div>
+    </b-collapse>
   </div>
 </template>
 
@@ -40,7 +61,7 @@
 export default {
   name: 'TagEditor',
   props: {
-    tags: {
+    modelTags: {
       type: Array,
       default: function () {
         return []
@@ -49,27 +70,12 @@ export default {
   },
   data () {
     return {
-      tagName: '',
-      selectedCategory: null,
-      tagList: []
-    }
-  },
-  computed: {
-    filteredTags () {
-      if (this.selectedCategory === null) return []
-      var category = this.tagList.filter((tag) => {
-        return tag.name === this.selectedCategory
-      })
-      return category[0].types.filter((type) => {
-        return type
-          .toString()
-          .toLowerCase()
-          .indexOf(this.tagName.toLowerCase()) >= 0
-      })
+      aviablesTags: [],
+      isOpen: 0
     }
   },
   async mounted () {
-    this.tagList = await this.getTags()
+    this.aviablesTags = await this.getTags()
   },
   methods: {
     async getTags () {
@@ -81,36 +87,34 @@ export default {
         return null
       }
     },
-    addNewTagDialog () {
+    addNewTagDialog (categoryId) {
       this.$buefy.dialog.prompt({
         message: 'Tag',
         inputAttrs: {
-          maxlength: 20,
-          value: this.name
+          maxlength: 20
         },
         confirmText: 'Add',
-        onConfirm: (value) => {
-          this.addNewTag(value)
-          var category = this.tagList.filter((tag) => {
-            return tag.name === this.selectedCategory
-          })
-          category[0].types.push(value)
+        onConfirm: async (value) => {
+          await this.addNewTag(value, categoryId)
+          this.aviablesTags = await this.getTags()
         }
       })
     },
-    async addNewTag (tag) {
+    async addNewTag (tag, categoryId) {
       const url = this.$serverurl + 'models/tags'
+      const token = await localStorage.getItem('token')
       try {
         const response = await fetch(
           url, {
             method: 'POST',
             headers: {
               Accept: 'application/json',
-              'Content-Type': 'application/json'
+              'Content-Type': 'application/json',
+              Authorization: 'Bearer ' + token
             },
             body: JSON.stringify({
-              name: this.selectedCategory,
-              type: tag
+              name: tag,
+              categoryId: categoryId
             })
           }
         )
@@ -119,23 +123,19 @@ export default {
         return null
       }
     },
-    addTagToModel () {
-      this.tags.push({
-        name: this.selectedCategory,
-        type: this.tagName
-      })
-      this.tagName = ''
+    addTagToModel (tag) {
+      this.modelTags.push(tag)
       this.syncToParent()
     },
     removeTagFromModel (tag) {
-      const index = this.tags.indexOf(tag)
+      const index = this.modelTags.indexOf(tag)
       if (index > -1) {
-        this.tags.splice(index, 1)
+        this.modelTags.splice(index, 1)
       }
       this.syncToParent()
     },
     syncToParent () {
-      this.$emit('update-tags', this.tags)
+      this.$emit('update-tags', this.modelTags)
     }
   }
 }
diff --git a/src/components/TagEditorOLD.vue b/src/components/TagEditorOLD.vue
new file mode 100644
index 0000000000000000000000000000000000000000..23a212badeca5d3f85c94d47f2a455814a629221
--- /dev/null
+++ b/src/components/TagEditorOLD.vue
@@ -0,0 +1,146 @@
+<template>
+  <div class="tagEditor">
+    <b-field position="is-centered" has-addons>
+      <b-autocomplete
+        v-model="tagName"
+        :open-on-focus="true"
+        :data="filteredTags"
+        icon-right="close-circle"
+        icon-right-clickable>
+        <template slot="header">
+          <a @click="addNewTagDialog">
+            <span> Add new... </span>
+          </a>
+        </template>
+      </b-autocomplete>
+      <p class="control">
+        <b-select placeholder="Select a category" v-model="selectedCategory">
+          <option v-for="category in tagList" v-bind:key="category.name" :value="category.name">{{category.name}}</option>
+        </b-select>
+      </p>
+      <p class="control">
+        <b-button class="control is-primary" @click="addTagToModel">Add</b-button>
+      </p>
+    </b-field>
+
+    <b-taglist>
+      <b-tag
+        v-for="tag in tags"
+        v-bind:key="tag.name"
+        type="is-info"
+        @close="removeTagFromModel(tag)"
+        closable>
+      {{tag.name}}
+      </b-tag>
+    </b-taglist>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'TagEditor',
+  props: {
+    tags: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      tagName: '',
+      selectedCategory: null,
+      tagList: []
+    }
+  },
+  computed: {
+    filteredTags () {
+      if (this.selectedCategory === null) return []
+      var category = this.tagList.filter((tag) => {
+        return tag.name === this.selectedCategory
+      })
+      return category[0].tags.filter((tag) => {
+        return tag
+          .toString()
+          .toLowerCase()
+          .indexOf(this.tagName.toLowerCase()) >= 0
+      })
+    }
+  },
+  async mounted () {
+    this.tagList = await this.getTags()
+  },
+  methods: {
+    async getTags () {
+      const url = this.$serverurl + 'models/tags'
+      const response = await fetch(url)
+      try {
+        return await response.json()
+      } catch (error) {
+        return null
+      }
+    },
+    addNewTagDialog () {
+      this.$buefy.dialog.prompt({
+        message: 'Tag',
+        inputAttrs: {
+          maxlength: 20,
+          value: this.name
+        },
+        confirmText: 'Add',
+        onConfirm: (value) => {
+          this.addNewTag(value)
+          var category = this.tagList.filter((tag) => {
+            return tag.name === this.selectedCategory
+          })
+          category[0].types.push(value)
+        }
+      })
+    },
+    async addNewTag (tag) {
+      const url = this.$serverurl + 'models/tags'
+      try {
+        const response = await fetch(
+          url, {
+            method: 'POST',
+            headers: {
+              Accept: 'application/json',
+              'Content-Type': 'application/json'
+            },
+            body: JSON.stringify({
+              name: this.selectedCategory,
+              type: tag
+            })
+          }
+        )
+        return await response.json()
+      } catch (error) {
+        return null
+      }
+    },
+    addTagToModel () {
+      this.tags.push({
+        name: this.selectedCategory,
+        type: this.tagName
+      })
+      this.tagName = ''
+      this.syncToParent()
+    },
+    removeTagFromModel (tag) {
+      const index = this.tags.indexOf(tag)
+      if (index > -1) {
+        this.tags.splice(index, 1)
+      }
+      this.syncToParent()
+    },
+    syncToParent () {
+      this.$emit('update-tags', this.tags)
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>
diff --git a/src/main.js b/src/main.js
index ab4d3ec04d2b8173a1d693ac8c9fd4fff6800c14..33ad0b8f8fd649d8c90e9d0e1438fcb487d51707 100644
--- a/src/main.js
+++ b/src/main.js
@@ -9,7 +9,7 @@ Vue.use(Buefy)
 Vue.config.productionTip = false
 
 // Vue.prototype.$serverurl = process.env.VUE_APP_SERVER_URL
-Vue.prototype.$serverurl = 'http://localhost:8181/v1/'
+Vue.prototype.$serverurl = 'http://localhost:8181/'
 
 new Vue({
   router,
diff --git a/src/views/Model.vue b/src/views/Model.vue
index faa6a63e7f0ec6ac917e752f8f0e4682a3af3091..5687df5c0371c15d8acd9fc44fc2126d002414a4 100644
--- a/src/views/Model.vue
+++ b/src/views/Model.vue
@@ -10,30 +10,28 @@
           <h1 class="title is-1">{{model.name}}</h1>
           <h2 class="subtitle">{{model.shortDescription}}</h2>
           <b-taglist>
-            <b-tag v-for="tag in model.tags" v-bind:key="tag.type" type="is-info">{{tag.type}}</b-tag>
-            <b-tag type="is-info">{{model.performance}}%</b-tag>
+            <b-tag v-for="tag in model.tags" v-bind:key="tag.name" type="is-info">{{tag.name}}</b-tag>
           </b-taglist>
         </div>
         <div class="column infoColumn">
           <h1 class="title is-4">{{model.vote}} votes <b-button size="is-small" icon-left="heart-outline" style="top:-2px"/></h1>
-          <small>Author: </small><strong>{{model.author}}</strong>
+          <small>Author: </small><strong>{{model.author.username}}</strong>
           <br>
           <small>Added: </small><strong>{{new Date(model.addedDate).toLocaleDateString()}}</strong>
           <br>
           <small>Last modification: </small><strong>{{new Date(model.modificationDate).toLocaleDateString()}}</strong>
           <br>
           <br>
-          <b-button type="is-primary" size="is-medium" icon-left="download">
+          <b-button type="is-primary" size="is-medium" icon-left="download" @click="downloadModel(model.id)">
             Download model
           </b-button>
           <hr>
           <strong>{{model.customLayers.length}} customs layers</strong>
           <br>
           <template v-for="layer in model.customLayers">
-            <b-button class="customLayer" type="is-primary" icon-left="download" v-bind:key="layer.name">
+              <b-button class="customLayer" type="is-primary" icon-left="download" v-bind:key="layer.name" @click="downloadLayer(layer.id)">
               Download {{layer.name}}
-            </b-button>
-            <br v-bind:key="layer.name">
+              </b-button>
           </template>
         </div>
       </div>
@@ -91,6 +89,10 @@ export default {
       } catch (error) {
         return null
       }
+    },
+    downloadModel (id) {
+    },
+    downloadLayer (id) {
     }
   }
 }
diff --git a/src/views/Search.vue b/src/views/Search.vue
index fde2ef7051ef6c033ca520a2be7642a3b567f451..e547c4f73ac6d1c5c476f3c379ef7ee5fc6decb0 100644
--- a/src/views/Search.vue
+++ b/src/views/Search.vue
@@ -20,7 +20,7 @@
             <option value="date">Most recent</option>
           </b-select>
         </b-field>
-        <h1 class="title is-6">{{result.total}} result - page {{result.page}}</h1>
+        <h1 class="title is-6">{{result.total}} results - page {{result.page}}</h1>
         <div v-for="model in result.models" v-bind:key="model.name">
           <ModelCard v-bind:model="model"/>
         </div>
@@ -94,9 +94,9 @@ export default {
       const url = new URL(this.$serverurl + 'search')
       const params = new URLSearchParams()
 
-      if (this.paramSearch != null) params.append('q', this.paramSearch)
+      if (this.paramSearch != null) params.append('name', this.paramSearch)
       if (this.paramTags != null) params.append('tag', this.paramTags)
-      if (this.paramPerf != null) params.append('perf', this.paramPerf)
+      if (this.paramPerf != null) params.append('param', this.paramPerf)
       if (this.paramOrder != null) params.append('order', this.paramOrder)
 
       params.append('size', this.resultSize)