Skip to content
Snippets Groups Projects
Commit 14320e91 authored by Valdemar Åstorp Beere's avatar Valdemar Åstorp Beere
Browse files

refactor(homePage):

Make goal reactive
parent 9867787f
No related branches found
No related tags found
3 merge requests!66Final merge,!50fix(styling):,!4Pipeline fix
......@@ -37,10 +37,22 @@
<Countdown
v-if="screenSize > 768 && currentStreak! > 0"
class="flex flex-row"
countdownSize="1rem"
labelSize=".5rem"
mainColor="white"
secondFlipColor="white"
countdownSize="1.4rem"
labelSize="0.8rem"
mainColor="black"
secondFlipColor="black"
mainFlipBackgroundColor="#30ab0e"
secondFlipBackgroundColor="#9af781"
:labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
:deadlineISO="deadline"
></Countdown>
<Countdown
v-if="screenSize <= 768 && currentStreak! > 0"
class="flex flex-row"
countdownSize="1.1rem"
labelSize=".6rem"
mainColor="black"
secondFlipColor="black"
mainFlipBackgroundColor="#30ab0e"
secondFlipBackgroundColor="#9af781"
:labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
......@@ -55,13 +67,13 @@
<div class="flex flex-col justify-around items-center">
<!-- Display the current streak day number adjusted by index -->
<span class="text-black text-xs md:text-1xl font-bold">
{{ currentStreak! - ((currentStreak! % 7) + 1 - index) }}
{{ currentStreak! - ((currentStreak! % 7) - index) }}
</span>
<!-- Display images based on completion -->
<img
src="@/assets/pengesekkStreak.png"
:alt="index <= currentStreak! % 7 ? 'challenge completed' : 'challenge not completed'"
:class="{'max-h-6 max-w-6 md:max-h-10 md:max-w-10': true, 'grayscale': index-1 > currentStreak! % 7}"
:class="{'max-h-6 max-w-6 md:max-h-10 md:max-w-10': true, 'grayscale': index > currentStreak! % 7}"
/>
</div>
</div>
......@@ -73,21 +85,20 @@
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { onMounted, onUnmounted, ref } from 'vue'
import { useUserStore } from '@/stores/userStore'
// @ts-ignore
import { Countdown } from 'vue3-flip-countdown'
const userStore = useUserStore()
const currentStreak = ref<number>()
const streakStart = ref<string>()
const deadline = ref<string>()
onMounted(async () => {
await userStore.getUserStreak()
userStore.getUserStreak()
if (userStore.streak) {
currentStreak.value = userStore.streak?.streak
streakStart.value = userStore.streak?.streakStart
deadline.value = userStore.streak?.streakStart
deadline.value = userStore.streak?.firstDue
}
console.log('Streak:', currentStreak.value)
if (typeof window !== 'undefined') {
......@@ -105,21 +116,15 @@ const handleWindowSizeChange = () => {
screenSize.value = window.innerWidth
}
watch(
() => currentStreak.value,
(newStreak, oldStreak) => {
if (newStreak !== oldStreak) {
currentStreak.value = newStreak
console.log('Updated Steak:', currentStreak)
}
},
{ immediate: true }
)
const displayStreakCard = ref(false)
const display = () => {
displayStreakCard.value = true
userStore.getUserStreak();
currentStreak.value = userStore.streak?.streak;
deadline.value = userStore.streak?.firstDue;
}
const hide = () => {
......
<template>
<!-- Challenge Icon and Details -->
<div class="flex items-center justify-center shadow-black min-w-24 w-full h-auto md:max-h-full min-h-24 max-w-32 max-h-32 md:min-h-32 md:min-w-32 md:max-w-48 overflow-hidden">
<div v-if="challenge" class="flex items-center justify-center shadow-black min-w-24 w-full h-auto md:max-h-full min-h-24 max-w-32 max-h-32 md:min-h-32 md:min-w-32 md:max-w-48 overflow-hidden">
<!-- Challenge Icon -->
<div class="flex flex-col items-center mx-auto md:mx-2 my-auto">
......@@ -78,45 +78,37 @@
<script setup lang="ts">
import type {Challenge} from "@/types/challenge";
import {useChallengeStore} from "@/stores/challengeStore";
import type {Goal} from "@/types/goal";
import {useGoalStore} from "@/stores/goalStore";
import router from "@/router";
const challengeStore = useChallengeStore();
const goalStore = useGoalStore();
interface Props {
challenge: Challenge,
goal: Goal
}
const props = defineProps<Props>()
defineProps<Props>()
const emit = defineEmits(['update-challenge', 'complete-challenge']);
// Increment saved amount
// In your incrementSaved function in the child component
const incrementSaved = async (challenge: Challenge) => {
// Safely increment the saved amount, ensuring it exists
challenge.saved += challenge.perPurchase
// Check if the saved amount meets or exceeds the target
if (challenge.saved >= challenge.target) {
challenge.completion = 100
await challengeStore.completeUserChallenge(challenge)
}
// Safely update the goal's saved value, ensuring goal.value exists and is not null
if (props.goal) {
props.goal.saved = (props.goal.saved || 0) + challenge.perPurchase
// Update the goal in the store, ensuring goal is not null or undefined
if (props.goal) {
await goalStore.editUserGoal(props.goal)
}
} else {
console.error('No goal selected for incrementing saved value.')
}
// Update the challenge in the store
await challengeStore.editUserChallenge(challenge)
challenge.saved += challenge.perPurchase;
// Trigger the update in the store
const updatedChallenge = await challengeStore.editUserChallenge(challenge) as Challenge;
console.log('updated challenge in child: ', updatedChallenge);
// Emit an event to inform the parent component of the update
emit('update-challenge', updatedChallenge);
}
const editChallenge = (challenge: Challenge) => {
router.push(`/spareutfordringer/rediger/${challenge.id}`)
}
......
This diff is collapsed.
......@@ -12,7 +12,6 @@ export const useChallengeStore = defineStore('challenge', () => {
const response = await authInterceptor('/challenges')
if (response.data && response.data.content) {
challenges.value = response.data.content
console.log('Fetched Challenges:', challenges.value)
} else {
challenges.value = []
console.error('No challenge content found:', response.data)
......@@ -33,12 +32,15 @@ export const useChallengeStore = defineStore('challenge', () => {
if (index !== -1) {
challenges.value[index] = { ...challenges.value[index], ...response.data }
console.log('Updated Challenge:', response.data)
return challenges.value[index];
}
} else {
console.error('No challenge content found in response data')
return null;
}
} catch (error) {
console.error('Error updating challenge:', error)
return null;
}
}
const completeUserChallenge = async (challenge: Challenge) => {
......@@ -53,12 +55,16 @@ export const useChallengeStore = defineStore('challenge', () => {
if (index !== -1) {
challenges.value[index] = { ...challenges.value[index], ...response.data }
console.log('Updated Challenge:', response.data)
console.log('Challenge Completed store:', challenges.value[index])
return challenges.value[index];
}
} else {
console.error('No challenge content found in response data')
return null;
}
} catch (error) {
console.error('Error updating challenge:', error)
return null;
}
}
......
......@@ -12,10 +12,13 @@ export const useGoalStore = defineStore('goal', () => {
if (response.data && response.data.content) {
goals.value = response.data.content
for (const goal of goals.value) {
if (goal.priority) {
if (goal.priority === 1) {
priorityGoal.value = goal
break
}
else {
priorityGoal.value = null
}
}
console.log(response.data.content)
} else {
......@@ -41,7 +44,6 @@ export const useGoalStore = defineStore('goal', () => {
const index = goals.value.findIndex((g) => g.id === goal.id)
if (index !== -1) {
goals.value[index] = { ...goals.value[index], ...response.data }
console.log('Updated Goal:', response.data)
}
} else {
console.error('No goal content found in response data')
......
export interface Streak {
streakStart?: string
streak?: number
firstDue?: string
}
......@@ -24,7 +24,7 @@
/>
</div>
</div>
<savings-path :challenges="challenges" :goal="goal"></savings-path>
<savings-path v-if="isMounted" :challenges="challenges" :goal="goal"></savings-path>
</div>
<InteractiveSpare
:speech="speech"
......@@ -41,7 +41,7 @@
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {onMounted, ref} from 'vue'
import InteractiveSpare from '@/components/InteractiveSpare.vue'
import ButtonAddGoalOrChallenge from '@/components/ButtonAddGoalOrChallenge.vue'
import type { Challenge } from '@/types/challenge'
......@@ -59,9 +59,8 @@ const speech = ref<string[]>([])
const newSpeechAvailable = ref(false)
const challenges = ref<Challenge[]>([])
const goals = ref<Goal[]>([])
const goal = ref<Goal | null | undefined>(null)
const isMounted = ref(false)
onMounted(async () => {
await goalStore.getUserGoals()
......@@ -69,8 +68,11 @@ onMounted(async () => {
challenges.value = challengeStore.challenges
goal.value = goalStore.priorityGoal
firstLoggedInSpeech()
isMounted.value = true
})
// Check if the user is logging in for the first time, and display the first login speech
const firstLoggedInSpeech = () => {
const isFirstLogin = router.currentRoute.value.query.firstLogin === 'true'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment