From ad060f206cceb9fe0453eab2cc0bb7f55b0949cb Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 10:59:16 +0200
Subject: [PATCH 1/7] refac: component-ize creating household

---
 src/components/CreateHouseholdComponent.vue | 51 ++++++++++++++
 src/components/RegisterComponent.vue        | 73 +++++++++------------
 src/components/SideNavBar.vue               |  6 ++
 src/router/index.ts                         |  2 +-
 src/views/RegisterView.vue                  | 49 +++++++-------
 5 files changed, 115 insertions(+), 66 deletions(-)
 create mode 100644 src/components/CreateHouseholdComponent.vue

diff --git a/src/components/CreateHouseholdComponent.vue b/src/components/CreateHouseholdComponent.vue
new file mode 100644
index 0000000..cb1a61c
--- /dev/null
+++ b/src/components/CreateHouseholdComponent.vue
@@ -0,0 +1,51 @@
+<template>
+  <h2>Lag husholdning</h2>
+  <el-form :model="householdName" ref="ruleFormRef" label-position="top" status-icon>
+    <el-form-item label="Navn på husholdning" prop="houseHoldName">
+      <el-input v-model="householdName" placeholder="husholdning"></el-input>
+    </el-form-item>
+    <el-row>
+      <div class="spacer"></div>
+      <el-link @click="skipCreateHousehold">Jeg ønsker ikke å lage husholdning</el-link>
+    </el-row>
+    <el-form-item>
+      <el-button @click="createHousehold" type="primary">Lag husholdning</el-button>
+    </el-form-item>
+  </el-form>
+</template>
+<script setup lang="ts">
+import { computed, ref } from "vue";
+import type { FormInstance } from "element-plus";
+
+const props = defineProps<{
+  householdName: string;
+}>();
+const ruleFormRef = ref<FormInstance>();
+
+const emit = defineEmits<{
+  "update:householdName": (householdName: string) => void;
+  skip: () => void;
+  submit: () => void;
+}>();
+
+const householdName = computed({
+  get: () => props.householdName,
+  set: (value) => emit("update:householdName", value),
+});
+
+const validationRules = ref({
+  householdName: [{ required: true, message: "Husholdningens navn er påkrevd", trigger: "blur" }],
+});
+
+function skipCreateHousehold() {
+  emit("skip");
+}
+
+function createHousehold() {
+  ruleFormRef.value.validate((valid) => {
+    if (valid) {
+      emit("submit");
+    }
+  });
+}
+</script>
diff --git a/src/components/RegisterComponent.vue b/src/components/RegisterComponent.vue
index fa65ee8..90ddfb8 100644
--- a/src/components/RegisterComponent.vue
+++ b/src/components/RegisterComponent.vue
@@ -1,42 +1,39 @@
 <template>
-  <el-card class="container">
-    <h2 class="my-3">Registrer deg</h2>
+  <h2 class="my-3">Registrer deg</h2>
+  <el-form
+    ref="ruleFormRef"
+    label-position="top"
+    :model="newUser"
+    :rules="validationRules"
+    status-icon
+  >
+    <el-form-item label="Email" prop="email">
+      <el-input placeholder="Email" type="text" v-model="email" size="large" />
+    </el-form-item>
 
-    <el-form
-      ref="ruleFormRef"
-      label-position="top"
-      :model="newUser"
-      :rules="validationRules"
-      status-icon
-    >
-      <el-form-item label="Email" prop="email">
-        <el-input placeholder="Email" type="text" v-model="email" size="large" />
-      </el-form-item>
+    <el-form-item label="Fornavn" prop="firstName">
+      <el-input placeholder="fornavn" type="text" v-model="firstName" size="large" />
+    </el-form-item>
 
-      <el-form-item label="Fornavn" prop="firstName">
-        <el-input placeholder="fornavn" type="text" v-model="firstName" size="large" />
-      </el-form-item>
+    <el-form-item label="Passord" prop="password">
+      <el-input type="password" v-model="password" placeholder="Password" size="large" />
+    </el-form-item>
 
-      <el-form-item label="Passord" prop="password">
-        <el-input type="password" v-model="password" placeholder="Password" size="large" />
-      </el-form-item>
+    <el-form-item label="Gjenta passord" prop="passwordConfirm">
+      <el-input type="password" v-model="passwordConfirm" placeholder="Password" size="large" />
+    </el-form-item>
 
