mirror of
https://github.com/tabler/tabler.git
synced 2026-06-17 04:40:04 +04:00
Add CRM dashboard with JSON-based cards and charts
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: CRM Dashboard
|
||||
page-header: CRM Dashboard
|
||||
page-menu: dashboards.crm
|
||||
page-libs: [apexcharts]
|
||||
layout: default
|
||||
permalink: dashboard-crm.html
|
||||
---
|
||||
|
||||
<div>
|
||||
<p>Welcome back — here's your CRM overview for today.</p>
|
||||
<div class="col-12">
|
||||
<div class="row row-cards">
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="primary" icon="currency-dollar" lt=true
|
||||
title="MRR" description="$92.4K" change-value="+9.5%" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="azure" icon="filter" lt=true
|
||||
title="Pipeline" description="$2.4M" change-value="+14%" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="green" icon="circle-check" lt=true
|
||||
title="Deals won" description="74" change-value="+8" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="purple" icon="percentage" lt=true
|
||||
title="Conversion" description="5.97%" change-value="+0.4%" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="yellow" icon="activity" lt=true
|
||||
title="Activities" description="318" change-value="+22" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="red" icon="clock" lt=true
|
||||
title="Tasks due" description="12" change-value="3 urgent" change-value-color="red" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="cyan" icon="user-plus" lt=true
|
||||
title="Leads added" description="148" change-value="+31" %}
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
{% include "cards/crm-stats.html" color="green" icon="trending-up" lt=true
|
||||
title="Churn rate" description="1.8%" change-value="-0.3%" %}
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<div class="row row-cards">
|
||||
<div class="col-12">
|
||||
{% include "cards/charts/mrr-overview.html" %}
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
{% include "cards/top-deals.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
<div class="row row-cards">
|
||||
<div class="col-12">
|
||||
{% include "cards/charts/pipeline-funnel.html" %}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
{% include "cards/recent-activity.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
{% include "cards/tasks-due.html" %}
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{% include "cards/team-leaderboard.html" %}
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{% include "cards/churn-risk.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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,
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
{
|
||||
"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": {
|
||||
"title": "Team leaderboard",
|
||||
"period": "Q2 - May 1, 2026",
|
||||
"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": {
|
||||
"title": "Churn risk",
|
||||
"badge": "3 accounts",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": {
|
||||
"title": "Top deals",
|
||||
"filter_text": "Filter",
|
||||
"add_deal_text": "Add deal",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,10 @@
|
||||
"crypto": {
|
||||
"url": "dashboard-crypto.html",
|
||||
"title": "Crypto"
|
||||
},
|
||||
"crm": {
|
||||
"url": "dashboard-crm.html",
|
||||
"title": "CRM"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between gap-3 mb-2">
|
||||
<div>
|
||||
<div class="fw-medium">Monthly recurring revenue</div>
|
||||
<div class="d-flex align-items-baseline gap-2 mt-1">
|
||||
<div class="h1 mb-0">$92,400</div>
|
||||
<div class="text-green small fw-medium">+9.5%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="legend bg-primary"></span>
|
||||
<span class="small text-secondary">This year</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="legend bg-secondary"></span>
|
||||
<span class="small text-secondary">Last year</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "ui/chart.html" chart-id="crm-mrr-overview" height=10 %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
<div class="card h-100">
|
||||
{% assign funnel = crm-dashboard.pipeline_funnel %}
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between mb-4">
|
||||
<div class="fw-medium">{{ funnel.title }}</div>
|
||||
<div class="small text-secondary">{{ funnel.period }}</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column gap-2">
|
||||
{% for item in funnel.items %}
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col-3 small text-secondary">{{ item.label }}</div>
|
||||
<div class="col">
|
||||
<div class="position-relative">
|
||||
{% include "ui/progress.html" value=item.progress color=item.color class="h-4" %}
|
||||
<div class="position-absolute top-50 start-0 translate-middle-y px-2 small fw-semibold text-white">
|
||||
{{
|
||||
item.count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto small fw-medium text-body text-nowrap">{{ item.amount }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between border-top mt-4 pt-3">
|
||||
<div class="small text-secondary">{{ funnel.conversion_label }}</div>
|
||||
<div class="small fw-semibold text-green">{{ funnel.conversion_value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
<div class="card h-100">
|
||||
{% assign churn = crm-dashboard.churn_risk %}
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
{% include "ui/icon.html" icon="alert-triangle" class="text-red" %}
|
||||
<h3 class="card-title mb-0">{{ churn.title }}</h3>
|
||||
<span class="badge bg-red-lt">{{ churn.badge }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-group list-group-flush">
|
||||
{% for item in churn.items %}
|
||||
<div class="list-group-item">
|
||||
<div class="row align-items-center g-2">
|
||||
<div class="col">
|
||||
<div class="fw-medium">{{ item.company }}</div>
|
||||
<div class="small text-secondary">Last contact: {{ item.last_contact }}</div>
|
||||
</div>
|
||||
<div class="col-auto"><span class="badge bg-{{ item.level_color }}-lt">{{ item.level }}</span></div>
|
||||
<div class="col-auto fw-semibold">{{ item.amount }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,65 @@
|
||||
{% assign chart-type = include.chart-type | default: 'line' %}
|
||||
{% assign chart-position = include.chart-position | default: 'right' %}
|
||||
{% assign chart-color = include.color | default: 'primary' %}
|
||||
|
||||
<div class="card card-sm{% if include.class %} {{ include.class }}{% endif %}">
|
||||
<div class="card-body px-3 py-2">
|
||||
<div class="row align-items-center">
|
||||
{% if include.icon %}
|
||||
<div class="col-auto">
|
||||
<span
|
||||
class="{% if include.color %}bg-{{ include.color }}{% if include.lt %}-lt{% else %} text-white{% endif %}{% endif %} avatar avatar-square">{%
|
||||
include "ui/icon.html" icon=include.icon %}</span>
|
||||
</div>
|
||||
{% elsif include.person-id %}
|
||||
<div class="col-auto">
|
||||
{% include "ui/avatar.html" person-id=include.person-id %}
|
||||
</div>
|
||||
{% elsif include.chart-data and chart-position == "left" %}
|
||||
<div class="col-auto">
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="col">
|
||||
<div class="text-secondary small">
|
||||
{{ 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 %}
|
||||
<span class="float-end fw-medium text-{{ include.description-value-color | default: 'green' }}">{{
|
||||
include.description-value }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="h3 m-0 p-0">
|
||||
{{ include.description | default: "Users" }}
|
||||
</div>
|
||||
<div class="text-secondary small text-{{ include.change-value-color | default: 'green' }}">
|
||||
{{ include.change-value | default: "" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if include.chart-data and chart-position=="right" %}
|
||||
<div class="col-auto">
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if include.trending %}
|
||||
<div class="col-auto">
|
||||
{% include "ui/trending.html" value=include.trending %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if include.button %}
|
||||
<div class="col-auto">
|
||||
{% include "ui/button.html" text=include.button size="sm" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="card" style="height: 28rem">
|
||||
{% assign activity = crm-dashboard.recent_activity %}
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">{{ activity.title }}</h3>
|
||||
<div class="card-actions">
|
||||
<a href="#" class="small fw-medium text-primary">{{ activity.view_all_text }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body card-body-scrollable card-body-scrollable-shadow">
|
||||
<div class="divide-y">
|
||||
{% for item in activity.items %}
|
||||
<div class="py-3">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto">
|
||||
<span class="avatar avatar-sm bg-{{ item.icon_color }}-lt">
|
||||
{% include "ui/icon.html" icon=item.icon class="icon text-{{ item.icon_color }}" %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="fw-medium">{{ item.text }}</div>
|
||||
<div class="small text-secondary">{{ item.time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,34 @@
|
||||
<div class="card h-100">
|
||||
{% assign tasks = crm-dashboard.tasks_due %}
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h3 class="card-title mb-0">{{ tasks.title }}</h3>
|
||||
<span class="badge bg-red text-white">{{ tasks.badge }}</span>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<button type="button" class="btn btn-primary btn-sm">
|
||||
{% include "ui/icon.html" icon="plus" class="me-1" %}
|
||||
{{ tasks.button_text }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-group list-group-flush list-group-hoverable">
|
||||
{% for item in tasks.items %}
|
||||
<label class="list-group-item">
|
||||
<div class="row align-items-center g-2">
|
||||
<div class="col-auto">
|
||||
<input type="checkbox" class="form-check-input m-0">
|
||||
</div>
|
||||
<div class="col">
|
||||
<div>{{ item.text }}</div>
|
||||
</div>
|
||||
<div class="col-auto d-flex align-items-center gap-2">
|
||||
<span class="legend bg-{{ item.color }}"></span>
|
||||
<span class="small text-secondary">{{ item.due }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="card h-100">
|
||||
{% assign leaderboard = crm-dashboard.leaderboard %}
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<h3 class="card-title mb-0">{{ leaderboard.title }}</h3>
|
||||
<div class="small text-secondary mt-1">{{ leaderboard.period }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-group list-group-flush">
|
||||
{% for item in leaderboard.items %}
|
||||
<div class="list-group-item">
|
||||
<div class="row align-items-center g-2">
|
||||
<div class="col-auto fw-bold {% if forloop.first %}text-yellow{% else %}text-secondary{% endif %} w-1 px-3">{{ forloop.index }}</div>
|
||||
<div class="col-auto">{% include "ui/avatar.html" placeholder=item.initials color=item.avatar_color size="sm" %}</div>
|
||||
<div class="col">
|
||||
<div class="fw-medium">{{ item.name }}</div>
|
||||
{% include "ui/progress.html" size="sm" value=item.progress color=item.avatar_color class="mt-2" %}
|
||||
</div>
|
||||
<div class="col-auto text-end">
|
||||
<div class="fw-semibold">{{ item.amount }}</div>
|
||||
<div class="small text-secondary">{{ item.deals }} deals - {{ item.score }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,55 @@
|
||||
<div class="card">
|
||||
{% assign deals = crm-dashboard.top_deals %}
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">{{ deals.title }}</h3>
|
||||
<div class="card-actions d-flex gap-2">
|
||||
<button type="button" class="btn btn-sm">
|
||||
{% include "ui/icon.html" icon="filter" class="me-1" %}
|
||||
{{ deals.filter_text }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-sm">
|
||||
{% include "ui/icon.html" icon="plus" class="me-1" %}
|
||||
{{ deals.add_deal_text }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter card-table text-nowrap">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for column in deals.columns %}
|
||||
<th>{{ column }}</th>
|
||||
{% endfor %}
|
||||
<th class="w-1"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in deals.items %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-medium">{{ item.company }}</div>
|
||||
<div class="small text-secondary">{{ item.contact }}</div>
|
||||
</td>
|
||||
<td><span class="badge bg-{{ item.stage_color }}-lt text-{{ item.stage_color }}">{{ item.stage }}</span></td>
|
||||
<td class="fw-semibold">{{ item.value }}</td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<div class="w-100">
|
||||
{% include "ui/progress.html" size="sm" value=item.probability color=item.probability_color %}
|
||||
</div>
|
||||
<span class="small text-secondary">{{ item.probability }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>{% include "ui/avatar.html" placeholder=item.owner_initials color=item.owner_color size="sm" %}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-icon btn-sm">
|
||||
{% include "ui/icon.html" icon="dots" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user