Skip to content
Snippets Groups Projects
Commit 25b3304b authored by Eline Evje's avatar Eline Evje
Browse files

fix: finished modal for generated challenges

parent a29ed7e8
No related branches found
No related tags found
3 merge requests!66Final merge,!47Feat/implement genereated challenges modal,!4Pipeline fix
...@@ -25,20 +25,26 @@ ...@@ -25,20 +25,26 @@
import { defineProps, ref } from 'vue' import { defineProps, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
interface Props { const props = defineProps({
buttonText: string buttonText: String,
type: 'goal' | 'challenge' type: String,
} showModal: Boolean
});
const emit = defineEmits(['update:showModal']);
const router = useRouter() const router = useRouter()
const props = defineProps<Props>()
const btnText = ref(props.buttonText) const btnText = ref(props.buttonText)
const routeToGoalOrChallenge = () => { const routeToGoalOrChallenge = () => {
if (props.type === 'goal') { if (props.type === 'goal') {
router.push('/sparemaal') router.push('/sparemaal');
} else { } else if (props.type === 'challenge') {
router.push('/spareutfordringer') router.push('/spareutfordringer');
} else if (props.type === 'generatedChallenge') {
emit('update:showModal', true);
} }
} };
</script> </script>
<template> <template>
<div <div
v-if="generatedChallenges.length > 0" v-if="showModal"
class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50"
> >
<div class="relative bg-white pt-10 p-4 rounded-lg shadow-xl" style="width: 40rem"> <div class="relative bg-white pt-10 p-4 rounded-lg shadow-xl" style="width: 40rem">
...@@ -20,91 +20,85 @@ ...@@ -20,91 +20,85 @@
/> />
</svg> </svg>
</button> </button>
<div class="text-center font-bold text-3xl mb-4 mt-2"> <div v-if="generatedChallenges.length > 0">
Personlig tilpassede spareutfordringer: <div class="text-center font-bold text-3xl mb-4 mt-2">
</div> Personlig tilpassede spareutfordringer:
<div class="grid grid-cols-7 sm:grid-cols-11 gap-2 p-3 pb-1 border-b-2"> </div>
<span class="font-bold col-span-2 md:col-span-3 sm:text-lg pt-1 mb-0">Tittel</span> <div class="grid grid-cols-7 sm:grid-cols-11 gap-2 p-3 pb-1 border-b-2">
<span class="font-bold col-span-2 md:col-span-2 sm:text-lg pt-1 mb-0">Målsum</span> <span class="font-bold col-span-2 md:col-span-3 sm:text-lg pt-1 mb-0">Tittel</span>
<span class="font-bold col-span-2 md:col-span-1 sm:text-lg pt-1 pr-1 md:pr-3 mb-0" <span class="font-bold col-span-2 md:col-span-2 sm:text-lg pt-1 mb-0">Målsum</span>
>Frist</span <span class="font-bold col-span-2 md:col-span-1 sm:text-lg pt-1 pr-1 md:pr-3 mb-0">Frist</span>
> <span class="col-span-2"></span>
<span class="col-span-2"></span> </div>
</div> <div class="space-y-2">
<div class="space-y-2">
<div
v-for="(challenge, index) in generatedChallenges"
:key="challenge.id"
:class="{ 'bg-gray-100': index % 2 === 0 }"
class="grid grid-cols-7 md:grid-cols-7 sm:grid-cols-2 lg:grid-cols-7 gap-4 items-center border p-3 rounded mt-[-8px]"
>
<span class="break-words col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{
challenge.title
}}</span>
<span class="col-span-2 md:col-span-2 lg:col-span-1 text-lg">{{
challenge.target
}}</span>
<span class="col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{
challenge.due
}}</span>
<div <div
class="col-span-7 sm:col-start-3 sm:col-span-2 md:col-span-2 lg:col-span-2 flex items-center justify-end space-x-2" v-for="(challenge, index) in generatedChallenges"
:key="index"
:class="{ 'bg-gray-100': index % 2 === 0 }"
class="grid grid-cols-7 md:grid-cols-7 sm:grid-cols-2 lg:grid-cols-7 gap-4 items-center border p-3 rounded mt-[-8px]"
> >
<button <span class="break-words col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{ challenge.title }}</span>
@click="declineChallenge(challenge.id)" <span class="col-span-2 md:col-span-2 lg:col-span-1 text-lg">{{ challenge.target }}</span>
class="bg-gray-500 hover:bg-gray-700 text-white font-bold py-1 px-4 mt-[-14px] sm:mt-0" <span class="col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{ challenge.due }}</span>
<div
class="col-span-7 sm:col-start-3 sm:col-span-2 md:col-span-2 lg:col-span-2 flex items-center justify-end space-x-2"
> >
Skip <span v-if="challenge.isAccepted" class="font-bold text-lg">Godtatt!</span>
</button> <button
<button @click="acceptChallenge(challenge)"
@click="acceptChallenge(challenge)" class="text-white font-bold py-1 px-4 mt-[-14px] sm:mt-0"
class="text-white font-bold py-1 px-4 mt-[-14px] sm:mt-0"> >
Godta Godta
</button> </button>
</div>
</div> </div>
</div> </div>
</div> </div>
<div v-else class="text-center text-2xl font-bold mt-1">
Ingen nye spareutfordringer enda ... sjekk igjen senere!
</div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, reactive, onMounted } from 'vue'
import authInterceptor from '@/services/authInterceptor' import authInterceptor from '@/services/authInterceptor'
const generatedChallenges = ref([]) const showModal = ref(true);
const generatedChallenges = reactive([]);
async function fetchGeneratedChallenges() {
const fetchGeneratedChallenges = async () => {
try { try {
const response = await authInterceptor.get('/challenges/generate'); const response = await authInterceptor.get('/challenges/generate');
if (response.status === 200 && response.data.length > 0) { if (response.status === 200) {
generatedChallenges.value = response.data.map(challenge => ({ generatedChallenges.splice(0, generatedChallenges.length, ...response.data.map(ch => ({
...challenge, ...ch,
due: new Date(challenge.due).toISOString().split('T')[0], due: new Date(ch.due).toISOString().split('T')[0],
dueFull: challenge.due dueFull: ch.due,
})); accepted: false
console.log('Generated challenges:', generatedChallenges.value); })));
console.log('Generated challenges:', generatedChallenges);
} else { } else {
console.log('No challenges found for the user.'); console.log('No challenges found for the user.');
generatedChallenges.value = []; generatedChallenges.splice(0, generatedChallenges.length);
} }
} catch (error) { } catch (error) {
console.error('Error fetching challenges:', error); console.error('Error fetching challenges:', error);
generatedChallenges.value = [];
} }
} }
onMounted(fetchGeneratedChallenges) onMounted(() => {
fetchGeneratedChallenges();
localStorage.setItem('lastModalShow', Date.now().toString());
});
function acceptChallenge(challenge) { function acceptChallenge(challenge) {
if (!challenge) { if (!challenge) {
console.error('No challenge data provided to acceptChallenge function.'); console.error('No challenge data provided to acceptChallenge function.');
return; return;
} }
console.log('Accepting challenge:', challenge);
const postData = { const postData = {
title: challenge.title, title: challenge.title,
saved: 0, saved: 0,
...@@ -114,39 +108,17 @@ function acceptChallenge(challenge) { ...@@ -114,39 +108,17 @@ function acceptChallenge(challenge) {
due: challenge.dueFull, due: challenge.dueFull,
type: challenge.type type: challenge.type
}; };
console.log('Posting data:', postData);
authInterceptor.post('/challenges', postData) authInterceptor.post('/challenges', postData)
.then(response => { .then(response => {
console.log('Challenge accepted and saved:', response.data); console.log('Challenge accepted and saved:', response.data);
removeChallenge(challenge.id); challenge.isAccepted = true;
}) })
.catch(error => { .catch(error => {
console.error('Failed to save challenge:', error); console.error('Failed to save challenge:', error);
if (error.response && error.response.data) {
console.error('Error details:', error.response.data);
}
}); });
} }
function declineChallenge(id) {
removeChallenge(id);
}
const removeChallenge = (id) => {
const index = generatedChallenges.value.findIndex(c => c.id === id);
if (index !== -1) {
generatedChallenges.value.splice(index, 1);
generatedChallenges.value = [...generatedChallenges.value];
}
if (generatedChallenges.value.length === 0) {
closeModal();
}
}
const closeModal = () => { const closeModal = () => {
generatedChallenges.value = []; showModal.value = false;
} }
</script> </script>
...@@ -13,11 +13,18 @@ ...@@ -13,11 +13,18 @@
:buttonText="'Legg til spareutfordring'" :buttonText="'Legg til spareutfordring'"
:type="'challenge'" :type="'challenge'"
/> />
<ButtonAddGoalOrChallenge
:buttonText="'Generer spareutfordring'"
:type="'generatedChallenge'"
:showModal="showModal"
@click="showModal = true"
@update:showModal="showModal = $event"
/>
</div> </div>
</div> </div>
<savings-path :challenges="challenges" :goal="goal"></savings-path> <savings-path :challenges="challenges" :goal="goal"></savings-path>
</div> </div>
<GeneratedChallengesModal v-if="showModal" /> <GeneratedChallengesModal v-show="showModal" @update:showModal="showModal = $event" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
...@@ -31,7 +38,7 @@ import { useChallengeStore } from '@/stores/challengeStore' ...@@ -31,7 +38,7 @@ import { useChallengeStore } from '@/stores/challengeStore'
import SavingsPath from '@/components/SavingsPath.vue' import SavingsPath from '@/components/SavingsPath.vue'
import GeneratedChallengesModal from '@/components/GeneratedChallengesModal.vue' import GeneratedChallengesModal from '@/components/GeneratedChallengesModal.vue'
const showModal = ref(true) const showModal = ref(false)
const goalStore = useGoalStore() const goalStore = useGoalStore()
const challengeStore = useChallengeStore() const challengeStore = useChallengeStore()
...@@ -42,13 +49,18 @@ const goals = ref<Goal[]>([]) ...@@ -42,13 +49,18 @@ const goals = ref<Goal[]>([])
const goal = ref<Goal | null | undefined>(null) const goal = ref<Goal | null | undefined>(null)
onMounted(async () => { onMounted(async () => {
await goalStore.getUserGoals() await goalStore.getUserGoals();
await challengeStore.getUserChallenges() await challengeStore.getUserChallenges();
challenges.value = challengeStore.challenges challenges.value = challengeStore.challenges;
goals.value = goalStore.goals goals.value = goalStore.goals;
goal.value = goals.value[0] goal.value = goals.value[0];
console.log('Goals:', goals.value) console.log('Goals:', goals.value);
})
const lastModalShow = localStorage.getItem('lastModalShow');
if (!lastModalShow || Date.now() - Number(lastModalShow) >= 24 * 60 * 60 * 1000) {
showModal.value = true;
}
});
// Define your speech array // Define your speech array
const speechArray = [ const speechArray = [
......
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