From 62178f8ef10977a38f5ed8b951874ce5a6eb9e7a Mon Sep 17 00:00:00 2001 From: Bartosz-Do Date: Thu, 9 Jul 2026 23:17:40 +0200 Subject: [PATCH] Add CRM dashboard preview page (#2650) Co-authored-by: codecalm --- .changeset/crm-dashboard-page.md | 5 + preview/pages/dashboard-crm.html | 81 +++++ shared/data/charts.json | 64 ++++ shared/data/crm-dashboard.json | 283 ++++++++++++++++++ shared/data/menu.json | 8 +- .../includes/cards/charts/mrr-overview.html | 26 ++ .../cards/charts/pipeline-funnel.html | 32 ++ shared/includes/cards/churn-risk.html | 27 ++ shared/includes/cards/crm-stats.html | 66 ++++ shared/includes/cards/recent-activity.html | 28 ++ shared/includes/cards/tasks-due.html | 34 +++ shared/includes/cards/team-leaderboard.html | 28 ++ shared/includes/cards/top-deals.html | 55 ++++ shared/includes/ui/trending.html | 2 +- 14 files changed, 737 insertions(+), 2 deletions(-) create mode 100644 .changeset/crm-dashboard-page.md create mode 100644 preview/pages/dashboard-crm.html create mode 100644 shared/data/crm-dashboard.json create mode 100644 shared/includes/cards/charts/mrr-overview.html create mode 100644 shared/includes/cards/charts/pipeline-funnel.html create mode 100644 shared/includes/cards/churn-risk.html create mode 100644 shared/includes/cards/crm-stats.html create mode 100644 shared/includes/cards/recent-activity.html create mode 100644 shared/includes/cards/tasks-due.html create mode 100644 shared/includes/cards/team-leaderboard.html create mode 100644 shared/includes/cards/top-deals.html diff --git a/.changeset/crm-dashboard-page.md b/.changeset/crm-dashboard-page.md new file mode 100644 index 000000000..a08796dca --- /dev/null +++ b/.changeset/crm-dashboard-page.md @@ -0,0 +1,5 @@ +--- +"@tabler/preview": minor +--- + +Added new `dashboard-crm.html` page with reusable CRM cards. diff --git a/preview/pages/dashboard-crm.html b/preview/pages/dashboard-crm.html new file mode 100644 index 000000000..101faee6e --- /dev/null +++ b/preview/pages/dashboard-crm.html @@ -0,0 +1,81 @@ +--- +title: CRM Dashboard +page-header: CRM Dashboard +page-header-description: Welcome back — here's your CRM overview for today. +page-menu: dashboards.crm +page-libs: [apexcharts] +layout: default +permalink: dashboard-crm.html +--- + +
+
+
+
+ {% include "cards/crm-stats.html" color="primary" icon="currency-dollar" lt=true + title="MRR" description="$92.4K" change-value="+9.5" %} +
+
+ {% include "cards/crm-stats.html" color="azure" icon="filter" lt=true + title="Pipeline" description="$2.4M" change-value="+14" %} +
+
+ {% include "cards/crm-stats.html" color="green" icon="circle-check" lt=true + title="Deals won" description="74" change-value="+8" %} +
+
+ {% include "cards/crm-stats.html" color="purple" icon="percentage" lt=true + title="Conversion" description="5.97%" change-value="+0.4" %} +
+
+ {% include "cards/crm-stats.html" color="yellow" icon="activity" lt=true + title="Activities" description="318" change-value="+22" %} +
+
+ {% include "cards/crm-stats.html" color="red" icon="clock" lt=true + title="Tasks due" description="12" change-value="-3" change-value-unit=" urgent" %} +
+
+ {% include "cards/crm-stats.html" color="cyan" icon="user-plus" lt=true + title="Leads added" description="148" change-value="+31" %} +
+
+ {% include "cards/crm-stats.html" color="green" icon="trending-up" lt=true + title="Churn rate" description="1.8%" change-value="-0.3" %} +
+ +
+
+
+ {% include "cards/charts/mrr-overview.html" %} +
+ +
+ {% include "cards/top-deals.html" %} +
+
+
+ +
+
+
+ {% include "cards/charts/pipeline-funnel.html" %} +
+
+ {% include "cards/recent-activity.html" %} +
+
+
+ +
+ {% include "cards/tasks-due.html" %} +
+
+ {% include "cards/team-leaderboard.html" %} +
+
+ {% include "cards/churn-risk.html" %} +
+
+
+
\ No newline at end of file diff --git a/shared/data/charts.json b/shared/data/charts.json index 16f817cfd..da46c49ae 100644 --- a/shared/data/charts.json +++ b/shared/data/charts.json @@ -1877,6 +1877,70 @@ } ] }, + "crm-mrr-overview": { + "type": "line", + "stroke-width": [ + 3, + 2 + ], + "stroke-dash": [ + 0, + 6 + ], + "series": [ + { + "name": "This year", + "color": "primary", + "data": [ + 62, + 65, + 64, + 71, + 75, + 73, + 79, + 84, + 82, + 90, + 94, + 101 + ] + }, + { + "name": "Last year", + "color": "secondary", + "data": [ + 56, + 58, + 57, + 63, + 66, + 65, + 68, + 72, + 73, + 77, + 79, + 83 + ] + } + ], + "categories": [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + ], + "y-max": 110 + }, "new-clients": { "type": "line", "datetime": true, diff --git a/shared/data/crm-dashboard.json b/shared/data/crm-dashboard.json new file mode 100644 index 000000000..a2d6ce3d8 --- /dev/null +++ b/shared/data/crm-dashboard.json @@ -0,0 +1,283 @@ +{ + "tasks_due": { + "title": "Tasks due", + "badge": 3, + "button_text": "Add task", + "items": [ + { + "text": "Send Q2 proposal to Skyline Retail", + "due": "Today", + "color": "red" + }, + { + "text": "Follow up with CloudBase - 2nd touch", + "due": "Today", + "color": "red" + }, + { + "text": "Schedule demo for NovaBuild Co", + "due": "Tomorrow", + "color": "yellow" + }, + { + "text": "Update pipeline notes - Orion Logistics", + "due": "Tomorrow", + "color": "secondary" + }, + { + "text": "Prepare renewal deck for MetroPay", + "due": "May 4", + "color": "yellow" + }, + { + "text": "Review churn signals - 3 at-risk accounts", + "due": "May 5", + "color": "red" + } + ] + }, + "leaderboard": { + "items": [ + { + "name": "Olivia Bennett", + "initials": "OB", + "avatar_color": "primary", + "progress": 92, + "amount": "$148K", + "deals": 18, + "score": 92 + }, + { + "name": "Marcus Lee", + "initials": "ML", + "avatar_color": "purple", + "progress": 78, + "amount": "$124K", + "deals": 15, + "score": 78 + }, + { + "name": "Sara Mitchell", + "initials": "SM", + "avatar_color": "green", + "progress": 65, + "amount": "$98K", + "deals": 12, + "score": 65 + }, + { + "name": "James Okonkwo", + "initials": "JO", + "avatar_color": "yellow", + "progress": 54, + "amount": "$82K", + "deals": 10, + "score": 54 + }, + { + "name": "Lena Muller", + "initials": "LM", + "avatar_color": "red", + "progress": 40, + "amount": "$61K", + "deals": 8, + "score": 40 + } + ] + }, + "churn_risk": { + "items": [ + { + "company": "Orion Logistics", + "last_contact": "18 days ago", + "level": "High", + "level_color": "red", + "amount": "$24K" + }, + { + "company": "Summit Media", + "last_contact": "22 days ago", + "level": "High", + "level_color": "red", + "amount": "$18K" + }, + { + "company": "BluePeak Tech", + "last_contact": "12 days ago", + "level": "Medium", + "level_color": "yellow", + "amount": "$31K" + }, + { + "company": "Greenridge Partners", + "last_contact": "8 days ago", + "level": "Low", + "level_color": "green", + "amount": "$12K" + }, + { + "company": "MetroPay Ltd", + "last_contact": "5 days ago", + "level": "Medium", + "level_color": "yellow", + "amount": "$24K" + } + ] + }, + "recent_activity": { + "title": "Recent activity", + "view_all_text": "View all", + "items": [ + { + "text": "Olivia Bennett moved Skyline Retail to Negotiation", + "time": "4 min ago", + "icon": "git-merge", + "icon_color": "primary" + }, + { + "text": "Marcus Lee added note to CloudBase opportunity", + "time": "22 min ago", + "icon": "notes", + "icon_color": "purple" + }, + { + "text": "Sara Mitchell completed task: Schedule NovaBuild demo", + "time": "1 hour ago", + "icon": "check", + "icon_color": "green" + }, + { + "text": "Churn alert triggered for Orion Logistics account", + "time": "2 hours ago", + "icon": "alert-triangle", + "icon_color": "red" + }, + { + "text": "James Okonkwo created proposal for MetroPay renewal", + "time": "Yesterday", + "icon": "file-text", + "icon_color": "yellow" + } + ] + }, + "top_deals": { + "columns": [ + "Company", + "Stage", + "Value", + "Probability", + "Owner" + ], + "items": [ + { + "company": "Skyline Retail", + "contact": "Hannah Cruz", + "stage": "Negotiation", + "stage_color": "yellow", + "value": "$48,000", + "probability": 80, + "probability_color": "green", + "owner_initials": "OB", + "owner_color": "primary" + }, + { + "company": "CloudBase Inc", + "contact": "David Park", + "stage": "Proposal", + "stage_color": "purple", + "value": "$32,500", + "probability": 60, + "probability_color": "yellow", + "owner_initials": "ML", + "owner_color": "purple" + }, + { + "company": "NovaBuild Co", + "contact": "Priya Sharma", + "stage": "Qualified", + "stage_color": "azure", + "value": "$27,000", + "probability": 45, + "probability_color": "primary", + "owner_initials": "SR", + "owner_color": "green" + }, + { + "company": "MetroPay Ltd", + "contact": "Tom Ellis", + "stage": "Proposal", + "stage_color": "purple", + "value": "$21,800", + "probability": 55, + "probability_color": "yellow", + "owner_initials": "JO", + "owner_color": "yellow" + }, + { + "company": "Greenridge Partners", + "contact": "Amy Tan", + "stage": "Negotiation", + "stage_color": "yellow", + "value": "$18,400", + "probability": 70, + "probability_color": "green", + "owner_initials": "OB", + "owner_color": "primary" + }, + { + "company": "Orion Logistics", + "contact": "Ben Okafor", + "stage": "Qualified", + "stage_color": "azure", + "value": "$14,200", + "probability": 35, + "probability_color": "primary", + "owner_initials": "LM", + "owner_color": "red" + } + ] + }, + "pipeline_funnel": { + "title": "Pipeline funnel", + "period": "This quarter", + "conversion_label": "Conversion rate", + "conversion_value": "5.97%", + "items": [ + { + "label": "Leads", + "count": 1240, + "amount": "$2.4M", + "progress": 100, + "color": "primary" + }, + { + "label": "Qualified", + "count": 680, + "amount": "$1.6M", + "progress": 75, + "color": "azure" + }, + { + "label": "Proposal", + "count": 310, + "amount": "$940K", + "progress": 52, + "color": "purple" + }, + { + "label": "Negotiation", + "count": 148, + "amount": "$580K", + "progress": 34, + "color": "yellow" + }, + { + "label": "Closed won", + "count": 74, + "amount": "$312K", + "progress": 18, + "color": "green" + } + ] + } +} diff --git a/shared/data/menu.json b/shared/data/menu.json index da882acaa..23c4fc593 100644 --- a/shared/data/menu.json +++ b/shared/data/menu.json @@ -9,7 +9,13 @@ }, "crypto": { "url": "dashboard-crypto.html", - "title": "Crypto" + "title": "Crypto", + "badge": "New" + }, + "crm": { + "url": "dashboard-crm.html", + "title": "CRM", + "badge": "New" } } }, diff --git a/shared/includes/cards/charts/mrr-overview.html b/shared/includes/cards/charts/mrr-overview.html new file mode 100644 index 000000000..4fb2ddcef --- /dev/null +++ b/shared/includes/cards/charts/mrr-overview.html @@ -0,0 +1,26 @@ +
+
+
+
+
Monthly recurring revenue
+
+
$92,400
+
+9.5%
+
+
+ +
+
+ + This year +
+
+ + Last year +
+
+
+ + {% include "ui/chart.html" chart-id="crm-mrr-overview" height=15 %} +
+
diff --git a/shared/includes/cards/charts/pipeline-funnel.html b/shared/includes/cards/charts/pipeline-funnel.html new file mode 100644 index 000000000..ec212a666 --- /dev/null +++ b/shared/includes/cards/charts/pipeline-funnel.html @@ -0,0 +1,32 @@ +
+ {% assign funnel = crm-dashboard.pipeline_funnel %} +
+
+
+
{{ funnel.title }}
+
{{ funnel.period }}
+
+
+
+ {% for item in funnel.items %} +
+
{{ item.label }}
+
+
+ {% include "ui/progress.html" value=item.progress color=item.color class="h-4" %} +
+ {{ + item.count }}
+
+
+
{{ item.amount }}
+
+ {% endfor %} +
+ +
+
{{ funnel.conversion_label }}
+
{{ funnel.conversion_value }}
+
+
+
\ No newline at end of file diff --git a/shared/includes/cards/churn-risk.html b/shared/includes/cards/churn-risk.html new file mode 100644 index 000000000..8160eef62 --- /dev/null +++ b/shared/includes/cards/churn-risk.html @@ -0,0 +1,27 @@ +
+ {% assign churn = crm-dashboard.churn_risk %} +
+
+ {% include "ui/icon.html" icon="alert-triangle" class="text-red" %} +

