diff --git a/expenses_manager/expenses/static/expenses/css/base.css b/expenses_manager/expenses/static/expenses/css/base.css
new file mode 100644
index 0000000..c847f94
--- /dev/null
+++ b/expenses_manager/expenses/static/expenses/css/base.css
@@ -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;
+}
\ No newline at end of file
diff --git a/expenses_manager/expenses/templates/expenses/home.html b/expenses_manager/expenses/templates/expenses/home.html
index fd2c857..27f74d1 100644
--- a/expenses_manager/expenses/templates/expenses/home.html
+++ b/expenses_manager/expenses/templates/expenses/home.html
@@ -1,53 +1,68 @@
+{% load static %}
Home
+
+
- Resumen del mes
+ Home
-
- Indicadores
-
+ Resumen del mes
+ Total: {{ kpi_total }}
+ Gastos: {{ kpi_count }}
+ Categorías: {{ kpi_categories }}
+
+
+
+ Últimos gastos
- -
- Total gastado:
- {{ kpi_total }}
-
-
- -
- Nº de gastos:
- {{ kpi_difference }}
-
-
- -
- Variación (%):
- {% if kpi_percentage is not None %}
- {{ kpi_percentage|floatformat:2 }} %
- {% else %}
- N/A
- {% endif %}
-
+ {% for expense in last_expenses %}
+ -
+ {{ expense.date }} -
+ {{ expense.category.name }} -
+ {{ expense.amount }}
+
+ {% empty %}
+ - No hay gastos
+ {% endfor %}
-
-
-
diff --git a/expenses_manager/expenses/views.py b/expenses_manager/expenses/views.py
index 785d0ef..ed2e45e 100644
--- a/expenses_manager/expenses/views.py
+++ b/expenses_manager/expenses/views.py
@@ -32,66 +32,68 @@ def _get_int(value):
except (TypeError, ValueError):
return None
+def sub_months(year, month, n):
+ month -= n
+ while month <= 0:
+ month += 12
+ year -= 1
+ return year, month
+
@login_required
def home(request):
- today = date.today()
- year = today.year
- month = today.month
+ expenses = Expense.objects.filter(owner=request.user)
- expenses = Expense.objects.filter(
- owner=request.user,
- date__year=year,
- date__month=month,
+ # Last expenses
+ last_expenses = (
+ expenses
+ .select_related('category')
+ .order_by('-date')[:5]
)
- # Current KPIs
- total_amount = expenses.aggregate(
+ # Simple KPIs (current month)
+ today = date.today()
+ month_expenses = expenses.filter(
+ date__year=today.year,
+ date__month=today.month
+ )
+
+ kpi_total = month_expenses.aggregate(
total=Sum('amount')
)['total'] or 0
- expense_count = expenses.count()
+ kpi_count = month_expenses.count()
- # ------------------
- # Previous period
- # ------------------
- if month == 1:
- prev_year = year - 1
- 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]
+ kpi_categories = (
+ month_expenses
+ .values('category')
+ .distinct()
+ .count()
)
+ 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', {
- 'kpi_total': total_amount,
- 'kpi_amount': expense_count,
- 'kpi_difference': difference,
- 'kpi_percentage': percentage,
- 'kpi_previous_total': previous_total,
- 'top_categories': top_categories,
+ 'last_expenses': last_expenses,
+ 'kpi_total': kpi_total,
+ 'kpi_count': kpi_count,
+ 'kpi_categories': kpi_categories,
+ 'mini_chart_labels': [x['label'] for x in mini_data],
+ 'mini_chart_data': [x['total'] for x in mini_data],
})
@login_required