πŸ“Š Dashboard Widgets Reference #

Complete reference for all dashboard widgets and chart components available in Admindek.

Overview #

Admindek includes 70+ interactive widgets for building comprehensive dashboards:

  • Metric Cards: Revenue, users, orders, conversion rates
  • Chart Widgets: Line, area, bar, donut, and specialized charts
  • Progress Indicators: Linear and circular progress components
  • Statistical Displays: Comparison charts and trend indicators
  • Interactive Elements: Clickable charts with tooltips and legends

Metric Cards #

Basic Metric Card #

Usage:

<div class="col-md-6 col-xl-3">
  <div class="card">
    <div class="card-body">
      <div class="d-flex align-items-center">
        <div class="flex-grow-1">
          <h6 class="mb-2">Total Revenue</h6>
          <h3 class="mb-0 f-w-300">$125,000</h3>
          <p class="text-muted mb-0">
            <span class="text-success f-12 me-1">
              <i class="ph-duotone ph-trend-up me-1"></i>12.5%
            </span>
            from last month
          </p>
        </div>
        <div class="flex-shrink-0">
          <div class="avtar avtar-s bg-primary">
            <i class="ph-duotone ph-currency-dollar f-18"></i>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Customization Options:

PropertyTypeDefaultDescription
bg-{color}stringbg-primaryBackground color variant
avtar-{size}stringavtar-sIcon container size (s, m, l, xl)
text-{color}stringtext-mutedText color for secondary information
f-w-{weight}stringf-w-300Font weight (300, 400, 500, 600, 700)

Enhanced Metric Card with Chart #

Usage:

<div class="col-md-6 col-xl-3">
  <div class="card bg-primary">
    <div class="card-body">
      <div class="d-flex align-items-center">
        <div class="flex-grow-1">
          <h6 class="mb-2 text-white">Active Users</h6>
          <h3 class="text-white mb-0 f-w-300">8,549</h3>
          <div id="user-trend-chart"></div>
        </div>
        <div class="flex-shrink-0">
          <div class="avtar avtar-s bg-light-primary">
            <i class="ph-duotone ph-users f-18"></i>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

JavaScript Integration:

// Initialize trend chart
var userTrendOptions = {
  chart: {
    height: 40,
    type: 'line',
    sparkline: { enabled: true }
  },
  series: [{
    name: 'Users',
    data: [25, 45, 35, 65, 45, 75, 65]
  }],
  stroke: {
    width: 2,
    curve: 'smooth'
  },
  colors: ['#ffffff'],
  tooltip: {
    theme: 'dark'
  }
};
 
var userTrendChart = new ApexCharts(
  document.querySelector('#user-trend-chart'), 
  userTrendOptions
);
userTrendChart.render();

Chart Widgets #

Line Chart Widget #

HTML Structure:

<div class="col-lg-8">
  <div class="card">
    <div class="card-header">
      <div class="d-flex align-items-center justify-content-between">
        <h5 class="mb-0">Sales Overview</h5>
        <div class="dropdown">
          <a class="avtar avtar-s btn-link-secondary dropdown-toggle arrow-none" 
             href="#" data-bs-toggle="dropdown">
            <i class="ph-duotone ph-dots-three f-18"></i>
          </a>
          <div class="dropdown-menu dropdown-menu-end">
            <a class="dropdown-item" href="#">Today</a>
            <a class="dropdown-item" href="#">Weekly</a>
            <a class="dropdown-item" href="#">Monthly</a>
          </div>
        </div>
      </div>
    </div>
    <div class="card-body">
      <div id="sales-overview-chart"></div>
    </div>
  </div>
</div>

JavaScript Configuration:

var salesOptions = {
  chart: {
    height: 350,
    type: 'area',
    toolbar: { show: false },
    zoom: { enabled: false }
  },
  dataLabels: { enabled: false },
  stroke: {
    curve: 'smooth',
    width: 3
  },
  series: [
    {
      name: 'Sales',
      data: [31, 40, 28, 51, 42, 109, 100, 120, 85, 95]
    },
    {
      name: 'Revenue', 
      data: [11, 32, 45, 32, 34, 52, 41, 65, 55, 75]
    }
  ],
  xaxis: {
    categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct']
  },
  colors: ['#4f46e5', '#10b981'],
  fill: {
    type: 'gradient',
    gradient: {
      shadeIntensity: 1,
      opacityFrom: 0.7,
      opacityTo: 0.3,
      stops: [0, 90, 100]
    }
  },
  tooltip: {
    shared: true,
    intersect: false
  },
  legend: {
    position: 'top',
    horizontalAlign: 'right'
  }
};
 
