diff --git a/src/components/HistoryBox.vue b/src/components/HistoryBox.vue
index 53d97059860c2faa7397fdee8ef2109664fbc117..f6df71f47c308d1da035a873783979f4af21f1ad 100644
--- a/src/components/HistoryBox.vue
+++ b/src/components/HistoryBox.vue
@@ -9,6 +9,7 @@ const props = defineProps({
   username: String,
   difficulty: String,
   score: Number,
+  date: String,
 });
 
 
@@ -17,7 +18,8 @@ const props = defineProps({
 <template>
   <div class="quiz-box">
     <div class="quiz-info">
-      <img src="/src/assets/trivio.svg" alt="Question picture">
+      <img v-if="image" :src="image" alt="trivio image">
+      <img v-else src="/src/assets/trivio.svg" alt="no picture found">
       <div class="quiz-text">
         <div class="quiz-title">{{title}}</div>
         <div class="difficulty">Difficulty: {{difficulty}}</div>
@@ -28,7 +30,7 @@ const props = defineProps({
       </div>
       <div class="right-side">
         <H1 class="score-text">Score: {{ score }}/{{ numberOfQuestion }}</H1>
-        <H3 class="date">Date: 04.03.24</h3>
+        <H3 class="date">{{date}}</h3>
       </div>
 
     </div>
diff --git a/src/components/TrivioQuestion.vue b/src/components/TrivioQuestion.vue
index 955800eae989d6d38d9d23a11d59ec23cf645c05..7c6ba8063b4c239cad0f511c7b24172e8339deaa 100644
--- a/src/components/TrivioQuestion.vue
+++ b/src/components/TrivioQuestion.vue
@@ -6,6 +6,7 @@ const props = defineProps<{
   index:number;
   questionId:number;
   question: questionData;
+  blobUrl: string;
 }>();
 
 const tokenStore = useTokenStore()
@@ -26,7 +27,7 @@ const answers = ref<Answer[]>(questionType.value === 'multiple'
   ]
 );
 const tags = ref<string[]>(props.question && props.question.tags ? [...props.question.tags] : []);
-
+const changed = ref(false)
 const media = ref( props.question? props.question.media || props.question.media: "")
 const blobUrl = ref("")
 
@@ -82,6 +83,7 @@ const handleFileUpload = async () => {
       const uploadedImage = await uploadPicture(file, tokenStore.jwtToken);
       const uploadedImageUrl = await getPicture(uploadedImage, tokenStore.jwtToken)
       media.value = uploadedImage;
+      changed.value = true
       blobUrl.value = uploadedImageUrl
       console.log('Uploaded picture URL:', uploadedImageUrl);
       console.log(uploadedImageUrl);
@@ -174,7 +176,8 @@ watch(media, saveQuestionData, {deep: true})
         <div class="image-box">
           <label>
             <input type="file" style="display: none" ref="fileInput" accept="image/png, image/jpeg" @change="handleFileUpload">
-            <img v-if="media" :src="blobUrl" alt="Uploaded Image" width="150px" height="150px">
+            <img v-if="media && !changed" :src="props.blobUrl" alt="Uploaded Image" width="150px" height="150px">
+            <img v-else-if="media && changed" :src="blobUrl" alt="Uploaded Image" width="150px" height="150px">
             <img v-else src="/src/components/icons/AddImage.png" alt="Add Image" width="50px" height="50px" @click="handleDefaultImageClick">
           </label>
         </div>
diff --git a/src/main.ts b/src/main.ts
index b7fc8e7a49dead55a6e4d5113cb531a3083dd189..1f28a364bf6d0b5fad1b0220dbe85303cbf6739b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,7 +1,7 @@
 import './assets/main.css'
 import piniaPluginPersistedState from "pinia-plugin-persistedstate"
 
-import { createApp } from 'vue'
+import {createApp, markRaw} from 'vue'
 import { createPinia } from 'pinia'
 
 import App from './App.vue'
@@ -10,6 +10,9 @@ import router from './router'
 const app = createApp(App)
 const pinia = createPinia();
 pinia.use(piniaPluginPersistedState)
+pinia.use(({ store }) => {
+    store.router = markRaw(router)
+})
 
 app.use(pinia)
 app.use(router)
diff --git a/src/stores/token.ts b/src/stores/token.ts
index cfb627e9aa591b2265cfdbea115a31a0d2eff34a..93dfa0da73faf028a621334998ceddf5bea2aa15 100644
--- a/src/stores/token.ts
+++ b/src/stores/token.ts
@@ -1,14 +1,19 @@
-import axios from "axios";
+  import axios from "axios";
 import { defineStore } from "pinia";
 import {getJWTToken} from "@/utils/httputils";
 import { jwtDecode } from "jwt-decode";
+  import router from "@/router";
+  import {useRouter} from "vue-router";
+  import {markRaw} from "vue";
 
-export const useTokenStore = defineStore({
+export const useTokenStore = defineStore( {
     id: 'token',
     state: () => ({
         jwtToken: "",
         loggedInUser: "",
-        password: ""
+        password: "",
+        tokenExpirationTimer: null as number | null,
+        router: markRaw(router), // Add Vue Router instance to the store
     }),
 
     persist: {
@@ -24,17 +29,54 @@ export const useTokenStore = defineStore({
                 this.jwtToken = ''
                 console.log(response.data)
                 const decoded = jwtDecode(response.data)
-                console.log(jwtDecode(response.data))
-                console.log(decoded.sub)
-                if(data != null && data !== '' && data !== undefined){
-                    this.jwtToken = data;
-                    this.loggedInUser = username
-                    this.password = password
+                if(data != null && data !== '' && data !== undefined && decoded !== undefined){
+                    const currentTime = Math.floor(Date.now() / 1000);
+                    const timeToExpiration = decoded.exp - currentTime
+                    if(timeToExpiration>0){
+                        this.jwtToken=data
+                        this.loggedInUser=username
+                        this.password=password
+                        this.refreshTokenExpirationTimer(timeToExpiration);
+                    }
                 }
-                console.log(this.loggedInUser)
+
+
             } catch (err){
                 console.log(err)
             }
-        }
+        },
+        async refreshToken(username: string, password:string) {
+            try {
+                // Make a request to the backend API to refresh the token
+                const response = await getJWTToken(username, password)
+                this.jwtToken = response.data
+                // Refresh the expiration timer with the new token's expiration time
+                const decoded = jwtDecode(this.jwtToken);
+                const currentTime = Math.floor(Date.now() / 1000);
+                const timeToExpiration = decoded.exp - currentTime;
+                this.refreshTokenExpirationTimer(timeToExpiration);
+            } catch (err) {
+                console.log(err);
+            }
+        },
+
+        refreshTokenExpirationTimer(timeToExpiration: number) {
+            // Clear existing timer if it exists
+            if (this.tokenExpirationTimer !== null) {
+                clearTimeout(this.tokenExpirationTimer);
+            }
+            // Start new timer to alert user when token is about to expire
+            this.tokenExpirationTimer = setTimeout(async () => {
+                if (confirm('Token is about to expire. Do you want to refresh?')) {
+                    console.log(this.tokenExpirationTimer)
+                    await this.refreshToken(this.loggedInUser, this.password);
+                    // window.location.reload();
+                } else {
+                    await router.push("/")
+                    console.log('Token expiration timer stopped.');
+                }     // Call token refresh method
+            }, timeToExpiration * 1000); // Convert seconds to milliseconds
+        },
+
     },
 });
diff --git a/src/utils/httputils.ts b/src/utils/httputils.ts
index 277bd1354f664fc717465ce9d3e360e4574d085d..9c5c85c07ca5fa77852811cf84cb7cfab0e634b0 100644
--- a/src/utils/httputils.ts
+++ b/src/utils/httputils.ts
@@ -340,3 +340,121 @@ export const getPicture = async (imageName: String, token: String) => {
         // Handle the error, display a message to the user, etc.
     }
 };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+export const createUser = async (username: string, password: string, email: string) => {
+    try {
+        const data= {
+            username: username,
+            password: password,
+            email: email
+        }
+
+        return await axios.post('http://localhost:8080/signup', data);
+    } catch (e) {
+        return "Failed to create user in backend"
+    }
+}
diff --git a/src/views/FrontPageView.vue b/src/views/FrontPageView.vue
index 4e86b6fadcb7702901253d31f554ac7b6e53f99e..22efae7d11c82bf1e79bc5111020a3ce707cf1f3 100644
--- a/src/views/FrontPageView.vue
+++ b/src/views/FrontPageView.vue
@@ -10,6 +10,7 @@ onMounted(() => {
   tokenStore.jwtToken = ''
   tokenStore.loggedInUser=''
   tokenStore.password=''
+  tokenStore.tokenExpirationTimer=null
 })
 </script>
 
diff --git a/src/views/frontpage/SignUpView.vue b/src/views/frontpage/SignUpView.vue
index 4ed434e33e72c9921d5eecc0bc6e29d1ab48aa3e..9ded0f165b8e1a9a737584cc8b25856d4b3e1b7b 100644
--- a/src/views/frontpage/SignUpView.vue
+++ b/src/views/frontpage/SignUpView.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="signup">
     <UserSchema buttonText="Create Account" header-text="Create Account" :status="loginStatus"
-      :customLogin="customLoginFunction"></UserSchema>
+      :customLogin="handleLoginClick"></UserSchema>
   </div>
 </template>
 
@@ -10,9 +10,11 @@
 import { ref } from 'vue';
 import UserSchema from '@/components/UserSchema.vue';
 import router from '@/router'
+import {useTokenStore} from "@/stores/token";
+import {createUser} from "@/utils/httputils";
 
 let loginStatus = ref('');
-
+const tokenStore = useTokenStore()
 const customLoginFunction = async (username: string, password: string, email: string) => {
   if (!username) {
     loginStatus.value = 'Please enter a username';
@@ -30,7 +32,7 @@ const customLoginFunction = async (username: string, password: string, email: st
     return;
   }
 
-  const apiUrl = 'http://localhost:8080/users/create'; 
+  const apiUrl = 'http://localhost:8080/users/create';
   try {
     const response = await fetch(apiUrl, {
       method: 'POST',
@@ -51,4 +53,31 @@ const customLoginFunction = async (username: string, password: string, email: st
     loginStatus.value = err.message;
   }
 }
+
+async function handleLoginClick(username: string, password: string, email: string) {
+  if (!username) {
+    loginStatus.value = 'Please enter a username';
+    return;
+  }
+  if (!password) {
+    loginStatus.value = 'Please enter a password';
+    return;
+  }
+  const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
+  if (!emailRegex.test(email)) {
+    loginStatus.value = 'Please enter a valid email address';
+    return;
+  }
+  try{
+    await createUser(username, password, email)
+    await tokenStore.getTokenAndSaveInStore(username, password)
+    if(tokenStore.jwtToken) {
+      await router.push("/homepage/discovery")
+    } else {
+      loginStatus.value = "Failed to retrieve token!"
+    }
+  } catch (err: any) {
+      loginStatus.value = err
+    }
+}
 </script>
diff --git a/src/views/mainpage/CreateTrivio.vue b/src/views/mainpage/CreateTrivio.vue
index b429352e7761fb0dc554558d0b59eac65498a026..77acbff502735ca2552ae078c7fb054ef48bfa02 100644
--- a/src/views/mainpage/CreateTrivio.vue
+++ b/src/views/mainpage/CreateTrivio.vue
@@ -3,6 +3,7 @@ import { ref, watch} from 'vue'
 import EditTrivioQuestion from '@/components/TrivioQuestion.vue'
 import { useTokenStore } from '@/stores/token'
 import {getPicture, postNewTrivio, uploadPicture} from "@/utils/httputils";
+import {useRouter} from "vue-router";
 
 const tokenStore = useTokenStore();
 // Reactive variables
@@ -15,6 +16,7 @@ const questions = ref<Question[]>([])
 const numberOfQuestions = ref<number[]>([])
 const fileInput = ref(null);
 const uploadStatus = ref('');
+const router = useRouter()
 //default user = 1
 const userID = 1
 let uniqueComponentId = 0;
@@ -89,6 +91,7 @@ const saveQuizToBackend = async () => {
     const token = tokenStore.jwtToken;
     if(!token){
       console.log("unauthorized user")
+      alert("session ended or unauthorized user")
     } else{
       const trivioData = {
         trivio: {
@@ -115,6 +118,7 @@ const saveQuizToBackend = async () => {
       };
       await postNewTrivio(token, trivioData);
       console.log('Quiz saved successfully!');
+      await router.push("/homepage/mytrivios")
     }
   } catch (error) {
     console.error('Error saving quiz:', error);
@@ -151,9 +155,7 @@ const handleFileUpload = async () => {
 }
 
 
-// Function to handle click on the default image
 const handleDefaultImageClick = () => {
-  // Trigger file input click to select a new image
   const fileInput = document.getElementById('fileInput');
   if (fileInput) {
     fileInput.click();
diff --git a/src/views/mainpage/EditTrivioView.vue b/src/views/mainpage/EditTrivioView.vue
index 49a25342da598f2f1fb912c5466768f722be5d04..a0055e8fd223fb1dec8eeeff20339c8322c06a9b 100644
--- a/src/views/mainpage/EditTrivioView.vue
+++ b/src/views/mainpage/EditTrivioView.vue
@@ -4,7 +4,7 @@ import EditTrivioQuestion from '@/components/TrivioQuestion.vue'
 import { useRoute } from 'vue-router'
 import { onMounted, ref } from 'vue'
 import { useTokenStore } from '@/stores/token'
-import { getTrivioById, editTrivio } from '@/utils/httputils'
+import {getTrivioById, editTrivio, getPicture, uploadPicture} from '@/utils/httputils'
 
 const route = useRoute()
 const tokenStore = useTokenStore()
@@ -20,29 +20,39 @@ const numberOfQuestions = ref<number[]>([])
 const userID = ref('');
 const trivioImage = ref('')
 let uniqueComponentId = 0;
-
+const trivioBlobUrl = ref("")
 const trivio = ref();
+const questionBlobs = ref(new Map())
+const questionBlobUrl = ref("")
+const fileInput = ref(null);
 onMounted(async () => {
   try {
     if(!tokenStore.jwtToken){
       console.log("unauthorized user")
     } else {
       const response = await getTrivioById(tokenStore.jwtToken, trivioId);
+
       trivio.value = response.data
       title.value = response.data.title;
       description.value = response.data.description;
       difficulty.value = response.data.difficulty.toLowerCase();
       category.value = response.data.category.toLowerCase();
       visibility.value = response.data.visibility.toLowerCase();
-
+      trivioBlobUrl.value = await getPicture(response.data.multimedia_url, tokenStore.jwtToken)
+      console.log(trivioBlobUrl.value)
       for (let i = 0; i < response.data.questionList.length; i++) {
         const questionData = response.data.questionList[i];
+        questionBlobUrl.value = await getPicture(questionData.media, tokenStore.jwtToken)
+        questionBlobs.value.set(questionData.media, questionBlobUrl.value); // Store blob URL in the map with trivio ID as key
+        console.log(questionBlobUrl.value)
         questions.value.push({
           questionId: i,
           question: questionData.question,
           questionType: questionData.questionType,
           answers: questionData.answers,
-          tags: questionData.tags
+          tags: questionData.tags,
+          media: questionData.media,
+          blobUrl: questionBlobUrl.value
         });
         numberOfQuestions.value.push(i);
       }
@@ -61,7 +71,9 @@ const addQuestion = () => {
     question: '',
     questionType: '',
     answers: [],
-    tags: []
+    tags: [],
+    media: '',
+    blobUrl: ''
   })
   uniqueComponentId ++;
   console.log(uniqueComponentId)
@@ -83,7 +95,8 @@ const saveQuestion = (questionData: Question) => {
       question: question.question,
       questionType: question.questionType,
       answers: question.answers,
-      tags: question.tags
+      tags: question.tags,
+      media: question.media
     })))
   }
 };
@@ -101,13 +114,14 @@ const saveTrivio = async () =>{
           difficulty: difficulty.value,
           visibility: visibility.value,
           category: category.value,
-          multimedia_url: "cat.png"
+          multimedia_url: trivioImage.value
         },
         questionsWithAnswers: questions.value.map(question => ({
           question: {
             question: question.question,
             questionType: question.questionType,
-            tags: question.tags.map(tag => tag)
+            tags: question.tags.map(tag => tag),
+            media: question.media,
           },
           answers: question.answers.map(answer => ({
             answer: answer.answer,
@@ -116,6 +130,7 @@ const saveTrivio = async () =>{
         })),
         userId: null
       };
+      console.log(trivioData)
       console.log('data implemented');
       await editTrivio(token, trivioData, trivioId);
       console.log('Quiz saved successfully!');
@@ -142,8 +157,56 @@ interface Question {
   questionType: string;
   answers: Answer[]; // Adjust the type of inputFields as needed
   tags: String[];
+  media: string;
+  blobUrl: string;
+}
+const handleFileUpload = async () => {
+  if (fileInput && fileInput.value && fileInput.value.files && fileInput.value.files.length > 0) {
+    const file = fileInput.value.files[0];
+    console.log(fileInput.value.files[0])
+    try {
+      // Call the function to upload the picture
+      const uploadedImageUrl = await uploadPicture(file, tokenStore.jwtToken);
+
+      const response = await getPicture(uploadedImageUrl, tokenStore.jwtToken)
+      trivioImage.value = uploadedImageUrl
+      trivioBlobUrl.value = response
+      console.log('Uploaded picture URL:', uploadedImageUrl);
+      console.log(uploadedImageUrl);
+
+      console.log('Uploaded picture URL:', imageUrl);
+
+    } catch (error) {
+      console.error('Error uploading picture:', error);
+      // Handle the error, display a message to the user, etc.
+    }
+  } else {
+    console.error('No file selected.');
+    // Handle the case where no file is selected, display a message to the user, etc.
+  }
 }
 
+const getBlobUrl = async (multimediaUrl: string) => {
+  if (!multimediaUrl) return "";
+  try {
+    return await getPicture(multimediaUrl, tokenStore.jwtToken);
+  } catch (error) {
+    console.error("Error fetching blobUrl:", error);
+    return "";
+  }
+};
+
+const fetchBlobUrls = async () => {
+
+};
+// Function to handle click on the default image
+const handleDefaultImageClick = () => {
+  // Trigger file input click to select a new image
+  const fileInput = document.getElementById('fileInput');
+  if (fileInput) {
+    fileInput.click();
+  }
+}
 </script>
 
 <template>
@@ -184,8 +247,11 @@ interface Question {
       </div>
       <div class="right">
         <div class="image-box">
-          <h1>Add image</h1>
-          <img src="/src/components/icons/AddImage.png" alt="Image" width="50px" height="50px">
+          <label>
+            <input type="file" style="display: none" ref="fileInput" accept="image/png, image/jpeg" @change="handleFileUpload">
+            <img v-if="trivioBlobUrl" :src="trivioBlobUrl" alt="Uploaded Image" width="150px" height="150px">
+            <img v-else src="/src/components/icons/AddImage.png" alt="Add Image" width="50px" height="50px" @click="handleDefaultImageClick">
+          </label>
         </div>
       </div>
     </div>
@@ -197,6 +263,7 @@ interface Question {
         :index="index + 1"
         :question-id="questionId"
         :question="questions[questionId]"
+        :blob-url="questionBlobs.get(questions[questionId].media)"
         @delete-question="deleteQuestion(questionId)"
         @save-question="saveQuestion"
       ></EditTrivioQuestion>
diff --git a/src/views/mainpage/HistoryView.vue b/src/views/mainpage/HistoryView.vue
index c21419ecb0538848d5e9692f7cad9d72b08d49f5..bc2bb0639e4db0e82c4d92bfaefcf287248cbf1e 100644
--- a/src/views/mainpage/HistoryView.vue
+++ b/src/views/mainpage/HistoryView.vue
@@ -3,15 +3,37 @@ import {onMounted, ref} from "vue";
 import axios from "axios";
 import HistoryBox from "@/components/HistoryBox.vue";
 import TrivioCard from "@/components/TrivioCard.vue";
-import {getHistoryByUser} from "@/utils/httputils";
+import {getHistoryByUser, getPicture} from "@/utils/httputils";
 import {useTokenStore} from "@/stores/token";
 const results = ref("")
 const tokenStore = useTokenStore()
+const trivioBlobUrls = ref(new Map()); // Store blob URLs for each trivio
+const getBlobUrl = async (multimediaUrl: string) => {
+  if (!multimediaUrl) return "";
+  try {
+    return await getPicture(multimediaUrl, tokenStore.jwtToken);
+  } catch (error) {
+    console.error("Error fetching blobUrl:", error);
+    return "";
+  }
+};
+
+const fetchBlobUrls = async () => {
+  for (const result of results.value) {
+    console.log(result)
+    const trivio = result.trivio
+    console.log(trivio)
+    const blobUrl = await getBlobUrl(trivio.multimedia_url);
+    trivioBlobUrls.value.set(trivio.id, blobUrl); // Store blob URL in the map with trivio ID as key
+  }
+};
+
 onMounted(async () => {
   try {
     const response = await getHistoryByUser(tokenStore.jwtToken); //for now just hardcode userId
     results.value = response.data;
-    console.log(results.value)
+    //console.log(results.value[0].trivio)
+    await fetchBlobUrls()
   } catch (error) {
     console.error('Error fetching quiz data:', error);
   }
@@ -31,6 +53,8 @@ onMounted(async () => {
           :difficulty="result.trivio?.difficulty"
           :score="result.score"
           :username="result.user?.username"
+          :image="trivioBlobUrls.get(result.trivio?.id)"
+          :date="result.postedDate"
       ></history-box>
     </div>
   </div>