diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000000000000000000000000000000000000..32b1361ade9580debee6f6d8fd35d5dcca036948
--- /dev/null
+++ b/.env.development
@@ -0,0 +1 @@
+VUE_APP_SERVER_URL = http://localhost:8181/v1/
\ No newline at end of file
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000000000000000000000000000000000000..503dcc1a0f0ecca28b78d3ab664e0aaebc14b7a4
--- /dev/null
+++ b/.env.production
@@ -0,0 +1 @@
+VUE_APP_SERVER_URL = /api/v1/
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index b2ed14075c38c2a71b424eb365428a32bf21407a..a52f921fbab6a16712218abb1da314afad9c463c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9783,6 +9783,11 @@
         "object-visit": "^1.0.0"
       }
     },
+    "marked": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz",
+      "integrity": "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng=="
+    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
diff --git a/package.json b/package.json
index d5aa5b65c68d255c671406a8f6b2bf1d37a4793a..29ffb0d3b315ed1ce10ab3b935be5315af36309b 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
   "dependencies": {
     "buefy": "^0.8.17",
     "core-js": "^3.6.4",
+    "marked": "^1.0.0",
     "node-sass": "^4.14.0",
     "sass-loader": "^8.0.2",
     "vue": "^2.6.11",
diff --git a/src/components/Comments.vue b/src/components/Comments.vue
index 3253ef447ed8938e6df794232142e0219b8af05d..85c823308f6d56ba462ef69c21772411bf43ffb0 100644
--- a/src/components/Comments.vue
+++ b/src/components/Comments.vue
@@ -1,11 +1,11 @@
 <template>
   <div class="comments" v-if="comments">
-    <h1 class="title is-5">{{comments.length}} commentaires</h1>
+    <h1 class="title is-5">{{comments.length}} comments</h1>
     <article class="media" v-for="comment in comments" v-bind:key="comment.id">
       <div class="media-content">
         <div class="content">
           <p>
-            <strong>{{comment.author}}</strong> - <small>{{comment.date}}</small>
+            <strong>{{comment.author}}</strong> - <small>{{new Date(comment.date).toLocaleDateString()}}</small>
             <br>
             {{comment.content}}
           </p>
diff --git a/src/components/Filters.vue b/src/components/Filters.vue
index ce9d76dd381b978301ecf5c347960c480f5c05b0..021763c143dca9c9d6e397a52dea1eb5832730de 100644
--- a/src/components/Filters.vue
+++ b/src/components/Filters.vue
@@ -1,7 +1,7 @@
 <template>
   <b-menu>
     <div>
-      <b-menu-list label="Performance">
+      <b-menu-list label="minimum performance">
         <b-slider v-model="perfValue" lazy @change="changeTag"></b-slider>
       </b-menu-list>
       <b-menu-list v-for="tag in tags" v-bind:key="tag.name" :label="tag.name">
diff --git a/src/components/LayersEditor.vue b/src/components/LayersEditor.vue
new file mode 100644
index 0000000000000000000000000000000000000000..088476b85157447de65c8b04473c7cb79b369f1f
--- /dev/null
+++ b/src/components/LayersEditor.vue
@@ -0,0 +1,15 @@
+<template>
+  <div class="layersEditor">
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'LayersEditor'
+}
+</script>
+
+<style>
+
+</style>
diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue
index 6a48e4bd5e8b3fc2c6bc8c98e96221bb73d1c711..44afa98208fb4d1b7ecd9ff64c61f00c33fcb952 100644
--- a/src/components/LoginForm.vue
+++ b/src/components/LoginForm.vue
@@ -2,22 +2,22 @@
   <form action="">
     <div class="modal-card" style="width: auto">
       <header class="modal-card-head">
-        <p class="modal-card-title">Se connecter</p>
+        <p class="modal-card-title">Login</p>
       </header>
       <section class="modal-card-body">
         <b-field label="Email">
           <b-input type="email" v-model="email" placeholder="email" required/>
         </b-field>
 
-        <b-field label="Mot de passe">
-          <b-input type="password" v-model="password" password-reveal placeholder="mot de passe" required/>
+        <b-field label="Password">
+          <b-input type="password" v-model="password" password-reveal placeholder="password" required/>
         </b-field>
 
