diff --git a/src/components/challenge/ActiveChallengeDisplay.vue b/src/components/challenge/ActiveChallengeDisplay.vue index 6ab8201d979daf9845dc287470dad00b6757209d..fbacb0668a0e17c4cda05fadb4151653d10d61b8 100644 --- a/src/components/challenge/ActiveChallengeDisplay.vue +++ b/src/components/challenge/ActiveChallengeDisplay.vue @@ -1,18 +1,38 @@ <script setup lang="ts"> +import { completeChallenge } from '@/utils/challengeutils' +import { useTokenStore } from '@/stores/token' +import { ref } from 'vue' + +const token:string = useTokenStore().jwtToken; + +const emits = defineEmits(['challengeCompleted']); +const milestoneId = ref(1) + const props = defineProps({ - id: Number, - title: String, - description: String + challengeId: Number, + challengeTitle: String, + challengeDescription: String }); +const completeTheChallenge = async () => { + if(props.challengeId){ + try{ + await completeChallenge(token,props.challengeId, milestoneId.value) + emits('challengeCompleted', props.challengeId); + } catch (error){ + alert('Noe gikk galt! Venligst prøv på nytt!') + } + } +} + </script> <template> <div class="potential-challenge-display"> - <h3 class="title">{{props.title}}</h3> - <h4 class="description">{{props.description}}</h4> + <h3 class="title">{{ props.challengeTitle }}</h3> + <h4 class="description">{{ props.challengeDescription }}</h4> <div class="button-container"> - <button class="complete-button"> + <button class="complete-button" @click="completeTheChallenge()"> <h3 class="complete-button-text">Fullfør</h3> </button> </div> diff --git a/src/components/challenge/PotentialChallengeDisplay.vue b/src/components/challenge/PotentialChallengeDisplay.vue index 01d0e7e88673895a5453f40e580a85df2881f9e2..8ba724bf6666eeeb37a3154e4d49f8fc9cffeb02 100644 --- a/src/components/challenge/PotentialChallengeDisplay.vue +++ b/src/components/challenge/PotentialChallengeDisplay.vue @@ -1,22 +1,52 @@ <script setup lang="ts"> +import { activateChallenge, deleteChallenge } from '@/utils/challengeutils' +import { useTokenStore } from '@/stores/token' + +const token:string = useTokenStore().jwtToken; +const emits = defineEmits(['challengeAccepted', 'challengeDeclined']); + const props = defineProps({ - id: Number, - title: String, - description: String + challengeId: Number, + challengeTitle: String, + challengeDescription: String }); +const declineChallenge = async () => { + console.log('decline-button clicked') + if(props.challengeId){ + try{ + await deleteChallenge(token, props.challengeId); + emits('challengeDeclined', props.challengeId); + } catch (error){ + alert('Noe gikk galt! Venligst prøv på nytt.') + } + } else { + alert('challengeId not defined') + } +} + +const acceptChallenge = async () => { + if(props.challengeId){ + try{ + await activateChallenge(token, props.challengeId); + emits('challengeAccepted', props.challengeId); + } catch (error){ + alert('Noe gikk galt! Venligst prøv på nytt.') + } + } +} </script> <template> <div class="potential-challenge-display"> - <h2 class="title">{{props.title}}</h2> - <h4 class="description">{{props.description}}</h4> + <h2 class="title">{{ props.challengeTitle }}</h2> + <h4 class="description">{{ props.challengeDescription }}</h4> <div class="options"> - <button class="option-button" id="decline-button"> + <button class="option-button" id="decline-button" @click="declineChallenge"> <h3 class="button-text">Avslå</h3> </button> - <button class="option-button" id="accept-button"> + <button class="option-button" id="accept-button" @click="acceptChallenge"> <h3 class="button-text">Godta</h3> </button> diff --git a/src/components/profile/BankAccountInfo.vue b/src/components/profile/BankAccountInfo.vue index 0ff7f8f90ea6963505d2cf9fb46bc514654f897c..5d7e7c03d0490a791191d895e1b1b0d2933eaf3d 100644 --- a/src/components/profile/BankAccountInfo.vue +++ b/src/components/profile/BankAccountInfo.vue @@ -36,6 +36,7 @@ const fetchUserInfo = async () =>{ const fetchAccountInfo = async () => { const response = await getUserAccountInfo(token); + console.log('account info') console.log(response) for(let i = 0; i < response.length; i++){ console.log(response[i].accountNumber) diff --git a/src/components/profile/UserInfo.vue b/src/components/profile/UserInfo.vue index 62558198b4efd8fc196839ce587472dd16296a4c..22c8f7eb7c9859c6ec2bbc12f12522d9d49b8508 100644 --- a/src/components/profile/UserInfo.vue +++ b/src/components/profile/UserInfo.vue @@ -24,7 +24,6 @@ onMounted(async () => { const fetchUserInfo = async () =>{ try{ const response = await getUserInfo(token) - console.log(response) username.value = response.username; email.value = response.email; profilePictureBase64.value = response.profilePictureBase64; diff --git a/src/utils/challengeutils.ts b/src/utils/challengeutils.ts new file mode 100644 index 0000000000000000000000000000000000000000..d2340ef1d08e5a9157dfcd889752d9fc9a5920ce --- /dev/null +++ b/src/utils/challengeutils.ts @@ -0,0 +1,182 @@ +import axios from "axios"; + +const challengeRecomendationsTestData = [ + { + challengeId:1, + challengeTitle:'Gå til skolen!', + challengeDescription:'Spar 46kr hver dag du går isteden for å ta buss til skolen denne uken.' + }, + { challengeId: 2, + challengeTitle:'Unngå kjøp av kaffe!', + challengeDescription:'Spar 59kr for å unngå kjøp av kaffe i dag.' + }, + { challengeId: 3, + challengeTitle:'Bruk handlenett på butikken!', + challengeDescription:'Spar 5kr for å burke handlenett på butikken.' + }, +]; + +const activeChallengesTestData = [ + { + challengeId: 4, + challengeTitle:'Spis middag hjemme!', + challengeDescription:'Spar 200kr for å spise middag hjemme i dag.' + }, + { challengeId: 5, + challengeTitle:'Kjøp brukt isteden for nytt!', + challengeDescription:'Spar 250kr for å kun kjøpe brukt denne uken.' + }, + { challengeId: 6, + challengeTitle: 'Ta med lunsj hjemmefra!', + challengeDescription:'Spar 100kr for å ta med lunsj hjemmefra i dag.' + }, + { challengeId: 7, + challengeTitle: 'Unngå netthandel!', + challengeDescription:'Spar 500kr for å unngå netthandel denne måneden.' + }, +] + +export const createChallenge = async ( + token:string, + challengeTitle: string, + challengeDescription: string, + goalSum: number, + expirationData:string, + recurring: number ):Promise<any>=>{ + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }; + const data = { + 'challengeTitle': challengeTitle, + 'challengeDescription':challengeDescription, + 'goalSum': goalSum, + 'expirationDate': expirationData, + 'recurring': recurring, + } + return await axios.post(`http://localhost:8080/user/challenge/create/`,data,config); + } catch (error){ + console.error(error); + } +} + +export const deleteChallenge = async (token:string, challengeId: number):Promise<any>=>{ + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }; + return await axios.delete(`http://localhost:8080/user/challenge/delete/${challengeId}`,config); + } catch (error){ + console.error(error); + throw error; + } +} + +export const completeChallenge= async (token:string, challengeId:number, milestoneId:number):Promise<any>=>{ + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + params: { + challengeId: challengeId, + milestoneId: milestoneId + } + }; + console.log(config) + return await axios.post(`http://localhost:8080/user/challenge/complete`,{},config); + } catch (error){ + console.error(error); + throw error; + } +} + +export const activateChallenge= async (token:string, challengeId: number):Promise<any>=>{ + console.log(challengeId) + console.log(token) + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }; + return await axios.post(`http://localhost:8080/user/challenge/activate/${challengeId}`,{},config); + } catch (error){ + console.error(error); + throw error; + } +} + +export const getChallenge = async (token:string, challengeId: number):Promise<any>=>{ + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }; + return await axios.get(`http://localhost:8080/user/challenge/${challengeId}`,config); + } catch (error){ + console.error(error); + } +} + + +export const getActiveChallenges = async (token:string):Promise<any>=>{ + console.log(token) + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + params: { + 'page': 0, + 'size': 10 + } + + }; + const result = await axios.get('http://localhost:8080/user/challenge/paginated/active',config); + console.log('result') + console.log(result) + return result.data; + } catch (error){ + console.error(error); + return activeChallengesTestData + } +} + +export const getInactiveChallenges = async (token:string):Promise<any>=>{ + try{ + const config = { + headers:{ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + params: { + 'page': 0, + 'size': 10 + } + }; + const result = await axios.get('http://localhost:8080/user/challenge/paginated/inactive',config); + console.log('interactive') + console.log(result); + return result.data; + } catch (error){ + console.error(error); + return challengeRecomendationsTestData + } +} + + + + + diff --git a/src/utils/profileutils.ts b/src/utils/profileutils.ts index 2ea224995cee97e54a233cefcda90d407cb2c6a4..2d39b7afcb9d5a7754627be8729b0de132d2fc62 100644 --- a/src/utils/profileutils.ts +++ b/src/utils/profileutils.ts @@ -123,7 +123,8 @@ export const getUserAccountInfo = async (token:string):Promise<any> => { 'Authorization': `Bearer ${token}` }, }; - return await axios.get('http://localhost:8080/users/get', config); + const result = await axios.get('http://localhost:8080/user/account', config); + return result.data; } catch (error){ console.log('sending mock data') return testDataUserAccounts; @@ -137,7 +138,8 @@ export const getUserInfo = async (token:string): Promise<any> => { 'Authorization': `Bearer ${token}` }, }; - return await axios.get('http://localhost:8080/user/account', config); + const result = await axios.get('http://localhost:8080/users/get', config); + return result.data; } catch (error){ console.log('sending mock data') return testDataUser; @@ -159,7 +161,7 @@ export const updateUserInfo = async ( 'email': email, 'profilePictureBase64': profilePictureBase64 }; - return await axios.put('http://localhost:8080/users/update',data,config); + return await axios.post('http://localhost:8080/users/update',data,config); } catch (error){ console.error(error) throw error; @@ -181,7 +183,7 @@ export const updatePasswordInfo = async ( 'password': currentPassword, 'newPassword': newPassword }; - return await axios.put('http://localhost:8080/usersCredentials/updatePassword',data,config); + return await axios.post('http://localhost:8080/userCredentials/updatePassword',data,config); } catch (error){ console.error(error) throw error; @@ -202,7 +204,7 @@ export const updateBankAccountInfo = async ( 'currentAccount': checkingAccount, 'savingAccount': savingAccount }; - return await axios.put('http://localhost:8080/users/update',data,config); + return await axios.post('http://localhost:8080/users/update',data,config); } catch (error){ console.error(error) throw error; @@ -226,7 +228,7 @@ export const updateIncomeInfo = async ( 'monthlyFixedExpenses': monthlyFixedExpenses, 'monthlySavings': monthlySavings }; - return await axios.put('http://localhost:8080/users/update',data,config); + return await axios.post('http://localhost:8080/users/update',data,config); } catch (error){ console.error(error) throw error; diff --git a/src/views/HomePage/ChallengeView.vue b/src/views/HomePage/ChallengeView.vue index dcbdb72d9c7ab960f41591abd76bc597bd6588fd..d95122d15d0e0a0b86a3dc38033165aa8a58dccc 100644 --- a/src/views/HomePage/ChallengeView.vue +++ b/src/views/HomePage/ChallengeView.vue @@ -1,65 +1,98 @@ <script setup lang="ts"> import PotentialChallengeDisplay from '@/components/challenge/PotentialChallengeDisplay.vue' -import { ref } from 'vue' +import { onMounted, ref } from 'vue' import ActiveChallengeDisplay from '@/components/challenge/ActiveChallengeDisplay.vue' import router from '@/router' +import { useTokenStore } from '@/stores/token' +import { getActiveChallenges, getInactiveChallenges } from '@/utils/challengeutils' -const challengeRecomendationsTestData = [ - { - id:1, - title:'Gå til skolen!', - description:'Spar 46kr hver dag du går isteden for å ta buss til skolen denne uken.' - }, - { id: 2, - title:'Unngå kjøp av kaffe!', - description:'Spar 59kr for å unngå kjøp av kaffe i dag.' - }, - { id: 3, - title:'Bruk handlenett på butikken!', - description:'Spar 5kr for å burke handlenett på butikken.' - }, -]; - -const activeChallengesTestData = [ - { - id: 4, - title:'Spis middag hjemme!', - description:'Spar 200kr for å spise middag hjemme i dag.' - }, - { id: 5, - title:'Kjøp brukt isteden for nytt!', - description:'Spar 250kr for å kun kjøpe brukt denne uken.' - }, - { id: 6, - title: 'Ta med lunsj hjemmefra!', - description:'Spar 100kr for å ta med lunsj hjemmefra i dag.' - }, - { id: 7, - title: 'Unngå netthandel!', - description:'Spar 500kr for å unngå netthandel denne måneden.' - }, -] - -const activeChallenges = ref<Challenge[] | null>(activeChallengesTestData) - -const challengeRecommendations = ref<Challenge[] | null>(challengeRecomendationsTestData) +interface Challenge{ + challengeId: number; + challengeTitle: string; + challengeDescription: string +} + +const token:string = useTokenStore().jwtToken; + +const activeChallenges = ref<Challenge[]>([]) +const inactiveChallenges = ref<Challenge[]>([]) const pages = ref<number>(1) const currentPage = ref<number>(0) -const navigateTo = (path: string) => { - router.push(path) + + +onMounted(async () => { + try { + await fetchInactiveChallenges(); + await fetchActiveChallenges(); + } catch (error) { + console.error('Error fetching user info:', error); + } +}) + +const fetchInactiveChallenges = async () => { + try { + const response = await getInactiveChallenges(token) + inactiveChallenges.value = [] + for (let i = 0; i < response.length; i++) { + inactiveChallenges.value.push({ + challengeId: response[i].challengeId, + challengeTitle: response[i].challengeTitle, + challengeDescription: response[i].challengeDescription + }) + } + + console.log(inactiveChallenges.value) + } catch (error) { + console.error('Error fetching active challenges:', error); + } +} + +const fetchActiveChallenges = async () => { + try{ + const response = await getActiveChallenges(token) + console.log(response) + activeChallenges.value = []; + for(let i = 0; i < response.length; i ++){ + console.log(response.data) + activeChallenges.value.push({ + challengeId:response[i].challengeId, + challengeTitle:response[i].challengeTitle, + challengeDescription:response[i].challengeDescription + }) + } + console.log(activeChallenges.value) + } catch (error){ + console.error('Error fetching inactive challenges:', error); + } +} + +// Function to handle the emitted challengeAccepted event +const handleChallengeAccepted = async () => { + console.log('handling it') + await fetchActiveChallenges(); + await fetchInactiveChallenges(); +} + +// Function to handle the emitted challengeDeclined event +const handleChallengeDeclined = async () => { + await fetchInactiveChallenges(); +} + +const handleChallengeCompleted = async () => { + await fetchActiveChallenges(); } const previousPage = () => {} -const goToPage = (pageNumber:number) => {} +const goToPage = (pageNumber:number) => { + currentPage.value = pageNumber; +} const nextPage = () =>{} -interface Challenge{ - id: number; - title: string; - description: string +const navigateTo = (path: string) => { + router.push(path) } </script> @@ -75,11 +108,13 @@ interface Challenge{ <div class="challenge-recommendations"> <PotentialChallengeDisplay class="potential-challenge" - v-for="(potentialChallenge, index) in challengeRecommendations" + v-for="(potentialChallenge, index) in inactiveChallenges" :key="index" - :id="potentialChallenge.id" - :title="potentialChallenge.title" - :description="potentialChallenge.description" + :challengeId="potentialChallenge.challengeId" + :challengeTitle="potentialChallenge.challengeTitle" + :challengeDescription="potentialChallenge.challengeDescription" + @challengeAccepted="handleChallengeAccepted" + @challengeDeclined="handleChallengeDeclined" ></PotentialChallengeDisplay> </div> </div> @@ -92,9 +127,10 @@ interface Challenge{ class="active-challenge" v-for="(activeChallenge, index) in activeChallenges" :key="index" - :id="activeChallenge.id" - :title="activeChallenge.title" - :description="activeChallenge.description" + :challengeId="activeChallenge.challengeId" + :challengeTitle="activeChallenge.challengeTitle" + :challengeDescription="activeChallenge.challengeDescription" + @challengeCompleted="handleChallengeCompleted" ></ActiveChallengeDisplay> <div class="pagination"> <button @click="previousPage" :disabled="currentPage === 0">Forige side</button> @@ -102,8 +138,8 @@ interface Challenge{ <button v-for="pageNumber in pages" :key="pageNumber-2" - @click="goToPage(pageNumber-1)" :class="{ chosen: pageNumber-1 === currentPage }" + @click="goToPage(pageNumber-1)" >{{ pageNumber}}</button> </div> <button @click="nextPage" :disabled="currentPage === pages - 1 || pages === 0">Neste side</button>