All frontend elements now use Stores instead of requesting their own data

6 times less requests!
This commit is contained in:
2023-10-26 23:02:25 +03:00
parent e24ca0d2d5
commit a2b7b38bf1
10 changed files with 142 additions and 214 deletions

View File

@@ -8,17 +8,19 @@
import {incomeData} from "../stores.js"; import {incomeData} from "../stores.js";
import {expenseData} from "../stores.js"; import {expenseData} from "../stores.js";
import {incomeTypes} from "../stores.js"; import {incomeTypes} from "../stores.js";
import {expenseTypes} from "../stores.js";
import axios from "axios"; import axios from "axios";
onMount(() => { onMount(() => {
if (getCookie('access_token') === null) { if (getCookie('access_token') === '') {
window.location.href = '/auth/login'; window.location.href = '/auth/login';
console.log("no token"); console.log("no token");
} }
const token = getCookie('access_token'); const token = getCookie('access_token');
const config = { const config = {
headers: { headers: {
'Authorization': `Bearer ${token}` 'Authorization': `Bearer ${token}`
@@ -46,7 +48,14 @@
}) })
.catch(error => console.error('Error:', error)); .catch(error => console.error('Error:', error));
Promise.all([incomePromise, expensePromise, incomeTypesPromise]) const expenseTypesPromise = axios.get('http://localhost:8081/expenses/categories', config)
.then(response => {
expenseTypes.set(response.data);
console.log("Received Expense Type Data");
})
.catch(error => console.error('Error:', error));
Promise.all([incomePromise, expensePromise, incomeTypesPromise, expenseTypesPromise])
.then(() => { .then(() => {
console.log(getCookie('access_token')); console.log(getCookie('access_token'));
}); });

View File

@@ -7,21 +7,22 @@
let chartCanvas; let chartCanvas;
let chart = null; let chart = null;
function groupAndSumByCategory(incomes) {
const groupedData = new Map();
incomes.forEach(income => {
const category = income.incomeCategory.name;
if (groupedData.has(category)) {
groupedData.set(category, groupedData.get(category) + parseInt(income.amount));
} else {
groupedData.set(category, income.amount);
}
}
);
return groupedData;
}
function createGraph(data) { function createGraph(data) {
try { try {
function groupAndSumByCategory(incomes) {
const groupedData = new Map();
incomes.forEach(income => {
const category = income.incomeCategory.name;
if (groupedData.has(category)) {
groupedData.set(category, groupedData.get(category) + parseInt(income.amount));
} else {
groupedData.set(category, income.amount);
}
}
);
return groupedData;
}
const groupedIncomeData = groupAndSumByCategory(data); const groupedIncomeData = groupAndSumByCategory(data);

View File

@@ -1,72 +1,73 @@
<script> <script>
import Chart from 'chart.js/auto'; import Chart from 'chart.js/auto';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import axios from 'axios'; import {expenseData} from "../../stores.js";
import {getCookie} from "svelte-cookie";
let ctx; let ctx;
let chartCanvas; let chartCanvas;
let chart = null;
async function updateGraph() { function groupAndSumByCategory(expenses) {
const token = getCookie('access_token'); const groupedData = new Map();
expenses.forEach(expense => {
const config = { const category = expense.expenseCategory.name;
headers: { if (groupedData.has(category)) {
'Authorization': `Bearer ${token}` groupedData.set(category, groupedData.get(category) + parseInt(expense.amount));
} } else {
}; groupedData.set(category, expense.amount);
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;
}
}
} }
} }
}); );
return groupedData;
}
function createGraph(data) {
try {
const groupedExpenseData = groupAndSumByCategory(data);
const chartLabels = Array.from(groupedExpenseData.keys());
const chartValues = Array.from(groupedExpenseData.values());
ctx = chartCanvas.getContext('2d');
if (!chart) {
chart = new Chart(ctx, {
type: 'bar',
data: {
labels: chartLabels,
datasets: [{
label: 'Spendings',
backgroundColor: 'rgb(255, 99, 132)',
data: chartValues
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
} else {
chart.data.labels = chartLabels;
chart.data.datasets[0].data = chartValues;
console.log(chart.data.datasets[0].data);
chart.update();
}
} catch (error) { } catch (error) {
console.error('Error:', error); console.error('Error:', error);
} }
} }
onMount(updateGraph); $: {
if ($expenseData) {
createGraph($expenseData);
console.log($expenseData);
}
}
onMount(() => {
createGraph($expenseData);
});
</script> </script>
<div id="chart"> <div id="chart">

View File

@@ -1,39 +1,24 @@
<script> <script>
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 { incomeData, expenseData } from "../../stores.js";
import { getCookie } from "svelte-cookie";
let ctx; let ctx;
let chartCanvas; let chartCanvas;
let chart = null;
async function updateGraph() { function createGraph(incomes, expenses) {
const token = getCookie('access_token');
const config = {
headers: {
'Authorization': `Bearer ${token}`
}
};
try { try {
const [incomesResponse, expensesResponse] = await Promise.all([
axios.get('http://localhost:8081/incomes/personal-incomes', config),
axios.get('http://localhost:8081/expenses/personal-expenses', config)
]);
const incomesData = incomesResponse.data; const totalIncomes = incomes.reduce((total, item) => total + item.amount, 0);
const expensesData = expensesResponse.data; const totalExpenses = expenses.reduce((total, item) => total + item.amount, 0);
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 chartLabels = ['Incomes', 'Expenses'];
const chartValues = [totalIncomes, totalExpenses]; const chartValues = [totalIncomes, totalExpenses];
ctx = chartCanvas.getContext('2d'); ctx = chartCanvas.getContext('2d');
new chartjs(ctx, { if (!chart) {
chart = new chartjs(ctx, {
type: 'pie', type: 'pie',
data: { data: {
labels: chartLabels, labels: chartLabels,
@@ -47,12 +32,27 @@
maintainAspectRatio: false maintainAspectRatio: false
} }
}); });
} else {
chart.data.labels = chartLabels;
chart.data.datasets[0].data = chartValues;
console.log(chart.data.datasets[0].data);
chart.update();
}
} catch (error) { } catch (error) {
console.error('Error:', error); console.error('Error:', error);
} }
} }
onMount(updateGraph); $: {
if ($incomeData || $expenseData) {
console.log("created");
createGraph($incomeData, $expenseData);
}
}
onMount(() => {
createGraph($incomeData, $expenseData);
});
</script> </script>
<div id="chart"> <div id="chart">

View File

@@ -1,36 +1,18 @@
<script> <script>
import { onMount, afterUpdate } from 'svelte'; import { onMount, afterUpdate } from 'svelte';
import axios from 'axios';
import { getCookie } from "svelte-cookie";
import ContentExpense from "./contents/ContentExpense.svelte"; import ContentExpense from "./contents/ContentExpense.svelte";
import {expenseData} from "../../stores.js";
let data = [];
let parentHeight; let parentHeight;
let listParentHeight; let listParentHeight;
async function updateInfo() { async function updateInfo() {
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);
}
}
onMount(updateInfo);
afterUpdate(() => {
parentHeight = document.querySelector('#expenseInfo').offsetHeight; parentHeight = document.querySelector('#expenseInfo').offsetHeight;
listParentHeight = document.querySelector('#expenseList').offsetHeight; listParentHeight = document.querySelector('#expenseList').offsetHeight;
}); }
onMount(updateInfo);
afterUpdate(updateInfo);
</script> </script>
<div id="expenseInfo" style="max-height: {parentHeight}px;"> <div id="expenseInfo" style="max-height: {parentHeight}px;">
@@ -38,7 +20,7 @@
<div id="expenseList" style="max-height: {listParentHeight}px;"> <div id="expenseList" style="max-height: {listParentHeight}px;">
<ul> <ul>
{#each data as item} {#each $expenseData as item}
<li> <li>
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}

View File

@@ -1,37 +1,18 @@
<script> <script>
import { onMount, afterUpdate } from 'svelte'; import { onMount, afterUpdate } from 'svelte';
import axios from 'axios'; import { incomeData } from "../../stores.js";
import {getCookie} from "svelte-cookie";
import ContentIncome from "./contents/ContentIncome.svelte"; import ContentIncome from "./contents/ContentIncome.svelte";
let data = [];
let parentHeight; let parentHeight;
let listParentHeight; let listParentHeight;
async function updateInfo() { async function updateInfo() {
const token = getCookie('access_token'); parentHeight = document.querySelector('#expenseInfo').offsetHeight;
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);
}
}
onMount(updateInfo);
afterUpdate(() => {
parentHeight = document.querySelector('#incomeInfo').offsetHeight;
listParentHeight = document.querySelector('#expenseList').offsetHeight; listParentHeight = document.querySelector('#expenseList').offsetHeight;
}); }
onMount(updateInfo);
afterUpdate(updateInfo);
</script> </script>
<div id="incomeInfo" style="max-height: {parentHeight}px;"> <div id="incomeInfo" style="max-height: {parentHeight}px;">
@@ -39,7 +20,7 @@
<div id="incomeList" style="max-height: {listParentHeight}px;"> <div id="incomeList" style="max-height: {listParentHeight}px;">
<ul> <ul>
{#each data as item} {#each $incomeData as item}
<li> <li>
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}

View File

@@ -1,37 +1,17 @@
<script> <script>
import Modal from '../modals/Modal.svelte'; import Modal from '../modals/Modal.svelte';
import { onMount } from 'svelte';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import axios from 'axios'; import axios from 'axios';
import { getCookie } from "svelte-cookie"; import { getCookie } from "svelte-cookie";
import {expenseTypes} from "../../../stores.js";
let showModal; let showModal;
let amount = ''; let amount = '';
const selectedExpenseId = writable(''); const selectedExpenseId = writable('');
onMount(async () => {
try {
const token = getCookie('access_token');
const config = {
headers: {
'Authorization': `Bearer ${token}`
}
};
const response = await axios.get('http://localhost:8081/expenses/categories', config);
expenseOptions.set(response.data);
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
});
const expenseOptions = writable([]);
const createExpense = async () => { const createExpense = async () => {
const selectedExpense = $expenseOptions.find(expense => expense.id === $selectedExpenseId); const selectedExpense = $expenseTypes.find(expense => expense.id === $selectedExpenseId);
const data = { const data = {
expenseCategory: selectedExpense.id, expenseCategory: selectedExpense.id,
amount: amount, amount: amount,
@@ -78,7 +58,7 @@
<div class="form-group"> <div class="form-group">
<label for="expenseCategory">Select Expense Category:</label> <label for="expenseCategory">Select Expense Category:</label>
<select id="expenseCategory" class="form-control" bind:value={$selectedExpenseId}> <select id="expenseCategory" class="form-control" bind:value={$selectedExpenseId}>
{#each $expenseOptions as expense (expense.id)} {#each $expenseTypes as expense (expense.id)}
{#if expense.id !== undefined} {#if expense.id !== undefined}
<option value={expense.id}>{expense.name}</option> <option value={expense.id}>{expense.name}</option>
{/if} {/if}

View File

@@ -1,6 +1,5 @@
<script> <script>
import Modal from '../modals/Modal.svelte'; import Modal from '../modals/Modal.svelte';
import { onMount } from 'svelte';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import axios from 'axios'; import axios from 'axios';
import { getCookie } from "svelte-cookie"; import { getCookie } from "svelte-cookie";
@@ -41,29 +40,8 @@
} }
} }
onMount(async () => {
try {
const token = getCookie('access_token');
const config = {
headers: {
'Authorization': `Bearer ${token}`
}
};
const response = await axios.get('http://localhost:8081/incomes/categories', config);
incomeOptions.set(response.data);
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
});
const incomeOptions = writable([]);
const createIncome = async () => { const createIncome = async () => {
const selectedIncome = $incomeOptions.find(income => income.id === $selectedIncomeId); const selectedIncome = $incomeTypes.find(income => income.id === $selectedIncomeId);
const data = { const data = {
incomeCategory: selectedIncome.id, incomeCategory: selectedIncome.id,
amount: amount, amount: amount,
@@ -110,7 +88,7 @@
<div class="form-group"> <div class="form-group">
<label for="incomeCategory">Select Income Category:</label> <label for="incomeCategory">Select Income Category:</label>
<select id="incomeCategory" class="form-control" bind:value={$selectedIncomeId}> <select id="incomeCategory" class="form-control" bind:value={$selectedIncomeId}>
{#each $incomeOptions as income (income.id)} {#each $incomeTypes as income (income.id)}
{#if income.id !== undefined} {#if income.id !== undefined}
<option value={income.id}>{income.name}</option> <option value={income.id}>{income.name}</option>
{/if} {/if}

View File

@@ -1,38 +1,32 @@
<script> <script>
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import axios from 'axios'; import {incomeData, expenseData} from "../../stores.js";
import { getCookie } from "svelte-cookie";
let infobar1, infobar2, infobar3, infobar4; let infobar1, infobar2, infobar3, infobar4;
let totalExpenses = 0; let totalExpenses = 0;
let totalIncomes = 0; let totalIncomes = 0;
onMount(async () => { function updateInfo() {
const token = getCookie('access_token'); totalExpenses = $expenseData.reduce((total, item) => total + item.amount, 0);
totalIncomes = $incomeData.reduce((total, item) => total + item.amount, 0);
const config = {
headers: {
'Authorization': `Bearer ${token}`
}
};
try { try {
const [incomesResponse, expensesResponse] = await Promise.all([
axios.get('http://localhost:8081/incomes/personal-incomes', config),
axios.get('http://localhost:8081/expenses/personal-expenses', config)
]);
const incomesData = incomesResponse.data;
const expensesData = expensesResponse.data;
totalExpenses = expensesData.reduce((total, item) => total + item.amount, 0);
totalIncomes = incomesData.reduce((total, item) => total + item.amount, 0);
infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: xxx-large">${totalExpenses}$`; infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: xxx-large">${totalExpenses}$`;
infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: xxx-large">${totalIncomes}$</span>`; infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: xxx-large">${totalIncomes}$</span>`;
} catch (error) { } catch {
console.error('Error:', error); console.log("not yet loaded");
} }
}
$: {
if ($incomeData && $expenseData) {
updateInfo();
}
}
onMount(() => {
updateInfo();
}); });
</script> </script>

View File

@@ -5,3 +5,5 @@ export const incomeData = writable([]);
export const expenseData = writable([]); export const expenseData = writable([]);
export const incomeTypes = writable([]); export const incomeTypes = writable([]);
export const expenseTypes = writable([]);