diff options
Diffstat (limited to 'assets/main.js')
-rw-r--r-- | assets/main.js | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/assets/main.js b/assets/main.js new file mode 100644 index 0000000..ba82a9f --- /dev/null +++ b/assets/main.js @@ -0,0 +1,226 @@ +const path = window.location.pathname + +// Setting up interactivity according to the current page + +if (path == '/login') { + + trim_inputs_on_blur() + +} else if (path == '/payment') { // Payment creation + + trim_inputs_on_blur() + auto_fill_category() + +} else if (path.startsWith('/payment/')) { // Payment modification + + trim_inputs_on_blur() + auto_fill_category() + control_remove_button() + +} else if (path == '/income') { // Income creation + + trim_inputs_on_blur() + +} else if (path.startsWith('/income/')) { // Income modification + + trim_inputs_on_blur() + control_remove_button() + +} else if (path == '/category') { // Category creation + + trim_inputs_on_blur() + +} else if (path.startsWith('/category/')) { // Category modification + + trim_inputs_on_blur() + control_remove_button() + +} else if (path == '/balance') { + +} else if (path == '/statistics') { + + show_statistics() + +} + +// Functions + +function trim_inputs_on_blur() { + document.querySelectorAll('input').forEach(function (input) { + input.addEventListener('blur', function () { + input.value = input.value.trim() + }) + }) +} + +function control_remove_button() { + const removeInput = document.getElementById('remove-input') + const removeButton = document.getElementById('remove-button') + + if (removeInput && removeButton) { + removeInput.addEventListener('input', function() { + if (removeInput.value.trim() == removeInput.getAttribute('data-name')) { + removeButton.removeAttribute('disabled') + } else { + removeButton.setAttribute('disabled', true) + } + }) + } +} + +function auto_fill_category() { + const name = document.getElementById('name') + const category = document.getElementById('category_id') + + function onNameChange() { + const query = name.value.trim() + if (query) { + const xhttp = new XMLHttpRequest() + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + category.value = this.responseText + } + } + xhttp.open('GET', `/payment/category?payment_name=${query}`, true) + xhttp.send() + } + } + + name.addEventListener('input', debounce(onNameChange, 500)) +} + +function show_statistics() { + const categories = JSON.parse(document.getElementById('categories').textContent) + const incomes = JSON.parse(document.getElementById('incomes').textContent) + const payments = JSON.parse(document.getElementById('payments').textContent) + + const dates = incomes.map(function (i) { return i.date }) + + const datasets = [ + { + label: 'Revenus', + data: incomes.map(function (i) { return i.amount }), + fill: false, + backgroundColor: '#222222', + borderColor: '#222222' + } + ] + + const total_payments = {}; + const categories_payments = {} + payments.forEach(function (p) { + if (categories_payments[p.category_id] === undefined) { + categories_payments[p.category_id] = {} + } + categories_payments[p.category_id][p.start_date] = p.cost + + if (total_payments[p.start_date] === undefined) { + total_payments[p.start_date] = 0 + } + total_payments[p.start_date] += p.cost + }) + + datasets.push({ + label: 'Total des paiements', + data: dates.map(function (d) { return total_payments[d] || 0 }), + fill: false, + backgroundColor: '#555555', + borderColor: '#555555' + }) + + Object.keys(categories_payments).forEach(function (category_id) { + const category_payments = categories_payments[category_id] + const category = categories.find(function (c) { return c.id == category_id }) + datasets.push({ + label: category.name, + data: dates.map(function (d) { return category_payments[d] || 0 }), + fill: false, + backgroundColor: category.color, + borderColor: category.color, + }) + }) + + const chart = new Chart(document.getElementById('g-Chart__Canvas').getContext('2d'), { + type: 'line', + + data: { + labels: dates, + datasets + }, + + options: { + responsive: true, + tooltips: { + mode: 'nearest', + intersect: false, + callbacks: { + title: function(tooltipItem, data) { + return capitalize(prettyPrintMonth(tooltipItem[0].xLabel)) + }, + label: function(tooltipItem, data) { + let label = data.datasets[tooltipItem.datasetIndex].label || '' + if (label) { + label += ': ' + } + label += `${tooltipItem.yLabel} €` + return label + } + } + }, + hover: { + mode: 'nearest', + intersect: true + }, + scales: { + xAxes: [ + { + ticks: { + callback: prettyPrintMonth + } + } + ], + yAxes: [ + { + ticks: { + beginAtZero: true, + callback: function(value) { + return `${value} €` + } + } + } + ] + } + } + }) +} + +function debounce(callback, delay) { + let timeout + return function() { + clearTimeout(timeout) + timeout = setTimeout(callback, delay) + } +} + +function prettyPrintMonth(isoDate) { + xs = isoDate.split('-') + months = [ + 'janvier', + 'février', + 'mars', + 'avril', + 'mai', + 'juin', + 'juillet', + 'août', + 'septembre', + 'octobre', + 'novembre', + 'décembre' + ] + return `${months[parseInt(xs[1]) - 1]} ${xs[0]}` +} + +function capitalize(str) { + return str.replace(/^\w/, function (c) { return c.toUpperCase() }) +} |