From e89c261f566f05ab4347f60dfd68b01303ad93ec Mon Sep 17 00:00:00 2001
From: jedi <git@m.j3d1.de>
Date: Wed, 10 May 2023 23:28:55 +0200
Subject: [PATCH] stash

---
 frontend/README.md               |  29 ++++
 frontend/src/App.vue             |  12 +-
 frontend/src/dns.js              |   2 +
 frontend/src/store.js            |   9 ++
 frontend/src/views/Dashboard.vue |  11 +-
 frontend/src/views/Inventory.vue |  27 +++-
 frontend/src/views/Profile.vue   | 257 +++++++++++++++++++++++++++++++
 frontend/src/views/Settings.vue  | 209 +++++++++++++++++++++++++
 frontend/vite.config.js          |   1 +
 9 files changed, 550 insertions(+), 7 deletions(-)
 create mode 100644 frontend/README.md
 create mode 100644 frontend/src/views/Profile.vue
 create mode 100644 frontend/src/views/Settings.vue

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/src/App.vue b/frontend/src/App.vue
index a7280b7..54ad06d 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -3,13 +3,23 @@
 
 <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'
+    name: 'App',
+    methods: {
+        ...mapMutations(['init'])
+    },
+    beforeCreate () {
+        store.commit('init')
+    }
 }
 </script>
 
diff --git a/frontend/src/dns.js b/frontend/src/dns.js
index 9446ccb..d3f2a8f 100644
--- a/frontend/src/dns.js
+++ b/frontend/src/dns.js
@@ -35,6 +35,7 @@ class FallBackResolver {
         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(
@@ -47,6 +48,7 @@ class FallBackResolver {
         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];
     }
 }
diff --git a/frontend/src/store.js b/frontend/src/store.js
index 0cadaff..dff2ce7 100644
--- a/frontend/src/store.js
+++ b/frontend/src/store.js
@@ -98,7 +98,9 @@ export default createStore({
                 this.commit('setToken', token);
                 if (keypair) {
                     this.commit('setKey', keypair)
+                } else {
                 }
+                router.push('/');
             }
             state.cache_loaded = true;
         }
@@ -118,9 +120,16 @@ export default createStore({
             } else {
                 return false;
             }
+
         },
         async lookupServer({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(
diff --git a/frontend/src/views/Dashboard.vue b/frontend/src/views/Dashboard.vue
index 6c19b16..1f23884 100644
--- a/frontend/src/views/Dashboard.vue
+++ b/frontend/src/views/Dashboard.vue
@@ -5,7 +5,16 @@
                 <h1 class="h3 mb-3">Dashboard</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>
diff --git a/frontend/src/views/Inventory.vue b/frontend/src/views/Inventory.vue
index 8687fa6..350ed44 100644
--- a/frontend/src/views/Inventory.vue
+++ b/frontend/src/views/Inventory.vue
@@ -2,6 +2,7 @@
     <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">
@@ -28,6 +29,7 @@
                                     <td>
                                         <router-link :to="`/inventory/${item.id}`">{{ item.name }}</router-link>
                                     </td>
+                                    <td>{{ item.owner }}</td>
                                     <td class="d-none d-md-table-cell">
                                         <span class="badge bg-secondary text-white">{{ item.availability_policy }}</span>
                                     </td>
@@ -75,7 +77,7 @@
 
                         </div>
                         <div class="card">
-                            <button class="btn" @click="fetchInventoryItems">Refresh</button>
+                            <button class="btn" @click="getInventoryItems">Refresh</button>
                             <router-link to="/inventory/new" class="btn btn-primary">Add</router-link>
                         </div>
                     </div>
@@ -102,14 +104,29 @@ export default {
         ...BIcons
     },
     computed: {
-        ...mapGetters(["inventory_items", "loaded_items"]),
-        ...mapState(["user"]),
+        ...mapGetters(["inventory_items"]),
+        username() {
+            return this.$route.params.username
+        }
     },
     methods: {
-        ...mapActions(["fetchInventoryItems", "deleteInventoryItem"]),
+        ...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.fetchInventoryItems()
+        await this.getInventoryItems()
     }
 }
 </script>
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/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
index c199937..ed6b2f1 100644
--- a/frontend/vite.config.js
+++ b/frontend/vite.config.js
@@ -3,6 +3,7 @@ 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: {