Merge pull request #42 from lumijiez/front-v3

Front v3
This commit was merged in pull request #42.
This commit is contained in:
Daniel
2023-12-08 19:57:53 +02:00
committed by GitHub
23 changed files with 828 additions and 146 deletions

View File

@@ -822,9 +822,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
"integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",

View File

@@ -2,7 +2,8 @@
"name": "expensetracker",
"version": "0.0.1",
"scripts": {
"dev": "vite dev",
"dev": "vite dev --host",
"devs": "vite dev --host --https",
"build": "vite build",
"preview": "vite preview",
"lint": "prettier --plugin-search-dir . --check . && eslint .",

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="icon" href="/favicon.png" />
<meta name="viewport" content="width=device-width" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,9 @@
<script>
import { onMount } from "svelte";
onMount(() => {
// Redirect to /auth/login
window.location.href = '/auth/login';
});
</script>

View File

@@ -22,11 +22,13 @@
event.preventDefault();
try {
const response = await axios.post('http://localhost:8081/api/v1/auth/authenticate', {
const response = await axios.post('https://trackio.online:8081/api/v1/auth/authenticate', {
email: username,
password: password,
});
console.log(response.data)
const { access_token, refresh_token } = response.data;
setCookie('access_token', access_token);
@@ -60,6 +62,10 @@
</div>
</div>
<svelte:head>
<link rel="icon" type="image/x-icon" href="../favicon.png" />
<title>Login into Track.IO</title>
</svelte:head>
<style>
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400');

View File

@@ -36,7 +36,7 @@
console.log(data)
const response = await axios.post('http://localhost:8081/api/v1/auth/register', data);
const response = await axios.post('https://trackio.online:8081/api/v1/auth/register', data);
const { access_token, refresh_token } = response.data;
@@ -78,6 +78,12 @@
</script>
<svelte:head>
<link rel="icon" type="image/x-icon" href="../favicon.png" />
<title>Register into Track.IO</title>
</svelte:head>
<div class="animated bounceInDown">
<div class="container">
{#if isErrorVisible}

View File

@@ -31,13 +31,17 @@
};
try {
var currentDate = new Date();
var currentMonth = currentDate.getMonth() + 1;
const [incomeResponse, expenseResponse, incomeTypesResponse, expenseTypesResponse] = await Promise.all([
axios.get('http://localhost:8081/incomes/personal-incomes', config),
axios.get('http://localhost:8081/expenses/personal-expenses', config),
axios.get('http://localhost:8081/incomes/categories', config),
axios.get('http://localhost:8081/expenses/categories', config)
axios.get('https://trackio.online:8081/incomes/personal-incomes?month=' + currentMonth , config),
axios.get('https://trackio.online:8081/expenses/personal-expenses?month=' + currentMonth, config),
axios.get('https://trackio.online:8081/incomes/categories', config),
axios.get('https://trackio.online:8081/expenses/categories', config)
]);
console.log("Data", incomeResponse.data);
incomeData.set(incomeResponse.data);
expenseData.set(expenseResponse.data);
incomeTypes.set(incomeTypesResponse.data);
@@ -48,6 +52,11 @@
});
</script>
<svelte:head>
<link rel="icon" type="image/x-icon" href="../favicon.png" />
<title>Track.IO</title>
</svelte:head>
<div id="dashboard" style="background-color: {componentStyles.dashColor}; color: {componentStyles.color}">
{#if $selectedTab === 'expenses'}
<ExpenseDashboard />
@@ -59,6 +68,7 @@
</div>
<style>
#dashboard {
font-family: 'Source Sans Pro', sans-serif;
border-radius: 20px;

View File

@@ -50,7 +50,17 @@
},
options: {
responsive: true,
maintainAspectRatio: false
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
font: {
weight: 'bold'
},
color: '#fff'
}
}
}
}
});
} else {

View File

@@ -33,7 +33,17 @@
},
options: {
responsive: true,
maintainAspectRatio: false
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
font: {
weight: 'bold'
},
color: '#fff'
}
}
}
}
});
} else {

View File

@@ -49,7 +49,7 @@
try {
const token = getCookie('access_token');
const response = await axios.post('http://localhost:8081/expenses', data, {
const response = await axios.post('https://trackio.online:8081/expenses', data, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',

View File

@@ -2,17 +2,37 @@
import ContentExpense from "./ContentExpense.svelte";
import { expenseData } from "../../../stores.js";
import { globalStyles } from "../../../styles.js";
const textToIcon = {
'Groceries': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M0 24C0 10.7 10.7 0 24 0H69.5c22 0 41.5 12.8 50.6 32h411c26.3 0 45.5 25 38.6 50.4l-41 152.3c-8.5 31.4-37 53.3-69.5 53.3H170.7l5.4 28.5c2.2 11.3 12.1 19.5 23.6 19.5H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H199.7c-34.6 0-64.3-24.6-70.7-58.5L77.4 54.5c-.7-3.8-4-6.5-7.9-6.5H24C10.7 48 0 37.3 0 24zM128 464a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm336-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96z\"/></svg>",
'Utilities': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M176 88v40H336V88c0-4.4-3.6-8-8-8H184c-4.4 0-8 3.6-8 8zm-48 40V88c0-30.9 25.1-56 56-56H328c30.9 0 56 25.1 56 56v40h28.1c12.7 0 24.9 5.1 33.9 14.1l51.9 51.9c9 9 14.1 21.2 14.1 33.9V304H384V288c0-17.7-14.3-32-32-32s-32 14.3-32 32v16H192V288c0-17.7-14.3-32-32-32s-32 14.3-32 32v16H0V227.9c0-12.7 5.1-24.9 14.1-33.9l51.9-51.9c9-9 21.2-14.1 33.9-14.1H128zM0 416V336H128v16c0 17.7 14.3 32 32 32s32-14.3 32-32V336H320v16c0 17.7 14.3 32 32 32s32-14.3 32-32V336H512v80c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64z\"/></svg>",
'Rent': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z\"/></svg>",
'Transportation': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M135.2 117.4L109.1 192H402.9l-26.1-74.6C372.3 104.6 360.2 96 346.6 96H165.4c-13.6 0-25.7 8.6-30.2 21.4zM39.6 196.8L74.8 96.3C88.3 57.8 124.6 32 165.4 32H346.6c40.8 0 77.1 25.8 90.6 64.3l35.2 100.5c23.2 9.6 39.6 32.5 39.6 59.2V400v48c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V400H96v48c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V400 256c0-26.7 16.4-49.6 39.6-59.2zM128 288a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z\"/></svg>",
'Education': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"20\" viewBox=\"0 0 640 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H256V416c0-35.3 28.7-64 64-64s64 28.7 64 64v96H592c26.5 0 48-21.5 48-48V144c0-26.5-21.5-48-48-48H473.7L337.8 5.4zM96 192h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V208c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H512c-8.8 0-16-7.2-16-16V208zM96 320h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H512c-8.8 0-16-7.2-16-16V336zM232 176a88 88 0 1 1 176 0 88 88 0 1 1 -176 0zm88-48c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H336V144c0-8.8-7.2-16-16-16z\"/></svg>",
'Restaurants & Cafes': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M0 192c0-35.3 28.7-64 64-64c.5 0 1.1 0 1.6 0C73 91.5 105.3 64 144 64c15 0 29 4.1 40.9 11.2C198.2 49.6 225.1 32 256 32s57.8 17.6 71.1 43.2C339 68.1 353 64 368 64c38.7 0 71 27.5 78.4 64c.5 0 1.1 0 1.6 0c35.3 0 64 28.7 64 64c0 11.7-3.1 22.6-8.6 32H8.6C3.1 214.6 0 203.7 0 192zm0 91.4C0 268.3 12.3 256 27.4 256H484.6c15.1 0 27.4 12.3 27.4 27.4c0 70.5-44.4 130.7-106.7 154.1L403.5 452c-2 16-15.6 28-31.8 28H140.2c-16.1 0-29.8-12-31.8-28l-1.8-14.4C44.4 414.1 0 353.9 0 283.4z\"/></svg>",
'Home Maintenance': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z\"/></svg>",
'Transport': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M135.2 117.4L109.1 192H402.9l-26.1-74.6C372.3 104.6 360.2 96 346.6 96H165.4c-13.6 0-25.7 8.6-30.2 21.4zM39.6 196.8L74.8 96.3C88.3 57.8 124.6 32 165.4 32H346.6c40.8 0 77.1 25.8 90.6 64.3l35.2 100.5c23.2 9.6 39.6 32.5 39.6 59.2V400v48c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V400H96v48c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V400 256c0-26.7 16.4-49.6 39.6-59.2zM128 288a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z\"/></svg>",
'Shopping': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M0 24C0 10.7 10.7 0 24 0H69.5c22 0 41.5 12.8 50.6 32h411c26.3 0 45.5 25 38.6 50.4l-41 152.3c-8.5 31.4-37 53.3-69.5 53.3H170.7l5.4 28.5c2.2 11.3 12.1 19.5 23.6 19.5H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H199.7c-34.6 0-64.3-24.6-70.7-58.5L77.4 54.5c-.7-3.8-4-6.5-7.9-6.5H24C10.7 48 0 37.3 0 24zM128 464a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm336-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96z\"/></svg>",
'Miscellaneous': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M403.8 34.4c12-5 25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V160H352c-10.1 0-19.6 4.7-25.6 12.8L284 229.3 244 176l31.2-41.6C293.3 110.2 321.8 96 352 96h32V64c0-12.9 7.8-24.6 19.8-29.6zM164 282.7L204 336l-31.2 41.6C154.7 401.8 126.2 416 96 416H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c10.1 0 19.6-4.7 25.6-12.8L164 282.7zm274.6 188c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V416H352c-30.2 0-58.7-14.2-76.8-38.4L121.6 172.8c-6-8.1-15.5-12.8-25.6-12.8H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c30.2 0 58.7 14.2 76.8 38.4L326.4 339.2c6 8.1 15.5 12.8 25.6 12.8h32V320c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64z\"/></svg>",
'Charity': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M163.9 136.9c-29.4-29.8-29.4-78.2 0-108s77-29.8 106.4 0l17.7 18 17.7-18c29.4-29.8 77-29.8 106.4 0s29.4 78.2 0 108L310.5 240.1c-6.2 6.3-14.3 9.4-22.5 9.4s-16.3-3.1-22.5-9.4L163.9 136.9zM568.2 336.3c13.1 17.8 9.3 42.8-8.5 55.9L433.1 485.5c-23.4 17.2-51.6 26.5-80.7 26.5H192 32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32H68.8l44.9-36c22.7-18.2 50.9-28 80-28H272h16 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H288 272c-8.8 0-16 7.2-16 16s7.2 16 16 16H392.6l119.7-88.2c17.8-13.1 42.8-9.3 55.9 8.5zM193.6 384l0 0-.9 0c.3 0 .6 0 .9 0z\"/></svg>",
'Legal Services': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M318.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-120 120c-12.5 12.5-12.5 32.8 0 45.3l16 16c12.5 12.5 32.8 12.5 45.3 0l4-4L325.4 293.4l-4 4c-12.5 12.5-12.5 32.8 0 45.3l16 16c12.5 12.5 32.8 12.5 45.3 0l120-120c12.5-12.5 12.5-32.8 0-45.3l-16-16c-12.5-12.5-32.8-12.5-45.3 0l-4 4L330.6 74.6l4-4c12.5-12.5 12.5-32.8 0-45.3l-16-16zm-152 288c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l48 48c12.5 12.5 32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-1.4-1.4L272 285.3 226.7 240 168 298.7l-1.4-1.4z\"/></svg>"
};
</script>
<div id="expenseInfo" style="background-color: {$globalStyles.mainColor}">
<ContentExpense />
<div id="listContainer" style="color: {$globalStyles.color}">
<ul>
{#each $expenseData as item}
<li style="color: {$globalStyles.color}">
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}
{`${item.date}`}
{#each $expenseData.reverse() as item}
<li style="display:flex; justify-content: space-between; color: {$globalStyles.color}">
<span>
{#if textToIcon[item.expenseCategory.name]}
{@html textToIcon[item.expenseCategory.name]}
{/if}
<span style="font-weight: bold">{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}</span>
<span style="margin-right: 10px; color: red; font-size: larger">{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}</span>
</span>
<span style="">{`${item.date}`}</span>
</li>
{/each}
</ul>
@@ -43,16 +63,25 @@
border-radius: 0 0 10px 10px;
}
#listContainer::-webkit-scrollbar {
width: 0;
::-webkit-scrollbar {
width: 10px;
}
#listContainer::-webkit-scrollbar-thumb {
background-color: transparent;
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
#listContainer::-webkit-scrollbar-track {
background-color: transparent;
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
#listContainer ul {

View File

@@ -4,10 +4,18 @@
import Expenses from "../infolists/Expenses.svelte";
import {globalStyles} from "../../../styles.js";
import { slide } from 'svelte/transition'
import {expenseTypes} from "../../../stores.js";
import {expenseTypes, expenseData, incomeData, dateText, tempExpense, tempIncome} from "../../../stores.js";
import axios from "axios";
import {getCookie} from "svelte-cookie";
import {onMount} from "svelte";
let isDateDropdownExpanded = false
let isCategoryDropdownExpanded = false
let expenseAnalysisText = "EXPENSE ANALYSIS: " + $dateText;
$ : {
expenseAnalysisText = "EXPENSE ANALYSIS: " + $dateText;
}
function clickHandlerDate() {
isDateDropdownExpanded = !isDateDropdownExpanded
@@ -17,33 +25,195 @@
isCategoryDropdownExpanded = !isCategoryDropdownExpanded;
}
function clickOutsideHandler(event) {
const isDateButton = event.target.closest("#btn1");
const isCategoryButton = event.target.closest("#btn2");
if (!isDateButton) {
isDateDropdownExpanded = false;
}
if (!isCategoryButton) {
isCategoryDropdownExpanded = false;
}
}
onMount(() => {
document.body.addEventListener("click", clickOutsideHandler);
// Clean up the event listener when the component is destroyed
return () => {
document.body.removeEventListener("click", clickOutsideHandler);
};
});
async function getToday() {
var currentDate = new Date();
var currentDay = currentDate.toISOString().split('T')[0];
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?date=' + currentDay, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?date=' + currentDay, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "Today"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getYesterday() {
var currentDate = new Date();
var yesterday = new Date(currentDate);
yesterday.setDate(currentDate.getDate() - 1);
var yesterdayString = yesterday.toISOString().split('T')[0];
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?date=' + yesterdayString, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?date=' + yesterdayString, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "Yesterday"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getMonth() {
var currentDate = new Date();
var year = currentDate.getMonth() + 1;
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "This Month"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getLastMonth() {
var currentDate = new Date();
var year = currentDate.getMonth();
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data)
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "Last Month"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getLastYear() {
var currentDate = new Date();
var year = currentDate.getFullYear();
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?year=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?year=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "This Year"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
function filterByCategory(category) {
console.log(category)
let tempArr = $tempExpense.filter(expense => expense.expenseCategory.name === category);
expenseData.set(tempArr);
}
</script>
<div id="main-data" style="background-color: {$globalStyles.dashColor}; color: {$globalStyles.color}">
<div id="data-header" style="background-color:{$globalStyles.mainColor}; color: {$globalStyles.altColor}">
<span style="color: {$globalStyles.altColor}">Revenue Analysis</span>
<span style="color: {$globalStyles.altColor}" contenteditable="false" bind:innerHTML={expenseAnalysisText}></span>
<div id="dropdown-date">
<button id="button" on:click={clickHandlerDate}>Filter by Date:</button>
<button id="btn1" class="button" on:click={clickHandlerDate}>Filter by Date </button>
{#if isDateDropdownExpanded}
<div id="date-list" transition:slide>
<div on:click={() => console.log("Today")}>Today</div>
<div on:click={() => console.log("Yesterday")}>Yesterday</div>
<div on:click={() => console.log("Last week")}>Last week</div>
<div on:click={() => console.log("Last month")}>Last month</div>
<div on:click={() => console.log("Current quarter")}>Current quarter</div>
<div on:click={() => console.log("This year")}>This year</div>
<div class="date-entry" on:click={() => getToday()}>Today</div>
<div class="date-entry" on:click={() => getYesterday()}>Yesterday</div>
<div class="date-entry" on:click={() => getMonth()}>This month</div>
<div class="date-entry" on:click={() => getLastMonth()}>Last month</div>
<!-- <div on:click={() => console.log("Last month")}>Last month</div>-->
<!-- <div on:click={() => console.log("Current quarter")}>Current quarter</div>-->
<div class="date-entry" on:click={() => getLastYear()}>This year</div>
</div>
{/if}
</div>
<div id="dropdown-category">
<button id="button" on:click={clickHandlerCategory}>Filter by Category:</button>
<button id="btn2" class="button" on:click={clickHandlerCategory}>Filter by Category </button>
{#if isCategoryDropdownExpanded}
<div id="category-list" transition:slide>
<div id="date-list" transition:slide>
{#each $expenseTypes as expense (expense.id)}
{#if expense.id !== undefined}
<option value={expense.id}>{expense.name}</option>
<div class="date-entry" on:click={() => filterByCategory(expense.name)} value={expense.id}>{expense.name}</div>
{/if}
{/each}
</div>
@@ -76,48 +246,147 @@
flex: 1 1 auto;
}
#button {
background-color: #fff000;
border-radius: 12px;
color: #000;
cursor: pointer;
font-weight: bold;
padding: 10px 15px;
text-align: center;
transition: 200ms;
width: 100%;
box-sizing: border-box;
/*#button {*/
/* background-color: #fff000;*/
/* border-radius: 12px;*/
/* color: #000;*/
/* cursor: pointer;*/
/* font-weight: bold;*/
/* padding: 10px 15px;*/
/* text-align: center;*/
/* transition: 200ms;*/
/* width: 100%;*/
/* box-sizing: border-box;*/
/* border: 0;*/
/* font-size: 16px;*/
/* user-select: none;*/
/* -webkit-user-select: none;*/
/* touch-action: manipulation;*/
/*}*/
/*#button:not(:disabled):hover,*/
/*#button:not(:disabled):focus {*/
/* outline: 0;*/
/* background: #f4e603;*/
/* box-shadow: 0 0 0 2px rgba(0,0,0,.2), 0 3px 8px 0 rgba(0,0,0,.15);*/
/*}*/
/*#button:disabled {*/
/* filter: saturate(0.2) opacity(0.5);*/
/* -webkit-filter: saturate(0.2) opacity(0.5);*/
/* cursor: not-allowed;*/
/*}*/
/*.button {*/
/* font-size: large;*/
/* background-color: #007BFF;*/
/* color: #fff;*/
/* border: none;*/
/* border-radius: 20px;*/
/* line-height: 40px;*/
/* cursor: pointer;*/
/* margin: 10px;*/
/*}*/
/*.button:hover {*/
/* background-color: #0056b3;*/
/*}*/
.button {
align-items: center;
background-color: #0A66C2;
border: 0;
border-radius: 100px;
box-sizing: border-box;
color: #ffffff;
cursor: pointer;
display: inline-flex;
font-family: -apple-system, system-ui, system-ui, "Segoe UI", Roboto, "Helvetica Neue", "Fira Sans", Ubuntu, Oxygen, "Oxygen Sans", Cantarell, "Droid Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Lucida Grande", Helvetica, Arial, sans-serif;
font-size: 16px;
font-weight: 600;
justify-content: center;
line-height: 20px;
max-width: 480px;
min-height: 40px;
min-width: 0px;
overflow: hidden;
padding: 0px;
padding-left: 20px;
padding-right: 20px;
text-align: center;
touch-action: manipulation;
transition: background-color 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s, box-shadow 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s, color 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
vertical-align: middle;
}
#button:not(:disabled):hover,
#button:not(:disabled):focus {
outline: 0;
background: #f4e603;
box-shadow: 0 0 0 2px rgba(0,0,0,.2), 0 3px 8px 0 rgba(0,0,0,.15);
.button:hover,
.button:focus {
background-color: #16437E;
color: #ffffff;
}
#button:disabled {
filter: saturate(0.2) opacity(0.5);
-webkit-filter: saturate(0.2) opacity(0.5);
.button:active {
background: #09223b;
color: rgb(255, 255, 255, .7);
}
.button:disabled {
cursor: not-allowed;
background: rgba(0, 0, 0, .08);
color: rgba(0, 0, 0, .3);
}
#date-list {
background-color: #8BD17C;
background-color: #007BFF;
position:absolute;
margin-top: 20px;
max-height: 400px;
overflow-y: scroll;
border-radius: 20px;
z-index:1;
}
#category-list {
background-color: #8BD17C;
position:absolute;
z-index:1;
.date-entry {
padding: 10px;
margin: 10px;
background-color: black;
color: white;
border-radius: 20px;
cursor: pointer;
}
.date-entry:hover {
background-color: rgb(128, 128, 128);
}
/*#category-list {*/
/* background-color: #8BD17C;*/
/* position:absolute;*/
/* z-index:1;*/
/*}*/
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
#data-header {
@@ -131,7 +400,8 @@
border-top-left-radius: 20px;
border-top-right-radius: 20px;
font-size: larger;
border: #8BD17C 2px solid;
margin-bottom: 5px;
/*border: #8BD17C 2px solid;*/
}
#data-menu {

View File

@@ -17,11 +17,11 @@
const expenseDifference = ((lastMonthExpense - totalExpenses) / lastMonthExpense) * 100;
try {
infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: 150%">${totalExpenses.toFixed(2)}$</span>`;
infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: 150%">${totalIncomes.toFixed(2)}$</span>`;
infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: xxx-large">${totalExpenses.toFixed(2)}$</span>`;
infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: xxx-large">${totalIncomes.toFixed(2)}$</span>`;
infobar3.innerHTML = `<span style="font-size: larger">Income by last month:</span><br><span style="color:blue;font-size: 150%">${incomeDifference.toFixed(2)}%</span>`;
infobar4.innerHTML = `<span style="font-size: larger">Expense by last month:</span><br><span style="color:orange;font-size: 150%">${expenseDifference.toFixed(2)}%</span>`;
infobar3.innerHTML = `<span style="font-size: larger">Income by last month:</span><br><span style="color:blue;font-size: xxx-large">${incomeDifference.toFixed(2)}%</span>`;
infobar4.innerHTML = `<span style="font-size: larger">Expense by last month:</span><br><span style="color:orange;font-size: xxx-large">${expenseDifference.toFixed(2)}%</span>`;
} catch {
console.log("not yet loaded");
}

View File

@@ -60,7 +60,17 @@
},
options: {
responsive: true,
maintainAspectRatio: false
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
font: {
weight: 'bold'
},
color: '#fff'
}
}
}
}
});
} else {

View File

@@ -40,7 +40,17 @@
},
options: {
responsive: true,
maintainAspectRatio: false
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
font: {
weight: 'bold'
},
color: '#fff'
}
}
}
}
});
} else {

View File

@@ -50,7 +50,7 @@
try {
const token = getCookie('access_token');
const response = await axios.post('http://localhost:8081/incomes', data, {
const response = await axios.post('https://trackio.online:8081/incomes', data, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',

View File

@@ -2,17 +2,33 @@
import ContentIncome from "./ContentIncome.svelte";
import { incomeData } from "../../../stores.js";
import { globalStyles } from "../../../styles.js";
const textToIcon = {
'Interest': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"20\" viewBox=\"0 0 640 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M539.7 237.3c3.1-12.3 4.3-24.8 4.3-37.4C544 107.4 468.6 32 376.1 32c-77.2 0-144.6 53-163 127.8-15.3-13.2-34.9-20.5-55.2-20.5-46.3 0-84 37.7-84 84 0 7.4 .9 15 3.1 22.4-42.9 20.2-70.8 63.7-70.8 111.2C6.2 424.8 61.7 480 129.4 480h381.2c67.7 0 123.2-55.2 123.2-123.2 0-56.4-38.9-106-94.1-119.5zM199.9 401.6c0 8.3-7 15.3-15.3 15.3H153.6c-8.3 0-15.3-7-15.3-15.3V290.6c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v110.9zm89.5 0c0 8.3-7 15.3-15.3 15.3h-30.9c-8.3 0-15.3-7-15.3-15.3V270.1c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v131.5zm89.5 0c0 8.3-7 15.3-15.3 15.3h-30.9c-8.3 0-15.3-7-15.3-15.3V238.8c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v162.7zm87 0c0 8.3-7 15.3-15.3 15.3h-28.5c-8.3 0-15.3-7-15.3-15.3V176.9c0-8.6 7-15.6 15.3-15.6h28.5c8.3 0 15.3 7 15.3 15.6v224.6z\"/></svg>",
'Salary': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM288 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z\"/></svg>",
'Freelance Income': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM288 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z\"/></svg>",
'Investment Income': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"20\" viewBox=\"0 0 640 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M539.7 237.3c3.1-12.3 4.3-24.8 4.3-37.4C544 107.4 468.6 32 376.1 32c-77.2 0-144.6 53-163 127.8-15.3-13.2-34.9-20.5-55.2-20.5-46.3 0-84 37.7-84 84 0 7.4 .9 15 3.1 22.4-42.9 20.2-70.8 63.7-70.8 111.2C6.2 424.8 61.7 480 129.4 480h381.2c67.7 0 123.2-55.2 123.2-123.2 0-56.4-38.9-106-94.1-119.5zM199.9 401.6c0 8.3-7 15.3-15.3 15.3H153.6c-8.3 0-15.3-7-15.3-15.3V290.6c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v110.9zm89.5 0c0 8.3-7 15.3-15.3 15.3h-30.9c-8.3 0-15.3-7-15.3-15.3V270.1c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v131.5zm89.5 0c0 8.3-7 15.3-15.3 15.3h-30.9c-8.3 0-15.3-7-15.3-15.3V238.8c0-8.3 7-15.3 15.3-15.3h30.9c8.3 0 15.3 7 15.3 15.3v162.7zm87 0c0 8.3-7 15.3-15.3 15.3h-28.5c-8.3 0-15.3-7-15.3-15.3V176.9c0-8.6 7-15.6 15.3-15.6h28.5c8.3 0 15.3 7 15.3 15.6v224.6z\"/></svg>",
'Comission': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M64 64C28.7 64 0 92.7 0 128v64c0 8.8 7.4 15.7 15.7 18.6C34.5 217.1 48 235 48 256s-13.5 38.9-32.3 45.4C7.4 304.3 0 311.2 0 320v64c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V320c0-8.8-7.4-15.7-15.7-18.6C541.5 294.9 528 277 528 256s13.5-38.9 32.3-45.4c8.3-2.9 15.7-9.8 15.7-18.6V128c0-35.3-28.7-64-64-64H64zm64 112l0 160c0 8.8 7.2 16 16 16H432c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H144c-8.8 0-16 7.2-16 16zM96 160c0-17.7 14.3-32 32-32H448c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32V160z\"/></svg>",
'Sold Products': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM288 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z\"/></svg>",
'Gifts': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M190.5 68.8L225.3 128H224 152c-22.1 0-40-17.9-40-40s17.9-40 40-40h2.2c14.9 0 28.8 7.9 36.3 20.8zM64 88c0 14.4 3.5 28 9.6 40H32c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H480c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H438.4c6.1-12 9.6-25.6 9.6-40c0-48.6-39.4-88-88-88h-2.2c-31.9 0-61.5 16.9-77.7 44.4L256 85.5l-24.1-41C215.7 16.9 186.1 0 154.2 0H152C103.4 0 64 39.4 64 88zm336 0c0 22.1-17.9 40-40 40H288h-1.3l34.8-59.2C329.1 55.9 342.9 48 357.8 48H360c22.1 0 40 17.9 40 40zM32 288V464c0 26.5 21.5 48 48 48H224V288H32zM288 512H432c26.5 0 48-21.5 48-48V288H288V512z\"/></svg>",
'Government Payments': "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"18\" viewBox=\"0 0 576 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM288 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z\"/></svg>"
};
</script>
<div id="incomeInfo" style="background-color: {$globalStyles.mainColor}">
<ContentIncome />
<div id="listContainer" style="color: {$globalStyles.color}">
<ul>
{#each $incomeData as item}
<li>
{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.incomeCategory.name}: `}
{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}
{`${item.date}`}
{#each $incomeData.reverse() as item}
<li style="display:flex; justify-content: space-between; color: {$globalStyles.color}">
<span>
{#if textToIcon[item.incomeCategory.name]}
{@html textToIcon[item.incomeCategory.name]}
{/if}
<span style="font-weight: bold">{item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `}</span>
<span style="margin-right: 10px; color: green; font-size: larger">{item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`}</span>
</span>
<span style="">{`${item.date}`}</span>
</li>
{/each}
</ul>
@@ -43,16 +59,25 @@
border-radius: 0 0 10px 10px;
}
#listContainer::-webkit-scrollbar {
width: 0;
::-webkit-scrollbar {
width: 10px;
}
#listContainer::-webkit-scrollbar-thumb {
background-color: transparent;
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
#listContainer::-webkit-scrollbar-track {
background-color: transparent;
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
#listContainer ul {

View File

@@ -4,10 +4,17 @@
import Incomes from "../infolists/Incomes.svelte";
import {globalStyles} from "../../../styles.js";
import { slide } from 'svelte/transition'
import {incomeTypes} from "../../../stores.js";
import {dateText, expenseData, incomeData, incomeTypes, tempIncome, tempExpense} from "../../../stores.js";
import axios from "axios";
import {getCookie} from "svelte-cookie";
import {onMount} from "svelte";
let isDateDropdownExpanded = false
let isCategoryDropdownExpanded = false
let incomeAnalysisText = "REVENUE ANALYSIS: ";
$ : {
incomeAnalysisText = "REVENUE ANALYSIS: " + $dateText;
}
function clickHandlerDate() {
isDateDropdownExpanded = !isDateDropdownExpanded
@@ -17,33 +24,196 @@
isCategoryDropdownExpanded = !isCategoryDropdownExpanded;
}
function clickOutsideHandler(event) {
const isDateButton = event.target.closest("#btn1");
const isCategoryButton = event.target.closest("#btn2");
if (!isDateButton) {
isDateDropdownExpanded = false;
}
if (!isCategoryButton) {
isCategoryDropdownExpanded = false;
}
}
onMount(() => {
document.body.addEventListener("click", clickOutsideHandler);
// Clean up the event listener when the component is destroyed
return () => {
document.body.removeEventListener("click", clickOutsideHandler);
};
});
async function getToday() {
var currentDate = new Date();
var currentDay = currentDate.toISOString().split('T')[0];
try {
const response1 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?date=' + currentDay, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response1.data);
tempIncome.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?date=' + currentDay, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response2.data);
tempExpense.set(response2.data);
$dateText = "Today"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getYesterday() {
var currentDate = new Date();
var yesterday = new Date(currentDate);
yesterday.setDate(currentDate.getDate() - 1);
var yesterdayString = yesterday.toISOString().split('T')[0];
try {
const response1 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?date=' + yesterdayString, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response1.data);
tempIncome.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?date=' + yesterdayString, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response2.data);
tempExpense.set(response2.data);
$dateText = "Yesterday"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getMonth() {
var currentDate = new Date();
var year = currentDate.getMonth() + 1;
try {
const response1 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response1.data);
tempIncome.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response2.data);
tempExpense.set(response2.data);
$dateText = "This Month"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getLastMonth() {
var currentDate = new Date();
var year = currentDate.getMonth();
try {
const response1 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response1.data);
tempExpense.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?month=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response2.data);
tempIncome.set(response2.data);
$dateText = "Last Month"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
async function getLastYear() {
var currentDate = new Date();
var year = currentDate.getFullYear();
try {
const response1 = await axios.get('https://trackio.online:8081/incomes/personal-incomes?year=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
incomeData.set(response1.data);
tempIncome.set(response1.data);
const response2 = await axios.get('https://trackio.online:8081/expenses/personal-expenses?year=' + year, {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
expenseData.set(response2.data);
tempExpense.set(response2.data);
$dateText = "This Year"
} catch (error) {
console.error("Error fetching expenses:", error);
}
}
function filterByCategory(category) {
console.log(category)
let tempArr = $tempIncome.filter(income => income.incomeCategory.name === category);
incomeData.set(tempArr);
}
</script>
<div id="main-data" style="background-color: {$globalStyles.dashColor}; color: {$globalStyles.color}">
<div id="data-header" style="background-color:{$globalStyles.mainColor}; color: {$globalStyles.altColor}">
<span>Revenue Analysis</span>
<span style="color: {$globalStyles.altColor}" contenteditable="false" bind:innerHTML={incomeAnalysisText}></span>
<div id="dropdown-date">
<button id="button" on:click={clickHandlerDate}>Filter by Date:</button>
<button id="btn1" class="button" on:click={clickHandlerDate}>Filter by Date </button>
{#if isDateDropdownExpanded}
<div id="date-list" transition:slide>
<div on:click={() => console.log("Today")}>Today</div>
<div on:click={() => console.log("Yesterday")}>Yesterday</div>
<div on:click={() => console.log("Last week")}>Last week</div>
<div on:click={() => console.log("Last month")}>Last month</div>
<div on:click={() => console.log("Current quarter")}>Current quarter</div>
<div on:click={() => console.log("This year")}>This year</div>
<div class="date-entry" on:click={() => getToday()}>Today</div>
<div class="date-entry" on:click={() => getYesterday()}>Yesterday</div>
<div class="date-entry" on:click={() => getMonth()}>This month</div>
<div class="date-entry" on:click={() => getLastMonth()}>Last month</div>
<!-- <div on:click={() => console.log("Current quarter")}>Current quarter</div>-->
<div class="date-entry" on:click={() => getLastYear()}>This year</div>
</div>
{/if}
</div>
<div id="dropdown-category">
<button id="button" on:click={clickHandlerCategory}>Filter by Category:</button>
<button id="btn2" class="button" on:click={clickHandlerCategory}>Filter by Category </button>
{#if isCategoryDropdownExpanded}
<div id="category-list" transition:slide>
<div id="date-list" transition:slide>
{#each $incomeTypes as income (income.id)}
{#if income.id !== undefined}
<option value={income.id}>{income.name}</option>
<div class="date-entry" on:click={() => filterByCategory(income.name)} value={income.id}>{income.name}</div>
{/if}
{/each}
</div>
@@ -76,48 +246,147 @@
flex: 1 1 auto;
}
#button {
background-color: #fff000;
border-radius: 12px;
color: #000;
cursor: pointer;
font-weight: bold;
padding: 10px 15px;
text-align: center;
transition: 200ms;
width: 100%;
box-sizing: border-box;
border: 0;
font-size: 16px;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
}
/*#button {*/
/* background-color: #fff000;*/
/* border-radius: 12px;*/
/* color: #000;*/
/* cursor: pointer;*/
/* font-weight: bold;*/
/* padding: 10px 15px;*/
/* text-align: center;*/
/* transition: 200ms;*/
/* width: 100%;*/
/* box-sizing: border-box;*/
/* border: 0;*/
/* font-size: 16px;*/
/* user-select: none;*/
/* -webkit-user-select: none;*/
/* touch-action: manipulation;*/
/*}*/
#button:not(:disabled):hover,
#button:not(:disabled):focus {
outline: 0;
background: #f4e603;
box-shadow: 0 0 0 2px rgba(0,0,0,.2), 0 3px 8px 0 rgba(0,0,0,.15);
}
#button:disabled {
filter: saturate(0.2) opacity(0.5);
-webkit-filter: saturate(0.2) opacity(0.5);
cursor: not-allowed;
}
/*#button:not(:disabled):hover,*/
/*#button:not(:disabled):focus {*/
/* outline: 0;*/
/* background: #f4e603;*/
/* box-shadow: 0 0 0 2px rgba(0,0,0,.2), 0 3px 8px 0 rgba(0,0,0,.15);*/
/*}*/
/*#button:disabled {*/
/* filter: saturate(0.2) opacity(0.5);*/
/* -webkit-filter: saturate(0.2) opacity(0.5);*/
/* cursor: not-allowed;*/
/*}*/
#date-list {
background-color: #8BD17C;
background-color: #007BFF;
position:absolute;
margin-top: 20px;
max-height: 400px;
overflow-y: scroll;
border-radius: 20px;
z-index:1;
}
#category-list {
background-color: #8BD17C;
position:absolute;
z-index:1;
.date-entry {
padding: 10px;
margin: 10px;
background-color: black;
color: white;
border-radius: 20px;
cursor: pointer;
}
.date-entry:hover {
background-color: rgb(128, 128, 128);
}
/*.button {*/
/* font-size: large;*/
/* margin: 10px;*/
/* background-color: #007BFF;*/
/* color: #fff;*/
/* border: none;*/
/* border-radius: 20px;*/
/* line-height: 40px;*/
/* cursor: pointer;*/
/*}*/
/*.button:hover {*/
/* background-color: #0056b3;*/
/*}*/
.button {
align-items: center;
background-color: #0A66C2;
border: 0;
border-radius: 100px;
box-sizing: border-box;
color: #ffffff;
cursor: pointer;
display: inline-flex;
font-family: -apple-system, system-ui, system-ui, "Segoe UI", Roboto, "Helvetica Neue", "Fira Sans", Ubuntu, Oxygen, "Oxygen Sans", Cantarell, "Droid Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Lucida Grande", Helvetica, Arial, sans-serif;
font-size: 16px;
font-weight: 600;
justify-content: center;
line-height: 20px;
max-width: 480px;
min-height: 40px;
min-width: 0px;
overflow: hidden;
padding: 0px;
padding-left: 20px;
padding-right: 20px;
text-align: center;
touch-action: manipulation;
transition: background-color 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s, box-shadow 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s, color 0.167s cubic-bezier(0.4, 0, 0.2, 1) 0s;
user-select: none;
-webkit-user-select: none;
vertical-align: middle;
}
.button:hover,
.button:focus {
background-color: #16437E;
color: #ffffff;
}
.button:active {
background: #09223b;
color: rgb(255, 255, 255, .7);
}
.button:disabled {
cursor: not-allowed;
background: rgba(0, 0, 0, .08);
color: rgba(0, 0, 0, .3);
}
/*#category-list {*/
/* background-color: #8BD17C;*/
/* position:absolute;*/
/* z-index:1;*/
/*}*/
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
#data-header {
@@ -131,7 +400,8 @@
border-top-left-radius: 20px;
border-top-right-radius: 20px;
font-size: larger;
border: #8BD17C 2px solid;
margin-bottom: 5px;
/*border: #8BD17C 2px solid;*/
}
#data-menu {

View File

@@ -24,11 +24,11 @@
const expenseDifference = ((lastMonthExpense - totalExpenses) / lastMonthExpense) * 100;
try {
infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: 150%">${totalExpenses.toFixed(2)}$</span>`;
infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: 150%">${totalIncomes.toFixed(2)}$</span>`;
infobar1.innerHTML = `<span style="font-size: larger">Total expenses:</span><br><span style="color:red;font-size: xxx-large">${totalExpenses.toFixed(2)}$</span>`;
infobar2.innerHTML = `<span style="font-size: larger">Total incomes:</span><br><span style="color:green;font-size: xxx-large">${totalIncomes.toFixed(2)}$</span>`;
infobar3.innerHTML = `<span style="font-size: larger">Income by last month:</span><br><span style="color:blue;font-size: 150%">${incomeDifference.toFixed(2)}%</span>`;
infobar4.innerHTML = `<span style="font-size: larger">Expense by last month:</span><br><span style="color:orange;font-size: 150%">${expenseDifference.toFixed(2)}%</span>`;
infobar3.innerHTML = `<span style="font-size: larger">Income by last month:</span><br><span style="color:blue;font-size: xxx-large">${incomeDifference.toFixed(2)}%</span>`;
infobar4.innerHTML = `<span style="font-size: larger">Expense by last month:</span><br><span style="color:orange;font-size: xxx-large">${expenseDifference.toFixed(2)}%</span>`;
} catch {
console.log("not yet loaded");
}

View File

@@ -17,7 +17,7 @@
};
try {
const response = await axios.get('http://localhost:8081/users/getUserData', config);
const response = await axios.get('https://trackio.online:8081/users/get-user-data', config);
const data = response.data;
username = data.username;
console.log(username)
@@ -110,6 +110,7 @@
justify-content: center;
align-items: center;
border-radius: 20px;
cursor: pointer;
}
.sideMenuItem:hover {

View File

@@ -8,4 +8,10 @@ export const incomeTypes = writable([]);
export const expenseTypes = writable([]);
export const tempExpense = writable([])
export const tempIncome = writable([]);
export let selectedTab = writable('expenses');
export let dateText = writable("This Month");

View File

@@ -1,6 +1,15 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import fs from 'fs'
export default defineConfig({
plugins: [sveltekit()]
plugins: [sveltekit()],
server: {
port: 443,
https: {
key: fs.readFileSync('D:\\Source\\JavaProjects\\ExpenseTrackerFAF\\src\\main\\java\\com\\faf223\\expensetrackerfaf\\web\\privkey.pem'),
cert: fs.readFileSync('D:\\Source\\JavaProjects\\ExpenseTrackerFAF\\src\\main\\java\\com\\faf223\\expensetrackerfaf\\web\\fullchain.pem'),
proxy: {}
}
},
});