diff --git a/src/assets/cowboySpare.gif b/src/assets/cowboySpare.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff0d6f0b3d077811bd1871ad7c7889fd11a7164c Binary files /dev/null and b/src/assets/cowboySpare.gif differ diff --git a/src/assets/golfSpare.gif b/src/assets/golfSpare.gif new file mode 100644 index 0000000000000000000000000000000000000000..b67cad84e2dc45e7b95d31b665eae3af1ebc3eb9 Binary files /dev/null and b/src/assets/golfSpare.gif differ diff --git a/src/assets/hotAirBalloonSpare.gif b/src/assets/hotAirBalloonSpare.gif new file mode 100644 index 0000000000000000000000000000000000000000..78f999f0295efdd779e47f0e74cb33bcd1e8a1ba Binary files /dev/null and b/src/assets/hotAirBalloonSpare.gif differ diff --git a/src/assets/sleepingSpare.gif b/src/assets/sleepingSpare.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ea7d3dcc3f1efaa6c9eb90fa75f70bd9b8856ff Binary files /dev/null and b/src/assets/sleepingSpare.gif differ diff --git a/src/components/InteractiveSpare.vue b/src/components/InteractiveSpare.vue index 30d6bfba84ae6a25849dcb3a749007f332900c71..b446ca531d0365f002d1afec763c527d7f0b974e 100644 --- a/src/components/InteractiveSpare.vue +++ b/src/components/InteractiveSpare.vue @@ -1,21 +1,26 @@ <template> <div - class="flex items-center max-w-80 w-full" + class="flex items-center mr-10 max-w-[60vh]" :class="{ 'flex-row': direction === 'right', 'flex-row-reverse': direction === 'left' }" > <!-- Image --> <img :src="spareImageSrc" - :class="['w-' + pngSize, 'h-' + pngSize, imageClass]" + :style="{ width: pngSize + 'rem', height: pngSize + 'rem' }" + :class="['object-contain', ...imageClass]" alt="Sparemannen" + class="w-dynamic h-dynamic object-contain" @click="nextSpeech" /> + <!-- Speech Bubble --> <div v-if="currentSpeech" - class="rounded-lg bg-white p-4 text-black border-black border-2 min-h-16 max-w-48" + :class="`mb-40 inline-block relative w-64 bg-white p-4 rounded-3xl border border-gray-600 tri-right round ${bubbleDirection}`" > - <span>{{ currentSpeech }}</span> + <div class="text-left leading-6"> + <p class="m-0">{{ currentSpeech }}</p> + </div> </div> </div> </template> @@ -59,4 +64,70 @@ const imageClass = computed(() => { props.direction === 'right' ? 'scale-x-[-1]' : '' // Flip image if right ] }) + +const bubbleDirection = computed(() => { + return props.direction === 'right' ? 'btm-left-in' : 'btm-right-in' +}) </script> +<style scoped> +/* CSS talk bubble */ + +.border { + border: 0.375rem solid black; +} +.round { + border-radius: 1.875rem; + -webkit-border-radius: 1.875rem; + -moz-border-radius: 1.875rem; +} + +/*Right triangle, placed bottom left side slightly in*/ +.tri-right.border.btm-left-in:before { + content: ' '; + position: absolute; + width: 0; + height: 0; + left: 1.875rem; + right: auto; + top: auto; + bottom: -2.5rem; + border: 1.25rem solid; + border-color: black transparent transparent black; +} +.tri-right.btm-left-in:after { + content: ' '; + position: absolute; + width: 0; + height: 0; + left: 2.375rem; + right: auto; + top: auto; + bottom: -1.25rem; + border: 0.75rem solid; + border-color: white transparent transparent white; +} + +/*Right triangle, placed bottom right side slightly in*/ +.tri-right.border.btm-right-in:before { + content: ' '; + position: absolute; + width: 0; + height: 0; + left: auto; + right: 1.875rem; + bottom: -2.5rem; + border: 1.25rem solid; + border-color: black black transparent transparent; +} +.tri-right.btm-right-in:after { + content: ' '; + position: absolute; + width: 0; + height: 0; + left: auto; + right: 2.375rem; + bottom: -1.25rem; + border: 0.75rem solid; + border-color: white white transparent transparent; +} +</style> diff --git a/src/components/__tests__/HomeViewTest.spec.ts b/src/components/__tests__/HomeViewTest.spec.ts index b48a96bb1c9e244380fecc67461d4277305ae604..e61e4355c3afcb94409b66f8fc4030d7c97a065b 100644 --- a/src/components/__tests__/HomeViewTest.spec.ts +++ b/src/components/__tests__/HomeViewTest.spec.ts @@ -77,7 +77,7 @@ describe('HomeView', () => { completion: 90 } wrapper.vm.incrementSaved(challenge) - expect(challenge.saved).toBe(100) + expect(challenge.saved).toBe(110) expect(challenge.completion).toBe(100) }) diff --git a/src/components/__tests__/InteractiveSpareTest.spec.ts b/src/components/__tests__/InteractiveSpareTest.spec.ts index cc6ae09f86276592d787d69d15f655290fd68b46..47ae6b194a393cae1b57360e631fe1b6e3ccc17a 100644 --- a/src/components/__tests__/InteractiveSpareTest.spec.ts +++ b/src/components/__tests__/InteractiveSpareTest.spec.ts @@ -52,8 +52,8 @@ describe('SpeechBubbleComponent', () => { pngSize: 100 } }) - expect(wrapper.find('span').text()).toBe('First speech') + expect(wrapper.find('p').text()).toBe('First speech') await wrapper.find('img').trigger('click') - expect(wrapper.find('span').text()).toBe('Second speech') + expect(wrapper.find('p').text()).toBe('Second speech') }) }) diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index ef848f68ecd2052db2c6e052931a7f9a417d3185..1b40fb3992915e355411ed1d4a573036e174a5cb 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -1,36 +1,34 @@ <template> - <div class="flex flex-col max-h-[60vh] md:flex-row md:max-h-[80vh] mx-auto"> + <div class="flex flex-col items-center max-h-[60vh] md:flex-row md:max-h-[80vh] mx-auto"> <div class="flex flex-col basis-1/3 order-last md:order-first md:basis-1/2"> <InteractiveSpare :speech="speech" :direction="'right'" - :pngSize="60" + :pngSize="15" class="opacity-0 h-0 w-0 md:opacity-100 md:h-auto md:w-auto md:mx-auto md:my-20" ></InteractiveSpare> - <div class="flex flex-row gap-12 items-center mx-auto p-8 md:flex-col md:gap-4 md:m-8"> + <div class="flex flex-row gap-2 items-center mx-auto my-4 md:flex-col md:gap-4 md:m-8"> <ButtonAddGoalOrChallenge :buttonText="'Legg til sparemÃ¥l'" /> <ButtonAddGoalOrChallenge :buttonText="'Legg til spareutfordring'" /> </div> </div> - <div - class="flex flex-col basis-2/3 max-h-[70vh] mx-auto max-w-5/6 md:basis-1/2 md:max-h-full" - > + <div class="flex flex-col basis-2/3 max-h-full mx-auto max-w-5/6 md:basis-1/2"> <div class="flex justify-center align-center"> <span - class="w-full max-w-60 max-h-12 bg-green-500 text-white font-bold py-2 rounded mt-8 text-center space-x-2" + class="w-full max-w-60 max-h-12 bg-green-500 text-white font-bold py-2 rounded mt-8 text-center space-x-2 drop-shadow-lg" > Din Sparesti </span> </div> - <div class="h-2 w-4/6 bg-black mx-auto my-2 opacity-10"></div> + <div class="h-1 w-4/6 bg-black mx-auto my-2 opacity-10"></div> <div ref="containerRef" - class="container relative mx-auto p-6 no-scrollbar max-h-[60vh] overflow-y-auto" + class="container relative mx-auto pt-6 w-4/5 md:w-3/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60v] overflow-y-auto border-2 border-black rounded-lg bg-white shadow-lg" > <div v-for="(challenge, index) in challenges" :key="challenge.title" - class="flex flex-col items-center mx-8" + class="flex flex-col items-center" > <!-- Challenge Row --> <div @@ -40,6 +38,20 @@ }" class="flex flex-row w-2/3 ml-8" > + <div class="mr-10"> + <img + v-if="index === 3" + src="@/assets/sleepingSpare.gif" + alt="could not load" + class="w-32 h-32 border-2 border-black" + /> + <img + v-else-if="index === 1" + src="@/assets/golfSpare.gif" + alt="could not load" + class="w-32 h-32 border-2 border-black" + /> + </div> <!-- Challenge Icon and Details --> <div class="flex"> <!-- Challenge Icon --> @@ -104,6 +116,20 @@ <img src="@/assets/pending.png" alt="" />ï¸ </div> </div> + <div class=""> + <img + v-if="index === 0" + src="@/assets/cowboySpare.gif" + alt="could not load" + class="h-32 w-32 border-2 border-black" + /> + <img + v-else-if="index === 2" + src="@/assets/hotAirBalloonSpare.gif" + class="h-32 w-32 border-black border-2" + alt="could not load" + /> + </div> </div> <!-- Piggy Steps, centered --> <div v-if="index !== challenges.length" class="flex justify-center w-full"> @@ -133,18 +159,21 @@ + </button> </div> + <!-- Finish line --> </div> + <img + src="@/assets/finishLine.png" + class="w-full max-h-4 mx-auto mt-10" + alt="Finish Line" + /> <!-- Sparemannen --> <InteractiveSpare :speech="speech" :direction="'left'" - :pngSize="20" + :pngSize="6" class="fixed bottom-0 right-0 mb-40 mr-4 md:opacity-0 md:h-0 md:w-0" ></InteractiveSpare> </div> - <!-- Finish line --> - <img src="@/assets/finishLine.png" class="w-1/2 max-h-4 mx-auto" alt="Finish Line" /> - <!-- Goal --> <div v-if="goal" class="flex flex-row gap-24 m-t-2 pt-6 mx-auto"> <div class="flex flex-col items-start"> @@ -208,13 +237,13 @@ const goal: Goal = { } const challenge: Challenge = { - title: 'Coffe', - saved: 1200.5, - target: 3000, + title: 'Coffee', + saved: 50, + target: 100, description: 'Saving monthly for a year-end vacation to Bali', createdOn: new Date('2023-01-01T00:00:00Z'), dueDate: new Date('2023-12-31T23:59:59Z'), - type: 'COFFE', + type: 'COFFEE', completion: 40, completedOn: undefined // Not yet completed } @@ -234,12 +263,23 @@ const challenges = ref([challenge, challenge1]) // AddSpareUtfordring function addSpareUtfordring() { - console.log('Add Spare Utfordring') + const newChallenge: Challenge = { + title: 'Coffee', + saved: 0, + target: 1000, + description: 'Saving monthly for a year-end vacation to Bali', + createdOn: new Date('2023-01-01T00:00:00Z'), + dueDate: new Date('2023-12-31T23:59:59Z'), + type: 'COFFEE', + completion: 0, + completedOn: undefined // Not yet completed + } + challenges.value.push(newChallenge) } // Increment saved amount function incrementSaved(challenge: Challenge) { - challenge.saved += 10 + challenge.saved += 20 if (challenge.saved >= challenge.target) { challenge.completion = 100 }