var salesChart = new ApexCharts(
  document.querySelector('#sales-overview-chart'), 
  salesOptions
);
salesChart.render();

Donut Chart Widget #

HTML Structure:

<div class="col-lg-4">
  <div class="card">
    <div class="card-header">
      <h5 class="mb-0">Traffic Sources</h5>
    </div>
    <div class="card-body">
      <div id="traffic-sources-chart"></div>
      <div class="row text-center mt-3">
        <div class="col-4">
          <h6 class="mb-0">62%</h6>
          <p class="text-muted mb-0 f-12">Direct</p>
        </div>
        <div class="col-4">
          <h6 class="mb-0">28%</h6>
          <p class="text-muted mb-0 f-12">Social</p>
        </div>
        <div class="col-4">
          <h6 class="mb-0">10%</h6>
          <p class="text-muted mb-0 f-12">Email</p>
        </div>
      </div>
    </div>
  </div>
</div>

JavaScript Configuration:

var trafficOptions = {
  chart: {
    height: 300,
    type: 'donut'
  },
  series: [62, 28, 10],
  labels: ['Direct', 'Social Media', 'Email'],
  colors: ['#4f46e5', '#10b981', '#f59e0b'],
  plotOptions: {
    pie: {
      donut: {
        size: '70%',
        labels: {
          show: true,
          total: {
            show: true,
            label: 'Total Visits',
            formatter: function (w) {
              return '12.4K'
            }
          }
        }
      }
    }
  },
  legend: {
    show: false
  },
  tooltip: {
    y: {
      formatter: function (val) {
        return val + '%'
      }
    }
  }
};
 
var trafficChart = new ApexCharts(
  document.querySelector('#traffic-sources-chart'), 
  trafficOptions
);
trafficChart.render();

Progress Widgets #

Circular Progress #

HTML Structure:

<div class="col-md-6 col-xl-4">
  <div class="card">
    <div class="card-body text-center">
      <div id="goal-progress" class="d-inline-block"></div>
      <h6 class="mt-3 mb-0">Goal Completion</h6>
      <p class="text-muted mb-0">Monthly target progress</p>
    </div>
  </div>
</div>

JavaScript Configuration:

var goalProgressOptions = {
  chart: {
    height: 150,
    type: 'radialBar'
  },
  series: [75],
  plotOptions: {
    radialBar: {
      hollow: {
        size: '60%'
      },
      dataLabels: {
        show: true,
        name: {
          show: false
        },
        value: {
          fontSize: '20px',
          fontWeight: 600,
          formatter: function (val) {
            return val + '%'
          }
        }
      },
      track: {
        background: '#f1f5f9'
      }
    }
  },
  colors: ['#4f46e5'],
  stroke: {
    lineCap: 'round'
  }
};
 
var goalProgress = new ApexCharts(
  document.querySelector('#goal-progress'), 
  goalProgressOptions
);
goalProgress.render();

Linear Progress Bars #

HTML Structure:

<div class="col-md-6 col-xl-8">
  <div class="card">
    <div class="card-header">
      <h5 class="mb-0">Project Progress</h5>
    </div>
    <div class="card-body">
      <div class="row">
        <div class="col-6">
          <div class="d-flex align-items-center mb-3">
            <div class="flex-grow-1">
              <h6 class="mb-1">Website Redesign</h6>
              <div class="progress" style="height: 6px;">
                <div class="progress-bar bg-primary" style="width: 85%"></div>
              </div>
            </div>
            <div class="flex-shrink-0 ms-3">
              <span class="f-12 text-muted">85%</span>
            </div>
          </div>
          
          <div class="d-flex align-items-center mb-3">
            <div class="flex-grow-1">
              <h6 class="mb-1">Mobile App</h6>
              <div class="progress" style="height: 6px;">
                <div class="progress-bar bg-success" style="width: 65%"></div>
              </div>
            </div>
            <div class="flex-shrink-0 ms-3">
              <span class="f-12 text-muted">65%</span>
            </div>
          </div>
          
          <div class="d-flex align-items-center">
            <div class="flex-grow-1">
              <h6 class="mb-1">Database Migration</h6>
              <div class="progress" style="height: 6px;">
                <div class="progress-bar bg-warning" style="width: 45%"></div>
              </div>
            </div>
            <div class="flex-shrink-0 ms-3">
              <span class="f-12 text-muted">45%</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Statistical Widgets #

