Skip to content
Snippets Groups Projects
Commit c6b0c239 authored by Sverre Frogner Haugen's avatar Sverre Frogner Haugen
Browse files

Merge branch 'div-frontend' into 'master'

Div frontend

See merge request !68
parents b8d350b9 af7b2e79
No related branches found
No related tags found
1 merge request!68Div frontend
Pipeline #281266 failed
Showing
with 255 additions and 113 deletions
......@@ -7,10 +7,21 @@ import { RouterView } from 'vue-router'
<RouterView />
</div>
</template>
<style scoped>
<style>
.app{
height: 100vh;
width: 100vw;
}
button:hover{
cursor: pointer;
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: pointer;
}
}
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: default;
}
</style>
src/assets/background/img.png

1.14 MiB

......@@ -63,6 +63,6 @@ describe('ActiveChallengeDisplay', () => {
expect(wrapper.text()).toContain(challenge.challengeTitle);
expect(wrapper.text()).toContain(challenge.challengeDescription);
expect(wrapper.text()).toContain('Utløpsdato: 01/05/2024');
expect(wrapper.text()).toContain('Sparesum: 100 kr,-');
expect(wrapper.text()).toContain('Sparesum: 100kr');
});
});
......@@ -14,8 +14,10 @@ const props = defineProps({
challenge: {
type: Object as () => Challenge,
required: true
}
},
expanded: Boolean
});
const expirationDate = () => {
return new Date(props.challenge?.expirationDate).
toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' });
......@@ -41,14 +43,21 @@ const deleteTheChallenge = () => {
src="/src/components/icons/navigation/close.svg"
alt="delete-button"
@click="deleteTheChallenge()">
<h3 class="title">{{ props.challenge.challengeTitle }}</h3>
<div class="content">
<h3 class="title">{{ props.challenge.challengeTitle }}</h3>
<h4 class="description">{{ props.challenge.challengeDescription }}</h4>
<div class="description-container">
<h4 class="description-title">Beskrivelse</h4>
<img src="/src/components/icons/navigation/info.svg" alt="show-more" class="show-more-icon">
<div class="description" :class="{'expanded':expanded}">
<h4 class="description-info" >{{ props.challenge.challengeDescription}}</h4>
</div>
</div>
<div class="extra-info">
<h4 class="expiration-date">Utløpsdato: {{expirationDate()}} |</h4>
<h4 class="sum"> Sparesum: {{props.challenge.goalSum}} kr,-</h4>
<h4 class="expiration-date">Utløpsdato: {{expirationDate()}} | Sparesum: {{props.challenge.goalSum}}kr</h4>
</div>
</div>
<div class="button-container">
<button class="complete-button" @click="completeTheChallenge()">
<h3 class="complete-button-text">Fullfør</h3>
......@@ -63,17 +72,15 @@ const deleteTheChallenge = () => {
display: flex;
flex-direction: column;
place-items: end;
place-content: space-between;
height: 100%;
width: 100%;
padding: 1.5%;
gap: 1.0%;
}
.content{
display: flex;
flex-direction: column;
width: 100%;
height: 65%;
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: pointer;
}
.close-img{
width: 5.0%;
}
......@@ -83,58 +90,72 @@ const deleteTheChallenge = () => {
}
.title{
width: 100%;
text-align: center;
color: var(--color-text-black);
}
.description{
.content{
display: flex;
flex-direction: column;
place-items: center;
place-content: space-between;
width: 100%;
height: 75%;
}
.description-container{
display: flex;
flex-direction: column;
width: 100%;
}
.description-title{
text-decoration: underline;
text-align: center;
color: var(--color-text-black);
overflow: hidden;
}
.show-more-icon{
height: 1.5vh;
}
.extra-info{
display: none;
display: flex;
flex-direction: row;
place-content: center;
gap: 1.0%;
}
.expiration-date{
color: var(--color-text-black);
}
.sum{
.description{
display: none;
place-content: center;
color: var(--color-text-black);
}
.potential-challenge-display:hover{
.extra-info{
display: flex;
flex-direction: row;
place-content: center;
gap: 1.0%;
}
.content{
overflow: scroll;
}
.description{
overflow: visible;
}
.expanded{
display: flex;
place-content: center;
}
.description-info{
text-align: center;
color: var(--color-text-black);
}
.button-container{
margin-top: 1.5%;
display: flex;
width: 100%;
height: 25%;
place-content: center;
}
.complete-button{
border-radius: 20px;
width: 50%;
height: 100%;
border: none;
background-color: var(--color-save-button);
}
......@@ -152,30 +173,4 @@ const deleteTheChallenge = () => {
font-weight: bold;
}
@media only screen and (max-width: 1000px){
.extra-info{
display: flex;
flex-direction: row;
place-content: center;
gap: 1.0%;
}
.potential-challenge-display:hover{
.description{
text-align: center;
color: var(--color-text-black);
}
}
.potential-challenge-display:hover{
.extra-info{
display: flex;
flex-direction: row;
place-content: center;
gap: 1.0%;
}
}
}
</style>
\ No newline at end of file
......@@ -29,7 +29,9 @@ const activeChallenges = ref<Challenge[]>([])
const challengeToBeCompleted = ref<number|any>(null)
const challengeToBeDeleted = ref<number|any>(null)
const SIZE = 4
const expandedChallengeId = ref<number>(-1);
const SIZE = 3
const pages = ref<number>(1)
const currentPage = ref<number>(0)
......@@ -72,6 +74,7 @@ const closeDeletePopUp = async () => {
}
const handleChallengeCompleted = async () => {
eventBus.emit('updateMilestones');
await closePopUp();
await jsConfetti.addConfetti();
await fetchActiveChallenges();
......@@ -93,6 +96,14 @@ const nextPage = () =>{
currentPage.value ++;
}
const toggleMilestoneHeight = (id: number) => {
if(expandedChallengeId.value == id){
expandedChallengeId.value = -1;
} else {
expandedChallengeId.value = id;
}
};
eventBus.on('updateChallenges', () => {
fetchActiveChallenges();
});
......@@ -123,10 +134,13 @@ watch(currentPage, fetchActiveChallenges);
<ActiveChallengeDisplay
class="active-challenge"
v-for="(activeChallenge, index) in activeChallenges"
:class="{'expanded': expandedChallengeId == activeChallenge.challengeId}"
:key="index"
:challenge="activeChallenge"
:expanded="expandedChallengeId == activeChallenge.challengeId"
@challengeCompleted="handleRequestToCompleteChallenge(activeChallenge.challengeId)"
@challengeDeleted ="handleRequestToDeleteChallenge(activeChallenge.challengeId)"
@click="toggleMilestoneHeight(activeChallenge.challengeId)"
></ActiveChallengeDisplay>
<h4 class="challenge-placeholder" id="active-challenge-placeholder" v-if="activeChallenges.length == 0">
Du har ingen aktive utfordringer.<br>
......@@ -134,6 +148,7 @@ watch(currentPage, fetchActiveChallenges);
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>1" class="page-numbers">
......@@ -169,20 +184,16 @@ watch(currentPage, fetchActiveChallenges);
.active-challenge-component{
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
padding: 5.0%;
gap: 2.5%;
place-content: space-between;
}
.active-challenges{
display: flex;
flex-direction: column;
height: 100%;
height: 90%;
width: 100%;
gap:2.5%
}
......@@ -192,13 +203,19 @@ watch(currentPage, fetchActiveChallenges);
border: 2px solid var(--color-border);
background-color: var(--color-background-white);
min-height: calc(calc(100% - 2.5*4%)/4);
height: calc(calc(100% - 2.5*2%)/3);
width: 100%;
}
.active-challenge:hover{
transform: scale(1.05);
transform: scale(1.02);
cursor: pointer;
}
.expanded{
height: calc(calc(calc(100% - 2.5*2%)/3)*1.5);
}
#active-challenge-placeholder{
color: var(--color-headerText);
}
......@@ -211,6 +228,7 @@ watch(currentPage, fetchActiveChallenges);
justify-content: center;
align-items: center;
width: 100%;
height: 10%;
flex: 1;
}
......
......@@ -97,7 +97,6 @@ const acceptChallenge = async () => {
gap: 1.0%;
}
.options{
display: flex;
flex-direction: row;
......
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 330 330" xml:space="preserve">
<path id="XMLID_225_" d="M325.607,79.393c-5.857-5.857-15.355-5.858-21.213,0.001l-139.39,139.393L25.607,79.393
c-5.857-5.857-15.355-5.858-21.213,0.001c-5.858,5.858-5.858,15.355,0,21.213l150.004,150c2.813,2.813,6.628,4.393,10.606,4.393
s7.794-1.581,10.606-4.394l149.996-150C331.465,94.749,331.465,85.251,325.607,79.393z"/>
</svg>
\ No newline at end of file
......@@ -48,7 +48,9 @@ const isToExpire = () => {
<template>
<div class="active-milestone-display" @click="openMilestone">
<h2 class="title" :class="{'expire': isToExpire()}">{{props.title}}</h2>
<div class="img"> [Bilde]</div>
<div class="img">
<img src="/src/assets/background/img.png" alt="milestone-img" class="milestone-img">
</div>
<div class="progress-description">
<h4 class="description" v-if="goalSum&&currentSum">{{props.currentSum}}kr av {{props.goalSum}}kr</h4>
......@@ -69,6 +71,11 @@ const isToExpire = () => {
width: 100%;
padding: 1.5%;
}
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: pointer;
}
.title{
text-align: left;
}
......@@ -81,7 +88,14 @@ const isToExpire = () => {
place-content: center;
place-items: center;
background-color: lightgrey;
overflow: hidden;
}
.milestone-img{
display: flex;
width: 100%;
}
.description{
text-align: left;
}
......
......@@ -4,6 +4,7 @@ import ActiveMilestoneDisplay from '@/components/milestone/ActiveMilestoneDispla
import { onMounted, ref } from 'vue'
import { useTokenStore } from '@/stores/token'
import { getAllMilestonesPaginated } from '@/utils/MilestoneUtils'
import eventBus from '@/components/service/eventBus.js'
interface Milestone{
milestoneId: number;
......@@ -55,6 +56,11 @@ const nextPage = () =>{
fetchActiveMilestones();
}
eventBus.on('updateMilestones', () => {
fetchActiveMilestones();
});
</script>
<template>
......@@ -111,7 +117,7 @@ const nextPage = () =>{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
height: 90%;
gap: 2.5%;
}
......@@ -121,21 +127,21 @@ const nextPage = () =>{
border: 2px solid var(--color-border);
box-shadow: 0 4px 4px var(--color-shadow);
height: calc(100%/3);
height: calc(95%/3);
width: 100%;
}
.active-milestone:hover{
transform: scale(1.02);
transition: 0.3s;
cursor: pointer;
}
.pagination {
display: flex;
justify-content: left;
align-items: center;
width: 100%;
height: 10%;
}
.pagination button {
......
<script setup lang="ts">
import {ref} from "vue";
const props = defineProps({
id: Number,
......@@ -9,28 +8,28 @@ const props = defineProps({
currentSum: Number,
deadline: Date,
startDate: Date,
image: String
image: String,
expanded: Boolean
});
const imageUrl = "src/assets/pig.png"
const displayDescription = ref(false)
</script>
<template>
<div class="completed-milestone-display"
@mouseover="displayDescription = true"
@mouseleave="displayDescription = false"
:style="{
backgroundImage: image ? 'url(' + image + ')' : 'url(' + imageUrl + ')'
}">
<div class="completed-milestone-display">
<h2 class="title">{{props.title}}</h2>
<div class="info" v-if="!displayDescription">
<h4 v-if="currentSum">Du sparte {{props.currentSum}}kr</h4>
<h4 v-if="deadline">{{new Date(deadline).getDate()}}/{{new Date(deadline).getMonth()}}-{{new Date(deadline).getFullYear()}}</h4>
<div class="center-content">
<div class="img">
<img src="/src/assets/background/img.png" alt="milestone-img" class="milestone-img">
</div>
<div class="description-info" :class="{'expanded':expanded}">
<h4 class="description-title">Beskrivelse: </h4>
<h4 class="description">{{props.description}}</h4>
</div>
</div>
<div class="info" v-if="displayDescription">
<h4>{{props.description}}</h4>
<div class="info">
<h4 v-if="currentSum">Du sparte {{props.currentSum}}kr av {{props.goalSum}}kr</h4>
<h4 v-if="deadline">{{new Date(deadline).getDate()}}/{{new Date(deadline).getMonth()}}-{{new Date(deadline).getFullYear()}}</h4>
</div>
</div>
......@@ -40,18 +39,76 @@ const displayDescription = ref(false)
.completed-milestone-display{
display:flex;
flex-direction: column;
place-content: space-between;
place-items: start;
height: 100%;
width: 100%;
padding: 1.5%;
color: var(--color-text-black);
}
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: pointer;
}
.title{
text-align: left;
place-content: start;
}
.center-content{
display: flex;
flex-direction: column;
width: 100%;
height: 50%;
}
.img{
display: flex;
border-radius: 10px;
background-color: lightgrey;
place-content: center;
place-items: center;
height: 10vh;
min-height: 50px;
overflow: hidden;
}
.milestone-img{
display: flex;
filter: grayscale(100%);
width: 100%;
}
.description-info{
display: none;
}
.expanded{
display: flex;
flex-direction: column;
height: 50%;
width: 100%;
align-content: start;
place-content: start;
text-align: start;
}
.description-title{
text-decoration: underline;
}
.description{
overflow-y: scroll;
}
.info{
display: flex;
flex-direction: row;
height: 100%;
width: 100%;
text-align: left;
justify-content: space-between;
align-content: end;
place-items: end;
}
......
......@@ -18,11 +18,11 @@ interface Milestone{
}
const token = useTokenStore().jwtToken
const expandedMileStoneId = ref<number>(-1);
const completedMilestones = ref<Milestone[]>([])
const currentPage = ref<number>(0)
const pages = ref<number>(1)
const SIZE = 4
const SIZE = 3
onMounted( () => {
fetchActiveMilestones();
......@@ -54,14 +54,23 @@ const nextPage = () =>{
fetchActiveMilestones();
}
const toggleMilestoneHeight = (id: number) => {
if(expandedMileStoneId.value == id){
expandedMileStoneId.value = -1;
} else {
expandedMileStoneId.value = id;
}
};
</script>
<template>
<div class="completed-milestones-component">
<div class="milestones">
<CompletedMilestoneDisplay
class="completed-milestone"
v-for="(completedMilestone, index) in completedMilestones"
class="completed-milestone"
:class="{'expanded': expandedMileStoneId == completedMilestone.milestoneId}"
:key="index"
:id="completedMilestone.milestoneId"
:title="completedMilestone.milestoneTitle"
......@@ -71,6 +80,8 @@ const nextPage = () =>{
:deadline="completedMilestone.deadlineDate"
:start-date="completedMilestone.startDate"
:image="completedMilestone.milestoneImage"
:expanded="expandedMileStoneId == completedMilestone.milestoneId"
@click="toggleMilestoneHeight(completedMilestone.milestoneId)"
></CompletedMilestoneDisplay>
<h4 class="milestone-placeholder" v-if="completedMilestones.length == 0">
Du har ingen fullførte sparemål
......@@ -103,8 +114,6 @@ const nextPage = () =>{
height: 100%;
width: 100%;
place-content: space-between;
padding: 5.0%;
gap: 2.5%;
}
......@@ -113,9 +122,8 @@ const nextPage = () =>{
display: flex;
flex-direction: column;
gap: 2.5%;
width: 100%;
height: 100%;
height: 90%;
}
.completed-milestone{
......@@ -123,13 +131,18 @@ const nextPage = () =>{
border: 2px solid var(--color-border);
background-color: var(--color-background-white);
min-height: calc(calc(100% - 2.5*4%)/4);
height: calc(calc(100% - 2.5*2%)/3);
width: 100%;
}
.completed-milestone:hover{
transform: scale(1.05);
transition: 0.3s;
transform: scale(1.02);
cursor: pointer;
transition: none;
}
.expanded{
height: calc(calc(calc(100% - 2.5*2%)/3)*1.5);
}
.milestone-placeholder{
......@@ -141,6 +154,7 @@ const nextPage = () =>{
justify-content: center;
align-items: center;
width: 100%;
height: 10%;
flex: 1;
}
......
......@@ -87,6 +87,7 @@ const closeHelpPopUp = async () => {
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.popup-container {
......@@ -115,7 +116,7 @@ const closeHelpPopUp = async () => {
display: flex;
flex-direction: row;
width: 100%;
min-height: 115%;
min-height: 120%;
padding-bottom: 1.5%;
gap: 2.5%;
}
......@@ -133,7 +134,7 @@ const closeHelpPopUp = async () => {
background-color: var(--color-confirm-button);
border: 2px solid var(--color-border);
color: var(--color-button-text);
min-height: 12%;
min-height: 10%;
}
.create-challenge-button:active{
......@@ -158,7 +159,7 @@ const closeHelpPopUp = async () => {
box-shadow: 0 4px 4px var(--color-shadow);
background-color: var(--color-heading);
height: 100%;
min-height: 100%;
width: 40%;
}
......
......@@ -102,6 +102,7 @@ onMounted(async () => {
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.popup-container {
......@@ -140,6 +141,9 @@ onMounted(async () => {
.article-item {
width: calc(calc(100% - 2 * 1.5%) / 3);
height: 7.0%;
h1:hover, h3:hover, h2:hover, h4:hover{
cursor: pointer;
}
}
.article-content {
......@@ -190,6 +194,9 @@ onMounted(async () => {
.article-link {
text-decoration: none;
color: inherit;
background: none;
transition: none;
border-radius: 20px;
}
</style>
\ No newline at end of file
......@@ -252,6 +252,7 @@ const getRandomColor = () => {
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.title{
......
......@@ -68,7 +68,7 @@ userSavings()
Ny til Sparesti? Klikk her!
</h2>
</button>
<ActiveMilestonesList></ActiveMilestonesList>
<ActiveMilestonesList class="active-challenges"></ActiveMilestonesList>
</div>
<div class="right" :class="{ 'mobile-hide': displayType }">
<h2 class="active-challenges-title">Aktive utfordringer</h2>
......@@ -98,6 +98,7 @@ userSavings()
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.popup-container {
......@@ -144,7 +145,7 @@ userSavings()
background-color: var(--color-confirm-button);
border: 2px solid var(--color-border);
color: var(--color-button-text);
min-height: 12%;
min-height: 10%;
}
.create-challenge-button:active{
......@@ -155,6 +156,10 @@ userSavings()
transform: scale(1.02);
}
.active-challenges{
height: 90%;
}
.display-help-button{
font-weight: bold;
}
......
......@@ -135,6 +135,7 @@ const closeHelpPopUp = async () => {
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.popup-container {
......
......@@ -86,6 +86,7 @@ const closeHelpPopUp = () => {
.help-icon:hover{
transform: scale(1.05);
cursor: pointer;
}
.popup-container {
......@@ -132,7 +133,7 @@ const closeHelpPopUp = () => {
background-color: var(--color-confirm-button);
border: 2px solid var(--color-border);
color: var(--color-button-text);
min-height: 12%;
min-height: 10%;
}
.create-milestone-button:active{
......@@ -147,6 +148,10 @@ const closeHelpPopUp = () => {
font-weight: bold;
}
.active-milestones{
height: 90%;
}
.right{
display: flex;
flex-direction: column;
......@@ -157,7 +162,7 @@ const closeHelpPopUp = () => {
box-shadow: 0 4px 4px var(--color-shadow);
background-color: var(--color-heading);
height: 100%;
min-height: 100%;
width: 40%;
}
......
......@@ -91,7 +91,7 @@ const closePopup = () => {
flex-direction: row;
height: 88%;
width: 100%;
min-height: 650px;
min-height: 700px;
}
.side-nav{
......
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