-      <el-form-item label="Gjenta passord" prop="passwordConfirm">
-        <el-input type="password" v-model="passwordConfirm" placeholder="Password" size="large" />
-      </el-form-item>
-
-      <el-button ref="submitButton" type="primary" size="large" @click="submit"
-        >Registrer deg
-      </el-button>
-    </el-form>
-    <el-alert
-      type="error"
-      show-icon
-      :title="errorMessage"
-      v-if="errorMessage"
-      style="margin-top: 1rem"
-    />
-  </el-card>
+    <el-button ref="submitButton" type="primary" size="large" @click="submit"
+      >Registrer deg
+    </el-button>
+  </el-form>
+  <el-alert
+    type="error"
+    show-icon
+    :title="errorMessage"
+    v-if="errorMessage"
+    style="margin-top: 1rem"
+  />
 </template>
 <script setup lang="ts">
 import type { CreateUser } from "@/services";
@@ -122,10 +119,4 @@ function submit() {
   });
 }
 </script>
-<style scoped>
-.container {
-  width: 90%;
-  margin: 10vh auto;
-  max-width: 500px;
-}
-</style>
+<style scoped></style>
diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index afbc667..b0f6ae8 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -19,6 +19,12 @@
         :label="item.name"
         :value="item.id"
       ></el-option>
+      <el-button style="width: 100%" type="primary">
+        <el-icon>
+          <HomeFilled />
+        </el-icon>
+        <span>Legg til husholdning</span>
+      </el-button>
     </el-select>
     <el-menu-item index="/shopping-list">
       <el-icon>
diff --git a/src/router/index.ts b/src/router/index.ts
index d28271c..1876a8c 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -4,7 +4,7 @@ import NotFoundView from "../views/NotFoundView.vue";
 import { useSessionStore } from "@/stores/session";
 import { AccountApi } from "@/services/index";
 