Comparison Widget #

HTML Structure:

<div class="col-md-12 col-xl-6">
  <div class="card">
    <div class="card-header">
      <h5 class="mb-0">Sales Comparison</h5>
    </div>
    <div class="card-body">
      <div class="row align-items-center">
        <div class="col-6">
          <h3 class="mb-0">$24,780</h3>
          <p class="text-muted mb-2">This Month</p>
          <div class="d-flex align-items-center">
            <i class="ph-duotone ph-trend-up f-18 text-success me-1"></i>
            <span class="text-success f-12">+12.5%</span>
          </div>
        </div>
        <div class="col-6">
          <div id="sales-comparison-chart"></div>
        </div>
      </div>
    </div>
  </div>
</div>

JavaScript Configuration:

var comparisonOptions = {
  chart: {
    height: 80,
    type: 'bar',
    sparkline: { enabled: true }
  },
  series: [{
    data: [25, 45, 32, 67, 49, 72, 52, 55, 46, 54]
  }],
  plotOptions: {
    bar: {
      columnWidth: '50%',
      distributed: true,
      borderRadius: 2
    }
  },
  colors: ['#e3f2fd', '#bbdefb', '#90caf9', '#64b5f6', '#42a5f5', 
           '#2196f3', '#1e88e5', '#1976d2', '#1565c0', '#0d47a1'],
  tooltip: {
    enabled: false
  }
};
 
var comparisonChart = new ApexCharts(
  document.querySelector('#sales-comparison-chart'), 
  comparisonOptions
);
comparisonChart.render();

Widget Categories #

Analytics Widgets #

  • Revenue tracking: Multiple currency support
  • User analytics: Active users, new registrations
  • Conversion metrics: Funnel analysis, goal completion
  • Traffic analysis: Sources, geographic distribution

E-commerce Widgets #

  • Sales performance: Revenue, orders, average order value
  • Product metrics: Top products, category performance
  • Inventory tracking: Stock levels, reorder alerts
  • Customer insights: Lifetime value, retention rates

Project Management Widgets #

  • Task progress: Completion rates, milestone tracking
  • Team performance: Individual and group metrics
  • Timeline widgets: Gantt-style progress indicators
  • Resource utilization: Workload distribution

Financial Widgets #

  • Profit & loss: Income vs expenses tracking
  • Cash flow: Inflow and outflow visualization
  • Budget tracking: Planned vs actual spending
  • Investment performance: Portfolio tracking

Responsive Behavior #

All widgets automatically adapt to screen size:

// Widget responsive behavior
.card {
  // Mobile: Full width
  @media (max-width: 767.98px) {
    .row > [class*="col-"] {
      margin-bottom: 1rem;
    }
  }
  
  // Tablet: 2 columns
  @media (min-width: 768px) and (max-width: 991.98px) {
    .col-xl-3 {
      flex: 0 0 50%;
      max-width: 50%;
    }
  }
  
  // Desktop: Original layout
  @media (min-width: 992px) {
    // Default grid behavior
  }
}

Widget Data Binding #

Static Data #

<h3 class="mb-0">$125,000</h3>

Dynamic Data (JavaScript) #

// Update widget values
function updateWidget(elementId, value, change) {
  const element = document.querySelector(elementId);
  if (element) {
    element.textContent = value;
    
    // Update trend indicator
    const trendElement = element.parentNode.querySelector('.trend');
    if (trendElement) {
      trendElement.textContent = change;
      trendElement.className = change > 0 ? 'text-success' : 'text-danger';
    }
  }
}
 
// Usage
updateWidget('#revenue-value', '$142,350', '+12.5%');

API Integration #

// Fetch and update widget data
async function updateDashboardWidgets() {
  try {
    const response = await fetch('/api/dashboard-stats');
    const data = await response.json();
    
    // Update metric cards
    updateWidget('#revenue-value', data.revenue, data.revenueChange);
    updateWidget('#users-value', data.activeUsers, data.usersChange);
    
    // Update charts
    salesChart.updateSeries([{
      name: 'Sales',
      data: data.salesData
    }]);
    
  } catch (error) {
    console.error('Failed to update dashboard:', error);
  }
}
 
// Refresh every 5 minutes
setInterval(updateDashboardWidgets, 300000);

Customization Options #

Color Themes #

// Custom widget colors
.card.bg-gradient-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
 
.card.bg-gradient-success {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}

Size Variants #

<!-- Small widget -->
<div class="card card-sm">
  <div class="card-body p-3">
    <!-- Reduced padding -->
  </div>
</div>
 
<!-- Large widget -->
<div class="card card-lg">
  <div class="card-body p-4">
    <!-- Increased padding -->
  </div>
</div>

Animation Effects #

.card {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  
  &:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
  }
}

v3.4 Component Additions #

These components were added in Admindek 3.4. They're available across all dashboards and applications.

Command Palette (Cmd+K) #

A searchable command launcher with keyboard navigation. Triggered by ⌘K / Ctrl+K, lets users jump to any page or run any registered action.

<div class="command-palette" id="commandPalette" hidden>
  <div class="command-palette__backdrop"></div>
  <div class="command-palette__panel">
    <input type="search" class="command-palette__input" placeholder="Search pages, actions, or settings…" />
    <ul class="command-palette__results" role="listbox">
      <!-- results rendered dynamically -->
    </ul>
  </div>
</div>
document.addEventListener('keydown', (e) => {
  if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
    e.preventDefault()
    document.getElementById('commandPalette').hidden = false
  }
})

Keyboard shortcuts:

KeyAction
⌘K / Ctrl+KOpen palette
↑ / ↓Navigate results
EnterRun selected command
EscClose palette

Skeleton Loading #

Placeholder loading states for cards, tables, and profiles β€” show structure while real data loads.

<!-- Card skeleton -->
<div class="card skeleton-card">
  <div class="card-body">
    <div class="skeleton skeleton-line w-50 mb-2"></div>
    <div class="skeleton skeleton-line w-75 mb-2"></div>
    <div class="skeleton skeleton-line w-100"></div>
  </div>
</div>
 
<!-- Table skeleton -->
<table class="table">
  <tbody>
    <tr><td colspan="4"><div class="skeleton skeleton-line"></div></td></tr>
    <tr><td colspan="4"><div class="skeleton skeleton-line"></div></td></tr>
    <tr><td colspan="4"><div class="skeleton skeleton-line"></div></td></tr>
  </tbody>
</table>
 
<!-- Profile skeleton -->
<div class="d-flex align-items-center gap-3">
  <div class="skeleton skeleton-avatar"></div>
  <div class="flex-grow-1">
    <div class="skeleton skeleton-line w-50 mb-2"></div>
    <div class="skeleton skeleton-line w-25"></div>
  </div>
</div>

The .skeleton class applies a shimmer animation. Combine with .skeleton-line, .skeleton-avatar, .skeleton-thumbnail etc. for different shapes.

Empty States #

Illustrated empty states for inboxes, search results, drafts, and other "nothing here yet" scenarios.

<div class="empty-state">
  <img src="/assets/images/empty-states/inbox.svg" alt="" class="empty-state__illustration" />
  <h4 class="empty-state__title">Your inbox is empty</h4>
  <p class="empty-state__description">
    No new messages right now. We'll notify you when something arrives.
  </p>
  <button class="btn btn-primary">Compose new</button>
</div>

Available variants: inbox, search, 404, error, drafts, tasks-done, cart-empty.

Progress Animations #

Animated progress bars and micro-interactions for state transitions.

<div class="progress progress-animated">
  <div class="progress-bar bg-primary" style="--target-width: 75%"></div>
</div>
// Animate from 0 to target on viewport entry
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const bar = entry.target.querySelector('.progress-bar')
      bar.style.width = bar.style.getPropertyValue('--target-width')
      observer.unobserve(entry.target)
    }
  })
})
 
document.querySelectorAll('.progress-animated').forEach((p) => observer.observe(p))

Animated Counters #

Number counters that tick up smoothly when scrolled into view.

<h3 class="counter" data-target="12450" data-duration="1500">0</h3>
const counters = document.querySelectorAll('.counter')
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (!entry.isIntersecting) return
    const el = entry.target
    const target = parseInt(el.dataset.target, 10)
    const duration = parseInt(el.dataset.duration || '1000', 10)
    const start = performance.now()
 
    const tick = (now) => {
      const progress = Math.min((now - start) / duration, 1)
      el.textContent = Math.floor(progress * target).toLocaleString()
      if (progress < 1) requestAnimationFrame(tick)
    }
    requestAnimationFrame(tick)
    observer.unobserve(el)
  })
})
 
counters.forEach((c) => observer.observe(c))

Pair with data-format="currency" (or write your own format helper) to display dollar amounts, percentages, or other formatted values.