Skip to content
Snippets Groups Projects
Commit 1d5aef44 authored by Anders Høvik's avatar Anders Høvik
Browse files

Merge branch 'main' into feature/activity-history

parents bcaba017 748d542f
Branches feature/activity-history
No related tags found
1 merge request!20Feature/activity history
Pipeline #274584 failed
Showing
with 536 additions and 15 deletions
<script setup lang="ts">
import { RouterView } from 'vue-router'
import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue';
// import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue';
</script>
<template>
......
......@@ -9,6 +9,28 @@ import type { CancelablePromise } from '../core/CancelablePromise';
import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
export class AuthenticationService {
/**
* Validate email
* Check that the given email is valid
* @returns any Email is valid
* @throws ApiError
*/
public static validateEmail({
email,
}: {
email: string,
}): CancelablePromise<Record<string, any>> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/auth/valid-email/{email}',
path: {
'email': email,
},
errors: {
409: `Email already exists`,
},
});
}
/**
* User Signup
* Sign up a new user
......
<script setup lang="ts">
const props = defineProps({
id: {
type: String,
required: true
},
text: {
type: String,
default: ''
}
})
</script>
<template>
<span>
<input type="checkbox" class="btn-check" :id="props.id" autocomplete="off">
<label class="btn btn-outline-primary align-items-center justify-content-center" :for="props.id">{{ props.text }}</label>
</span>
</template>
<style scoped>
label {
margin: 5px
}
</style>
\ No newline at end of file
<script setup lang="ts">
import ProgressBar from '@/components/Configuration/ProgressBar.vue'
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const router = useRouter()
// The configuration steps with path and order value.
const configurationSteps = {'/bank-id': 1, '/commitment': 2, '/experience': 3, '/suitable-challenges': 4, '/first-saving-goal': 5}
const length = Object.keys(configurationSteps).length
let percentage = ref(1/length);
// Pushes to '/bank-id' RouterView and sets current path to this path.
router.push(Object.keys(configurationSteps)[0])
let currentRoute = useRoute()
let currentPath = currentRoute.fullPath
const onNewRouteEvent = (path) => {
currentPath = path
percentage.value = (1/length) * configurationSteps[path]
}
</script>
<template>
<div class="container">
<div class="progress-bar-container">
<ProgressBar id="progressbar" :percentage="percentage"/>
</div>
<div class="configuration-container">
<RouterView @changeRouterEvent="onNewRouteEvent"/>
</div>
</div>
</template>
<style scoped>
.container {
display: grid;
grid-template-rows: 0.5fr 2.3fr 0.2fr;
}
#progressbar {
padding-top: 2rem;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import Button1 from '@/components/Buttons/Button1.vue'
import { useRouter } from 'vue-router'
import { ref } from 'vue'
const formRef = ref()
const router = useRouter();
const emit = defineEmits(['changeRouterEvent']);
emit('changeRouterEvent', '/bank-id');
const onClick = () => {
const radios = formRef.value.querySelectorAll('input[type="radio"]');
const checkedRadios = Array.from(radios).filter(radio => radio.checked);
if (checkedRadios.length === 0) {
alert('Please select an option.');
return;
}
router.push('/commitment')
}
</script>
<template>
<div class="container">
<div>
<h3 class="d-flex align-items-center justify-content-center">
In order to provide best advice we need to connect to your bank account
</h3>
</div>
<form class="btn-group-vertical" ref="formRef" @submit.prevent="onClick">
<input type="radio" class="btn-check" name="bank-id" id="btn-check-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check-outlined">BankID på mobil</label>
<input type="radio" class="btn-check" name="bank-id" id="btn-check2-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check2-outlined">MinID</label>
<input type="radio" class="btn-check" name="bank-id" id="btn-check3-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check3-outlined">Vipps</label>
</form>
<div class="confirm-button-container">
<button1 id="confirmButton"
@click="onClick"
button-text="Continue">
</button1>
</div>
</div>
</template>
<style scoped>
#confirmButton {
margin-bottom: 2rem;
width: 300px;
}
.confirm-button-container {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import Button1 from '@/components/Buttons/Button1.vue'
import { useRouter } from 'vue-router'
import { ref } from 'vue'
const router = useRouter();
const formRef = ref()
const onClick = () => {
const radios = formRef.value.querySelectorAll('input[type="radio"]');
const checkedRadios = Array.from(radios).filter(radio => radio.checked);
if (checkedRadios.length === 0) {
alert('Please select an option.');
return;
}
router.push('/experience')
}
const emit = defineEmits(['changeRouterEvent'])
emit('changeRouterEvent', '/commitment')
</script>
<template>
<div class="container">
<div>
<h3 class="d-flex align-items-center justify-content-center">
In which degree are you willing to make changes?
</h3>
</div>
<form class="btn-group-vertical" ref="formRef" @submit.prevent="onClick">
<input type="radio" class="btn-check" name="commitment" id="btn-check-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check-outlined">Low</label>
<input type="radio" class="btn-check" name="commitment" id="btn-check2-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check2-outlined">Medium</label>
<input type="radio" class="btn-check" name="commitment" id="btn-check3-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check3-outlined">High</label>
</form>
<div class="confirm-button-container">
<button1 id="confirmButton" @click="onClick" button-text="Continue"></button1>
</div>
</div>
</template>
<style scoped>
#confirmButton {
margin-bottom: 2rem;
width: 300px;
}
.confirm-button-container {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import Button1 from '@/components/Buttons/Button1.vue'
import { useRouter } from 'vue-router'
import { ref } from 'vue'
const router = useRouter();
const formRef = ref()
const onClick = () => {
const radios = formRef.value.querySelectorAll('input[type="radio"]');
const checkedRadios = Array.from(radios).filter(radio => radio.checked);
if (checkedRadios.length === 0) {
alert('Please select an option.');
return;
}
router.push('/suitable-challenges')
}
const emit = defineEmits(['changeRouterEvent'])
emit('changeRouterEvent', '/experience')
</script>
<template>
<div class="container">
<div>
<h3 class="d-flex align-items-center justify-content-center">
How much experice do you have with saving money?
</h3>
</div>
<form class="btn-group-vertical" ref="formRef" @submit.prevent="onClick">
<input type="radio" class="btn-check" name="experience" id="btn-check-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check-outlined">Beginner</label>
<input type="radio" class="btn-check" name="experience" id="btn-check2-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check2-outlined">Some experience</label>
<input type="radio" class="btn-check" name="experience" id="btn-check3-outlined" autocomplete="off">
<label class="btn btn-outline-primary d-flex align-items-center justify-content-center" for="btn-check3-outlined">Expert</label>
</form>
<div class="confirm-button-container">
<button1 id="confirmButton" @click="onClick" button-text="Continue"></button1>
</div>
</div>
</template>
<style scoped>
#confirmButton {
margin-bottom: 2rem;
width: 300px;
}
.confirm-button-container {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import BaseInput from '@/components/InputFields/BaseInput.vue'
import { ref } from 'vue'
import Button1 from '@/components/Buttons/Button1.vue'
import { useRouter } from 'vue-router'
const router = useRouter();
const emit = defineEmits(['changeRouterEvent'])
emit('changeRouterEvent', '/first-saving-goal')
const formRef = ref()
const titleRef = ref()
const sumRef = ref()
const dateRef = ref()
const onClick = () => {
formRef.value.classList.add("was-validated")
}
const getTodayDate = () => {
const today = new Date();
const year = today.getFullYear();
let month = today.getMonth() + 1;
let day = today.getDate();
// Ensure month and day are in double digits
month = month < 10 ? `0${month}` : month;
day = day < 10 ? `0${day}` : day;
console.log(`${year}-${month}-${day}`)
return `${year}-${month}-${day}`;
};
</script>
<template>
<div class="container">
<div>
<h3 class="d-flex align-items-center justify-content-center">
Create your first saving goal
</h3>
</div>
<form ref="formRef" id="loginForm" @submit.prevent="handleSubmit">
<BaseInput :model-value="titleRef"
@input-change-event="handleEmailInputEvent"
id="titleInput"
input-id="title"
label="Title"
placeholder="Enter the title of the saving goal"/>
<BaseInput :model-value="sumRef"
@input-change-event="handlePasswordInputEvent"
id="sumToSaveInput"
input-id="sumToSpareInput"
type="number"
label="Sum to save"
min="0"
placeholder="Enter the sum you would like to spare"/>
<BaseInput :model-value="dateRef"
@input-change-event="handlePasswordInputEvent"
id="dueDateInput"
input-id="dueDate"
type="date"
:min="getTodayDate()"
label="Due date"/>
</form>
<div class="confirm-button-container">
<button1 id="confirmButton" @click="onClick" button-text="Continue"></button1>
</div>
</div>
</template>
<style scoped>
#confirmButton {
margin-bottom: 2rem;
width: 300px;
}
.confirm-button-container {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import { useRouter } from 'vue-router'
const router = useRouter();
const onClick = () => {
router.push('/first-saving-goal')
}
import ChallangeCheckBox from '@/components/Configuration/ChallangeCheckBox.vue'
import Button1 from '@/components/Buttons/Button1.vue'
const emit = defineEmits(['changeRouterEvent'])
emit('changeRouterEvent', '/suitable-challenges')
const challenges = ['Make packed lunch', 'Stop shopping', 'Drop coffee',
'Quit subscription', 'Drop car', 'Short showers', 'Exercise outside', 'Make budget', 'Others'
]
</script>
<template>
<div class="container">
<div>
<h3 class="d-flex align-items-center justify-content-center">
Which challenges are suitable for you?
</h3>
</div>
<div class="challenge-container">
<ChallangeCheckBox v-for="(item, index) in challenges" :id="index" :text="item"/>
</div>
<div class="confirm-button-container">
<button1 id="confirmButton" @click="onClick" button-text="Continue"></button1>
</div>
</div>
</template>
<style scoped>
.challenge-container {
justify-self: center;
max-width: 500px;
}
#confirmButton {
margin-bottom: 2rem;
width: 300px;
}
.confirm-button-container {
display: flex;
justify-content: center;
}
</style>
\ No newline at end of file
<script setup lang="ts">
const props = defineProps({
percentage: {
type: Number,
default: 0
}
})
</script>
<template>
<div class="container">
<div class="progress">
<div id="configuration-progress"
class="progress-bar progress-bar-striped bg-info progress-bar-animated"
role="progressbar"
:aria-valuenow="props.percentage"
:style="{ width: Math.round(props.percentage*100) + '%' }"
aria-valuemin="0"
aria-valuemax="100"/>
</div>
<label class="row text-info font-bold display-5">{{ Math.round(props.percentage*100) + '%' }} Completed</label>
</div>
</template>
<style scoped>
.progress {
height: 35px;
border-radius: 12px;
}
.row {
justify-content: center;
}
</style>
\ No newline at end of file
......@@ -25,6 +25,10 @@ const props = defineProps({
isValid: {
type: Boolean,
default: false
},
min: {
type: String,
required: false
}
});
......@@ -41,7 +45,9 @@ const onInputEvent = (event: any) => {
:type="props.type"
class="form-control"
:placeholder="props.placeholder"
:id="inputId" required />
:id="inputId" required
:min="min"
/>
<div v-if="props.isValid" class="invalid-feedback">Invalid {{ label }}</div>
<div v-else class="valid-feedback">Valid {{ label }}</div>
</div>
......
......@@ -9,7 +9,6 @@ const formRef = ref()
const handleEmailInputEvent = (newValue: any) => {
emailRef.value = newValue
console.log(emailRef.value)
}
const handlePasswordInputEvent = (newValue: any) => {
......
......@@ -20,7 +20,7 @@ export default {
if (timelineElement instanceof HTMLElement) {
// Calculate the max-height based on the height of the timeline
const timelineHeight = timelineElement.offsetHeight;
this.bluePanelMaxHeight = `${timelineHeight*1.25}px`;
this.bluePanelMaxHeight = `${timelineHeight*1.55}px`;
} else {
this.bluePanelMaxHeight = '700px';
}
......@@ -41,7 +41,7 @@ export default {
<div class="col-lg-4 blue-background overflow-auto" :style="{ 'max-height': bluePanelMaxHeight }">
<h3 style="color: white; margin-bottom: 16px">Your saving goals</h3>
<div>
<button class="btn btn-light" style="font-weight: 600; margin-bottom: 20px" @click="createGoal">Create new saving goal</button>
<button class="btn btn-success btn-lg" style="font-weight: 600; margin-bottom: 20px" @click="createGoal">Create new saving goal</button>
</div>
<saving-goal-list @goToSavingGoal="goToSavingGoal"></saving-goal-list>
</div>
......
......@@ -19,10 +19,9 @@
</div>
<!--Change this to date picker?-->
<p>How long should this saving goal last: </p>
<p>When should this saving goal end?:</p>
<div class="input-group mb-3">
<input type="text" class="form-control" aria-label="Amount of days" placeholder="Amount of days (as number)">
<span class="input-group-text">Days</span>
<input type="date" class="form-control" aria-label="Amount of days" placeholder="Amount of days (as number)">
</div>
<p>How much do you want to save during this saving goal: </p>
......
......@@ -2,7 +2,7 @@
import {ref} from "vue";
const savingGoalList = ref([
{ title: 'Spain trip', MoneyTarget: '200kr', description: 'You wanted to save 200kr on a spain trip' },
{ title: 'Spain trip', MoneyTarget: '200kr', description: 'You wanted to save 200kr for a spain trip' },
{ title: 'Italy Escapade', MoneyTarget: '200kr', description: 'Experience the magic of Italy with us! Our goal is to save 200kr for an amazing trip to Italy.' },
{ title: 'French Getaway', MoneyTarget: '200kr', description: 'Join us as we plan to save 200kr for a delightful trip to France!' },
{ title: 'Exploring Greece', MoneyTarget: '200kr', description: 'Dreaming of Greece? Lets work together to save 200kr for that unforgettable trip!' },
......@@ -17,6 +17,10 @@ const emits = defineEmits(['goToSavingGoal']);
const goToSavingGoal = () => {
emits('goToSavingGoal');
};
const deleteSavingGoal = () => {
};
</script>
<template>
......@@ -28,6 +32,7 @@ const goToSavingGoal = () => {
<h5 class="card-title">{{ savingGoal.title }}</h5>
<p class="card-text">{{ savingGoal.description }}</p>
<a href="#" class="btn btn-light" @click="goToSavingGoal">Go to saving goal</a>
<a href="#" class="btn btn-danger" @click="deleteSavingGoal" style="margin-left: 8px">Delete</a>
</div>
</div>
</template>
......
......@@ -45,10 +45,12 @@ export default {
<div class="SavingGoalTitle text-center">{{title}}</div>
<ul class="timeline">
<li v-for="(step, index) in steps" :key="index" :class="{ 'timeline-inverted': index % 2 !== 0 }">
<div class="timeline-image z-1" @click="togglePanel(step)">
<img class="circular-image" :src="step.showPanel ? altImage : image" alt="">
</div>
<div class="timeline-panel z-3" v-show="step.showPanel">
<a :href="'#panel-' + index">
<div class="timeline-image z-1" @click="togglePanel(step)">
<img class="circular-image" :src="step.showPanel ? altImage : image" alt="">
</div>
</a>
<div class="timeline-panel z-3" :id="'panel-' + index" v-show="step.showPanel">
<div class="timeline-heading">
<h4>{{ step.title }}</h4>
<h4 class="subheading">{{step.description}}</h4>
......@@ -88,10 +90,11 @@ export default {
.SavingGoalTitle {
font-weight: 600;
font-size: 45px;
margin-top: 20px;
margin-bottom:40px;
padding-bottom: 10px;
color: white;
border-radius: 0 0 1em 1em;
border-radius: 1em;
background-color: #0A58CA;
}
......
......@@ -2,7 +2,9 @@
import BaseInput from '@/components/InputFields/BaseInput.vue'
import Button1 from '@/components/Buttons/Button1.vue'
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter();
const firstNameRef = ref('')
const surnameRef = ref('')
const emailRef = ref('')
......@@ -34,6 +36,7 @@ const handleConfirmPasswordInputEvent = (newValue: any) => {
const handleSubmit = () => {
formRef.value.classList.add("was-validated")
alert("Expected to be transferred to initial configuration") // Todo remove this line
router.push("/configuration")
}
</script>
......
......@@ -81,6 +81,38 @@ const routes = [
name: 'sign up',
component: () => import('@/views/Authentication/SignUpView.vue'),
},
{
path: '/configuration',
name: 'configuration',
component: () => import('@/views/ConfigurationView.vue'),
children: [
{
path: '/bank-id',
name: 'bankId',
component: () => import('@/components/Configuration/ConfigurationSteps/BankId.vue'),
},
{
path: '/commitment',
name: 'commitment',
component: () => import('@/components/Configuration/ConfigurationSteps/Commitment.vue'),
},
{
path: '/experience',
name: 'experience',
component: () => import('@/components/Configuration/ConfigurationSteps/Experience.vue'),
},
{
path: '/suitable-challenges',
name: 'suitable challenges',
component: () => import('@/components/Configuration/ConfigurationSteps/SuitableChallenges.vue'),
},
{
path: '/first-saving-goal',
name: 'first saving goal',
component: () => import('@/components/Configuration/ConfigurationSteps/FirstSavingGoal.vue'),
}
]
},
{
path: '/:pathMatch(.*)*',
redirect: { name: 'not-found' },
......
<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import { RouterView } from 'vue-router'
import Footer from '@/components/BaseComponents/Footer.vue'
import Menu from '@/components/BaseComponents/Menu.vue'
</script>
......
<script setup lang="ts">
import Configuration from '@/components/Configuration/Configuration.vue'
import Menu from '@/components/BaseComponents/Menu.vue'
import Footer from '@/components/BaseComponents/Footer.vue'
</script>
<template>
<Menu/>
<Configuration/>
<Footer/>
</template>
\ 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