Skip to content
Snippets Groups Projects
Commit 2e0ca4d3 authored by vildemv's avatar vildemv
Browse files

Abstracted all main content into different components. Did some layout changes...

Abstracted all main content into different components. Did some layout changes to make the page more scalable. Added help-icon for pop up.
parent 6b24eff6
No related branches found
No related tags found
1 merge request!53Frontend improvements
<script setup lang="ts">
import PotentialChallengeDisplay from '@/components/challenge/PotentialChallengeDisplay.vue'
import { onMounted, ref, watch } from 'vue'
import ActiveChallengeDisplay from '@/components/challenge/ActiveChallengeDisplay.vue'
import {ref} from 'vue'
import ActiveChallengesList from '@/components/challenge/ActiveChallengesList.vue'
import InactiveChallengeList from '@/components/challenge/InactiveChallengeList.vue'
import router from '@/router'
import { useTokenStore } from '@/stores/token'
import { getActiveChallenges, getInactiveChallenges } from '@/utils/challengeutils'
import CompleteChallengePopUp from '@/components/challenge/CompleteChallengePopUp.vue'
import JSConfetti from 'js-confetti'
const jsConfetti = new JSConfetti()
interface Challenge{
challengeId: number,
challengeTitle: string,
challengeDescription: string,
goalSum:number,
expirationDate:string
}
const token:string = useTokenStore().jwtToken;
const activeChallenges = ref<Challenge[]>([])
const inactiveChallenges = ref<Challenge[]>([])
const SIZE = 4
const pages = ref<number>(1)
const currentPage = ref<number>(0)
import MilestoneHelpPopUp from '@/components/popups/help/MilestoneHelpPopUp.vue'
import ChallengeHelpPopUp from '@/components/popups/help/ChallengeHelpPopUp.vue'
const displayType = ref<boolean>(true);
const displayHelpPopUp = ref<boolean>(false)
const displayPopUp = ref<boolean>(false);
const completedChallenge = ref<number|any>(null)
onMounted(async () => {
try {
currentPage.value = 0;
await fetchInactiveChallenges();
await fetchActiveChallenges();
} catch (error) {
console.error('Error fetching user info:', error);
}
})
const fetchInactiveChallenges = async () => {
try {
const { content } = await getInactiveChallenges(token)
inactiveChallenges.value = []
for (let i = 0; i < content.length; i++) {
const date = new Date(content[i].expirationDate);
const formattedDate = date.toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
inactiveChallenges.value.push({
challengeId: content[i].challengeId,
challengeTitle: content[i].challengeTitle,
challengeDescription: content[i].challengeDescription,
goalSum: content[i].goalSum,
expirationDate: formattedDate
})
}
console.log(inactiveChallenges.value)
} catch (error) {
console.error('Error fetching active challenges:', error);
}
}
const fetchActiveChallenges = async () => {
try{
const { content, totalPages, number } =
await getActiveChallenges(token, currentPage.value,SIZE)
pages.value = totalPages;
currentPage.value = number;
activeChallenges.value = [];
for(let i = 0; i < content.length; i ++){
console.log(content.data)
const date = new Date(content[i].expirationDate);
const formattedDate = date.toLocaleDateString('en-US', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
activeChallenges.value.push({
challengeId:content[i].challengeId,
challengeTitle:content[i].challengeTitle,
challengeDescription:content[i].challengeDescription,
goalSum:content[i].goalSum,
expirationDate:formattedDate
})
}
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 handleRequestToCompleteChallenge = (challengeId: number) => {
displayPopUp.value = true;
completedChallenge.value = challengeId;
}
const handleChallengeCompleted = async () => {
await closePopUp();
await jsConfetti.addConfetti();
}
const closePopUp = async () => {
displayPopUp.value = false;
await fetchActiveChallenges();
}
const displayNewChallenges = () => {
displayType.value = false;
......@@ -145,121 +16,91 @@ const displayNewChallenges = () => {
const displayActiveChallenges = () => {
displayType.value = true;
}
const navigateTo = (path: string) => {
router.push(path)
}
const previousPage = () => {
currentPage.value --
}
const goToPage = (pageNumber:number) => {
currentPage.value = pageNumber;
}
const nextPage = () =>{
currentPage.value ++;
const openHelpPopUp = () => {
displayHelpPopUp.value = true;
}
const closeHelpPopUp = async () => {
displayHelpPopUp.value = false;
}
watch(currentPage, fetchActiveChallenges);
</script>
<template>
<div class="challenge-view" :aria-disabled="displayPopUp">
<div v-if="displayPopUp" class="popup-container">
<CompleteChallengePopUp
:challenge-id="completedChallenge"
@closePopUp="closePopUp"
@challengeCompleted="handleChallengeCompleted"
></CompleteChallengePopUp>
<div class="home-view">
<div class="header">
<h2 class="title">Dine utfordringer!</h2>
<img
src="/src/components/icons/navigation/help.svg"
alt="hjelp"
@click="openHelpPopUp"
class="help-icon">
<div v-if="displayHelpPopUp" class="popup-container">
<ChallengeHelpPopUp
@closePopUp="closeHelpPopUp"
></ChallengeHelpPopUp>
</div>
</div>
<h2 class="title">Dine utfordringer</h2>
<div class="toggle-buttons">
<button class="toggle-button" @click="displayActiveChallenges" :class="{ 'active-button': displayType}">
<h3 class="toggle-button-title">Nye utfordringer</h3>
</button>
<button class="toggle-button" @click="displayNewChallenges" :class="{ 'active-button': !displayType}">
<h3 class="toggle-button-title">Aktive utfordringer</h3>
</button>
</div>
<div class="main">
<div class="left" :class="{ 'mobile-hide': !displayType }">
<button class="create-challenge-button" @click="navigateTo('/homepage/create-challenge')">
<h2 class="create-challenge-button-title">Ny personlig utfordring + </h2>
<h2 class="display-help-button">Ny personlig utfordring + </h2>
</button>
<div class="challenge-recommendations">
<PotentialChallengeDisplay
class="potential-challenge"
v-for="(potentialChallenge, index) in inactiveChallenges"
:key="index"
:challenge="potentialChallenge"
@challengeAccepted="handleChallengeAccepted"
@challengeDeclined="handleChallengeDeclined"
></PotentialChallengeDisplay>
<h4 class="challenge-placeholder" v-if="inactiveChallenges.length == 0">
Ojda, her gikk det unna.<br>
Vi har for øyeblikket ingen flere forslag til utfordringer. <br>
Lag din egen personlige utfordring eller kom tilbake senere! <br>
Nye utfordringer blir generert med gjevne mellomrom.
</h4>
</div>
<InactiveChallengeList></InactiveChallengeList>
</div>
<div class="right" :class="{ 'mobile-hide': displayType }">
<h2 class="active-challenges-title">Aktive utfordringer</h2>
<div class="active-challenge-box">
<div class="active-challenges">
<ActiveChallengeDisplay
class="active-challenge"
v-for="(activeChallenge, index) in activeChallenges"
:key="index"
:challenge="activeChallenge"
@challengeCompleted="handleRequestToCompleteChallenge(activeChallenge.challengeId)"
></ActiveChallengeDisplay>
<h4 class="challenge-placeholder" id="active-challenge-placeholder" v-if="activeChallenges.length == 0">
Du har ingen aktive utfordringer.<br>
Lag din egen utfordring eller aksepter våre tilpassede forslag!
Aktive utfordringer vil vises i denne boksen.
</h4>
</div>
<div class="pagination">
<button @click="previousPage" :disabled="currentPage === 0">Forige side</button>
<div v-if="pages>0" class="page-numbers">
<button
v-for="pageNumber in pages"
:key="pageNumber-2"
:class="{ chosen: pageNumber-1 === currentPage }"
@click="goToPage(pageNumber-1)"
>{{ pageNumber}}</button>
</div>
<button @click="nextPage" :disabled="currentPage === pages - 1 || pages === 0">Neste side</button>
</div>
</div>
<ActiveChallengesList></ActiveChallengesList>
</div>
</div>
</div>
</template>
<style scoped>
.challenge-view{
.home-view{
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
gap: 2.5%;
}
height: 100%;
.header{
display: flex;
flex-direction: row;
place-content: space-between;
max-height: 6.5%;
}
.help-icon:hover{
transform: scale(1.05);
}
.popup-container {
position: fixed; /* Change to fixed to cover the entire viewport */
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
background-color: rgba(64, 64, 64, 0.5);
align-items: center;
z-index: 1000; /* Adjust z-index as needed */
}
.title{
......@@ -273,9 +114,9 @@ watch(currentPage, fetchActiveChallenges);
.main{
display: flex;
flex-direction: row;
min-height: 100%;
width: 100%;
min-height: 115%;
padding-bottom: 1.5%;
gap: 2.5%;
}
......@@ -283,8 +124,10 @@ watch(currentPage, fetchActiveChallenges);
display: flex;
flex-direction: column;
width: 60%;
min-height: 100%;
gap: 2.5%;
}
.create-challenge-button{
border-radius: 20px;
background-color: var(--color-confirm-button);
......@@ -301,48 +144,20 @@ watch(currentPage, fetchActiveChallenges);
transform: scale(1.02);
}
.create-challenge-button-title{
.display-help-button{
font-weight: bold;
}
.challenge-recommendations{
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
gap: 2.5%;
}
.challenge-placeholder{
text-align: center;
}
#active-challenge-placeholder{
color: var(--color-headerText);
}
.potential-challenge{
border-radius: 20px;
border: 2px solid var(--color-border);
box-shadow: 0 4px 4px var(--color-shadow);
height: calc(100%/3);
width: 100%;
}
.potential-challenge:hover{
transform: scale(1.02);
}
.right{
display: flex;
flex-direction: column;
place-content: space-evenly;
place-content: space-between;
border: 2px solid var(--color-border);
border-radius: 20px;
border: 2px solid var(--color-border);
box-shadow: 0 4px 4px var(--color-shadow);
background-color: var(--color-heading);
height: 100%;
width: 40%;
}
......@@ -353,118 +168,13 @@ watch(currentPage, fetchActiveChallenges);
font-weight: bold;
}
.active-challenge-box{
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
padding: 5.0%;
place-content: space-between;
}
.active-challenges{
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
gap:2.5%
}
.active-challenge{
border-radius: 20px;
border: 2px solid var(--color-border);
background-color: var(--color-background-white);
min-height: calc(calc(100% - 2.5*4%)/4);
width: 100%;
}
.active-challenge:hover{
transform: scale(1.05);
}
.pagination {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
flex: 1;
}
.pagination button {
padding: 5px 10px;
margin: 0 5px;
border: none;
border-radius: 5px;
background-color: var(--color-pageination-button);
}
.pagination button:hover {
transform: scale(1.05);
}
.pagination button:active{
background-color: var(--color-pageination-button-click);
}
.pagination button:disabled {
color: var(--color-inactive-button-text);
cursor: not-allowed;
transform: none;
background-color: var(--color-pageination-button) ;
}
.page-numbers {
display: flex;
}
.page-numbers button {
border: 1px solid var(--color-border);
border-radius: 5px;
background-color: var(--color-pageination-button);
}
.page-numbers button:hover {
transform: scale(1.05);
}
.page-numbers button:active {
background-color: var(--color-pageination-button-click);
}
.chosen{
color: var(--color-heading);
font-weight: bold;
}
.popup-container {
position: fixed; /* Change to fixed to cover the entire viewport */
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
background-color: rgba(64, 64, 64, 0.5);
align-items: center;
z-index: 1000; /* Adjust z-index as needed */
}
@media only screen and (max-width: 1000px){
.main{
display: flex;
flex-direction: column;
min-height: 100%;
min-height: 150%;
width: 100%;
padding-top: 1.0%;
padding-bottom: 1.0%;
}
.toggle-buttons{
......@@ -509,10 +219,12 @@ watch(currentPage, fetchActiveChallenges);
width: 100%;
}
.challenge-recommendations{
min-height: 100%;
}
}
@media (prefers-color-scheme: dark) {
.help-icon{
filter: invert(1);
}
}
</style>
\ No newline at end of file
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