121 lines
4.7 KiB
Plaintext
121 lines
4.7 KiB
Plaintext
@attribute [Authorize(Roles = "Budget")]
|
|
@using Microsoft.AspNetCore.Authorization
|
|
|
|
@{
|
|
ViewData["Title"] = "Budgetlista";
|
|
}
|
|
|
|
<div ng-app="budgetApp" ng-controller="BudgetListController" class="budget-page">
|
|
|
|
<!-- Toggle -->
|
|
<div class="details-toggle">
|
|
<label>
|
|
<input type="checkbox" ng-model="showDetails"> Visa mer detaljer
|
|
</label>
|
|
</div>
|
|
|
|
<div ng-repeat="(year, months) in monthsByYear">
|
|
<div class="year-header">{{ year }}</div>
|
|
|
|
<div class="budget-row">
|
|
<div class="budget-card" ng-repeat="month in months" ng-click="goToBudget(month)">
|
|
<!-- Flex-container med namn + bars -->
|
|
<div class="month-header">
|
|
<div class="month-name">{{ getMonthName(month) }}</div>
|
|
<div class="month-bars">
|
|
<div class="bar income" ng-style="{'height': month.barHeights.income + '%'}" title="Inkomst"></div>
|
|
<div class="bar expenses" ng-style="{'height': month.barHeights.expenses + '%'}" title="Utgifter"></div>
|
|
<div class="bar savings" ng-style="{'height': month.barHeights.savings + '%'}" title="Sparande"></div>
|
|
<!-- <div class="bar leftover" ng-style="{'height': month.barHeights.leftover + '%'}" title="Balans"></div>-->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="item-list" ng-if="showDetails">
|
|
<div class="item-row" ng-repeat="cat in month.categories">
|
|
<span class="item-label" style="color: {{ cat.color }}">{{ cat.name }}</span>
|
|
<span class="amount">{{ getCategorySum(cat) | number:0 }} kr</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="~/css/budget-list.css" />
|
|
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
|
|
<script>
|
|
angular.module('budgetApp', [])
|
|
.controller('BudgetListController', ['$scope', '$http', '$window', function($scope, $http, $window){
|
|
|
|
$scope.months = [];
|
|
$scope.monthsByYear = {};
|
|
$scope.showDetails = false;
|
|
const maxBarValue = 100000;
|
|
const monthNames = ["Januari","Februari","Mars","April","Maj","Juni",
|
|
"Juli","Augusti","September","Oktober","November","December"];
|
|
|
|
$scope.getMonthName = month => month.month ? monthNames[month.month-1] : month.name;
|
|
$scope.getCategorySum = cat => cat.items ? cat.items.reduce((sum,i)=>sum+i.amount,0) : 0;
|
|
$scope.goToBudget = month => $window.location.href = '/budget/' + (month.year || month.name) + '/' + (month.month || '');
|
|
|
|
$scope.getTotalIncome = period => {
|
|
return (period.categories || [])
|
|
.flatMap(c => c.items || [])
|
|
.filter(i => !i.isExpense && i.includeInSummary)
|
|
.reduce((sum,i)=>sum+i.amount,0);
|
|
};
|
|
|
|
$scope.getTotalSavings = period => {
|
|
return (period.categories || [])
|
|
.flatMap(c => c.items || [])
|
|
.filter(i => !i.isExpense && i.includeInSummary && i.name.toLowerCase().includes('spara'))
|
|
.reduce((sum,i)=>sum+i.amount,0);
|
|
};
|
|
|
|
$scope.getTotalExpenses = period => {
|
|
return (period.categories || [])
|
|
.flatMap(c => c.items || [])
|
|
.filter(i => i.isExpense && i.includeInSummary)
|
|
.reduce((sum,i)=>sum+i.amount,0);
|
|
};
|
|
|
|
$scope.getTotalLeftover = period => {
|
|
return $scope.getTotalIncome(period) - $scope.getTotalSavings(period) - $scope.getTotalExpenses(period);
|
|
};
|
|
|
|
$http.get('/api/budget/list').then(res => {
|
|
// Sortera från januari → december per år
|
|
const sorted = res.data.sort((a,b) => (a.year||0)-(b.year||0) || (a.month||0)-(b.month||0));
|
|
|
|
$scope.months = sorted.map(month => {
|
|
const income = $scope.getTotalIncome(month);
|
|
const savings = $scope.getTotalSavings(month);
|
|
const expenses = $scope.getTotalExpenses(month);
|
|
const leftover = $scope.getTotalLeftover(month);
|
|
|
|
month.barHeights = {
|
|
income: Math.max(income / maxBarValue * 100, 5),
|
|
savings: Math.max(savings / maxBarValue * 100, 5),
|
|
expenses: Math.max(expenses / maxBarValue * 100, 5),
|
|
leftover: Math.max(leftover / maxBarValue * 100, 5)
|
|
};
|
|
return month;
|
|
});
|
|
|
|
// Gruppera per år
|
|
$scope.monthsByYear = $scope.months.reduce((acc, m) => {
|
|
const year = m.year || 'Övrigt';
|
|
if (!acc[year]) acc[year] = [];
|
|
acc[year].push(m);
|
|
return acc;
|
|
}, {});
|
|
});
|
|
|
|
|
|
}]);
|
|
</script>
|