From 5ff25ac193138853004de10980ee1a5150a8cef5 Mon Sep 17 00:00:00 2001 From: Tatevik Date: Thu, 19 Mar 2026 21:36:56 +0400 Subject: [PATCH] Dashboard stats from api --- assets/vue/components/dashboard/KpiGrid.vue | 60 ++++++++++++++----- .../dashboard/RecentCampaignsCard.vue | 28 +-------- assets/vue/views/DashboardView.vue | 29 +++++++-- src/Controller/DashboardController.php | 52 ++++++++++++++++ templates/spa.html.twig | 3 +- 5 files changed, 124 insertions(+), 48 deletions(-) diff --git a/assets/vue/components/dashboard/KpiGrid.vue b/assets/vue/components/dashboard/KpiGrid.vue index 5adb984..4835163 100644 --- a/assets/vue/components/dashboard/KpiGrid.vue +++ b/assets/vue/components/dashboard/KpiGrid.vue @@ -10,40 +10,70 @@ diff --git a/assets/vue/components/dashboard/RecentCampaignsCard.vue b/assets/vue/components/dashboard/RecentCampaignsCard.vue index 57849dd..0f6f010 100644 --- a/assets/vue/components/dashboard/RecentCampaignsCard.vue +++ b/assets/vue/components/dashboard/RecentCampaignsCard.vue @@ -18,35 +18,9 @@ import BaseCard from '../../components/base/BaseCard.vue' import CampaignsTable from './CampaignsTable.vue' const props = defineProps({ - // todo: take from backend rows: { type: Array, - default: () => [ - { - id: 'campaign-1', - name: 'Summer Sale', - status: 'Sent', - date: '2023-07-01', - openRate: '15%', - clickRate: '5%', - }, - { - id: 'campaign-2', - name: 'Winter Sale', - status: 'scheduled', - date: '2023-07-01', - openRate: '23%', - clickRate: '0%', - }, - { - id: 'campaign-3', - name: 'Autumn Sale', - status: 'draft', - date: '2023-07-01', - openRate: '11%', - clickRate: '0%', - }, - ], + default: () => [], }, }) diff --git a/assets/vue/views/DashboardView.vue b/assets/vue/views/DashboardView.vue index 050be6b..b48125d 100644 --- a/assets/vue/views/DashboardView.vue +++ b/assets/vue/views/DashboardView.vue @@ -17,7 +17,7 @@
- +
@@ -30,11 +30,30 @@ import KpiGrid from '../components/dashboard/KpiGrid.vue' import PerformanceChartCard from '../components/dashboard/PerformanceChartCard.vue' import RecentCampaignsCard from '../components/dashboard/RecentCampaignsCard.vue' -const chart = { - labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], +const appElement = document.getElementById('vue-app') + +const parseDashboardStats = () => { + const raw = appElement?.dataset.dashboardStats + if (!raw) { + return {} + } + + try { + return JSON.parse(raw) + } catch { + return {} + } +} + +const dashboardStats = parseDashboardStats() + +const chart = dashboardStats.chart || { + labels: [], series: [ - { name: 'Opens', data: [2500, 2200, 10000, 4000, 4500, 3800] }, - { name: 'Clicks', data: [4200, 3500, 3200, 3000, 3600, 4100] }, + { name: 'Opens', data: [] }, + { name: 'Clicks', data: [] }, ], } + +const recentCampaigns = dashboardStats.recent_campaigns || [] diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php index 6215d3a..8a92959 100755 --- a/src/Controller/DashboardController.php +++ b/src/Controller/DashboardController.php @@ -4,6 +4,7 @@ namespace PhpList\WebFrontend\Controller; +use PhpList\RestApiClient\Endpoint\StatisticsClient; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -11,13 +12,64 @@ class DashboardController extends AbstractController { + public function __construct(private readonly StatisticsClient $statisticsClient) + { + } + #[Route('/', name: 'home', methods: ['GET'])] public function index(Request $request): Response { + $stats = $this->statisticsClient->getDashboardStats(); + $recentCampaigns = []; + foreach ($stats->recentCampaigns as $campaign) { + $recentCampaigns[] = [ + 'name' => $campaign->name, + 'status' => $campaign->status, + 'date' => $campaign->date?->format('Y-m-d') ?? '', + 'openRate' => $campaign->openRate, + 'clickRate' => $campaign->clickRate, + ]; + } + + $chartLabels = []; + $chartOpens = []; + $chartClicks = []; + foreach ($stats->campaignPerformance as $point) { + $chartLabels[] = $point->date?->format('M d') ?? ''; + $chartOpens[] = $point->opens; + $chartClicks[] = $point->clicks; + } + return $this->render('spa.html.twig', [ 'page' => 'Dashboard', 'api_token' => $request->getSession()->get('auth_token'), 'api_base_url' => $this->getParameter('api_base_url'), + 'dashboard_stats' => [ + 'total_subscribers' => [ + 'value' => $stats->totalSubscribers->value, + 'change_vs_last_month' => $stats->totalSubscribers->changeVsLastMonth, + ], + 'active_campaigns' => [ + 'value' => $stats->activeCampaigns->value, + 'change_vs_last_month' => $stats->activeCampaigns->changeVsLastMonth, + ], + 'open_rate' => [ + 'value' => $stats->openRate->value, + 'change_vs_last_month' => $stats->openRate->changeVsLastMonth, + ], + 'bounce_rate' => [ + 'value' => $stats->bounceRate->value, + 'change_vs_last_month' => $stats->bounceRate->changeVsLastMonth, + ], + 'recent_campaigns' => $recentCampaigns, + 'chart' => [ + 'labels' => $chartLabels, + 'series' => [ + ['name' => 'Opens', 'data' => $chartOpens], + ['name' => 'Clicks', 'data' => $chartClicks], + ], + ], + ], ]); } } diff --git a/templates/spa.html.twig b/templates/spa.html.twig index 668d4df..91e6c01 100644 --- a/templates/spa.html.twig +++ b/templates/spa.html.twig @@ -5,6 +5,7 @@ {% block body %}
+ data-api-base-url="{{ api_base_url|default('') }}" + data-dashboard-stats="{{ dashboard_stats|default({})|json_encode|e('html_attr') }}">
{% endblock %}