diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000..38adffa
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1,28 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..8d6c5ef
--- /dev/null
+++ b/frontend/README.md
@@ -0,0 +1,29 @@
+# frontend
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Compile and Minify for Production
+
+```sh
+npm run build
+```
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..b72e945
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <link rel="shortcut icon" href="/src/assets/icons/toolshed-48x48.png" type="image/png">
+    <title>Toolshed</title>
+    <link href="/src/assets/base.css" rel="stylesheet">
+</head>
+<body>
+<div id="app"></div>
+<script type="module" src="/src/main.js"></script>
+</body>
+</html>
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000..6ab03b4
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,23 @@
+{
+  "name": "frontend",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "bootstrap-icons-vue": "^1.10.3",
+    "dns-query": "^0.11.2",
+    "js-nacl": "^1.4.0",
+    "vue": "^3.2.47",
+    "vue-router": "^4.1.6",
+    "vuex": "^4.1.0"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^4.0.0",
+    "sass": "^1.62.1",
+    "vite": "^4.1.4"
+  }
+}
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
new file mode 100644
index 0000000..54ad06d
--- /dev/null
+++ b/frontend/src/App.vue
@@ -0,0 +1,28 @@
+<script setup>
+</script>
+
+<template>
+    <router-view></router-view>
+    <!-- TODO UI für Freunde liste, add, remove -->
+</template>
+
+<script>
+
+
+import {mapMutations} from 'vuex';
+import store from '@/store';
+
+export default {
+    name: 'App',
+    methods: {
+        ...mapMutations(['init'])
+    },
+    beforeCreate () {
+        store.commit('init')
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
diff --git a/frontend/src/components/BaseLayout.vue b/frontend/src/components/BaseLayout.vue
new file mode 100644
index 0000000..b5ff611
--- /dev/null
+++ b/frontend/src/components/BaseLayout.vue
@@ -0,0 +1,294 @@
+<template>
+    <div class="wrapper">
+        <nav id="sidebar" class="sidebar">
+            <div class="sidebar-content js-simplebar">
+                <router-link to="/" class="sidebar-brand">
+                    <span class="align-middle">Toolshed</span>
+                </router-link>
+                <ul class="sidebar-nav">
+                    <li class="sidebar-header">
+                        Tools & Components
+                    </li>
+                    <!--
+                    <li class="sidebar-item {% if 'icons' in segment %} active {% endif %}">
+                        <a class="sidebar-link" href="{% url 'inventory' %}">
+                            {% bs_icon 'archive' extra_classes="bi-valign-middle" %}
+                            <span class="align-middle">Inventory</span>
+                        </a>
+                    </li>
+                    -->
+                    <li class="sidebar-item">
+                        <router-link to="/inventory" class="sidebar-link">
+                            <b-icon-archive class="bi-valign-middle"></b-icon-archive>
+                            <span class="align-middle">Inventory</span>
+                        </router-link>
+                    </li>
+                    <li class="sidebar-item">
+                        <router-link to="/friends" class="sidebar-link">
+                            <b-icon-people class="bi-valign-middle"></b-icon-people>
+                            <span class="align-middle">Friends</span>
+                        </router-link>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+        <div class="main">
+            <nav class="navbar navbar-expand navbar-light navbar-bg">
+                <a class="sidebar-toggle d-flex">
+                    <i class="hamburger align-self-center"></i>
+                </a>
+                <form class="d-none d-sm-inline-block">
+                    <div class="input-group input-group-navbar">
+                        <input type="text" class="form-control" placeholder="Search…" aria-label="Search">
+                        <button class="btn" type="button">
+                            <b-icon-search class="bi-valign-middle"></b-icon-search>
+                        </button>
+                    </div>
+                </form>
+                <div class="navbar-collapse collapse">
+                    <ul class="navbar-nav navbar-align">
+                        <li class="nav-item dropdown">
+                            <a class="nav-icon dropdown-toggle" href="#" id="alertsDropdown" data-toggle="dropdown">
+                                <div class="position-relative">
+                                    <b-icon-bell class="bi-valign-middle"></b-icon-bell>
+                                    <span class="indicator">4</span>
+                                </div>
+                            </a>
+                            <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right py-0"
+                                 aria-labelledby="alertsDropdown">
+                                <div class="dropdown-menu-header">
+                                    4 New Notifications
+                                </div>
+                                <div class="list-group">
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <b-icon-exclamation-circle
+                                                        class="bi-valign-middle text-danger"></b-icon-exclamation-circle>
+                                            </div>
+                                            <div class="col-10">
+                                                <div class="text-dark">Update completed</div>
+                                                <div class="text-muted small mt-1">Restart server 12 to complete the
+                                                    update.
+                                                </div>
+                                                <div class="text-muted small mt-1">30m ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <b-icon-bell class="bi-valign-middle text-warning"></b-icon-bell>
+                                            </div>
+                                            <div class="col-10">
+                                                <div class="text-dark">Lorem ipsum</div>
+                                                <div class="text-muted small mt-1">Aliquam ex eros, imperdiet vulputate
+                                                    hendrerit
+                                                    et.
+                                                </div>
+                                                <div class="text-muted small mt-1">2h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <b-icon-house class="bi-valign-middle text-primary"></b-icon-house>
+                                            </div>
+                                            <div class="col-10">
+                                                <div class="text-dark">Login from 192.186.1.8</div>
+                                                <div class="text-muted small mt-1">5h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <!--{% for notification in top_notifications %}
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                {% bs_icon 'person-add' extra_classes="bi-valign-middle text-success" %}
+                                            </div>
+                                            <div class="col-10">
+                                                <div class="text-dark">New connection</div>
+                                                <div class="text-muted small mt-1">Christina accepted your request.</div>
+                                                <div class="text-muted small mt-1">14h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    {% endfor %}-->
+                                </div>
+                                <div class="dropdown-menu-footer">
+                                    <a href="#" class="text-muted">Show all notifications</a>
+                                </div>
+                            </div>
+                        </li>
+                        <li class="nav-item dropdown">
+                            <a class="nav-icon dropdown-toggle" href="#" id="messagesDropdown" data-toggle="dropdown">
+                                <div class="position-relative">
+                                    <b-icon-chat-left class="bi-valign-middle"></b-icon-chat-left>
+                                </div>
+                            </a>
+                            <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right py-0"
+                                 aria-labelledby="messagesDropdown">
+                                <div class="dropdown-menu-header">
+                                    <div class="position-relative">
+                                        4 New Messages
+                                    </div>
+                                </div>
+                                <div class="list-group">
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <!--<img src="/static/assets/img/avatars/avatar-5.png"
+                                                     class="avatar img-fluid rounded-circle" alt="Vanessa Tucker">-->
+                                            </div>
+                                            <div class="col-10 pl-2">
+                                                <div class="text-dark">Vanessa Tucker</div>
+                                                <div class="text-muted small mt-1">Nam pretium turpis et arcu. Duis arcu
+                                                    tortor.
+                                                </div>
+                                                <div class="text-muted small mt-1">15m ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <!--<img src="/static/assets/img/avatars/avatar-2.png"
+                                                     class="avatar img-fluid rounded-circle" alt="William Harris">-->
+                                            </div>
+                                            <div class="col-10 pl-2">
+                                                <div class="text-dark">William Harris</div>
+                                                <div class="text-muted small mt-1">Curabitur ligula sapien euismod
+                                                    vitae.
+                                                </div>
+                                                <div class="text-muted small mt-1">2h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <!--<img src="/static/assets/img/avatars/avatar-4.png"
+                                                     class="avatar img-fluid rounded-circle" alt="Christina Mason">-->
+                                            </div>
+                                            <div class="col-10 pl-2">
+                                                <div class="text-dark">Christina Mason</div>
+                                                <div class="text-muted small mt-1">Pellentesque auctor neque nec urna.
+                                                </div>
+                                                <div class="text-muted small mt-1">4h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                   <!-- {% for messege in top_messages %}-->
+                                    <a href="#" class="list-group-item">
+                                        <div class="row g-0 align-items-center">
+                                            <div class="col-2">
+                                                <!--<img src="/static/assets/img/avatars/avatar-3.png"
+                                                     class="avatar img-fluid rounded-circle" alt="Sharon Lessman">-->
+                                            </div>
+                                            <div class="col-10 pl-2">
+                                                <div class="text-dark">Sharon Lessman</div>
+                                                <div class="text-muted small mt-1">Aenean tellus metus, bibendum sed,
+                                                    posuere ac,
+                                                    mattis non.
+                                                </div>
+                                                <div class="text-muted small mt-1">5h ago</div>
+                                            </div>
+                                        </div>
+                                    </a>
+                                    <!--{% endfor %}-->
+                                </div>
+                                <div class="dropdown-menu-footer">
+                                    <a href="#" class="text-muted">Show all messages</a>
+                                </div>
+                            </div>
+                        </li>
+                        <li class="nav-item dropdown">
+                            <a class="nav-icon dropdown-toggle d-inline-block d-sm-none" href="#"
+                               data-toggle="dropdown">
+                                <i class="align-middle" data-feather="settings"></i>
+                                <b-icon-chat-left class="bi-valign-middle"></b-icon-chat-left>
+                            </a>
+
+                            <a class="nav-link dropdown-toggle d-none d-sm-inline-block" href="#"
+                               data-toggle="dropdown">
+                                <!--<img src="/static/assets/img/avatars/avatar.png" class="avatar img-fluid rounded mr-1"
+                                     alt="Charles Hall"/>-->
+                                <span class="text-dark">
+                        <!--{{ request.user.username }}-->
+                    </span>
+                            </a>
+
+                            <div class="dropdown-menu dropdown-menu-right">
+                                <router-link to="/profile" class="dropdown-item">
+                                    <b-icon-person class="bi-valign-middle mr-1"></b-icon-person>
+                                    Profile
+                                </router-link>
+                                <router-link to="/settings" class="dropdown-item">
+                                    <b-icon-sliders class="bi-valign-middle mr-1"></b-icon-sliders>
+                                    Settings &
+                                    Privacy
+                                </router-link>
+                                <div class="dropdown-divider"></div>
+                                <a class="dropdown-item" href="#" @click="logout"> Log out</a>
+                            </div>
+                        </li>
+                    </ul>
+                </div>
+            </nav>
+            <slot></slot>
+            <footer class="footer">
+                <div class="container-fluid">
+                    <div class="row text-muted">
+                        <div class="col-6 text-left">
+                            <p class="mb-0">
+                                <a target="_blank" href="https://www.gnu.org/licenses/gpl-3.0.de.html"
+                                   class="text-muted">
+                                    License: <strong>GPL-3.0</strong>
+                                </a>
+                            </p>
+                        </div>
+                        <div class="col-6 text-right">
+                            <ul class="list-inline">
+                                <li class="list-inline-item">
+                                    <a class="text-muted"
+                                       target="_blank" href="https://github.com/gr4yj3d1/toolshed">Dev Docs</a>
+                                </li>
+                                <li class="list-inline-item">
+                                    <a class="text-muted"
+                                       target="_blank" href="https://github.com/gr4yj3d1/toolshed">Sources</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </footer>
+        </div>
+    </div>
+</template>
+
+<script>
+import {mapGetters, mapMutations} from 'vuex';
+import * as BIcons from "bootstrap-icons-vue";
+
+export default {
+    name: 'BaseLayout',
+    components: {
+        ...BIcons
+    },
+    computed: {
+        username() {
+            return this.$route.params.username
+        }
+    },
+    methods: {
+        ...mapMutations(['logout'])
+    },
+    async mounted() {
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/dns.js b/frontend/src/dns.js
new file mode 100644
index 0000000..70f2ba5
--- /dev/null
+++ b/frontend/src/dns.js
@@ -0,0 +1,30 @@
+import {query} from 'dns-query';
+
+class FallBackResolver {
+    constructor() {
+        this._servers = ['1.1.1.1', '8.8.8.8'];
+        this._cache = JSON.parse(localStorage.getItem('dns-cache')) || {};
+    }
+
+    async query(domain, type) {
+        const key = domain + ':' + type;
+        if (key in this._cache && this._cache[key].time > Date.now() - 1000 * 60 * 60) {
+            const age_seconds = Math.ceil(Date.now() / 1000 - this._cache[key].time / 1000);
+            console.log('cache hit', key, this._cache[key].ttl - age_seconds);
+            return [this._cache[key].data];
+        }
+        const result = await query(
+            {question: {type: type, name: domain}},
+            {
+                endpoints: this._servers,
+            }
+        )
+        const first = result.answers[0];
+        this._cache[key] = {time: Date.now(), ...first}; // TODO hadle multiple answers
+        localStorage.setItem('dns-cache', JSON.stringify(this._cache));
+        console.log('cache miss', key, first.ttl);
+        return [first.data];
+    }
+}
+
+export default FallBackResolver;
\ No newline at end of file
diff --git a/frontend/src/main.js b/frontend/src/main.js
new file mode 100644
index 0000000..095e5e0
--- /dev/null
+++ b/frontend/src/main.js
@@ -0,0 +1,19 @@
+import {createApp} from 'vue'
+//import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue'
+import { BootstrapIconsPlugin } from 'bootstrap-icons-vue';
+import App from './App.vue'
+
+import './assets/css/toolshed.css'
+import './assets/js/app.js'
+
+import router from './router'
+import store from './store';
+
+import _nacl from 'js-nacl';
+
+const app = createApp(App).use(router).use(store).use(BootstrapIconsPlugin);
+
+_nacl.instantiate((nacl) => {
+    window.nacl = nacl
+    app.mount('#app')
+});
diff --git a/frontend/src/neigbors.js b/frontend/src/neigbors.js
new file mode 100644
index 0000000..8a205c0
--- /dev/null
+++ b/frontend/src/neigbors.js
@@ -0,0 +1,38 @@
+class NeighborsCache {
+    constructor() {
+        //this._max_age = 1000 * 60 * 60; // 1 hour
+        this._max_age = 1000 * 60 * 5; // 5 minutes
+        this._cache = JSON.parse(localStorage.getItem('neighbor-cache')) || {};
+    }
+
+    reachable(domain) {
+        console.log('reachable neighbor ' + domain)
+        if (domain in this._cache) {
+            delete this._cache[domain];
+            localStorage.setItem('neighbor-cache', JSON.stringify(this._cache));
+        }
+    }
+
+    unreachable(domain) {
+        console.log('unreachable neighbor ' + domain)
+        this._cache[domain] = {time: Date.now()};
+        localStorage.setItem('neighbor-cache', JSON.stringify(this._cache));
+    }
+
+    queryUnreachable(domain) {
+        //return false if unreachable
+        if (domain in this._cache) {
+            if (this._cache[domain].time > Date.now() - this._max_age) {
+                console.log('skip unreachable neighbor ' + domain + ' ' + Math.ceil(
+                    Date.now()/1000 - this._cache[domain].time/1000) + 's/' + Math.ceil(this._max_age/1000) + 's')
+                return true
+            } else {
+                delete this._cache[domain];
+                localStorage.setItem('neighbor-cache', JSON.stringify(this._cache));
+            }
+        }
+        return false;
+    }
+}
+
+export default NeighborsCache;
\ No newline at end of file
diff --git a/frontend/src/router.js b/frontend/src/router.js
new file mode 100644
index 0000000..75ea992
--- /dev/null
+++ b/frontend/src/router.js
@@ -0,0 +1,49 @@
+import {createRouter, createWebHistory} from 'vue-router'
+import Index from '@/views/Index.vue';
+import Login from '@/views/Login.vue';
+import Register from '@/views/Register.vue';
+import store from '@/store';
+import Profile from '@/views/Profile.vue';
+import Settings from '@/views/Settings.vue';
+import Inventory from '@/views/Inventory.vue';
+import Friends from "@/views/Friends.vue";
+import InventoryNew from "@/views/InventoryNew.vue";
+import InventoryEdit from "@/views/InventoryEdit.vue";
+import InventoryDetail from "@/views/InventoryDetail.vue";
+
+
+const routes = [
+    {path: '/', component: Index, meta: {requiresAuth: true}},
+    {path: '/profile', component: Profile, meta: {requiresAuth: true}},
+    {path: '/settings', component: Settings, meta: {requiresAuth: true}},
+    {path: '/inventory', component: Inventory, meta: {requiresAuth: true}},
+    {path: '/inventory/:id', component: InventoryDetail, meta: {requiresAuth: true}},
+    {path: '/inventory/:id/edit', component: InventoryEdit, meta: {requiresAuth: true}},
+    {path: '/inventory/new', component: InventoryNew, meta: {requiresAuth: true}},
+    {path: '/friends', component: Friends, meta: {requiresAuth: true}},
+    {path: '/login', component: Login, meta: {requiresAuth: false}},
+    {path: '/register', component: Register, meta: {requiresAuth: false}},
+]
+
+const router = createRouter({
+    // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
+    history: createWebHistory(),
+    linkActiveClass: "active",
+    routes, // short for `routes: routes`
+})
+
+router.beforeEach((to, from) => {
+    // instead of having to check every route record with
+    // to.matched.some(record => record.meta.requiresAuth)
+    if (to.meta.requiresAuth && !store.getters.isLoggedIn) {
+        // this route requires auth, check if logged in
+        // if not, redirect to login page.
+        return {
+            path: '/login',
+            // save the location we were at to come back later
+            query: {redirect: to.fullPath},
+        }
+    }
+})
+
+export default router
\ No newline at end of file
diff --git a/frontend/src/store.js b/frontend/src/store.js
new file mode 100644
index 0000000..b3475fc
--- /dev/null
+++ b/frontend/src/store.js
@@ -0,0 +1,186 @@
+import {createStore} from 'vuex';
+import router from '@/router';
+import FallBackResolver from "@/dns";
+import NeighborsCache from "@/neigbors";
+
+
+export default createStore({
+    state: {
+        user: null,
+        token: null,
+        keypair: null,
+        remember: false,
+        friends: [],
+        item_map: {},
+        resolver: new FallBackResolver(),
+        unreachable_neighbors: new NeighborsCache(),
+        /*wk: new Wellknown({
+            update: true, // Will load latest definitions from updateURL.
+            updateURL: new URL(), // URL to load the latest definitions. (default: project URL)
+            persist: false, // True to persist the loaded definitions (nodejs: in filesystem, browser: localStorage)
+            localStoragePrefix: 'dnsquery_', // Prefix for files persisted.
+            maxAge: 300000, // Max age of persisted data to be used in ms.
+            timeout: 5000 // Timeout when loading updates.
+        })*/
+    },
+    mutations: {
+        setUser(state, user) {
+            state.user = user;
+            if (state.remember)
+                localStorage.setItem('user', user);
+        },
+        setToken(state, token) {
+            state.token = token;
+            if (state.remember)
+                localStorage.setItem('token', token);
+        },
+        setKey(state, keypair) {
+            state.keypair = nacl.crypto_sign_keypair_from_seed(nacl.from_hex(keypair))
+            if (state.remember)
+                localStorage.setItem('keypair', nacl.to_hex(state.keypair.signSk).slice(0, 64))
+        },
+        setRemember(state, remember) {
+            state.remember = remember;
+            if (!remember) {
+                localStorage.removeItem('user');
+                localStorage.removeItem('token');
+                localStorage.removeItem('keypair');
+            }
+            localStorage.setItem('remember', remember);
+        },
+        setInventoryItems(state, {url, items}) {
+            state.item_map[url] = items;
+        },
+        logout(state) {
+            state.user = null;
+            state.token = null;
+            state.keypair = null;
+            localStorage.removeItem('user');
+            localStorage.removeItem('token');
+            localStorage.removeItem('keypair');
+            router.push('/login');
+        },
+        init(state) {
+            const remember = localStorage.getItem('remember');
+            const user = localStorage.getItem('user');
+            const token = localStorage.getItem('token');
+            const keypair = localStorage.getItem('keypair');
+            if (user && token) {
+                this.commit('setUser', user);
+                this.commit('setToken', token);
+                if (keypair) {
+                    this.commit('setKey', keypair)
+                } else {
+                }
+                router.push('/');
+            }
+        }
+    },
+    actions: {
+        async login({commit, dispatch, state}, {username, password, remember}) {
+            //this.setRemember(remember)
+            this.commit('setRemember', remember);
+            /*const response = await fetch('http://10.23.42.128:8000/auth/token/', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                },
+                body: JSON.stringify({
+                    username: username, password: password
+                })
+            })*/
+            const data = await dispatch('apiLocalPost', {
+                target: '/token/', data: {
+                    username: username, password: password
+                }
+            })
+            if (data.token) {
+                commit('setToken', data.token);
+                commit('setUser', username + '@example.com');
+                const j = await dispatch('apiLocalGet', {target: '/keys/'})
+                const k = j.key
+                this.commit('setKey', k)
+                await router.push({path: '/'});
+                return true;
+            } else {
+                return false;
+            }
+
+        },
+        async getFriends(state) {
+            return ['jedi@j3d1.de', 'foobar@example.com', 'foobaz@example.eleon'];
+        },
+        async getFriendServer({state}, {username}) {
+            const domain = username.split('@')[1]
+            if (domain === 'example.eleon')
+                return ['10.23.42.186:8000'];
+            if (domain === 'localhost')
+                return ['127.0.0.1:8000'];
+            if (domain === 'example.com')
+                return ['10.23.42.128:8000'];
+            const request = '_toolshed-server._tcp.' + domain + '.'
+            return await state.resolver.query(request, 'SRV').then(
+                (result) => result.map(
+                    (answer) => answer.target + ':' + answer.port))
+        },
+        async apiFederatedGet({state}, url) {
+            if (state.unreachable_neighbors.queryUnreachable(url)) {
+                throw new Error('unreachable neighbor')
+            }
+            const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url), state.keypair.signSk)
+            const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
+            return await fetch(url, {
+                method: 'GET',
+                headers: {
+                    'Authorization': auth
+                }
+            }).catch( err => state.unreachable_neighbors.unreachable(url)
+            ).then(response => response.json())
+        },
+        async apiFederatedPost({state}, {url, data}) {
+            if (state.unreachable_neighbors.queryUnreachable(url)) {
+                throw new Error('unreachable neighbor')
+            }
+            const json = JSON.stringify(data)
+            const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url + json), state.keypair.signSk)
+            const auth = 'Signature ' + state.user + ':' + nacl.to_hex(signature)
+            return await fetch(url, {
+                method: 'POST',
+                headers: {
+                    'Authorization': auth,
+                    'Content-Type': 'application/json'
+                },
+                body: json
+            }).catch( err => state.unreachable_neighbors.unreachable(url)
+            ).then(response => response.json())
+        },
+        async apiLocalGet({state}, {target}) {
+            const auth = state.token ? {'Authorization': 'Token ' + state.token} : {}
+            return await fetch('http://10.23.42.128:8000/auth' + target, {
+                method: 'GET',
+                headers: auth
+            }).then(response => response.json())
+        },
+        async apiLocalPost({state}, {target, data}) {
+            const auth = state.token ? {'Authorization': 'Token ' + state.token} : {}
+            return await fetch('http://10.23.42.128:8000/auth' + target, {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    ...auth
+                },
+                body: JSON.stringify(data)
+            }).then(response => response.json())
+        }
+    },
+    getters: {
+        isLoggedIn(state) {
+            return state.user !== null && state.token !== null;
+        },
+        inventory_items(state) {
+            return Object.entries(state.item_map).reduce((acc, [url, items]) => {
+                return acc.concat(items)
+            }, [])
+        }
+    }
+})
\ No newline at end of file
diff --git a/frontend/src/views/Friends.vue b/frontend/src/views/Friends.vue
new file mode 100644
index 0000000..3a21812
--- /dev/null
+++ b/frontend/src/views/Friends.vue
@@ -0,0 +1,88 @@
+<template>
+    <BaseLayout>
+        <main class="content">
+            <div class="container-fluid p-0">
+                <h1 class="h3 mb-3">Friends</h1>
+                <div class="row">
+                    <div class="col-12 col-xl-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Foo</h5>
+                                <h6 class="card-subtitle text-muted">Bar <code>baz</code>.</h6>
+                            </div>
+                            <table class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th style="width:40%;">Name</th>
+                                    <th class="d-none d-md-table-cell" style="width:25%">Server</th>
+                                    <th>Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr v-for="friend in friends" :key="friend.name">
+                                    <td>{{ friend.name }}</td>
+                                    <td class="d-none d-md-table-cell">{{ friend.server.join(', ') }}</td>
+                                    <td class="table-action">
+                                        <a href="#">
+                                            <b-icon-pencil-square></b-icon-pencil-square>
+                                        </a>
+                                        <a href="#">
+                                            <b-icon-trash></b-icon-trash>
+                                        </a>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import {mapActions, mapGetters} from "vuex";
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: 'Inventory',
+    components: {
+        BaseLayout,
+        ...BIcons
+    },
+    data() {
+        return {
+            friends: [],
+        }
+    },
+    computed: {
+        username() {
+            return this.$route.params.username
+        },
+        inventory_items() {
+            return this.local_items.concat(this.eleon_items)
+        }
+    },
+    methods: {
+        ...mapActions(['getFriends', "getFriendServer"]),
+    },
+    mounted() {
+        this.getFriends().then((friends) => {
+            friends.map((friend) => {
+                this.getFriendServer({username: friend}).then((server) => {
+                    this.friends.push({
+                        name: friend,
+                        server: server
+                    })
+                })
+            })
+        })
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Index.vue b/frontend/src/views/Index.vue
new file mode 100644
index 0000000..4a5d040
--- /dev/null
+++ b/frontend/src/views/Index.vue
@@ -0,0 +1,41 @@
+<template>
+    <BaseLayout>
+        <main class="content">
+            <div class="container-fluid p-0">
+                <h1 class="h3 mb-3">Blank Page</h1>
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title mb-0">Empty card</h5>
+                            </div>
+                            <div class="card-body">
+                                <div class="logo">
+                                    <img src="/src/assets/icons/toolshed-48x48.png" alt="Toolshed logo">
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import {mapGetters, mapMutations} from 'vuex';
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: 'Index',
+    components: {
+        ...BIcons,
+        BaseLayout
+    },
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Inventory.vue b/frontend/src/views/Inventory.vue
new file mode 100644
index 0000000..bb94db5
--- /dev/null
+++ b/frontend/src/views/Inventory.vue
@@ -0,0 +1,93 @@
+<template>
+    <BaseLayout>
+        <main class="content">
+            <div class="container-fluid p-0">
+                <h1 class="h3 mb-3">Inventory Own & Friends"</h1>
+                <div class="row">
+                    <div class="col-12 col-xl-6">
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title">Foo</h5>
+                                <h6 class="card-subtitle text-muted">Bar <code>baz</code>.</h6>
+                            </div>
+                            <table class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th style="width:40%;">Name</th>
+                                    <th style="width:25%">Owner</th>
+                                    <th class="d-none d-md-table-cell" style="width:25%">Amount</th>
+                                    <th>Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr v-for="item in inventory_items" :key="item.id">
+                                    <td>
+                                        <router-link :to="`/inventory/${item.id}`">{{ item.name }}</router-link>
+                                    </td>
+                                    <td>{{ item.owner }}</td>
+                                    <td class="d-none d-md-table-cell">{{ item.owned_amount }}</td>
+                                    <td class="table-action">
+                                        <router-link :to="`/inventory/${item.id}/edit`">
+                                            <b-icon-pencil-square></b-icon-pencil-square>
+                                        </router-link>
+                                        <a :href="`/inventory/${item.id}/delete`" @click.prevent="deleteItem(item.id)">
+                                            <b-icon-trash></b-icon-trash>
+                                        </a>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                        <div class="card">
+                            <button class="btn" @click="getInventoryItems">Refresh</button>
+                            <router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import {mapActions, mapGetters, mapMutations, mapState} from "vuex";
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: "Inventory",
+    components: {
+        BaseLayout,
+        ...BIcons
+    },
+    computed: {
+        ...mapGetters(["inventory_items"]),
+        username() {
+            return this.$route.params.username
+        }
+    },
+    methods: {
+        ...mapActions(["apiFederatedGet", "getFriends", "getFriendServer"]),
+        ...mapMutations(["setInventoryItems"]),
+        async getInventoryItems() {
+            try {
+                const servers = await this.getFriends().then(friends => friends.map(friend => this.getFriendServer({username: friend})))
+                const urls = servers.map(server => server.then(s => `http://${s}/api/inventory_items/`))
+                urls.map(url => url.then(u => this.apiFederatedGet(u).then(items => {
+                    this.setInventoryItems({url: u, items})
+                }).catch(e => {
+                }))) // TODO: handle error
+            } catch (e) {
+                console.error(e)
+            }
+        },
+    },
+    async mounted() {
+        await this.getInventoryItems()
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/InventoryDetail.vue b/frontend/src/views/InventoryDetail.vue
new file mode 100644
index 0000000..d3bd892
--- /dev/null
+++ b/frontend/src/views/InventoryDetail.vue
@@ -0,0 +1,65 @@
+<script setup>
+
+</script>
+
+<template>
+    <BaseLayout :username="username">
+        <main class="container">
+            <div class="row">
+                <div class="col">
+                    <div class="card">
+                        <div class="card-header">Inventory</div>
+                        <div class="card-body">
+                            <table class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th>Item</th>
+                                    <th>Quantity</th>
+                                    <th>Owner</th>
+                                    <th>Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr v-for="item in inventory_items" :key="item.id">
+                                    <td>{{ item.name }}</td>
+                                    <td>{{ item.quantity }}</td>
+                                    <td>{{ item.owner }}</td>
+                                    <td>
+                                        <a href="#">
+                                            <b-icon-pencil-square></b-icon-pencil-square>
+                                        </a>
+                                        <a href="#">
+                                            <b-icon-trash></b-icon-trash>
+                                        </a>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                        <div class="card">
+                            <button class="btn" @click="getInventoryItems">Refresh</button>
+                            <router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: "InventoryDetail",
+    components: {
+        BaseLayout,
+        ...BIcons
+    },
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/InventoryEdit.vue b/frontend/src/views/InventoryEdit.vue
new file mode 100644
index 0000000..f054c83
--- /dev/null
+++ b/frontend/src/views/InventoryEdit.vue
@@ -0,0 +1,65 @@
+<script setup>
+
+</script>
+
+<template>
+    <BaseLayout :username="username">
+        <main class="container">
+            <div class="row">
+                <div class="col">
+                    <div class="card">
+                        <div class="card-header">Inventory</div>
+                        <div class="card-body">
+                            <table class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th>Item</th>
+                                    <th>Quantity</th>
+                                    <th>Owner</th>
+                                    <th>Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr v-for="item in inventory_items" :key="item.id">
+                                    <td>{{ item.name }}</td>
+                                    <td>{{ item.quantity }}</td>
+                                    <td>{{ item.owner }}</td>
+                                    <td>
+                                        <a href="#">
+                                            <b-icon-pencil-square></b-icon-pencil-square>
+                                        </a>
+                                        <a href="#">
+                                            <b-icon-trash></b-icon-trash>
+                                        </a>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                        <div class="card">
+                            <button class="btn" @click="getInventoryItems">Refresh</button>
+                            <router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: "InventoryEdit",
+    components: {
+        BaseLayout,
+        ...BIcons
+    },
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/InventoryNew.vue b/frontend/src/views/InventoryNew.vue
new file mode 100644
index 0000000..758761b
--- /dev/null
+++ b/frontend/src/views/InventoryNew.vue
@@ -0,0 +1,65 @@
+<script setup>
+
+</script>
+
+<template>
+    <BaseLayout :username="username">
+        <main class="container">
+            <div class="row">
+                <div class="col">
+                    <div class="card">
+                        <div class="card-header">Inventory</div>
+                        <div class="card-body">
+                            <table class="table table-striped">
+                                <thead>
+                                <tr>
+                                    <th>Item</th>
+                                    <th>Quantity</th>
+                                    <th>Owner</th>
+                                    <th>Actions</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr v-for="item in inventory_items" :key="item.id">
+                                    <td>{{ item.name }}</td>
+                                    <td>{{ item.quantity }}</td>
+                                    <td>{{ item.owner }}</td>
+                                    <td>
+                                        <a href="#">
+                                            <b-icon-pencil-square></b-icon-pencil-square>
+                                        </a>
+                                        <a href="#">
+                                            <b-icon-trash></b-icon-trash>
+                                        </a>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                        <div class="card">
+                            <button class="btn" @click="getInventoryItems">Refresh</button>
+                            <router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import * as BIcons from "bootstrap-icons-vue";
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: "InventoryNew",
+    components: {
+        BaseLayout,
+        ...BIcons
+    },
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue
new file mode 100644
index 0000000..3686f6b
--- /dev/null
+++ b/frontend/src/views/Login.vue
@@ -0,0 +1,97 @@
+<template>
+    <main class="d-flex w-100">
+        <div class="container d-flex flex-column">
+            <div class="row vh-100">
+                <div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
+                    <div class="d-table-cell align-middle">
+                        <div class="text-center mt-4">
+                            <h1 class="h2">
+                                Toolshed
+                            </h1>
+                            <p class="lead" v-if="msg">
+                                {{ msg }}
+                            </p>
+                            <p class="lead" v-else>
+                                Sign in to your account to continue
+                            </p>
+                        </div>
+                        <div class="card">
+                            <div class="card-body">
+                                <div class="m-sm-4">
+                                    <form role="form" @submit.prevent="do_login">
+
+                                        <div class="mb-3">
+                                            <label class="form-label">Username</label>
+                                            <input class="form-control form-control-lg" type="text"
+                                                   name="username" placeholder="Enter your username"
+                                                   v-model="username"/>
+                                        </div>
+                                        <div class="mb-3">
+                                            <label class="form-label">Password</label>
+                                            <input class="form-control form-control-lg" type="password"
+                                                   name="password" placeholder="Enter your password"
+                                                   v-model="password"/>
+                                        </div>
+                                        <div>
+                                            <label class="form-check">
+                                                <input class="form-check-input" type="checkbox" value="remember-me"
+                                                       name="remember-me" checked v-model="remember"
+                                                       @change="setRemember(remember)">
+                                                <span class="form-check-label">
+												Remember me next time
+												</span>
+                                            </label>
+                                        </div>
+                                        <div class="text-center mt-3">
+                                            <button type="submit" name="login" class="btn btn-lg btn-primary">Login
+                                            </button>
+                                        </div>
+                                    </form>
+                                    <br/>
+                                    <div class="text-center">
+                                        <p class="mb-0 text-muted">
+                                            Don’t have an account?
+                                            <router-link to="/register">Sign up</router-link>
+                                        </p>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </main>
+</template>
+
+<script>
+import {mapActions, mapMutations} from 'vuex';
+
+export default {
+    name: 'Login',
+    data() {
+        return {
+            msg: 'Welcome to Your Vue.js App',
+            username: '',
+            password: '',
+            remember: false
+        }
+    },
+    methods: {
+        ...mapActions(['login']),
+        ...mapMutations(['setRemember']),
+        async do_login(e) {
+            e.preventDefault();
+            if (!await this.login({username: this.username, password: this.password, remember: this.remember})) {
+                this.msg = 'Invalid username or password';
+            }
+
+        },
+
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Profile.vue b/frontend/src/views/Profile.vue
new file mode 100644
index 0000000..50ecade
--- /dev/null
+++ b/frontend/src/views/Profile.vue
@@ -0,0 +1,257 @@
+<template>
+    <BaseLayout>
+        <main class="content">
+            <div class="container-fluid p-0">
+
+                <h1 class="h3 mb-3">Profile</h1>
+
+                <div class="row">
+                    <div class="col-md-4 col-xl-3">
+                        <div class="card mb-3">
+                            <div class="card-header">
+                                <h5 class="card-title mb-0">Profile Details</h5>
+                            </div>
+                            <div class="card-body text-center">
+                                <!--<img src="/static/assets/img/avatars/avatar.png"
+                                     alt="Christina Mason" class="img-fluid rounded-circle mb-2" width="128"
+                                     height="128"/>-->
+                                <h5 class="card-title mb-0">
+                                    {{ user.username }}
+                                </h5>
+                                <div class="text-muted mb-2">
+                                    {{ user.email }}
+                                </div>
+
+                                <div>
+                                    <a class="btn btn-primary btn-sm" href="#">Follow</a>
+                                    <a class="btn btn-primary btn-sm" href="#"><span
+                                            data-feather="message-square"></span> Message</a>
+                                </div>
+                            </div>
+                            <!--{% if user.bio %}-->
+                            <hr class="my-0"/>
+                            <div class="card-body">
+                                <h5 class="h6 card-title">Bio</h5>
+                                <div class="text-muted mb-2">
+                                    {{ user.bio }}
+                                </div>
+                            </div>
+                            <!--{% endif %}-->
+                            <hr class="my-0"/>
+                            <div class="card-body">
+                                <h5 class="h6 card-title">Skills</h5>
+                                <a href="#" class="badge bg-primary mr-1 my-1">HTML</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">JavaScript</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">Sass</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">Angular</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">Vue</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">React</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">Redux</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">UI</a>
+                                <a href="#" class="badge bg-primary mr-1 my-1">UX</a>
+                            </div>
+                            <hr class="my-0"/>
+                            <div class="card-body">
+                                <h5 class="h6 card-title">About</h5>
+                                <ul class="list-unstyled mb-0">
+                                    <!--{% if user.location %}-->
+                                    <li class="mb-1"><span data-feather="home" class="feather-sm mr-1"></span> Lives
+                                        in <a href="#">{{ user.location }}</a></li>
+                                    <!--{% endif %}-->
+
+                                    <li class="mb-1"><span data-feather="briefcase" class="feather-sm mr-1"></span>
+                                        Works at <a href="#">GitHub</a></li>
+                                    <li class="mb-1"><span data-feather="map-pin" class="feather-sm mr-1"></span>
+                                        From <a href="#">Boston</a></li>
+                                </ul>
+                            </div>
+                            <hr class="my-0"/>
+                            <div class="card-body">
+                                <h5 class="h6 card-title">Elsewhere</h5>
+                                <ul class="list-unstyled mb-0">
+                                    <li class="mb-1"><span class="fas fa-globe fa-fw mr-1"></span> <a href="#">staciehall.co</a>
+                                    </li>
+                                    <li class="mb-1"><span class="fab fa-twitter fa-fw mr-1"></span> <a
+                                            href="#">Twitter</a>
+                                    </li>
+                                    <li class="mb-1"><span class="fab fa-facebook fa-fw mr-1"></span> <a href="#">Facebook</a>
+                                    </li>
+                                    <li class="mb-1"><span class="fab fa-instagram fa-fw mr-1"></span> <a href="#">Instagram</a>
+                                    </li>
+                                    <li class="mb-1"><span class="fab fa-linkedin fa-fw mr-1"></span> <a href="#">LinkedIn</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="col-md-8 col-xl-9">
+                        <div class="card">
+                            <div class="card-header">
+
+                                <h5 class="card-title mb-0">Activities</h5>
+                            </div>
+                            <div class="card-body h-100">
+
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar-5.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="Vanessa Tucker">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">5m ago</small>
+                                        <strong>Vanessa Tucker</strong> started following <strong>Christina
+                                        Mason</strong><br/>
+                                        <small class="text-muted">Today 7:51 pm</small><br/>
+
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="Charles Hall">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">30m ago</small>
+                                        <strong>Charles Hall</strong> posted something on <strong>Christina
+                                        Mason</strong>'s timeline<br/>
+                                        <small class="text-muted">Today 7:21 pm</small>
+
+                                        <div class="border text-sm text-muted p-2 mt-1">
+                                            Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem
+                                            quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam
+                                            nunc, blandit vel, luctus
+                                            pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt
+                                            tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis
+                                            ante.
+                                        </div>
+
+                                        <a href="#" class="btn btn-sm btn-danger mt-1"><i class="feather-sm"
+                                                                                          data-feather="heart"></i>
+                                            Like</a>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar-4.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="Christina Mason">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">1h ago</small>
+                                        <strong>Christina Mason</strong> posted a new blog<br/>
+
+                                        <small class="text-muted">Today 6:35 pm</small>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar-2.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="William Harris">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">3h ago</small>
+                                        <strong>William Harris</strong> posted two photos on <strong>Christina
+                                        Mason</strong>'s timeline<br/>
+                                        <small class="text-muted">Today 5:12 pm</small>
+
+                                        <div class="row g-0 mt-1">
+                                            <div class="col-6 col-md-4 col-lg-4 col-xl-3">
+                                                <!--<img src="/static/assets/img/photos/unsplash-1.jpg"
+                                                     class="img-fluid pr-2" alt="Unsplash">-->
+                                            </div>
+                                            <div class="col-6 col-md-4 col-lg-4 col-xl-3">
+                                                <!--<img src="/static/assets/img/photos/unsplash-2.jpg"
+                                                     class="img-fluid pr-2" alt="Unsplash">-->
+                                            </div>
+                                        </div>
+
+                                        <a href="#" class="btn btn-sm btn-danger mt-1"><i class="feather-sm"
+                                                                                          data-feather="heart"></i>
+                                            Like</a>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar-2.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="William Harris">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">1d ago</small>
+                                        <strong>William Harris</strong> started following <strong>Christina
+                                        Mason</strong><br/>
+                                        <small class="text-muted">Yesterday 3:12 pm</small>
+
+                                        <div class="d-flex align-items-start mt-1">
+                                            <a class="pr-3" href="#">
+                                                <!--<img src="/static/assets/img/avatars/avatar-4.png" width="36"
+                                                     height="36" class="rounded-circle mr-2" alt="Christina Mason">-->
+                                            </a>
+                                            <div class="flex-grow-1">
+                                                <div class="border text-sm text-muted p-2 mt-1">
+                                                    Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id,
+                                                    lorem. Maecenas nec odio et ante tincidunt tempus.
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar-4.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="Christina Mason">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">1d ago</small>
+                                        <strong>Christina Mason</strong> posted a new blog<br/>
+                                        <small class="text-muted">Yesterday 2:43 pm</small>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <div class="d-flex align-items-start">
+                                    <!--<img src="/static/assets/img/avatars/avatar.png" width="36" height="36"
+                                         class="rounded-circle mr-2" alt="Charles Hall">-->
+                                    <div class="flex-grow-1">
+                                        <small class="float-right text-navy">1d ago</small>
+                                        <strong>Charles Hall</strong> started following <strong>Christina
+                                        Mason</strong><br/>
+                                        <small class="text-muted">Yesterdag 1:51 pm</small>
+                                    </div>
+                                </div>
+
+                                <hr/>
+                                <a href="#" class="btn btn-primary btn-block">Load more</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: 'Profile',
+    data() {
+        return {
+            user: {
+                name: 'John Doe',
+                avatar: '/static/assets/img/avatars/avatar.png',
+                cover: '/static/assets/img/photos/unsplash-1.jpg',
+                occupation: 'Frontend Developer',
+                company: 'Facebook Inc.',
+                email: 'foo@bar.com',
+                phone: '+12 345 678 001',
+                address: 'Boulevard of Broken Dreams, 1234',
+            }
+        }
+    },
+    components: {BaseLayout},
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Register.vue b/frontend/src/views/Register.vue
new file mode 100644
index 0000000..3396600
--- /dev/null
+++ b/frontend/src/views/Register.vue
@@ -0,0 +1,88 @@
+<template>
+    <main class="d-flex w-100">
+        <div class="container d-flex flex-column">
+            <div class="row vh-100">
+                <div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
+                    <div class="d-table-cell align-middle">
+                        <div class="text-center mt-4">
+                            <h1 class="h2">
+                                Toolshed
+                            </h1>
+
+                            <p class="lead" v-if="msg">
+                                {{ msg }}
+                            </p>
+                            <p class="lead" v-else>
+                                Create an account to get started
+                            </p>
+                        </div>
+                        <div class="card">
+                            <div class="card-body">
+                                <div class="m-sm-4">
+                                    <form role="form" method="post" action="">
+                                        <!--{% csrf_token %}-->
+                                        <div class="mb-3">
+                                            <label class="form-label">Username</label>
+                                            <input class="form-control form-control-lg" type="text"
+                                                   name="username" placeholder="Enter your username"/>
+                                        </div>
+                                        <span class="text-error">{{ form.username.errors }}</span>
+                                        <div class="mb-3">
+                                            <label class="form-label">Email</label>
+                                            <input class="form-control form-control-lg" type="email"
+                                                   name="email" placeholder="Enter your email"/>
+                                        </div>
+                                        <span class="text-error">{{ form.email.errors }}</span>
+                                        <div class="mb-3">
+                                            <label class="form-label">Password</label>
+                                            <input class="form-control form-control-lg" type="password"
+                                                   name="password1" placeholder="Enter your password"/>
+                                        </div>
+                                        <span class="text-error">{{ form.password1.errors }}</span>
+                                        <div class="mb-3">
+                                            <label class="form-label">Password Check</label>
+                                            <input class="form-control form-control-lg" type="password"
+                                                   name="password2" placeholder="Enter your password again"/>
+                                        </div>
+                                        <span class="text-error">{{ form.password2.errors }}</span>
+                                        <div class="text-center mt-3">
+                                            <button type="submit" name="register" class="btn btn-lg btn-primary">
+                                                Register
+                                            </button>
+                                        </div>
+                                    </form>
+                                    <br/>
+                                    <div class="text-center">
+                                        <p class="mb-0 text-muted">
+                                            Already have an account? <router-link to="/login">Login</router-link>
+                                        </p>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </main>
+</template>
+
+<script>
+export default {
+    name: 'Register',
+    data() {
+        return {
+            msg: 'Register',
+            form: {
+                username: '',
+                email: '',
+                password1: '',
+                password2: '',}
+        }
+    }
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/src/views/Settings.vue b/frontend/src/views/Settings.vue
new file mode 100644
index 0000000..d143c7e
--- /dev/null
+++ b/frontend/src/views/Settings.vue
@@ -0,0 +1,209 @@
+<template>
+    <BaseLayout>
+        <main class="content">
+            <div class="container-fluid p-0">
+
+                <h1 class="h3 mb-3">Settings</h1>
+
+                <div class="row">
+                    <div class="col-md-3 col-xl-2">
+
+                        <div class="card">
+                            <div class="card-header">
+                                <h5 class="card-title mb-0">Profile Settings</h5>
+                            </div>
+
+                            <div class="list-group list-group-flush" role="tablist">
+                                <a class="list-group-item list-group-item-action active" data-toggle="list"
+                                   href="#account" role="tab">
+                                    Account
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list"
+                                   href="#password" role="tab">
+                                    Password
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Privacy and safety
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Email notifications
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Web notifications
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Widgets
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Your data
+                                </a>
+                                <a class="list-group-item list-group-item-action" data-toggle="list" href="#"
+                                   role="tab">
+                                    Delete account
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="col-md-9 col-xl-10">
+                        <div class="tab-content">
+                            <div class="tab-pane fade show active" id="account" role="tabpanel">
+
+                                <div class="card">
+                                    <div class="card-header">
+
+                                        <h5 class="card-title mb-0">Public info</h5>
+                                    </div>
+                                    <div class="card-body">
+                                        <form>
+                                            <div class="row">
+                                                <div class="col-md-8">
+                                                    <div class="mb-3">
+                                                        <label class="form-label"
+                                                               for="inputUsername">Username</label>
+                                                        <input type="text" class="form-control" id="inputUsername"
+                                                               placeholder="Username">
+                                                    </div>
+                                                    <div class="mb-3">
+                                                        <label class="form-label"
+                                                               for="inputUsername">Biography</label>
+                                                        <textarea rows="2" class="form-control" id="inputBio"
+                                                                  placeholder="Tell something about yourself"></textarea>
+                                                    </div>
+                                                </div>
+                                                <div class="col-md-4">
+                                                    <div class="text-center">
+                                                        <img alt="Charles Hall"
+                                                             src="/static/assets/img/avatars/avatar.png"
+                                                             class="rounded-circle img-responsive mt-2" width="128"
+                                                             height="128"/>
+                                                        <div class="mt-2">
+                                                                <span class="btn btn-primary"><i
+                                                                        class="fas fa-upload"></i> Upload</span>
+                                                        </div>
+                                                        <small>For best results, use an image at least 128px by
+                                                            128px in .jpg format</small>
+                                                    </div>
+                                                </div>
+                                            </div>
+
+                                            <button type="submit" class="btn btn-primary">Save changes</button>
+                                        </form>
+
+                                    </div>
+                                </div>
+
+                                <div class="card">
+                                    <div class="card-header">
+
+                                        <h5 class="card-title mb-0">Private info</h5>
+                                    </div>
+                                    <div class="card-body">
+                                        <form>
+                                            <div class="row">
+                                                <div class="mb-3 col-md-6">
+                                                    <label class="form-label" for="inputFirstName">First
+                                                        name</label>
+                                                    <input type="text" class="form-control" id="inputFirstName"
+                                                           placeholder="First name">
+                                                </div>
+                                                <div class="mb-3 col-md-6">
+                                                    <label class="form-label" for="inputLastName">Last name</label>
+                                                    <input type="text" class="form-control" id="inputLastName"
+                                                           placeholder="Last name">
+                                                </div>
+                                            </div>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputEmail4">Email</label>
+                                                <input type="email" class="form-control" id="inputEmail4"
+                                                       placeholder="Email">
+                                            </div>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputAddress">Address</label>
+                                                <input type="text" class="form-control" id="inputAddress"
+                                                       placeholder="1234 Main St">
+                                            </div>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputAddress2">Address 2</label>
+                                                <input type="text" class="form-control" id="inputAddress2"
+                                                       placeholder="Apartment, studio, or floor">
+                                            </div>
+                                            <div class="row">
+                                                <div class="mb-3 col-md-6">
+                                                    <label class="form-label" for="inputCity">City</label>
+                                                    <input type="text" class="form-control" id="inputCity">
+                                                </div>
+                                                <div class="mb-3 col-md-4">
+                                                    <label class="form-label" for="inputState">State</label>
+                                                    <select id="inputState" class="form-control">
+                                                        <option selected>Choose...</option>
+                                                        <option>...</option>
+                                                    </select>
+                                                </div>
+                                                <div class="mb-3 col-md-2">
+                                                    <label class="form-label" for="inputZip">Zip</label>
+                                                    <input type="text" class="form-control" id="inputZip">
+                                                </div>
+                                            </div>
+                                            <button type="submit" class="btn btn-primary">Save changes</button>
+                                        </form>
+
+                                    </div>
+                                </div>
+
+                            </div>
+                            <div class="tab-pane fade" id="password" role="tabpanel">
+                                <div class="card">
+                                    <div class="card-body">
+                                        <h5 class="card-title">Password</h5>
+
+                                        <form>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputPasswordCurrent">Current
+                                                    password</label>
+                                                <input type="password" class="form-control"
+                                                       id="inputPasswordCurrent">
+                                                <small><a href="#">Forgot your password?</a></small>
+                                            </div>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputPasswordNew">New
+                                                    password</label>
+                                                <input type="password" class="form-control" id="inputPasswordNew">
+                                            </div>
+                                            <div class="mb-3">
+                                                <label class="form-label" for="inputPasswordNew2">Verify
+                                                    password</label>
+                                                <input type="password" class="form-control" id="inputPasswordNew2">
+                                            </div>
+                                            <button type="submit" class="btn btn-primary">Save changes</button>
+                                        </form>
+
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+        </main>
+    </BaseLayout>
+</template>
+
+<script>
+import BaseLayout from "@/components/BaseLayout.vue";
+
+export default {
+    name: 'Settings',
+    components: {BaseLayout},
+}
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
new file mode 100644
index 0000000..40c16c4
--- /dev/null
+++ b/frontend/vite.config.js
@@ -0,0 +1,28 @@
+import {fileURLToPath, URL} from 'node:url'
+
+import {defineConfig} from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+    plugins: [vue()],
+    resolve: {
+        alias: {
+            '@': fileURLToPath(new URL('./src', import.meta.url))
+        }
+    },
+    server: {
+        host: true,
+        cors: true,
+        headers: {
+            //allow all origins
+            //'Access-Control-Allow-Origin': 'http://10.23.42.128:8000, http://10.23.42.168:8000',
+            'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
+            'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token, Authorization, Accept,charset,boundary,Content-Length',
+            'Access-Control-Allow-Credentials': 'true'
+
+
+
+        }
+    }
+})