PlanTempusApp/PlanTempus.Application/Features/Reports/Pages/Index.cshtml
Janus C. H. Knudsen 2f92b0eb7b Refactors reports page search and filtering functionality
Moves search and filtering logic from inline script to a dedicated TypeScript module

Improves code organization by creating a ReportsController with:
- Enhanced search capabilities
- Advanced range query parsing
- Flexible filtering mechanisms

Removes inline JavaScript and integrates modular approach in the application
2026-01-21 21:49:10 +01:00

440 lines
22 KiB
Text

@page "/rapporter"
@model PlanTempus.Application.Features.Reports.Pages.IndexModel
@{
ViewData["Title"] = "Statistik og Rapporter";
}
<!-- Sticky Header with Tabs -->
<swp-sticky-header>
<swp-header-content>
<swp-page-header>
<swp-page-title>
<i class="ph ph-chart-line-up"></i>
<span>Statistik og Rapporter</span>
</swp-page-title>
<swp-page-actions>
<swp-btn class="secondary" id="exportBtn">
<i class="ph ph-export"></i>
Eksporter
</swp-btn>
</swp-page-actions>
</swp-page-header>
</swp-header-content>
<!-- Tab Bar -->
<swp-tab-bar>
<swp-tab class="active" data-tab="sales">
<i class="ph ph-receipt"></i>
<span>Salgsrapport</span>
</swp-tab>
<swp-tab data-tab="hours">
<i class="ph ph-clock"></i>
<span>Timerapport</span>
</swp-tab>
</swp-tab-bar>
</swp-sticky-header>
<!-- Tab Content: Salgsrapport -->
<swp-tab-content data-tab="sales" class="active">
<swp-page-container>
<!-- Stats Bar -->
<swp-stats-row class="cols-4">
<swp-stat-card class="highlight">
<swp-stat-value>12.450 kr</swp-stat-value>
<swp-stat-label>Omsætning i dag</swp-stat-label>
</swp-stat-card>
<swp-stat-card class="success">
<swp-stat-value>187.230 kr</swp-stat-value>
<swp-stat-label>Omsætning denne måned</swp-stat-label>
</swp-stat-card>
<swp-stat-card>
<swp-stat-value>18</swp-stat-value>
<swp-stat-label>Antal salg i dag</swp-stat-label>
</swp-stat-card>
<swp-stat-card>
<swp-stat-value>692 kr</swp-stat-value>
<swp-stat-label>Gns. ordreværdi</swp-stat-label>
</swp-stat-card>
</swp-stats-row>
<!-- Charts Grid -->
<swp-charts-grid>
<swp-chart-card>
<swp-chart-header>
<swp-chart-title>Omsætning pr. måned</swp-chart-title>
<swp-chart-hint>Sidste 12 måneder</swp-chart-hint>
</swp-chart-header>
<swp-chart-container id="revenueChart"></swp-chart-container>
</swp-chart-card>
<swp-chart-card>
<swp-chart-header>
<swp-chart-title>Betalingsmetoder</swp-chart-title>
<swp-chart-hint>Fordeling</swp-chart-hint>
</swp-chart-header>
<swp-chart-container id="paymentChart"></swp-chart-container>
</swp-chart-card>
</swp-charts-grid>
<!-- Filter Bar -->
<swp-filter-bar>
<swp-search-input>
<i class="ph ph-magnifying-glass"></i>
<input type="search" id="searchInput" placeholder="Søg fakturanr, kunde, medarbejder..." />
</swp-search-input>
<swp-filter-group>
<swp-filter-label>Fra</swp-filter-label>
<input type="date" id="dateFrom" value="2025-01-01" />
</swp-filter-group>
<swp-filter-group>
<swp-filter-label>Til</swp-filter-label>
<input type="date" id="dateTo" value="2025-01-06" />
</swp-filter-group>
<swp-filter-group>
<swp-filter-label>Status</swp-filter-label>
<select id="statusFilter">
<option value="">Alle</option>
<option value="paid">Betalt</option>
<option value="pending">Afventer</option>
<option value="credited">Krediteret</option>
</select>
</swp-filter-group>
<swp-filter-group>
<swp-filter-label>Betaling</swp-filter-label>
<select id="paymentFilter">
<option value="">Alle</option>
<option value="card">Kort</option>
<option value="cash">Kontant</option>
<option value="mobilepay">MobilePay</option>
<option value="invoice">Faktura</option>
<option value="giftcard">Fordelskort</option>
</select>
</swp-filter-group>
</swp-filter-bar>
<!-- Sales Table -->
<swp-card class="sales-table">
<swp-data-table>
<swp-data-table-header>
<swp-data-table-cell>Faktura</swp-data-table-cell>
<swp-data-table-cell>Dato/tid</swp-data-table-cell>
<swp-data-table-cell>Kunde</swp-data-table-cell>
<swp-data-table-cell>Medarbejder</swp-data-table-cell>
<swp-data-table-cell>Ydelser</swp-data-table-cell>
<swp-data-table-cell class="right">Beløb</swp-data-table-cell>
<swp-data-table-cell>Betaling</swp-data-table-cell>
<swp-data-table-cell>Status</swp-data-table-cell>
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-header>
<!-- Row 1 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1847</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">6. jan 2025</span>
<span class="time">14:32</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Maria Hansen</span>
<span class="phone">+45 23 45 67 89</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Louise P.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Dameklip, Farve</span>
<span class="more">+ 1 produkt</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>1.450 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="card"><i class="ph ph-credit-card"></i> Kort</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 2 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1846</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">6. jan 2025</span>
<span class="time">13:15</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Peter Sørensen</span>
<span class="phone">+45 30 12 34 56</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Anna J.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Herreklip</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>295 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="mobilepay"><i class="ph ph-device-mobile"></i> MobilePay</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 3 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1845</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">6. jan 2025</span>
<span class="time">11:45</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Lise Andersen</span>
<span class="phone">+45 42 56 78 90</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Louise P.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Dameklip, Balayage</span>
<span class="more">+ 2 produkter</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>2.350 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="card"><i class="ph ph-credit-card"></i> Kort</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 4 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1844</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">5. jan 2025</span>
<span class="time">16:20</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Thomas Nielsen</span>
<span class="phone">+45 51 23 45 67</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Mikkel H.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Herreklip, Skægtrim</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>395 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="cash"><i class="ph ph-money"></i> Kontant</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 5 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1843</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">5. jan 2025</span>
<span class="time">14:00</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Sofia Madsen</span>
<span class="phone">+45 60 78 90 12</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Anna J.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Extensions</span>
<span class="more">+ 1 produkt</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>4.500 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="invoice"><i class="ph ph-file-text"></i> Faktura</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="pending">Afventer</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 6 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1842</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">5. jan 2025</span>
<span class="time">11:30</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Emma Jensen</span>
<span class="phone">+45 71 23 45 67</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Louise P.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Dameklip</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>-450 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="card"><i class="ph ph-credit-card"></i> Kort</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="credited">Krediteret</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 7 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1841</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">4. jan 2025</span>
<span class="time">15:45</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Katrine Olsen</span>
<span class="phone">+45 82 34 56 78</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Mikkel H.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Dameklip, Highlights</span>
<span class="more">+ 3 produkter</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>1.895 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="giftcard"><i class="ph ph-gift"></i> Fordelskort</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
<!-- Row 8 -->
<swp-data-table-row>
<swp-data-table-cell>
<swp-invoice-cell>#1840</swp-invoice-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-datetime-cell>
<span class="date">4. jan 2025</span>
<span class="time">10:00</span>
</swp-datetime-cell>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-customer-cell>
<span class="name">Mads Christensen</span>
<span class="phone">+45 93 45 67 89</span>
</swp-customer-cell>
</swp-data-table-cell>
<swp-data-table-cell class="muted">Anna J.</swp-data-table-cell>
<swp-data-table-cell>
<swp-services-cell>
<span class="main">Herreklip</span>
</swp-services-cell>
</swp-data-table-cell>
<swp-data-table-cell><swp-amount-cell>275 kr</swp-amount-cell></swp-data-table-cell>
<swp-data-table-cell><swp-payment-badge class="mobilepay"><i class="ph ph-device-mobile"></i> MobilePay</swp-payment-badge></swp-data-table-cell>
<swp-data-table-cell><swp-status-badge class="paid">Betalt</swp-status-badge></swp-data-table-cell>
<swp-data-table-cell><swp-row-arrow><i class="ph ph-caret-right"></i></swp-row-arrow></swp-data-table-cell>
</swp-data-table-row>
</swp-data-table>
<swp-table-footer>
<span>Viser 1-8 af 1.847 fakturaer</span>
<swp-pagination>
<swp-page-btn><i class="ph ph-caret-left"></i></swp-page-btn>
<swp-page-btn class="active">1</swp-page-btn>
<swp-page-btn>2</swp-page-btn>
<swp-page-btn>3</swp-page-btn>
<swp-page-btn>...</swp-page-btn>
<swp-page-btn>231</swp-page-btn>
<swp-page-btn><i class="ph ph-caret-right"></i></swp-page-btn>
</swp-pagination>
</swp-table-footer>
</swp-card>
</swp-page-container>
</swp-tab-content>
<!-- Tab Content: Timerapport -->
<swp-tab-content data-tab="hours">
<swp-page-container>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-clock"></i>
<span>Timerapport</span>
</swp-card-title>
</swp-card-header>
<swp-empty-state>
<i class="ph ph-clock-counter-clockwise"></i>
<span>Timerapport kommer snart</span>
</swp-empty-state>
</swp-card>
</swp-page-container>
</swp-tab-content>
@section Scripts {
<script type="module">
import { createChart } from '/lib/swp-charting/dist/swp-charting.js';
// Revenue bar chart
createChart(document.getElementById('revenueChart'), {
height: 240,
xAxis: {
categories: ['Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec', 'Jan']
},
yAxis: {
format: (v) => `${Math.round(v / 1000)}k`
},
series: [{
name: 'Omsætning',
color: '#00897b',
type: 'bar',
unit: ' kr',
data: [
{ x: 'Feb', y: 142500 },
{ x: 'Mar', y: 168200 },
{ x: 'Apr', y: 155800 },
{ x: 'Maj', y: 178400 },
{ x: 'Jun', y: 145600 },
{ x: 'Jul', y: 98200 },
{ x: 'Aug', y: 134500 },
{ x: 'Sep', y: 189300 },
{ x: 'Okt', y: 201400 },
{ x: 'Nov', y: 178900 },
{ x: 'Dec', y: 245600 },
{ x: 'Jan', y: 187230 }
]
}]
});
// Payment methods pie chart
createChart(document.getElementById('paymentChart'), {
height: 240,
series: [
{ name: 'Kort', color: '#1976d2', type: 'pie', data: [{ x: '', y: 892400 }], unit: ' kr', pie: { innerRadius: 40, outerRadius: 90 } },
{ name: 'MobilePay', color: '#5C6BC0', type: 'pie', data: [{ x: '', y: 445200 }], unit: ' kr', pie: { innerRadius: 40, outerRadius: 90 } },
{ name: 'Kontant', color: '#43a047', type: 'pie', data: [{ x: '', y: 234800 }], unit: ' kr', pie: { innerRadius: 40, outerRadius: 90 } },
{ name: 'Faktura', color: '#f59e0b', type: 'pie', data: [{ x: '', y: 178500 }], unit: ' kr', pie: { innerRadius: 40, outerRadius: 90 } },
{ name: 'Fordelskort', color: '#8b5cf6', type: 'pie', data: [{ x: '', y: 74700 }], unit: ' kr', pie: { innerRadius: 40, outerRadius: 90 } }
],
tooltip: true,
legend: { position: 'right', align: 'center' }
});
</script>
}