Skip to main content

Frontend

The dashboard is composed of a main view that includes 4 sections via partials: stat cards, annual chart, welcome card, and quick lists.

File Structure

resources/views/dashboard/
├── index.blade.php
├── _stats-cards.blade.php
├── _chart.blade.php
├── _welcome-card.blade.php
├── _lists.blade.php
├── stats-cards/
│ ├── _profit.blade.php
│ ├── _pending-payments.blade.php
│ ├── _active-projects.blade.php
│ └── _open-tasks.blade.php
└── lists/
├── _tasks-due-soon.blade.php
├── _upcoming-meetings.blade.php
├── _overdue-payments.blade.php
├── _recent-payments.blade.php
└── _recent-costs.blade.php

resources/js/components/
└── annualTrendChart.js

Page Layout (index.blade.php)

Uses <x-app-layout>. Grid structure:

  1. Header - Page title and current date
  2. Stats cards - Row of 4 KPI cards (_stats-cards.blade.php)
  3. 2-column grid - Chart (2/3 width) + Welcome card (1/3 width)
  4. Quick lists - 3 rows: tasks+meetings, payments+costs, overdue full width (_lists.blade.php)

Stat Cards

_stats-cards.blade.php includes 4 cards from the stats-cards/ subfolder:

Profit This Month (_profit.blade.php)

  • Data: $stats['profit_this_month']['amount']
  • Dynamic color: green (emerald) if positive, red if negative
  • Breakdown: +payments, -costs

Pending Payments (_pending-payments.blade.php)

  • Data: $stats['pending_payments']['total'] (amount in currency)
  • Shows count and total amount to collect
  • Orange warning if there are overdue payments

Active Projects (_active-projects.blade.php)

  • Data: $stats['active_projects'] (count)
  • Number of projects in progress
  • Blue color

Open Tasks (_open-tasks.blade.php)

  • Data: $stats['open_tasks'] (array with breakdown)
  • Total + breakdown by status: todo (gray), in_progress (blue), blocked (red)
  • Purple color

Annual Chart (_chart.blade.php)

Mixed bar+line chart showing the annual financial trend.

Data Passed to Alpine.js Component

<div x-data="annualTrendChart(@js([...]))">
DataDescription
labelsMonth abbreviations
paymentsArray of 12 monthly payment totals
costsArray of 12 monthly cost totals
profitArray of 12 calculated profit
currencySymbolCurrency symbol from BusinessSettings
translationsTranslated labels for legend

JS Component (annualTrendChart.js)

Alpine.js component registered in app.js that uses Chart.js:

  • Type: Mixed - bars (payments/costs) + line (profit)
  • Colors: Payments emerald, costs red, profit indigo
  • Dark mode: MutationObserver watches only for changes to the dark class on <html> (dirty check: re-renders only if dark mode actually changed)
  • Responsive: responsive: false — Chart.js internal ResizeObserver disabled to avoid canvas being set to 0x0 during CSS sidebar transitions. Resize is managed manually via a ResizeObserver on the chart container
  • Initial render: ResizeObserver fires as soon as the container gets real dimensions (handles background tabs correctly, replaces the old requestAnimationFrame polling)
  • Tooltip: Currency formatting with it-IT locale
  • Y axis: Starts at zero, currency symbol prefix on ticks

Registration in app.js:

import annualTrendChart from './components/annualTrendChart';
Alpine.data('annualTrendChart', annualTrendChart);

Welcome Card (_welcome-card.blade.php)

Static informational card with:

  • Application logo
  • Title and subtitle
  • List of 4 features: client management (blue), projects (green), payments (amber), documentation (purple)

Quick Lists (_lists.blade.php)

_lists.blade.php includes 5 lists from the lists/ subfolder, arranged in 3 rows:

  • Row 1 (2 columns): Tasks Due Soon + Upcoming Meetings
  • Row 2 (2 columns): Recent Payments + Recent Costs
  • Row 3 (full width): Overdue Payments

Tasks Due Soon (_tasks-due-soon.blade.php)

  • Data: $lists['tasks_due_soon'] (max 5)
  • Shows: task title, project name, due date, <x-tasks.type-badge>
  • Colored dot for status: red (overdue), blue (in progress), gray (todo)
  • Each row links to projects.show?tab=tasks
  • "View all" link → route('tasks.index')

Upcoming Meetings (_upcoming-meetings.blade.php)

  • Data: $lists['upcoming_meetings'] (max 5)
  • Shows: date (large day + small month), title, project, time (H:i), <x-meetings.status-badge>
  • Each row links to projects.show?tab=meetings
  • "View all" link → route('meetings.index')

Recent Payments (_recent-payments.blade.php)

  • Data: $lists['recent_payments'] (max 5)
  • Shows: amount (green with +), project name, <x-payments.method-badge>, payment date
  • Each row links to projects.show?tab=payments
  • "View all" link → route('payments.index')

Recent Costs (_recent-costs.blade.php)

  • Data: $lists['recent_costs'] (max 5)
  • Shows: amount (red with -), project name, <x-costs.type-badge>, date
  • Each row links to projects.show?tab=costs
  • "View all" link → route('costs.index')

Overdue Payments (_overdue-payments.blade.php)

  • Data: $lists['overdue_payments'] (max 5)
  • Full width row — shows: amount + currency, client/project
  • Red warning: days overdue or amber "due today"
  • Each row links to projects.show?tab=payments
  • "View all" link → route('payments.index')

Empty State

Each list has a dedicated empty state message when there are no items.

Currency

The currency symbol ($currencySymbol) and code ($currencyCode) are globally injected into all views via the View Composer in AppServiceProvider. The stat cards and lists use them to format amounts.

Technical Notes

  • No Livewire components: all server-side rendering with Blade + Alpine.js only for the chart.
  • Dark mode supported on all components via Tailwind dark: classes.
  • All list rows are clickable links to the relevant project tab (projects.show?tab=*).
  • Existing badge components (<x-tasks.type-badge>, <x-meetings.status-badge>, <x-payments.method-badge>, <x-costs.type-badge>) are reused — no inline badge logic.
  • The chart is the only component that requires JavaScript (Chart.js + Alpine.js).