Churn risk

+
+
+ {% include "ui/badge.html" text="3 accounts" color="red" %} +
+
+ +
+ {% for item in churn.items %} +
+
+
+
{{ item.company }}
+
Last contact: {{ item.last_contact }}
+
+
{{ item.level }}
+
{{ item.amount }}
+
+
+ {% endfor %} +
+
\ No newline at end of file diff --git a/shared/includes/cards/crm-stats.html b/shared/includes/cards/crm-stats.html new file mode 100644 index 000000000..07e1f3b63 --- /dev/null +++ b/shared/includes/cards/crm-stats.html @@ -0,0 +1,66 @@ +{% assign chart-type = include.chart-type | default: 'line' %} +{% assign chart-position = include.chart-position | default: 'right' %} +{% assign chart-color = include.color | default: 'primary' %} + +
+
+
+ {% if include.icon %} +
+ {% + include "ui/icon.html" icon=include.icon %} +
+ {% elsif include.person-id %} +
+ {% include "ui/avatar.html" person-id=include.person-id %} +
+ {% elsif include.chart-data and chart-position == "left" %} +
+ {% include "ui/chart-sparkline.html" id=include.id data=include.chart-data type=chart-type + color=include.color label=include.chart-label label-icon=include.chart-label-icon %} +
+ {% endif %} + + +
+
+ {{ include.title | default: 1700 }} + {% if include.small-icon %} + {% include "ui/icon.html" icon=include.small-icon color=include.color class="icon-sm ms-1" %} + {% endif %} + {% if include.description-value %} + {{ + include.description-value }} + {% endif %} +
+
+ {{ include.description | default: "Users" }} +
+
+ +
+ {% include "ui/trending.html" value=include.change-value unit=include.change-value-unit %} +
+ + {% if include.chart-data and chart-position=="right" %} +
+ {% include "ui/chart-sparkline.html" id=include.id data=include.chart-data type=chart-type color=chart-color + label=include.chart-label label-icon=include.chart-label-icon %} +
+ {% endif %} + + {% if include.trending %} +
+ {% include "ui/trending.html" value=include.trending %} +
+ {% endif %} + + {% if include.button %} +
+ {% include "ui/button.html" text=include.button size="sm" %} +
+ {% endif %} +
+
+
\ No newline at end of file diff --git a/shared/includes/cards/recent-activity.html b/shared/includes/cards/recent-activity.html new file mode 100644 index 000000000..09e378cb9 --- /dev/null +++ b/shared/includes/cards/recent-activity.html @@ -0,0 +1,28 @@ +
+ {% assign activity = crm-dashboard.recent_activity %} +
+