-        <b-button class="is-text is-small">mot de passe oublié ?</b-button >
+        <b-button class="is-text is-small">forgot password ?</b-button >
 
       </section>
       <footer class="modal-card-foot">
-        <button class="button is-primary" @click="onLogin">Connexion</button>
+        <button class="button is-primary" @click="onLogin">Login</button>
       </footer>
     </div>
   </form>
diff --git a/src/components/MarkdownEditor.vue b/src/components/MarkdownEditor.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e0431d2f7db9d13c490e0201b0e7748bd519f505
--- /dev/null
+++ b/src/components/MarkdownEditor.vue
@@ -0,0 +1,38 @@
+<template>
+  <div class="markdownEditor container">
+    <b-tabs>
+      <b-tab-item label="Editor" class="edit">
+        <b-input type="textarea" v-model="input"/>
+      </b-tab-item>
+
+      <b-tab-item label="Preview">
+        <div class="content" v-html="compiledMarkdown"></div>
+      </b-tab-item>
+    </b-tabs>
+  </div>
+</template>
+
+<script>
+import marked from 'marked'
+
+export default {
+  name: 'MarkdownEditor',
+  props: {
+    input: {
+      type: String,
+      default: '# Readme'
+    }
+  },
+  computed: {
+    compiledMarkdown: function () {
+      return marked(this.input)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.edit textarea {
+  min-height: 800px;
+}
+</style>
diff --git a/src/components/ModelCard.vue b/src/components/ModelCard.vue
index 2981f29c345bc4b8a9a261cfbaeb01bde5c2b530..2c56fec228b7d183d5b75a7187665d2cc65f02af 100644
--- a/src/components/ModelCard.vue
+++ b/src/components/ModelCard.vue
@@ -8,7 +8,7 @@
         <p>
           <strong>{{model.name}}</strong>
           <br>
-          <small>{{model.author}}</small> - <small>{{model.modificationDate}}</small>
+          <small>{{model.author}}</small> - <small>{{new Date(model.modificationDate).toLocaleDateString()}}</small>
           <br>
           {{model.shortDescription}}
         </p>
diff --git a/src/components/ModelTable.vue b/src/components/ModelTable.vue
index 1345de204dc553d456813998263bebca785e5643..a6164b3a12506b3075fdb6961cce29d416c9eb13 100644
--- a/src/components/ModelTable.vue
+++ b/src/components/ModelTable.vue
@@ -1,7 +1,7 @@
 <template>
   <b-table :data="models" :loading="isLoading" striped hoverable>
     <template slot-scope="props">
-      <b-table-column field="name" label="Nom du modèle" searchable sortable>
+      <b-table-column field="name" label="Model name" searchable sortable>
         {{ props.row.name }}
       </b-table-column>
 
@@ -9,11 +9,11 @@
         {{ props.row.vote }}
       </b-table-column>
 
-      <b-table-column field="date" label="Date de modification" centered sortable>
+      <b-table-column field="date" label="Last modification" centered sortable>
         {{ new Date(props.row.modificationDate).toLocaleDateString() }}
       </b-table-column>
 
-      <b-table-column field="date" label="Date d'ajout" centered sortable>
+      <b-table-column field="date" label="Added" centered sortable>
         {{ new Date(props.row.addedDate).toLocaleDateString() }}
       </b-table-column>
 
@@ -55,9 +55,9 @@ export default {
     removePrompt (id) {
       const name = this.models[id].name
       this.$buefy.dialog.confirm({
-        message: 'Supprimer ' + name + ' ?',
-        cancelText: 'Annuler',
-        confirmText: 'Supprimer',
+        message: 'Delete ' + name + ' ?',
+        cancelText: 'Abort',
+        confirmText: 'Delete',
         type: 'is-danger',
         hasIcon: true,
         onConfirm: () => this.remove(id)
@@ -73,10 +73,10 @@ export default {
             Authorization: 'Bearer ' + this.token
           }
         })
-        this.$buefy.toast.open(name + ' supprimé')
+        this.$buefy.toast.open(name + ' deleted')
         this.getData()
       } catch (error) {
-        this.$buefy.toast.open('Erreur supprimer')
+        this.$buefy.toast.open('Delete error')
       }
     }
   }
diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue
index 9192095cbefd94d854b3a94c0733075b85593743..36571e436fdaf1ae914e935ddb9b8f5d0efea237 100644
--- a/src/components/Navbar.vue
+++ b/src/components/Navbar.vue
@@ -12,7 +12,7 @@
       <template slot="start">
         <b-navbar-item tag="div">
           <b-field>
-            <b-input placeholder="Rechercher..."
+            <b-input placeholder="Search..."
               type="search"
               icon="magnify"
               v-model="search"
@@ -27,10 +27,10 @@
           Home
         </b-navbar-item>
         <b-navbar-item tag="router-link" :to="{ name: 'Search' }">
-          Rechercher
+          Search
         </b-navbar-item>
         <b-navbar-item tag="router-link" :to="{ name: 'Docs' }">
-          Documentation
+          Docs
         </b-navbar-item>
         <b-navbar-item tag="router-link" :to="{ name: 'About' }">
           <b-icon icon="help-circle-outline"/>
@@ -38,18 +38,18 @@
         <b-navbar-item tag="div">
           <div v-if="isLogged" class="buttons">
             <b-button tag="router-link" :to="{ name: 'Account' }" type="is-light">
-              <strong>Mon compte</strong>
+              <strong>Account</strong>
             </b-button>
             <b-button @click="logout" type="is-warning">
-              Déconnexion
+              Logout
             </b-button>
           </div>
           <div v-else class="buttons">
             <b-button @click="openRegisterPrompt" type="is-primary">
-              <strong>S'inscrire</strong>
+              <strong>Sign up</strong>
             </b-button>
             <b-button @click="openLoginPrompt" type="is-light">
-              Se connecter
+              Login
             </b-button>
           </div>
         </b-navbar-item>
diff --git a/src/components/RegisterForm.vue b/src/components/RegisterForm.vue
index 1ce52a575987d49fe513511d35343b91af33e4e9..7151ed2780f8568f5230a81c61952edc62b7089b 100644
--- a/src/components/RegisterForm.vue
+++ b/src/components/RegisterForm.vue
@@ -2,28 +2,28 @@
   <form action="">
     <div class="modal-card" style="width: auto">
       <header class="modal-card-head">
-        <p class="modal-card-title">S'inscrire</p>
+        <p class="modal-card-title">Sign up</p>
       </header>
       <section class="modal-card-body">
         <b-field label="Email">
           <b-input type="email" v-model="email" placeholder="email" required/>
         </b-field>
 
-        <b-field label="Nom d'utilisateur">
-          <b-input v-model="username" placeholder="nom d'utilisateur" required/>
+        <b-field label="Username">
+          <b-input v-model="username" placeholder="username" required/>
         </b-field>
 
-        <b-field label="Mot de passe">
-          <b-input type="password" v-model="password" password-reveal placeholder="mot de passe" required/>
+        <b-field label="Password">
+          <b-input type="password" v-model="password" password-reveal placeholder="password" required/>
         </b-field>
 
-        <b-field label="Confirmer le mot de passe">
-          <b-input type="password" v-model="passwordConfirm" password-reveal placeholder="mot de passe" required/>
+        <b-field label="Confirm password">
+          <b-input type="password" v-model="passwordConfirm" password-reveal placeholder="password" required/>
         </b-field>
 
       </section>
       <footer class="modal-card-foot">
-        <button class="button is-primary">Créer un compte</button>
+        <button class="button is-primary">Make account</button>
       </footer>
     </div>
   </form>
diff --git a/src/components/TagEditor.vue b/src/components/TagEditor.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6855570885580e45157cb74a730ca85222e0fd07
--- /dev/null
+++ b/src/components/TagEditor.vue
@@ -0,0 +1,144 @@
+<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" @click="addTagToModel">Add</b-button>
+      </p>
+    </b-field>
+
+    <b-taglist>
+      <b-tag
+        v-for="tag in tags"
+        v-bind:key="tag.type"
+        type="is-info"
+        @close="removeTagFromModel(tag)"
+        closable>
+      {{tag.type}}
+      </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 []
+      console.log('SELECT ' + this.selectedCategory)
+      var category = this.tagList.filter((tag) => {
+        return tag.name === this.selectedCategory
+      })
+      console.log('SELECT ' + category)
+      return category[0].types.filter((type) => {
+        return type
+          .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 = ''
+    },
+    removeTagFromModel (tag) {
+      console.log('REMOVE TAG ' + tag)
+      const index = this.tags.indexOf(tag)
+      if (index > -1) {
+        this.tags.splice(index, 1)
+      }
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>
diff --git a/src/main.js b/src/main.js
index 2ba6ec9e2e2c259d112f6be15fa1a1baec547835..ab4d3ec04d2b8173a1d693ac8c9fd4fff6800c14 100644
--- a/src/main.js
+++ b/src/main.js
@@ -8,8 +8,8 @@ import './assets/style.scss'
 Vue.use(Buefy)
 Vue.config.productionTip = false
 
-Vue.prototype.$serverurl = 'http://localhost:8181/api/v1/'
-Vue.prototype.$isLogged = false
+// Vue.prototype.$serverurl = process.env.VUE_APP_SERVER_URL
+Vue.prototype.$serverurl = 'http://localhost:8181/v1/'
 
 new Vue({
   router,
diff --git a/src/router/index.js b/src/router/index.js
index cdcfc71c6fd74369f463a74bf0ce1bf40f3b4a0c..7c273dd945da3eaeef237f7d0091a894b1105105 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -34,12 +34,18 @@ const routes = [
     path: '/modeledit',
     name: 'ModelEdit',
     component: () => import('../views/ModelEdit.vue'),
-    props: true
+    props: true,
+    meta: {
+      requiresAuth: true
+    }
   },
   {
     path: '/account',
     name: 'Account',
-    component: () => import('../views/Account.vue')
+    component: () => import('../views/Account.vue'),
+    meta: {
+      requiresAuth: true
+    }
   }
 ]
 
@@ -47,4 +53,14 @@ const router = new VueRouter({
   routes
 })
 
+router.beforeEach((to, from, next) => {
+  if (to.matched.some(record => record.meta.requiresAuth)) {
+    if (localStorage.getItem('token') == null) {
+      next({ path: '/' })
+    } else next()
+  } else {
+    next()
+  }
+})
+
 export default router
diff --git a/src/views/Account.vue b/src/views/Account.vue
index 0718d87ebd23eab8e3521b300bea27ce7458b044..e85efa8f7451b6fcf923c8b857fe2e3f5b9261e8 100644
--- a/src/views/Account.vue
+++ b/src/views/Account.vue
@@ -1,14 +1,14 @@
 <template>
   <div class="account container">
     <div class="box">
-      <h1 class="title">Bienvenue {{account.username}}</h1>
+      <h1 class="title">Welcome {{account.username}}</h1>
       <div class="buttons">
-        <b-button>Ajouter un modèle</b-button>
-        <b-button>Modifier le compte</b-button>
+        <b-button>Add new model</b-button>
+        <b-button>Change account details</b-button>
       </div>
     </div>
     <div class="box">
-      <h1 class="title is-4">Mes modèles</h1>
+      <h1 class="title is-4">My models</h1>
       <ModelTable/>
     </div>
   </div>
diff --git a/src/views/Model.vue b/src/views/Model.vue
index f7427e02d428b9415b23dd006b95b9c560a6c406..a9b42755b887fa6ceb894d0b319d557e6e592596 100644
--- a/src/views/Model.vue
+++ b/src/views/Model.vue
@@ -16,15 +16,15 @@
         </div>
         <div class="column">
           <h1 class="title is-4">{{model.vote}} votes <b-button size="is-small" icon-left="heart-outline" style="top:-2px"/></h1>
-          <small>Auteur: </small><strong>{{model.author}}</strong>
+          <small>Author: </small><strong>{{model.author}}</strong>
           <br>
-          <small>Date d'ajout: </small><strong>{{model.addedDate}}</strong>
+          <small>Added: </small><strong>{{new Date(model.addedDate).toLocaleDateString()}}</strong>
           <br>
-          <small>Dernière modification: </small><strong>{{model.modificationDate}}</strong>
+          <small>Last modification: </small><strong>{{new Date(model.modificationDate).toLocaleDateString()}}</strong>
           <br>
           <br>
           <b-button type="is-primary" size="is-medium" icon-left="download">
-            Télécharger
+            Download
           </b-button>
         </div>
       </div>
diff --git a/src/views/ModelEdit.vue b/src/views/ModelEdit.vue
index 645179bd6b33cb145fc7029efa794a83a3b382a9..16df9c8b9580e333037482897da45e9ec25d8593 100644
--- a/src/views/ModelEdit.vue
+++ b/src/views/ModelEdit.vue
@@ -1,32 +1,61 @@
 <template>
   <div class="modelEdit container">
     <div class="box">
-      <b-field label="Nom du modèle">
-        <b-input maxlength="30" :value="model.name"/>
+      <b-field label="Model name">
+        <b-input maxlength="30" :v-model="model.name"/>
       </b-field>
 
-      <b-field label="Description courte">
-        <b-input maxlength="200" type="textarea" :value="model.shortDescription"/>
+      <h1 class="title">Description</h1>
+      <b-field label="Short description">
+        <b-input maxlength="200" type="textarea" :v-model="model.shortDescription"/>
       </b-field>
 
-      <b-field label="Description longue">
-        <b-input type="textarea" :value="model.longDescription"/>
+      <b-field label="Long description">
+        <markdownEditor v-bind:input="model.longDescription"/>
       </b-field>
+
+      <h1 class="title">Tags</h1>
+      <tagEditor v-bind:input="model.tags"/>
+
+      <h1 class="title">Files</h1>
+
+      <h2 class="title is-6">Model</h2>
+      <b-field position="is-centered">
+        <b-upload v-model="dropFiles" multiple drag-drop>
+          <section class="section">
+            <div class="content has-text-centered">
+              <p><b-icon icon="upload" size="is-large"/></p>
+              <p>Drop your files here or click to upload</p>
+            </div>
+          </section>
+        </b-upload>
+      </b-field>
+
+      <h2 class="title is-6">Custom layers</h2>
+      <layersEditor/>
     </div>
     <div class="box">
-      <b-button type="is-warning">Annuler</b-button>
-      <b-button type="is-danger">Supprimer</b-button>
-      <b-button type="is-success">Enregistrer</b-button>
+      <b-button type="is-warning">Abort</b-button>
+      <b-button type="is-success">Save</b-button>
     </div>
   </div>
 </template>
 
 <script>
+import markdownEditor from '@/components/MarkdownEditor.vue'
+import tagEditor from '@/components/TagEditor.vue'
+import layersEditor from '@/components/LayersEditor.vue'
+
 export default {
   name: 'ModelEdit',
-  props: ['model'],
+  components: {
+    markdownEditor,
+    tagEditor,
+    layersEditor
+  },
   data () {
     return {
+      model: '',
       name: '',
       shortDesc: '',
       longDesc: '',
diff --git a/src/views/Search.vue b/src/views/Search.vue
index 07be994e3ce3a1c08c684417c8ff6e450c7d79eb..0010425b9efd1bb08971fa0929b7add90ce8aa63 100644
--- a/src/views/Search.vue
+++ b/src/views/Search.vue
@@ -6,7 +6,7 @@
         <Filters v-bind:tags="tags" v-on:setTags="setTags"/>
       </div>
       <div v-if="result" class="column is-four-fifths">
-        <h1 class="title is-6">{{result.total}} résultats - page {{result.page}}</h1>
+        <h1 class="title is-6">{{result.total}} result - page {{result.page}}</h1>
         <div v-for="model in result.models" v-bind:key="model.name">
           <ModelCard v-bind:model="model"/>
         </div>
@@ -58,7 +58,7 @@ export default {
       this.result = await this.getResult()
     },
     async getTags () {
-      const url = this.$serverurl + 'tags'
+      const url = this.$serverurl + 'models/tags'
       const response = await fetch(url)
       try {
         return await response.json()