-let startup = true;
+const startup = true;
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
   routes: [
diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue
index 03e3bf6..7e8c65f 100644
--- a/src/views/RegisterView.vue
+++ b/src/views/RegisterView.vue
@@ -8,30 +8,23 @@
     <el-step title="Lag bruker"></el-step>
     <el-step title="Lag husholdning"></el-step>
   </el-steps>
-  <RegisterComponent
-    v-model:email="user.email"
-    v-model:first-name="user.firstName"
-    v-model:password="user.password"
-    @submit="submit"
-    :error-message="errorMessage"
-    v-if="active == 0"
-  >
-  </RegisterComponent>
-  <el-form v-if="active == 1" label-position="top">
-    <el-card style="max-width: 500px; width: 100%; margin: auto 10rem">
-      <h2>Lag husholdning</h2>
-      <el-form-item label="Navn på husholdning">
-        <el-input v-model="household.name" placeholder="husholdning"></el-input>
-      </el-form-item>
-      <el-row>
-        <div class="spacer"></div>
-        <el-link @click="skipCreateHousehold">Jeg ønsker ikke å lage husholdning</el-link>
-      </el-row>
-      <el-form-item>
-        <el-button @click="createHousehold" type="primary">Lag husholdning</el-button>
-      </el-form-item>
-    </el-card>
-  </el-form>
+  <el-card class="container">
+    <RegisterComponent
+      v-model:email="user.email"
+      v-model:first-name="user.firstName"
+      v-model:password="user.password"
+      @submit="submit"
+      :error-message="errorMessage"
+      v-if="active == 0"
+    >
+    </RegisterComponent>
+    <CreateHouseholdComponent
+      v-model:household-name="household.name"
+      @submit="createHousehold"
+      @skip="skipCreateHousehold"
+      v-if="active == 1"
+    ></CreateHouseholdComponent>
+  </el-card>
 </template>
 <script setup lang="ts">
 import { reactive, ref } from "vue";
@@ -42,6 +35,7 @@ import { useSessionStore } from "@/stores/session";
 import router from "@/router";
 import { showError } from "@/utils/error-utils";
 import { useHouseholdStore } from "@/stores/household";
+import CreateHouseholdComponent from "@/components/CreateHouseholdComponent.vue";
 
 const user = reactive({
   email: "",
@@ -109,3 +103,10 @@ function createHousehold() {
     });
 }
 </script>
+<style>
+.container {
+  width: 90%;
+  margin: 10vh auto;
+  max-width: 500px;
+}
+</style>
-- 
GitLab


From e8dc7e5e8a5d71e81e2e588785e4c8f1c7a02224 Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 11:17:18 +0200
Subject: [PATCH 2/7] chore: run formatter

---
 src/components/SideNavBar.vue | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index b0f6ae8..5632ff7 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -19,7 +19,7 @@
         :label="item.name"
         :value="item.id"
       ></el-option>
-      <el-button style="width: 100%" type="primary">
+      <el-button style="width: 100%" type="primary" @click="isCreateHousehold = true">
         <el-icon>
           <HomeFilled />
         </el-icon>
@@ -57,6 +57,13 @@
       <span>Rediger husholdning</span>
     </el-menu-item>
   </el-menu>
+  <el-dialog v-model="isCreateHousehold" show-close>
+    <CreateHouseholdComponent
+      v-model:household-name="newHousehold.name"
+      @submit="createHousehold"
+      @skip="skipCreateHousehold"
+    ></CreateHouseholdComponent>
+  </el-dialog>
 </template>
 
 <script lang="ts" setup>
@@ -64,8 +71,10 @@ import router from "@/router";
 import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue";
 import { getCurrentInstance, onMounted, ref } from "vue";
 import { useHouseholdStore } from "@/stores/household";
-import { Household, HouseholdApi } from "@/services/index";
+import { CreateHousehold, Household, HouseholdApi } from "@/services/index";
 import { useSessionStore } from "@/stores/session";
+import CreateHouseholdComponent from "@/components/CreateHouseholdComponent.vue";
+import { showError } from "@/utils/error-utils";
 
 const defaultActive = ref("/");
 onMounted(async () => {
@@ -84,9 +93,13 @@ const handleClose = (key: string, keyPath: string[]) => {
 const houseHoldStore = useHouseholdStore();
 const houseHoldApi = new HouseholdApi();
 const sessionStore = useSessionStore();
+const isCreateHousehold = ref(false);
 
 const households = ref([]);
 const household = ref(houseHoldStore.getHousehold());
+const newHousehold = ref({
+  name: "",
+} as CreateHousehold);
 const emit = defineEmits<{
   (event: "select", ...args: any[]): void;
 }>();
@@ -105,4 +118,21 @@ function setHouseHold(val: Household) {
   const root = getCurrentInstance();
   root?.emit("household-changed", val);
 }
+
+function createHousehold() {
+  houseHoldApi
+    .createHousehold(newHousehold.value)
+    .then((res) => {
+      households.value.push(res.data);
+      setHouseHold(res.data);
+      isCreateHousehold.value = false;
+    })
+    .catch(() => {
+      showError("En uventet feil oppstod", "vennligst prøv igjen senere", 0);
+    });
+}
+
+function skipCreateHousehold() {
+  isCreateHousehold.value = false;
+}
 </script>
-- 
GitLab


From a6d2d47a8b1e8a1186a6acbc63903c8676ee0e3b Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 12:32:16 +0200
Subject: [PATCH 3/7] refac: use computed on household instead of getters and
 setters

---
 src/components/SideNavBar.vue  | 11 +++++------
 src/stores/household.ts        | 25 +++++++++++++++----------
 src/views/InventoryView.vue    |  5 ++---
 src/views/LoginView.vue        |  2 +-
 src/views/ShoppingListView.vue |  2 +-
 5 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index 5632ff7..c21462c 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -96,7 +96,7 @@ const sessionStore = useSessionStore();
 const isCreateHousehold = ref(false);
 
 const households = ref([]);
-const household = ref(houseHoldStore.getHousehold());
+const household = houseHoldStore.household;
 const newHousehold = ref({
   name: "",
 } as CreateHousehold);
@@ -107,16 +107,15 @@ const emit = defineEmits<{
 houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
   households.value = res.data;
   console.log(res.data);
-  if (household.value == null) {
-    houseHoldStore.setHousehold(res.data[0]);
+  if (household == null) {
     household.value = res.data[0];
   }
 });
 
 function setHouseHold(val: Household) {
-  houseHoldStore.setHousehold(val);
-  const root = getCurrentInstance();
-  root?.emit("household-changed", val);
+  console.log("setting household" + val);
+  household.value = val;
+  console.log(houseHoldStore.household);
 }
 
 function createHousehold() {
diff --git a/src/stores/household.ts b/src/stores/household.ts
index 830472b..5dabce6 100644
--- a/src/stores/household.ts
+++ b/src/stores/household.ts
@@ -1,18 +1,23 @@
-import { ref } from "vue";
+import { computed, ref } from "vue";
 import { defineStore } from "pinia";
 
 import type { Household } from "@/services/index";
 
 export const useHouseholdStore = defineStore("household", () => {
-  const household = ref<Household | null>(null);
+  const householdValue = ref({} as Household);
 
-  function getHousehold() {
-    return household.value;
-  }
+  const household = computed({
+    get: () => {
+      if (!householdValue.value?.id) {
+        householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}");
+      }
+      return householdValue.value;
+    },
+    set: (val) => {
+      householdValue.value = val;
+      sessionStorage.setItem("household", JSON.stringify(val));
+    },
+  });
 
-  function setHousehold(newHousehold: Household) {
-    household.value = newHousehold;
-  }
-
-  return { getHousehold, setHousehold };
+  return { household };
 });
diff --git a/src/views/InventoryView.vue b/src/views/InventoryView.vue
index 7a0b31b..7dc64c6 100644
--- a/src/views/InventoryView.vue
+++ b/src/views/InventoryView.vue
@@ -85,7 +85,7 @@ const isLoading = computed(() => items.value === null && error.value === null);
 
 // Define callbacks
 function deleteItem(item: Item) {
-  let householdId = householdStore.getHousehold()?.id;
+  let householdId = householdStore.household.id;
   if (!householdId) {
     console.error(`Could not delete item ${item.type?.name}. No household id was selected.`);
     showError("Ingen hjem valgt.", "Velg et hjem for å slette et element.", 15000);
@@ -160,10 +160,9 @@ function removeItemClientSide(item: Item) {
 }
 
 function getHouseholdId(): number | null {
-  let householdId = householdStore.getHousehold()?.id;
+  let householdId = householdStore.household?.id;
 
   if (!householdId) {
-    console.error("No household id was selected. Can not fetch inventory items.");
     error.value = new Error("No household id was selected. Can not fetch inventory items.");
     showError("Ingen hjem valgt.", "Velg et hjem for å se inventaret til hjemmet.", 15000);
     return null;
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index 5fcd9fc..aa95038 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -85,7 +85,7 @@ function signIn() {
         .getHouseholds(data.id!)
         .then((response) => response.data)
         .then((households) => {
-          householdStore.setHousehold(households[0]);
+          householdStore.household = households[0];
           router.push({ name: "inventory" });
         });
     })
diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue
index be5890f..9da0628 100644
--- a/src/views/ShoppingListView.vue
+++ b/src/views/ShoppingListView.vue
@@ -191,7 +191,7 @@ const itemTypesApi = new ItemTypeApi();
 
 const houseHoldStore = useHouseholdStore();
 
-const householdId = houseHoldStore.getHousehold().id;
+const householdId = houseHoldStore.household.id;
 const itemTypeAutocomplete = ref(null as any);
 const loading = ref(undefined) as Ref<undefined | boolean>;
 const loadingSubmit = ref(false);
-- 
GitLab


From 8979c453244a4e97a96040a442163ce2e762b508 Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 13:08:29 +0200
Subject: [PATCH 4/7] fix: side nav picker not working

---
 src/components/SideNavBar.vue  | 25 ++++---------------------
 src/views/HouseholdView.vue    |  2 +-
 src/views/ShoppingListView.vue |  4 +---
 3 files changed, 6 insertions(+), 25 deletions(-)

diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index c21462c..12aea0d 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -1,23 +1,16 @@
 <template>
-  <el-menu
-    :default-active="defaultActive"
-    @open="handleOpen"
-    @close="handleClose"
-    router
-    @select="$emit('select')"
-  >
+  <el-menu :default-active="defaultActive" @open="handleOpen" @close="handleClose" router>
     <el-select
       style="width: calc(100% - 2rem); margin: 1rem"
-      :placeholder="household.name"
-      @change="setHouseHold(household)"
-      v-model="household"
+      :model-value="houseHoldStore.household.name"
       v-if="household"
     >
       <el-option
         v-for="item in households"
         :key="item.id"
         :label="item.name"
-        :value="item.id"
+        @click="houseHoldStore.household = item"
+        :value="item"
       ></el-option>
       <el-button style="width: 100%" type="primary" @click="isCreateHousehold = true">
         <el-icon>
@@ -100,9 +93,6 @@ const household = houseHoldStore.household;
 const newHousehold = ref({
   name: "",
 } as CreateHousehold);
-const emit = defineEmits<{
-  (event: "select", ...args: any[]): void;
-}>();
 
 houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
   households.value = res.data;
@@ -112,18 +102,11 @@ houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
   }
 });
 
-function setHouseHold(val: Household) {
-  console.log("setting household" + val);
-  household.value = val;
-  console.log(houseHoldStore.household);
-}
-
 function createHousehold() {
   houseHoldApi
     .createHousehold(newHousehold.value)
     .then((res) => {
       households.value.push(res.data);
-      setHouseHold(res.data);
       isCreateHousehold.value = false;
     })
     .catch(() => {
diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue
index f980615..b94f211 100644
--- a/src/views/HouseholdView.vue
+++ b/src/views/HouseholdView.vue
@@ -45,7 +45,7 @@ const householdApi = new HouseholdApi();
 const accountApi = new AccountApi();
 
 let users = ref([]);
-const currentHousehold = householdStore.getHousehold();
+const currentHousehold = householdStore.household;
 
 householdApi.getUsers(currentHousehold?.id!).then((data) => {
   users.value = data.data;
diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue
index 9da0628..c6276a8 100644
--- a/src/views/ShoppingListView.vue
+++ b/src/views/ShoppingListView.vue
@@ -314,9 +314,7 @@ async function declineAllSuggestions() {
 
 function completeShopping() {
   shoppingListApi
-    .markItemsAsBought(householdId, {
-      listEntryIds: Array.from(boughtItems.value.values()).map((item) => item.id),
-    } as ShoppinglistBuyBody)
+    .markItemsAsBought()
     .then(() => {
       ElNotification({
         message: "Handleturen er avsluttet. Du finner de kjøpte varene i vareoversikten!",
-- 
GitLab


From 81a5a81f034f9bab7a5ed7626d16275da2f1d63a Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 14:08:59 +0200
Subject: [PATCH 5/7] fix: bug on navbar, and show create household button when
 no households

---
 src/components/SideNavBar.vue | 28 ++++++++++++++++++++--------
 src/stores/household.ts       | 11 +++++++++--
 src/views/LoginView.vue       |  5 ++++-
 src/views/RegisterView.vue    |  2 +-
 4 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index 12aea0d..3f267a4 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -3,7 +3,7 @@
     <el-select
       style="width: calc(100% - 2rem); margin: 1rem"
       :model-value="houseHoldStore.household.name"
-      v-if="household"
+      v-if="households?.length > 0"
     >
       <el-option
         v-for="item in households"
@@ -19,6 +19,18 @@
         <span>Legg til husholdning</span>
       </el-button>
     </el-select>
+    <el-button
+      style="width: calc(100% - 2rem); margin: 1rem"
+      type="primary"
+      @click="isCreateHousehold = true"
+      v-else-if="households?.length === 0"
+    >
+      <el-icon>
+        <HomeFilled />
+      </el-icon>
+      <span>Legg til husholdning</span>
+    </el-button>
+
     <el-menu-item index="/shopping-list">
       <el-icon>
         <List />
@@ -62,7 +74,7 @@
 <script lang="ts" setup>
 import router from "@/router";
 import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue";
-import { getCurrentInstance, onMounted, ref } from "vue";
+import { onMounted, ref } from "vue";
 import { useHouseholdStore } from "@/stores/household";
 import { CreateHousehold, Household, HouseholdApi } from "@/services/index";
 import { useSessionStore } from "@/stores/session";
@@ -88,26 +100,26 @@ const houseHoldApi = new HouseholdApi();
 const sessionStore = useSessionStore();
 const isCreateHousehold = ref(false);
 
-const households = ref([]);
-const household = houseHoldStore.household;
+const households = ref(null as Household[] | null);
 const newHousehold = ref({
   name: "",
 } as CreateHousehold);
 
 houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
-  households.value = res.data;
   console.log(res.data);
-  if (household == null) {
-    household.value = res.data[0];
-  }
+  households.value = res.data;
 });
 
 function createHousehold() {
   houseHoldApi
     .createHousehold(newHousehold.value)
     .then((res) => {
+      if (households.value === null) {
+        households.value = [];
+      }
       households.value.push(res.data);
       isCreateHousehold.value = false;
+      houseHoldStore.household = res.data;
     })
     .catch(() => {
       showError("En uventet feil oppstod", "vennligst prøv igjen senere", 0);
diff --git a/src/stores/household.ts b/src/stores/household.ts
index 5dabce6..59289d3 100644
--- a/src/stores/household.ts
+++ b/src/stores/household.ts
@@ -9,7 +9,9 @@ export const useHouseholdStore = defineStore("household", () => {
   const household = computed({
     get: () => {
       if (!householdValue.value?.id) {
-        householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}");
+        if (sessionStorage.getItem("household")) {
+          householdValue.value = JSON.parse(sessionStorage.getItem("household") || "{}");
+        }
       }
       return householdValue.value;
     },
@@ -19,5 +21,10 @@ export const useHouseholdStore = defineStore("household", () => {
     },
   });
 
-  return { household };
+  function removeHousehold() {
+    household.value = {} as Household;
+    sessionStorage.removeItem("household");
+  }
+
+  return { household, removeHousehold };
 });
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index aa95038..3c67ce2 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -85,7 +85,10 @@ function signIn() {
         .getHouseholds(data.id!)
         .then((response) => response.data)
         .then((households) => {
-          householdStore.household = households[0];
+          console.log(households);
+          if (households?.length > 0) {
+            householdStore.household = households[0];
+          }
           router.push({ name: "inventory" });
         });
     })
diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue
index 7e8c65f..fa0380f 100644
--- a/src/views/RegisterView.vue
+++ b/src/views/RegisterView.vue
@@ -87,7 +87,7 @@ function createHousehold() {
   householdApi
     .createHousehold(household)
     .then((data) => {
-      useHouseholdStore().setHousehold(data.data);
+      useHouseholdStore().household = data.data;
       next();
       router.push({ name: "inventory" });
     })
-- 
GitLab


From cd6eba61a5d49bc980e889f1bd4ad04867a59779 Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 14:23:09 +0200
Subject: [PATCH 6/7] fix: show create household button when there are no
 households

---
 src/components/SideNavBar.vue | 4 ++--
 src/views/HouseholdView.vue   | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index 3f267a4..c9bfa2f 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -3,7 +3,7 @@
     <el-select
       style="width: calc(100% - 2rem); margin: 1rem"
       :model-value="houseHoldStore.household.name"
-      v-if="households?.length > 0"
+      v-if="households?.length > 0 && houseHoldStore.household?.id"
     >
       <el-option
         v-for="item in households"
@@ -23,7 +23,7 @@
       style="width: calc(100% - 2rem); margin: 1rem"
       type="primary"
       @click="isCreateHousehold = true"
-      v-else-if="households?.length === 0"
+      v-else-if="households?.length === 0 || !houseHoldStore.household?.id"
     >
       <el-icon>
         <HomeFilled />
diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue
index b94f211..413c2dc 100644
--- a/src/views/HouseholdView.vue
+++ b/src/views/HouseholdView.vue
@@ -146,6 +146,7 @@ function deleteHousehold() {
     .then(() => {
       ElMessage.success("Slettet husholdning");
       console.log("deleted household: " + currentHousehold?.name);
+      householdStore.removeHousehold();
     })
     .catch((error) => {
       ElMessage.error("Kunne ikke slette husholdning" + error);
-- 
GitLab


From 6a65ec255f8a746dde7b4cd879f1f514d4ada04b Mon Sep 17 00:00:00 2001
From: Arunan Gnanasekaran <arunan2212@gmail.com>
Date: Wed, 26 Apr 2023 15:06:36 +0200
Subject: [PATCH 7/7] fix: global events when updating household

---
 package-lock.json              |  6 ++++
 package.json                   |  1 +
 src/components/SideNavBar.vue  | 53 ++++++++++++++++++----------------
 src/main.ts                    |  3 ++
 src/stores/household.ts        |  6 +++-
 src/views/HouseholdView.vue    | 26 +++++++++++------
 src/views/InventoryView.vue    |  7 ++++-
 src/views/ShoppingListView.vue | 49 ++++++++++++++++++-------------
 8 files changed, 95 insertions(+), 56 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index cc152e8..1f70eae 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
         "@vuelidate/core": "^2.0.2",
         "@vuelidate/validators": "^2.0.2",
         "element-plus": "^2.3.3",
+        "mitt": "^3.0.0",
         "pinia": "^2.0.32",
         "vue": "^3.2.47",
         "vue-router": "^4.1.6"
@@ -4950,6 +4951,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/mitt": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz",
+      "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ=="
+    },
     "node_modules/mlly": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.0.tgz",
diff --git a/package.json b/package.json
index 789b6e6..68acbf6 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
     "@vuelidate/core": "^2.0.2",
     "@vuelidate/validators": "^2.0.2",
     "element-plus": "^2.3.3",
+    "mitt": "^3.0.0",
     "pinia": "^2.0.32",
     "vue": "^3.2.47",
     "vue-router": "^4.1.6"
diff --git a/src/components/SideNavBar.vue b/src/components/SideNavBar.vue
index c9bfa2f..66ea298 100644
--- a/src/components/SideNavBar.vue
+++ b/src/components/SideNavBar.vue
@@ -1,9 +1,20 @@
 <template>
-  <el-menu :default-active="defaultActive" @open="handleOpen" @close="handleClose" router>
+  <el-menu :default-active="defaultActive" router>
+    <el-button
+      style="width: calc(100% - 2rem); margin: 1rem"
+      type="primary"
+      @click="isCreateHousehold = true"
+      v-if="households?.length == 0"
+    >
+      <el-icon>
+        <HomeFilled />
+      </el-icon>
+      <span>Legg til husholdning</span>
+    </el-button>
     <el-select
       style="width: calc(100% - 2rem); margin: 1rem"
       :model-value="houseHoldStore.household.name"
-      v-if="households?.length > 0 && houseHoldStore.household?.id"
+      v-else-if="households?.length > 0"
     >
       <el-option
         v-for="item in households"
@@ -19,17 +30,6 @@
         <span>Legg til husholdning</span>
       </el-button>
     </el-select>
-    <el-button
-      style="width: calc(100% - 2rem); margin: 1rem"
-      type="primary"
-      @click="isCreateHousehold = true"
-      v-else-if="households?.length === 0 || !houseHoldStore.household?.id"
-    >
-      <el-icon>
-        <HomeFilled />
-      </el-icon>
-      <span>Legg til husholdning</span>
-    </el-button>
 
     <el-menu-item index="/shopping-list">
       <el-icon>
@@ -74,7 +74,7 @@
 <script lang="ts" setup>
 import router from "@/router";
 import { DataAnalysis, Dish, HomeFilled, List, Management, Setting } from "@element-plus/icons-vue";
-import { onMounted, ref } from "vue";
+import { inject, onMounted, ref } from "vue";
 import { useHouseholdStore } from "@/stores/household";
 import { CreateHousehold, Household, HouseholdApi } from "@/services/index";
 import { useSessionStore } from "@/stores/session";
@@ -85,31 +85,34 @@ const defaultActive = ref("/");
 onMounted(async () => {
   await router.isReady();
   defaultActive.value = router.currentRoute.value.path;
-  console.log(defaultActive.value);
 });
 
-const handleOpen = (key: string, keyPath: string[]) => {
-  console.log(key, keyPath);
-};
-const handleClose = (key: string, keyPath: string[]) => {
-  console.log(key, keyPath);
-};
-
 const houseHoldStore = useHouseholdStore();
 const houseHoldApi = new HouseholdApi();
 const sessionStore = useSessionStore();
 const isCreateHousehold = ref(false);
+const emitter = inject("emitter");
 
 const households = ref(null as Household[] | null);
 const newHousehold = ref({
   name: "",
 } as CreateHousehold);
 
-houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
-  console.log(res.data);
-  households.value = res.data;
+emitter.on("household-removed", () => {
+  console.log("removing");
+  getHouseholds();
 });
 
+getHouseholds();
+function getHouseholds() {
+  houseHoldApi.getHouseholds(sessionStore.getUser()?.id!).then((res) => {
+    households.value = res.data;
+    if (households.value?.length > 0 && !houseHoldStore.household?.id) {
+      houseHoldStore.household = households.value[0];
+    }
+  });
+}
+
 function createHousehold() {
   houseHoldApi
     .createHousehold(newHousehold.value)
diff --git a/src/main.ts b/src/main.ts
index 8fa27d8..15ed4d1 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,5 +1,6 @@
 import { createApp } from "vue";
 import { createPinia } from "pinia";
+import mitt from "mitt";
 
 import App from "./App.vue";
 import router from "./router";
@@ -9,9 +10,11 @@ import "./assets/main.css";
 import "element-plus/dist/index.css";
 
 const app = createApp(App);
+const emitter = mitt();
 
 app.use(createPinia());
 app.use(router);
 app.use(ElementPlus);
 
+app.provide("emitter", emitter);
 app.mount("#app");
diff --git a/src/stores/household.ts b/src/stores/household.ts
index 59289d3..3b6c1b4 100644
--- a/src/stores/household.ts
+++ b/src/stores/household.ts
@@ -1,10 +1,11 @@
-import { computed, ref } from "vue";
+import { computed, inject, ref } from "vue";
 import { defineStore } from "pinia";
 
 import type { Household } from "@/services/index";
 
 export const useHouseholdStore = defineStore("household", () => {
   const householdValue = ref({} as Household);
+  const emitter = inject("emitter");
 
   const household = computed({
     get: () => {
@@ -18,12 +19,15 @@ export const useHouseholdStore = defineStore("household", () => {
     set: (val) => {
       householdValue.value = val;
       sessionStorage.setItem("household", JSON.stringify(val));
+      emitter.emit("household-updated");
     },
   });
 
   function removeHousehold() {
     household.value = {} as Household;
     sessionStorage.removeItem("household");
+    emitter.emit("household-removed");
+    emitter.emit("household-updated");
   }
 
   return { household, removeHousehold };
diff --git a/src/views/HouseholdView.vue b/src/views/HouseholdView.vue
index 413c2dc..f7ebf0f 100644
--- a/src/views/HouseholdView.vue
+++ b/src/views/HouseholdView.vue
@@ -1,8 +1,8 @@
 <template>
   <div id="householdview" class="householdview-wrapper">
-    <h1 v-if="currentHousehold?.id">{{ currentHousehold?.name }}</h1>
+    <h1 v-if="householdStore.household?.id">{{ householdStore.household?.name }}</h1>
     <h1 v-else>Velg husholdning i meny</h1>
-    <div class="top-bar" v-if="currentHousehold?.id">
+    <div class="top-bar" v-if="householdStore.household?.id">
       <HouseholdTopBar @delete-household="deleteHousehold()" @add-user="addUser" />
     </div>
     <div>
@@ -30,7 +30,7 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref } from "vue";
+import { inject, onMounted, ref } from "vue";
 import type { UserFull } from "@/services";
 import UserCard from "@/components/HouseholdCard.vue";
 import HouseholdTopBar from "@/components/HouseholdTopBar.vue";
@@ -45,12 +45,20 @@ const householdApi = new HouseholdApi();
 const accountApi = new AccountApi();
 
 let users = ref([]);
-const currentHousehold = householdStore.household;
+const emitter = inject("emitter");
 
-householdApi.getUsers(currentHousehold?.id!).then((data) => {
-  users.value = data.data;
+emitter.on("household-updated", () => {
+  getUsers();
 });
 
+getUsers();
+
+function getUsers() {
+  householdApi.getUsers(householdStore.household?.id!).then((data) => {
+    users.value = data.data;
+  });
+}
+
 function removeUser(user: UserFull) {
   return householdApi
     .removeUserFromHousehold(23, user.id!)
@@ -115,7 +123,7 @@ function addUser(value: string) {
     console.log(error);
   })
   return householdApi
-    .addUser(currentHousehold?.id!, { userId })
+    .addUser(householdStore.household?.id!, { userId })
     .then((data) => {
       ElMessage.success("La til " + value + " i husholdning");
       addUserLocally(userId);
@@ -142,10 +150,10 @@ function addUserLocally(id: number) {
 
 function deleteHousehold() {
   householdApi
-    .deleteHousehold(currentHousehold?.id!)
+    .deleteHousehold(householdStore.household?.id!)
     .then(() => {
       ElMessage.success("Slettet husholdning");
-      console.log("deleted household: " + currentHousehold?.name);
+      console.log("deleted household: " + householdStore.household?.name);
       householdStore.removeHousehold();
     })
     .catch((error) => {
diff --git a/src/views/InventoryView.vue b/src/views/InventoryView.vue
index 7dc64c6..98f1f19 100644
--- a/src/views/InventoryView.vue
+++ b/src/views/InventoryView.vue
@@ -51,7 +51,7 @@
 
 <script setup lang="ts">
 import axios from "axios";
-import { ref, computed } from "vue";
+import { ref, computed, inject } from "vue";
 import { ElDialog } from "element-plus";
 
 import type { Item, UpdateItem } from "@/services/index";
@@ -106,6 +106,11 @@ function useItemDialog(item: Item) {
   useItemDialogVisible.value = true;
 }
 
+const emitter = inject("emitter");
+
+emitter.on("household-updated", () => {
+  updateItems();
+});
 // Other script logic
 function useItem(item: Item, amount: number | null) {
   if (amount === null) {
diff --git a/src/views/ShoppingListView.vue b/src/views/ShoppingListView.vue
index c6276a8..acdd0a2 100644
--- a/src/views/ShoppingListView.vue
+++ b/src/views/ShoppingListView.vue
@@ -139,7 +139,7 @@ import type {
   ShoppingListEntry,
   UpdateShoppingListEntry,
 } from "@/services";
-import { Ref, ref } from "vue";
+import { inject, Ref, ref } from "vue";
 import { ElMessage, ElNotification, FormInstance } from "element-plus";
 import { ItemTypeApi, ShoppingListApi } from "@/services/index";
 import ShoppingListCardSkeleton from "@/components/ShoppingListCardSkeleton.vue";
@@ -197,26 +197,35 @@ const loading = ref(undefined) as Ref<undefined | boolean>;
 const loadingSubmit = ref(false);
 
 const timeout = setTimeout(() => (loading.value = true), 100);
-shoppingListApi
-  .getShoppingList(householdId)
-  .then((response) => {
-    activeItems.value.clear();
-    suggestedItems.value.clear();
-    boughtItems.value.clear();
-    response.data.forEach((item) => {
-      setItemLocal(item);
-    });
-  })
-  .catch((error) => {
-    ElMessage.error({
-      message: "Noe gikk galt ved henting av handleliste",
-      type: "error",
+const emitter = inject("emitter");
+
+emitter.on("household-updated", () => {
+  getShoppingList();
+});
+
+getShoppingList();
+function getShoppingList() {
+  shoppingListApi
+    .getShoppingList(houseHoldStore.household?.id)
+    .then((response) => {
+      activeItems.value.clear();
+      suggestedItems.value.clear();
+      boughtItems.value.clear();
+      response.data.forEach((item) => {
+        setItemLocal(item);
+      });
+    })
+    .catch((error) => {
+      ElMessage.error({
+        message: "Noe gikk galt ved henting av handleliste",
+        type: "error",
+      });
+    })
+    .finally(() => {
+      clearTimeout(timeout);
+      loading.value = false;
     });
-  })
-  .finally(() => {
-    clearTimeout(timeout);
-    loading.value = false;
-  });
+}
 
 async function searchItemType(queryString: string, cb: any) {
   const results = await itemTypesApi.searchItemTypes(queryString).then((response) => {
-- 
GitLab