Fixed couple of endpoints, implemented more of the frontend
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -22,11 +22,7 @@
|
|||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
<version>3.1.4</version>
|
<version>3.1.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
|
||||||
<artifactId>httpclient</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import com.faf223.expensetrackerfaf.service.UserService;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -33,11 +36,16 @@ public class UserController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{userUuid}")
|
@GetMapping("/getUserData")
|
||||||
public ResponseEntity<UserDTO> getUser(@PathVariable String userUuid) {
|
public ResponseEntity<UserDTO> getUser() {
|
||||||
User user = userService.getUserById(userUuid);
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
if (user != null) return ResponseEntity.ok(userMapper.toDto(user));
|
|
||||||
else return ResponseEntity.notFound().build();
|
if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) {
|
||||||
|
User user = userService.getUserByEmail(userDetails.getUsername());
|
||||||
|
if (user != null) return ResponseEntity.ok(userMapper.toDto(user));
|
||||||
|
else return ResponseEntity.notFound().build();
|
||||||
|
}
|
||||||
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.faf223.expensetrackerfaf.dto;
|
package com.faf223.expensetrackerfaf.dto;
|
||||||
|
|
||||||
import com.faf223.expensetrackerfaf.model.ExpenseCategory;
|
import com.faf223.expensetrackerfaf.model.ExpenseCategory;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -10,7 +9,6 @@ import java.time.LocalDate;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@JsonIgnoreProperties({"expenseCategory"})
|
|
||||||
public class ExpenseDTO {
|
public class ExpenseDTO {
|
||||||
private long expenseId;
|
private long expenseId;
|
||||||
private UserDTO userDTO;
|
private UserDTO userDTO;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.faf223.expensetrackerfaf.dto;
|
package com.faf223.expensetrackerfaf.dto;
|
||||||
|
|
||||||
import com.faf223.expensetrackerfaf.model.IncomeCategory;
|
import com.faf223.expensetrackerfaf.model.IncomeCategory;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -10,7 +9,6 @@ import java.time.LocalDate;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@JsonIgnoreProperties({"incomeCategory"})
|
|
||||||
public class IncomeDTO {
|
public class IncomeDTO {
|
||||||
private long incomeId;
|
private long incomeId;
|
||||||
private UserDTO userDTO;
|
private UserDTO userDTO;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
setCookie('access_token', access_token);
|
setCookie('access_token', access_token);
|
||||||
setCookie('refresh_token', refresh_token);
|
setCookie('refresh_token', refresh_token);
|
||||||
console.log(access_token, refresh_token);
|
console.log(access_token, refresh_token);
|
||||||
|
window.location.href = '/dashboard'
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Login failed:', error);
|
console.error('Login failed:', error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -2,7 +2,14 @@
|
|||||||
import DashHeader from "./DashHeader.svelte";
|
import DashHeader from "./DashHeader.svelte";
|
||||||
import DataMenu from "./DataMenu.svelte";
|
import DataMenu from "./DataMenu.svelte";
|
||||||
import QuickInfobar from "./QuickInfobar.svelte";
|
import QuickInfobar from "./QuickInfobar.svelte";
|
||||||
import NotificationBoard from "./NotificationBoard.svelte";
|
import { getCookie } from "svelte-cookie";
|
||||||
|
import {onMount} from "svelte";
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (getCookie('access_token') === null ) {
|
||||||
|
window.location.href = '/auth/login';
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="dashboard">
|
<div id="dashboard">
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
import Graph1 from './graphs/Graph1.svelte';
|
import Graph1 from './graphs/Graph1.svelte';
|
||||||
import Graph2 from './graphs/Graph2.svelte';
|
import Graph2 from './graphs/Graph2.svelte';
|
||||||
import Graph3 from './graphs/Graph3.svelte';
|
import Graph3 from './graphs/Graph3.svelte';
|
||||||
import Graph4 from './graphs/Graph4.svelte';
|
import Expenses from "./Expenses.svelte";
|
||||||
import Graph5 from './graphs/Graph5.svelte';
|
import Incomes from "./Incomes.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="dataMenu">
|
<div id="dataMenu">
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
<div id="oneVertical">
|
<div id="oneVertical">
|
||||||
<Graph3 />
|
<Graph3 />
|
||||||
</div>
|
</div>
|
||||||
<div id="twoHorizontal">
|
<div id="dataPanel">
|
||||||
<Graph4 />
|
<Incomes />
|
||||||
<Graph5 />
|
<Expenses />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#twoVertical {
|
#twoVertical {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -53,9 +52,9 @@
|
|||||||
min-height:0;
|
min-height:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#twoHorizontal {
|
#dataPanel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount, afterUpdate } from 'svelte';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { getCookie } from "svelte-cookie";
|
||||||
|
|
||||||
|
let data = [];
|
||||||
|
let parentHeight;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get('http://localhost:8081/expenses/personal-expenses', config);
|
||||||
|
data = response.data;
|
||||||
|
parentHeight = document.querySelector('#expenseInfo').offsetHeight;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
parentHeight = document.querySelector('#expenseInfo').offsetHeight;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="expenseInfo" style="max-height: {parentHeight}px;">
|
||||||
|
<h2>Expenses</h2>
|
||||||
|
<ul>
|
||||||
|
{#each data as item}
|
||||||
|
<li>
|
||||||
|
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}
|
||||||
|
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}
|
||||||
|
{`${item.date}`}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#expenseInfo {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||||
|
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover {
|
||||||
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount, afterUpdate } from 'svelte';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { getCookie } from "svelte-cookie";
|
||||||
|
|
||||||
|
let data = [];
|
||||||
|
let parentHeight;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get('http://localhost:8081/incomes/personal-incomes', config);
|
||||||
|
data = response.data;
|
||||||
|
parentHeight = document.querySelector('#incomeInfo').offsetHeight;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
parentHeight = document.querySelector('#incomeInfo').offsetHeight;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="incomeInfo" style="max-height: {parentHeight}px;">
|
||||||
|
<h2>Incomes</h2>
|
||||||
|
<ul>
|
||||||
|
{#each data as item}
|
||||||
|
<li>
|
||||||
|
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}
|
||||||
|
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}
|
||||||
|
{`${item.date}`}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#incomeInfo {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||||
|
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover {
|
||||||
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<script>
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div id="notificationBoard">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#notificationBoard {
|
|
||||||
display: none;
|
|
||||||
width:0;
|
|
||||||
height:0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -23,15 +23,12 @@
|
|||||||
height: 100px;
|
height: 100px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: #ffdde2;
|
background-color: #d3d3d3;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||||
/* border: 1px solid black; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.infobarElement:hover {
|
.infobarElement:hover {
|
||||||
/* color:white; */
|
|
||||||
/* background-color: black; */
|
|
||||||
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
|
||||||
const token = getCookie('access_token');
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
@@ -17,21 +18,22 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get('http://localhost:8081/incomes/00112233-4455-6677-8899-aabbccddeeaa', config);
|
const response = await axios.get('http://localhost:8081/incomes/personal-incomes', config);
|
||||||
|
console.log(response.data);
|
||||||
const incomeData = response.data;
|
const incomeData = response.data;
|
||||||
|
|
||||||
const chartLabels = incomeData.map(item => item.category.categoryName);
|
const chartLabels = incomeData.map(item => item.incomeCategory.name);
|
||||||
const chartValues = incomeData.map(item => item.amount);
|
const chartValues = incomeData.map(item => item.amount);
|
||||||
|
|
||||||
ctx = chartCanvas.getContext('2d');
|
ctx = chartCanvas.getContext('2d');
|
||||||
new Chart(ctx, {
|
new Chart(ctx, {
|
||||||
type: 'bar', // Set chart type to 'bar' for a bar graph
|
type: 'bar',
|
||||||
data: {
|
data: {
|
||||||
labels: chartLabels,
|
labels: chartLabels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Revenue',
|
label: 'Revenue',
|
||||||
backgroundColor: 'rgb(255, 99, 132)',
|
backgroundColor: 'rgb(255, 99, 132)',
|
||||||
data: chartValues // Changed from 'data' to 'chartValues'
|
data: chartValues
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -56,7 +58,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
background-color: #ffdde2;
|
background-color: #d3d3d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart:hover {
|
#chart:hover {
|
||||||
|
|||||||
@@ -1,48 +1,70 @@
|
|||||||
<script>
|
<script>
|
||||||
import chartjs from 'chart.js/auto';
|
import Chart from 'chart.js/auto';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
import axios from 'axios';
|
||||||
|
import {getCookie} from "svelte-cookie";
|
||||||
|
|
||||||
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
||||||
var config = {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
|
||||||
datasets: [{
|
|
||||||
fill: false,
|
|
||||||
data: [
|
|
||||||
5,
|
|
||||||
6,
|
|
||||||
3,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
label: "My Second dataset ",
|
|
||||||
fill: false,
|
|
||||||
data: [
|
|
||||||
5,
|
|
||||||
6,
|
|
||||||
3,
|
|
||||||
4
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
title:{
|
|
||||||
display:true,
|
|
||||||
text: "Chart.js Line Chart - Animation Progress Bar"
|
|
||||||
},
|
|
||||||
maintainAspectRatio: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let chartValues = [20, 10, 5, 2, 20, 30, 45];
|
|
||||||
let chartLabels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
|
||||||
let ctx;
|
let ctx;
|
||||||
let chartCanvas;
|
let chartCanvas;
|
||||||
|
|
||||||
onMount(async (promise) => {
|
onMount(async () => {
|
||||||
ctx = chartCanvas.getContext('2d');
|
|
||||||
var chart = new chartjs(ctx, config);
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get('http://localhost:8081/expenses/personal-expenses', config);
|
||||||
|
|
||||||
|
const aggregatedData = {};
|
||||||
|
|
||||||
|
response.data.forEach(item => {
|
||||||
|
const category = item.expenseCategory.name;
|
||||||
|
const amount = item.amount;
|
||||||
|
|
||||||
|
if (aggregatedData[category]) {
|
||||||
|
aggregatedData[category] += amount;
|
||||||
|
} else {
|
||||||
|
aggregatedData[category] = amount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const chartLabels = Object.keys(aggregatedData);
|
||||||
|
const chartValues = Object.values(aggregatedData);
|
||||||
|
|
||||||
|
ctx = chartCanvas.getContext('2d');
|
||||||
|
new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: chartLabels,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Revenue',
|
||||||
|
backgroundColor: 'rgb(255, 99, 132)',
|
||||||
|
data: chartValues
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
callbacks: {
|
||||||
|
label: (tooltipItem) => {
|
||||||
|
return tooltipItem.yLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -52,15 +74,15 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
#chart {
|
#chart {
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin:10px;
|
margin: 10px;
|
||||||
background-color: #ffdde2;
|
background-color: #d3d3d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart:hover {
|
#chart:hover {
|
||||||
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -2,33 +2,44 @@
|
|||||||
import chartjs from 'chart.js/auto';
|
import chartjs from 'chart.js/auto';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { getCookie } from "svelte-cookie";
|
||||||
|
|
||||||
let ctx;
|
let ctx;
|
||||||
let chartCanvas;
|
let chartCanvas;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYW4uYmFsYW5AZ21haWwuY29tIiwiaWF0IjoxNjk3NzQ0MjY3LCJleHAiOjE2OTc4MzA2Njd9.hzbEDDuOVCY_EQAA8xGlJskQ2FQjw8o0CtFKB1dKYOU`
|
'Authorization': `Bearer ${token}`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get('http://localhost:8081/incomes/00112233-4455-6677-8899-aabbccddeeaa', config);
|
const [incomesResponse, expensesResponse] = await Promise.all([
|
||||||
const incomeData = response.data; // Assuming the response is an array of income data
|
axios.get('http://localhost:8081/incomes/personal-incomes', config),
|
||||||
|
axios.get('http://localhost:8081/expenses/personal-expenses', config)
|
||||||
|
]);
|
||||||
|
|
||||||
// Extract income categories and their values
|
const incomesData = incomesResponse.data;
|
||||||
const chartLabels = incomeData.map(item => item.category.categoryName);
|
const expensesData = expensesResponse.data;
|
||||||
const chartValues = incomeData.map(item => item.amount);
|
|
||||||
|
const totalIncomes = incomesData.reduce((total, item) => total + item.amount, 0);
|
||||||
|
|
||||||
|
const totalExpenses = expensesData.reduce((total, item) => total + item.amount, 0);
|
||||||
|
|
||||||
|
const chartLabels = ['Incomes', 'Expenses'];
|
||||||
|
const chartValues = [totalIncomes, totalExpenses];
|
||||||
|
|
||||||
ctx = chartCanvas.getContext('2d');
|
ctx = chartCanvas.getContext('2d');
|
||||||
new chartjs(ctx, {
|
new chartjs(ctx, {
|
||||||
type: 'pie', // Set chart type to 'pie' for a pie chart
|
type: 'pie',
|
||||||
data: {
|
data: {
|
||||||
labels: chartLabels,
|
labels: chartLabels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
data: chartValues,
|
data: chartValues,
|
||||||
backgroundColor: ['red', 'orange', 'yellow', 'green', 'blue'], // Customize colors as needed
|
backgroundColor: ['green', 'red'],
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -53,7 +64,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
background-color: #ffdde2;
|
background-color: #d3d3d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chart:hover {
|
#chart:hover {
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
<script>
|
|
||||||
import chartjs from 'chart.js/auto';
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
let chartValues = [20, 10, 5, 2, 20, 30, 45];
|
|
||||||
let chartLabels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
|
||||||
let ctx;
|
|
||||||
let chartCanvas;
|
|
||||||
|
|
||||||
onMount(async (promise) => {
|
|
||||||
ctx = chartCanvas.getContext('2d');
|
|
||||||
var chart = new chartjs(ctx, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: chartLabels,
|
|
||||||
datasets: [{
|
|
||||||
label: 'Revenue',
|
|
||||||
backgroundColor: 'rgb(255, 99, 132)',
|
|
||||||
borderColor: 'rgb(255, 99, 132)',
|
|
||||||
data: chartValues
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div id="chart">
|
|
||||||
<canvas bind:this={chartCanvas}></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#chart {
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
|
||||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
|
||||||
flex: 1;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin:10px;
|
|
||||||
background-color: #ffdde2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chart:hover {
|
|
||||||
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<script>
|
|
||||||
import chartjs from 'chart.js/auto';
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
let chartValues = [20, 10, 5, 2, 20, 30, 45];
|
|
||||||
let chartLabels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
|
||||||
let ctx;
|
|
||||||
let chartCanvas;
|
|
||||||
|
|
||||||
onMount(async (promise) => {
|
|
||||||
ctx = chartCanvas.getContext('2d');
|
|
||||||
var chart = new chartjs(ctx, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: chartLabels,
|
|
||||||
datasets: [{
|
|
||||||
label: 'Revenue',
|
|
||||||
backgroundColor: 'rgb(255, 99, 132)',
|
|
||||||
borderColor: 'rgb(255, 99, 132)',
|
|
||||||
data: chartValues
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div id="chart">
|
|
||||||
<canvas bind:this={chartCanvas}></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#chart {
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
|
||||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
|
||||||
flex: 1;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin:10px;
|
|
||||||
background-color: #ffdde2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chart:hover {
|
|
||||||
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,4 +1,29 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { getCookie } from "svelte-cookie";
|
||||||
|
|
||||||
|
let username;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
const token = getCookie('access_token');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get('http://localhost:8081/users/getUserData', config);
|
||||||
|
const data = response.data;
|
||||||
|
username = data.username;
|
||||||
|
console.log(username)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -37,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="profileSpace">
|
<div id="profileSpace">
|
||||||
<div id="profileInfo">Profile Info</div>
|
<div id="profileInfo">Hello, {username}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user