Updated home with a mini dashboard and created the base.css

This commit is contained in:
JKuijperM 2026-01-27 16:08:35 +01:00
parent cf3869c370
commit b75efb1553
3 changed files with 120 additions and 82 deletions

View File

@ -0,0 +1,21 @@
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 500px));
gap: 20px
}
.card {
background: #fff;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.card-chart {
max-width: 500px;
}
.card-chart canvas {
width: 100% !important;
height: 220px !important;
}

View File

@ -1,53 +1,68 @@
{% load static %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Home</title> <title>Home</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="{% static 'expenses/css/base.css' %}">
</head> </head>
<body> <body>
<h1>Resumen del mes</h1> <h1>Home</h1>
<!-- KPIs -->
<section> <section>
<h2>Indicadores</h2> <h2>Resumen del mes</h2>
<p>Total: {{ kpi_total }}</p>
<p>Gastos: {{ kpi_count }}</p>
<p>Categorías: {{ kpi_categories }}</p>
</section>
<section>
<h2>Últimos gastos</h2>
<ul> <ul>
<li> {% for expense in last_expenses %}
<strong>Total gastado:</strong> <li>
{{ kpi_total }} {{ expense.date }} -
</li> {{ expense.category.name }} -
{{ expense.amount }}
<li> </li>
<strong>Nº de gastos:</strong> {% empty %}
{{ kpi_difference }} <li>No hay gastos</li>
</li> {% endfor %}
<li>
<strong>Variación (%):</strong>
{% if kpi_percentage is not None %}
{{ kpi_percentage|floatformat:2 }} %
{% else %}
N/A
{% endif %}
</li>
</ul> </ul>
</section> </section>
<hr>
<!-- Actions -->
<section> <section>
<h2>Acciones</h2> <div class="dashboard-grid">
<div class="card card-chart">
<h2>Últimos meses</h2>
<canvas id="miniChart"></canvas>
</div>
</div>
<script>
const labels = {{ mini_chart_labels|safe }};
const data = {{ mini_chart_data|safe }};
const ctx = document.getElementById('miniChart');
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets:[{
label: 'Gastos',
data: data,
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
</script>
<ul>
<li>
<a href="{% url 'dashboard' %}">Ir al dashboard</a>
</li>
<li>
<a href="{% url 'expense_create' %}">Añadir gasto</a>
</li>
</ul>
</section> </section>
</body> </body>

View File

@ -32,66 +32,68 @@ def _get_int(value):
except (TypeError, ValueError): except (TypeError, ValueError):
return None return None
def sub_months(year, month, n):
month -= n
while month <= 0:
month += 12
year -= 1
return year, month
@login_required @login_required
def home(request): def home(request):
today = date.today() expenses = Expense.objects.filter(owner=request.user)
year = today.year
month = today.month
expenses = Expense.objects.filter( # Last expenses
owner=request.user, last_expenses = (
date__year=year, expenses
date__month=month, .select_related('category')
.order_by('-date')[:5]
) )
# Current KPIs # Simple KPIs (current month)
total_amount = expenses.aggregate( today = date.today()
month_expenses = expenses.filter(
date__year=today.year,
date__month=today.month
)
kpi_total = month_expenses.aggregate(
total=Sum('amount') total=Sum('amount')
)['total'] or 0 )['total'] or 0
expense_count = expenses.count() kpi_count = month_expenses.count()
# ------------------ kpi_categories = (
# Previous period month_expenses
# ------------------ .values('category')
if month == 1: .distinct()
prev_year = year - 1 .count()
prev_month = 12
else:
prev_year = year
prev_month = month - 1
previous_expenses = Expense.objects.filter(
owner=request.user,
date__year=prev_year,
date__month=prev_month,
)
previous_total = (
previous_expenses.aggregate(total=Sum('amount'))['total'] or 0
)
difference = total_amount - previous_total
percentage = (difference / previous_total) * 100 if previous_total else None
# ------------------
# Top categories
# ------------------
top_categories = (
expenses
.values('category__name')
.annotate(total=Sum('amount'))
.order_by('-total')[:3]
) )
six_months = []
for i in range(5, -1, -1):
y, m = sub_months(today.year, today.month, i)
six_months.append((y, m))
mini_data = []
for y, m in six_months:
total = expenses.filter(
date__year=y,
date__month=m
).aggregate(total=Sum('amount'))['total'] or 0
mini_data.append({
'label': f'{m}/{y}',
'total': float(total),
})
return render(request, 'expenses/home.html', { return render(request, 'expenses/home.html', {
'kpi_total': total_amount, 'last_expenses': last_expenses,
'kpi_amount': expense_count, 'kpi_total': kpi_total,
'kpi_difference': difference, 'kpi_count': kpi_count,
'kpi_percentage': percentage, 'kpi_categories': kpi_categories,
'kpi_previous_total': previous_total, 'mini_chart_labels': [x['label'] for x in mini_data],
'top_categories': top_categories, 'mini_chart_data': [x['total'] for x in mini_data],
}) })
@login_required @login_required