Labs ICT
Pro Login

Practical Example: Dashboard

Building a dynamic dashboard with EJS.

Setting Up the Dashboard Route

Let's build a complete dashboard that ties together everything you've learned. Start by creating a route that passes all the necessary data to your template.


app.get('/dashboard', async (req, res) => {
  const user = req.user;
  const stats = await getStats();
  const activity = await getRecentActivity();
  const chartData = await getChartData();
  
  res.render('dashboard', {
    user,
    stats,
    activity,
    chartData,
    title: 'Dashboard'
  });
});
    

The route gathers data from multiple sources and passes it all to the template in one clean object.

Stats Cards

Display key metrics in card format. Each card shows an icon, value, and label.


<div class="stats-grid">
  <% stats.forEach(stat => { %>
    <div class="stat-card">
      <div class="stat-icon"><%= stat.icon %></div>
      <div class="stat-value"><%= stat.value %></div>
      <div class="stat-label"><%= stat.label %></div>
      <div class="stat-change <%= stat.trend %>">
        <%= stat.trend === 'up' ? '↑' : '↓' %>
        <%= stat.change %>
      </div>
    </div>
  <% }); %>
</div>
    
Try it Yourself →

User Profile Cards

Create a user card component that displays avatar, name, role, and quick actions.


<div class="user-card">
  <img src="<%= user.avatar || '/images/default-avatar.png' %>" 
       alt="<%= user.name %>" 
       class="user-avatar">
  <h3><%= user.name %></h3>
  <p class="user-role"><%= user.role %></p>
  <div class="user-stats">
    <span><%= user.posts || 0 %> posts</span>
    <span><%= user.followers || 0 %> followers</span>
  </div>
  <a href="/profile/<%= user.id %>" class="btn">View Profile</a>
</div>
    

Activity Feed

Show recent user activities with timestamps and action descriptions.


<div class="activity-feed">
  <h2>Recent Activity</h2>
  <% if (activity && activity.length) { %>
    <% activity.forEach(item => { %>
      <div class="activity-item">
        <div class="activity-icon"><%= item.icon %></div>
        <div class="activity-content">
          <p><%= item.message %></p>
          <time><%= item.timeAgo %></time>
        </div>
      </div>
    <% }); %>
  <% } else { %>
    <p class="empty-state">No recent activity.</p>
  <% } %>
</div>
    
Try it Yourself →

Chart Data Display

Pass chart data to a JavaScript charting library. EJS renders the data, and the client-side library visualizes it.


<div class="chart-container">
  <h2>Performance Overview</h2>
  <canvas id="performanceChart"></canvas>
</div>

<script>
  const chartData = <%= JSON.stringify(chartData) %>;
  
  new Chart(document.getElementById('performanceChart'), {
    type: 'line',
    data: {
      labels: chartData.labels,
      datasets: [{
        label: 'Revenue',
        data: chartData.values,
        borderColor: '#3b82f6'
      }]
    }
  });
</script>
    

Using JSON.stringify() safely passes complex data from EJS to JavaScript.

Putting It All Together

Combine all components into a complete dashboard layout using partials.


<%- include('partials/header', { title }) %>
<%- include('partials/nav', { active: 'dashboard' }) %>

<div class="dashboard">
  <%- include('partials/user-card', { user }) %>
  <%- include('partials/stats-grid', { stats }) %>
  <%- include('partials/chart', { data: chartData }) %>
  <%- include('partials/activity-feed', { activity }) %>
</div>

<%- include('partials/footer') %>
    

This approach keeps your dashboard modular, maintainable, and easy to extend with new components.