{{ activity.title }}

+ +
+
+
+ {% for item in activity.items %} +
+
+
+ + {% include "ui/icon.html" icon=item.icon class="icon text-{{ item.icon_color }}" %} + +
+
+
{{ item.text }}
+
{{ item.time }}
+
+
+
+ {% endfor %} +
+
+
diff --git a/shared/includes/cards/tasks-due.html b/shared/includes/cards/tasks-due.html new file mode 100644 index 000000000..7b221c32c --- /dev/null +++ b/shared/includes/cards/tasks-due.html @@ -0,0 +1,34 @@ +
+ {% assign tasks = crm-dashboard.tasks_due %} +
+
+

{{ tasks.title }}

+ {{ tasks.badge }} +
+
+ +
+
+ +
+ {% for item in tasks.items %} + + {% endfor %} +
+
\ No newline at end of file diff --git a/shared/includes/cards/team-leaderboard.html b/shared/includes/cards/team-leaderboard.html new file mode 100644 index 000000000..eb9dbeedb --- /dev/null +++ b/shared/includes/cards/team-leaderboard.html @@ -0,0 +1,28 @@ +
+ {% assign leaderboard = crm-dashboard.leaderboard %} +
+
+

Team leaderboard

+
Q2 - May 1, 2026
+
+
+ +
+ {% for item in leaderboard.items %} +
+
+
{{ forloop.index }}
+
{% include "ui/avatar.html" person-id=forloop.index color=item.avatar_color size="sm" %}
+
+
{{ item.name }}
+ {% include "ui/progress.html" size="sm" value=item.progress color=item.avatar_color class="mt-2" %} +
+
+
{{ item.amount }}
+
{{ item.deals }} deals - {{ item.score }}%
+
+
+
+ {% endfor %} +
+
\ No newline at end of file diff --git a/shared/includes/cards/top-deals.html b/shared/includes/cards/top-deals.html new file mode 100644 index 000000000..e61e04b0a --- /dev/null +++ b/shared/includes/cards/top-deals.html @@ -0,0 +1,55 @@ +
+ {% assign deals = crm-dashboard.top_deals %} +
+

Top deals

+
+ + +
+
+ +
+ + + + {% for column in deals.columns %} + + {% endfor %} + + + + + {% for item in deals.items %} + + + + + + + + + {% endfor %} + +
{{ column }}
+
{{ item.company }}
+
{{ item.contact }}
+
{{ item.stage }}{{ item.value }} +
+
+ {% include "ui/progress.html" size="sm" value=item.probability color=item.probability_color %} +
+ {{ item.probability }}% +
+
{% include "ui/avatar.html" placeholder=item.owner_initials color=item.owner_color size="sm" %} + +
+
+
diff --git a/shared/includes/ui/trending.html b/shared/includes/ui/trending.html index 0ec4233f9..4db5ae603 100644 --- a/shared/includes/ui/trending.html +++ b/shared/includes/ui/trending.html @@ -11,5 +11,5 @@ {% endif %} - {{ value }}% {% include "ui/icon.html" icon=trending-icon class="ms-0" size="sm" %} + {{ value }}{{ include.unit | default: "%" }} {% include "ui/icon.html" icon=trending-icon class="ms-0" size="sm" %}