Skip to content

Instantly share code, notes, and snippets.

@lossendae
Forked from alOneh/DashboardApp.vue
Created December 11, 2022 19:05
Show Gist options
  • Save lossendae/9507d7f51f7e338d8325e72f8d564929 to your computer and use it in GitHub Desktop.
Save lossendae/9507d7f51f7e338d8325e72f8d564929 to your computer and use it in GitHub Desktop.
Example of a Vue.js app integrated in a twig template
{% extends 'base.html.twig' %}
{% block main %}
<div id="admin-dashboard"
data-users-count="{{ usersCount }}"
data-deleted-users-count="{{ deletedUsersCount }}"
data-users-by-date="{{ usersByDate|json_encode }}"
></div>
{% endblock %}
{% block body_javascript %}
{{ encore_entry_script_tags('admin/dashboard') }}
{% endblock %}
import Vue from 'vue'
import toInteger from 'lodash/toInteger'
import DashboardApp from './components/App.vue'
document.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('admin-dashboard')
/* eslint-disable no-new */
new Vue({
el,
name: 'Dashboard',
components: { DashboardApp },
data () {
const { dataset } = el
return {
deletedUsersCount: toInteger(dataset.deletedUsersCount),
usersByDate: JSON.parse(dataset.usersByDate),
usersCount: toInteger(dataset.usersCount)
}
},
render (createElement) {
return createElement('dashboard-app', {
props: {
deletedUsersCount: this.deletedUsersCount,
usersByDate: this.usersByDate,
usersCount: this.usersCount
}
})
}
})
})
<template>
<div class="row">
<div class="col-md-6 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-green"><i class="fa fa-users"/></span>
<div class="info-box-content">
<span class="info-box-text">Active users</span>
<span class="info-box-number">{{ usersCount || 0 }}</span>
</div>
</div>
</div>
<div class="col-md-6 col-sm-6 col-xs-12">
<div class="info-box">
<span class="info-box-icon bg-red"><i class="fa fa-users"/></span>
<div class="info-box-content">
<span class="info-box-text">Deleted users count</span>
<span class="info-box-number">{{ deletedUsersCount || 0 }}</span>
</div>
</div>
</div>
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Monthly registered users report</h3>
</div>
<div
class="box-body"
style="">
<div class="chart">
<line-chart
:chart-data="chartData"
:options="options"
:height="120"/>
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</template>
<script>
import getObjectKeys from 'lodash/keys'
import getObjectValues from 'lodash/values'
import LineChart from './LineChart'
export default {
name: 'DashboardApp',
components: { LineChart },
props: {
deletedUsersCount: {
type: Number,
required: true,
default: 0
},
usersByDate: {
type: Object,
required: true,
default: () => ({ })
},
usersCount: {
type: Number,
required: true,
default: 0
}
},
computed: {
options () {
return {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
},
chartData () {
return {
labels: getObjectKeys(this.usersByDate),
datasets: [
{
label: 'Registered users',
backgroundColor: '#437bf8',
data: getObjectValues(this.usersByDate)
}
]
}
}
}
}
</script>
import { Line, mixins } from 'vue-chartjs'
export default {
extends: Line,
mixins: [mixins.reactiveProp],
props: ['chartData', 'options'],
mounted () {
this.renderChart(this.chartData, this.options)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment