First commit

This commit is contained in:
2022-02-27 15:37:42 +01:00
commit e474549aad
397 changed files with 151157 additions and 0 deletions

19
src/api/index.js Normal file
View File

@ -0,0 +1,19 @@
import axios from 'axios'
import config from '../config'
export default {
request (method, uri, data = null) {
if (!method) {
console.error('API function call requires method argument')
return
}
if (!uri) {
console.error('API function call requires uri argument')
return
}
var url = config.serverURI + uri
return axios({ method, url, data })
}
}

0
src/assets/.gitkeep Normal file
View File

23
src/components/404.vue Normal file
View File

@ -0,0 +1,23 @@
<template>
<div id="notFound">
<img src="/static/img/logo.png" class="center-block logo">
<div class="text-center col-sm-12">
<h1>You are lost.</h1>
<h4>This page doesn't exist.</h4>
<router-link to="/" class="vertical-5p lead">Take me home.</router-link>
</div>
</div>
</template>
<script>
export default {
name: 'NotFound'
}
</script>
<style>
#notFound {
padding: 10em;
color: white;
}
</style>

29
src/components/App.vue Normal file
View File

@ -0,0 +1,29 @@
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
section: 'Head'
}
},
methods: {
logout () {
this.$store.commit('SET_USER', null)
this.$store.commit('SET_TOKEN', null)
if (window.localStorage) {
window.localStorage.setItem('user', null)
window.localStorage.setItem('token', null)
}
this.$router.push('/login')
}
}
}
</script>

115
src/components/Dash.vue Normal file
View File

@ -0,0 +1,115 @@
<template>
<div :class="['wrapper', classes]">
<!-- Horizontal bar at top. Contains messages, notifications, tasks and user menu -->
<dash-header :user="user"></dash-header>
<!-- Left side column. contains the logo and sidebar -->
<sidebar :user="user" />
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
{{$route.name.toUpperCase() }}
<small>{{ $route.meta.description }}</small>
</h1>
<ol class="breadcrumb">
<li>
<a href="javascript:;">
<i class="fa fa-home"></i>Home</a>
</li>
<li class="active">{{$route.name.toUpperCase()}}</li>
</ol>
</section>
<router-view></router-view>
</div>
<!-- /.content-wrapper -->
<!-- Horizontal bar at bottom. Contains copy right -->
<dash-footer></dash-footer>
</div>
</template>
<script>
import faker from 'faker'
import config from '../config'
import DashFooter from './layout/DashFooter'
import DashHeader from './layout/DashHeader'
import Sidebar from './layout/Sidebar'
import 'hideseek'
export default {
name: 'Dash',
components: {
DashFooter,
DashHeader,
Sidebar
},
data: function () {
return {
// section: 'Dash',
classes: {
fixed_layout: config.fixedLayout,
hide_logo: config.hideLogoOnMobile
}
}
},
computed: {
user () {
return {
displayName: faker.name.findName(),
avatar: faker.image.avatar(),
roles: [faker.name.jobTitle(), faker.name.jobTitle()]
}
}
}
}
</script>
<style>
.wrapper.fixed_layout .main-header {
position: fixed;
width: 100%;
}
.wrapper.fixed_layout .content-wrapper {
padding-top: 50px;
}
.wrapper.fixed_layout .main-sidebar {
position: fixed;
height: 100vh;
}
@media (max-width: 767px) {
.wrapper.hide_logo .main-header .logo {
display: none;
}
}
.logo-mini,
.logo-lg {
text-align: left;
}
.logo-mini img,
.logo-lg img {
padding: 0.4em !important;
}
.logo-lg img {
display: -webkit-inline-box;
width: 25%;
}
.user-panel {
height: 4em;
}
hr.visible-xs-block {
width: 100%;
background-color: rgba(0, 0, 0, 0.17);
height: 1px;
border-color: transparent;
}
</style>

167
src/components/Login.vue Normal file
View File

@ -0,0 +1,167 @@
<template>
<div id="login">
<img src="/static/img/logo.png" class="center-block logo">
<div class="text-center col-sm-12">
<!-- login form -->
<form @submit.prevent="checkCreds">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<input class="form-control" name="username" placeholder="Username" type="text" v-model="username">
</div>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock"></i></span>
<input class="form-control" name="password" placeholder="Password" type="password" v-model="password">
</div>
<button type="submit" v-bind:class="'btn btn-primary btn-lg ' + loading">Submit</button>
</form>
<!-- errors -->
<div v-if=response class="text-red"><p class="vertical-5p lead">{{response}}</p></div>
</div>
</div>
</template>
<script>
import api from '../api'
export default {
name: 'Login',
data(router) {
return {
section: 'Login',
loading: '',
username: '',
password: '',
response: ''
}
},
methods: {
checkCreds() {
const { username, password } = this
this.toggleLoading()
this.resetResponse()
this.$store.commit('TOGGLE_LOADING')
/* Making API call to authenticate a user */
api
.request('post', '/login', { username, password })
.then(response => {
this.toggleLoading()
var data = response.data
/* Checking if error object was returned from the server */
if (data.error) {
var errorName = data.error.name
if (errorName) {
this.response =
errorName === 'InvalidCredentialsError'
? 'Username/Password incorrect. Please try again.'
: errorName
} else {
this.response = data.error
}
return
}
/* Setting user in the state and caching record to the localStorage */
if (data.user) {
var token = 'Bearer ' + data.token
this.$store.commit('SET_USER', data.user)
this.$store.commit('SET_TOKEN', token)
if (window.localStorage) {
window.localStorage.setItem('user', JSON.stringify(data.user))
window.localStorage.setItem('token', token)
}
this.$router.push(data.redirect ? data.redirect : '/')
}
})
.catch(error => {
this.$store.commit('TOGGLE_LOADING')
console.log(error)
this.response = 'Server appears to be offline'
this.toggleLoading()
})
},
toggleLoading() {
this.loading = this.loading === '' ? 'loading' : ''
},
resetResponse() {
this.response = ''
}
}
}
</script>
<style>
#login {
padding: 10em;
}
html,
body,
.container-table {
height: 100%;
background-color: #282b30 !important;
}
.container-table {
display: table;
color: white;
}
.vertical-center-row {
display: table-cell;
vertical-align: middle;
}
.vertical-20p {
padding-top: 20%;
}
.vertical-10p {
padding-top: 10%;
}
.vertical-5p {
padding-top: 5%;
}
.logo {
width: 15em;
padding: 3em;
}
.input-group {
padding-bottom: 2em;
height: 4em;
width: 100%;
}
.input-group span.input-group-addon {
width: 2em;
height: 4em;
}
@media (max-width: 1241px) {
.input-group input {
height: 4em;
}
}
@media (min-width: 1242px) {
form {
padding-left: 20em;
padding-right: 20em;
}
.input-group input {
height: 6em;
}
}
.input-group-addon i {
height: 15px;
width: 15px;
}
</style>

View File

@ -0,0 +1,17 @@
<template>
<footer class="main-footer">
<strong>Copyright &copy; {{ year }}
<a href="https://discord.gg/Mh9mTEA">CPHA.pt</a>.</strong> All rights reserved.
</footer>
</template>
<script>
export default {
name: 'DashFooter',
data: function () {
return {
year: new Date().getFullYear()
}
}
}
</script>

View File

@ -0,0 +1,38 @@
<template>
<header class="main-header">
<span class="logo-mini">
<a href="/"><img src="/static/img/copilot-logo-white.svg" alt="Logo" class="img-responsive center-block logo"></a>
</span>
<!-- Header Navbar -->
<nav class="navbar navbar-static-top" role="navigation">
<!-- Sidebar toggle button-->
<a href="javascript:;" class="sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">Toggle navigation</span>
</a>
</nav>
</header>
</template>
<script>
import { mapState } from 'vuex'
import MessagesMenu from './MessagesMenu'
import NotificationsMenu from './NotificationsMenu'
import TasksMenu from './TasksMenu'
import UserMenu from './UserMenu'
export default {
name: 'DashHeader',
components: {
MessagesMenu,
NotificationsMenu,
TasksMenu,
UserMenu
},
props: ['user'],
computed: {
...mapState([
'userInfo'
])
}
}
</script>

View File

@ -0,0 +1,28 @@
<template>
<li>
<a href="javascript:;">
<h4>
<span>{{message.title}}</span>
<small>
<i class="fa fa-clock-o"></i>
<span>{{message.createdAt}}</span>
</small>
</h4>
<p>{{message.body}}</p>
</a>
</li>
</template>
<script>
export default {
name: 'MessageItem',
props: ['message']
}
</script>
<style scoped>
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4,
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p {
margin-left: 0;
}
</style>

View File

@ -0,0 +1,40 @@
<template>
<li class="dropdown messages-menu">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-envelope-o"></i>
<span class="label label-success">{{ userInfo.messages | count }}</span>
</a>
<ul class="dropdown-menu">
<li class="header">You have {{ userInfo.messages | count }} message(s)</li>
<li v-if="userInfo.messages.length > 0">
<!-- inner menu: contains the messages -->
<ul class="menu">
<message-item v-for="message in userInfo.messages"
:key="message.id"
:message="message"></message-item>
</ul>
<!-- /.menu -->
</li>
<li class="footer" v-if="userInfo.messages.length > 0">
<a href="javascript:;">See All Messages</a>
</li>
</ul>
</li>
</template>
<script>
import { mapState } from 'vuex'
import MessageItem from './MessageItem'
export default {
name: 'MessagesMenu',
components: {
MessageItem
},
computed: {
...mapState([
'userInfo'
])
}
}
</script>

View File

@ -0,0 +1,48 @@
<template>
<li class="notification-item">
<a href="javascript:;">
<h4>
<span>{{ notification.title }}</span>
<small class="time pull-right">
<i class="fa fa-clock-o"></i>
<span>{{ notification.createdAt }}</span>
</small>
</h4>
<p>{{ notification.body }}</p>
</a>
</li>
</template>
<script>
export default {
props: {
notification: {
type: Object,
required: true
}
}
}
</script>
<style scoped>
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > h4, .navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > p {
margin: 0;
white-space: normal;
word-break: break-word;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > h4 {
font-size: 15px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > h4 small {
font-size: 10px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > p {
font-size: 12px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > h4 > span {
display: inline-block;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu > li > ul.menu li > a > h4 > small.time {
margin-top: 3px;
}
</style>

View File

@ -0,0 +1,115 @@
<template>
<li class="dropdown notifications-menu">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-bell-o"></i>
<span class="label label-warning">{{ newNotifications | count }}</span>
</a>
<ul class="dropdown-menu">
<li class="header">
<div class="row no-margin">
<span class="col-xs-12 col-md-6 tab-link" :class="{active: tab === 'new'}" @click="switchTab($event, 'new')">
<a href="javascript:;">New</a>
</span>
<span class="col-xs-12 col-md-6 tab-link" :class="{active: tab === 'old'}" @click="switchTab($event, 'old')">
<a href="javascript:;">Old</a>
</span>
</div>
</li>
<li>
<ul v-if="tab === 'new'" class="menu">
<notification-item v-for="notification in newNotifications" :key="notification.id" :notification="notification"></notification-item>
<li v-if="!newNotifications.length">
<span class="center-block text-center">There are no new notifications</span>
</li>
</ul>
<ul v-if="tab === 'old'" class="menu">
<notification-item v-for="notification in oldNotifications" :key="notification.id" :notification="notification"></notification-item>
<li v-if="!oldNotifications.length">
<span class="center-block text-center">There are no old notifications</span>
</li>
</ul>
</li>
<li v-if="newNotifications.length && tab === 'new'" class="footer">
<a href="javascript:;" @click="markAllAsRead">
<i class="fa fa-check"></i>
<span>Mark all as read</span>
</a>
</li>
</ul>
</li>
</template>
<script>
import { mapState } from 'vuex'
import NotificationItem from './NotificationItem'
export default {
name: 'NotificationsMenu',
components: {
NotificationItem
},
data() {
return {
tab: 'new'
}
},
computed: {
...mapState([
'userInfo'
]),
newNotifications() {
return this.userInfo.notifications.filter(n => !n.readAt)
},
oldNotifications() {
return this.userInfo.notifications.filter(n => n.readAt)
}
},
methods: {
markAllAsRead() {
event.stopPropagation()
this.userInfo.notifications.filter(n => !n.readAt).forEach(function(notification) {
notification.readAt = new Date().toUTCString
})
},
switchTab(event, tab) {
event.stopPropagation()
this.tab = tab
}
}
}
</script>
<style scoped>
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu {
width: 400px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li.header {
padding: 0;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li.header span.tab-link {
padding: 4px;
text-align: center;
cursor: pointer;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li.header span.tab-link a {
color: #444;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li.header span.tab-link.active {
font-weight: bold;
border-bottom: 2px solid #3c8dbc;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li.header span:hover.tab-link > a {
color: #3c8dbc !important;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li > ul.menu {
max-height: 300px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li > ul.menu li > span {
padding: 10px;
}
.navbar-custom-menu > .navbar-nav > li.notifications-menu > .dropdown-menu li:hover.footer > a {
color: #3c8dbc !important;
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel (optional) -->
<div class="user-panel">
<div class="pull-left image">
<img :src="user.avatar" />
</div>
<div class="pull-left info">
<div>
<p class="white">{{user.displayName}}</p>
</div>
<a href="javascript:;">
<i class="fa fa-circle text-success"></i> Online
</a>
</div>
</div>
<!-- search form (Optional) -->
<form v-on:submit.prevent class="sidebar-form" id="searchForm">
<div class="input-group" id="searchContainer">
<span class="input-group-btn">
<input type="text"
name="search"
id="search"
class="search form-control"
data-toggle="hideseek" p
laceholder="Search Menus"
data-list=".sidebar-menu">
<button type="submit" name="search" id="search-btn" class="btn btn-flat">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<!-- /.search form -->
<!-- Sidebar Menu -->
<sidebar-menu />
<!-- /.sidebar-menu -->
</section>
<!-- /.sidebar -->
</aside>
</template>
<script>
import SidebarMenu from './SidebarMenu'
export default {
name: 'Sidebar',
props: ['user'],
components: { SidebarMenu },
mounted: function() {
window
.jQuery('[data-toggle="hideseek"]')
.off()
.hideseek()
}
}
</script>
<style scope="local">
.user-panel .image img {
border-radius: 50%;
}
#searchForm {
padding-left: 0em;
padding-right: 0em;
}
#searchContainer {
height: 100%;
padding-bottom: 0em;
}
#search {
width: 80%;
float: right;
}
#search-btn {
width: 20%;
}
</style>

View File

@ -0,0 +1,171 @@
<template>
<ul class="sidebar-menu">
<li class="header">TOOLS</li>
<router-link tag="li" class="pageLink" to="/">
<a>
<i class="fa fa-desktop"></i>
<span class="page">Dashboard</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/tables">
<a>
<i class="fa fa-table"></i>
<span class="page">Tables</span>
</a>
</router-link>
<li class="header">CPHA</li>
<router-link tag="li" class="pageLink" to="/personalfinances">
<a>
<i class="fa fa-money"></i>
<span class="page">Finances</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/cryptos">
<a>
<i class="fa fa-btc"></i>
<span class="page">Cryptos</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/setting">
<a>
<i class="fa fa-cog"></i>
<span class="page">Settings</span>
</a>
</router-link>
<li class="treeview">
<a href="#">
<i class="fa fa-folder-o"></i>
<span class="treeview-title">Files</span>
<span class="pull-right-container pull-right">
<i class="fa fa-angle-left fa-fw"></i>
</span>
</a>
<ul class="treeview-menu">
<li>
<a href="#">
<i class="fa fa-file-word-o"></i> Item 1
</a>
</li>
<li>
<a href="#">
<i class="fa fa-file-picture-o"></i> Item 2
</a>
</li>
<li>
<a href="#">
<i class="fa fa-file-pdf-o"></i> Item 3
</a>
</li>
</ul>
</li>
<li class="header">ME</li>
<router-link tag="li" class="pageLink" to="/tasks">
<a>
<i class="fa fa-tasks"></i>
<span class="page">Tasks</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/setting">
<a>
<i class="fa fa-cog"></i>
<span class="page">Settings</span>
</a>
</router-link>
<li class="treeview">
<a href="#">
<i class="fa fa-folder-o"></i>
<span class="treeview-title">Files</span>
<span class="pull-right-container pull-right">
<i class="fa fa-angle-left fa-fw"></i>
</span>
</a>
<ul class="treeview-menu">
<li>
<a href="#">
<i class="fa fa-file-word-o"></i> Item 1
</a>
</li>
<li>
<a href="#">
<i class="fa fa-file-picture-o"></i> Item 2
</a>
</li>
<li>
<a href="#">
<i class="fa fa-file-pdf-o"></i> Item 3
</a>
</li>
</ul>
</li>
<li class="header">LOGS</li>
<router-link tag="li" class="pageLink" to="/access">
<a>
<i class="fa fa-book"></i>
<span class="page">Access</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/server">
<a>
<i class="fa fa-hdd-o"></i>
<span class="page">Server</span>
</a>
</router-link>
<!-- <router-link tag="li" class="pageLink" to="/repos">
<a>
<i class="fa fa-heart"></i>
<span class="page">Repos</span>
<small class="label pull-right bg-green">AJAX</small>
</a>
</router-link> -->
<li class="header">PAGES</li>
<router-link tag="li" class="pageLink" to="/login">
<a>
<i class="fa fa-circle-o text-yellow"></i>
<span class="page"> Login</span>
</a>
</router-link>
<router-link tag="li" class="pageLink" to="/404">
<a>
<i class="fa fa-circle-o text-red"></i>
<span class="page"> 404</span>
</a>
</router-link>
</ul>
</template>
<script>
export default {
name: 'SidebarMenu'
}
</script>
<style>
/* override default */
.sidebar-menu > li > a {
padding: 12px 15px 12px 15px;
}
.sidebar-menu li.active > a > .fa-angle-left,
.sidebar-menu li.active > a > .pull-right-container > .fa-angle-left {
animation-name: rotate;
animation-duration: 0.2s;
animation-fill-mode: forwards;
}
.treeview-title {
z-index: 1;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-90deg);
}
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<li class="dropdown tasks-menu">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-flag-o"></i>
<span class="label label-danger">{{ userInfo.tasks | count }} </span>
</a>
<ul class="dropdown-menu">
<li class="header">You have {{ userInfo.tasks | count }} task(s)</li>
<li v-if="userInfo.tasks.length > 0">
<!-- Inner menu: contains the tasks -->
<ul class="menu">
<li>
<!-- Task item -->
<a href="javascript:;">
<!-- Task title and progress text -->
<h3>
Design some buttons
<small class="pull-right">20%</small>
</h3>
<!-- The progress bar -->
<div class="progress xs">
<!-- Change the css width attribute to simulate progress -->
<div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
<span class="sr-only">20% Complete</span>
</div>
</div>
</a>
</li>
<!-- end task item -->
</ul>
</li>
<li class="footer" v-if="userInfo.tasks.length > 0">
<a href="javascript:;">View all tasks</a>
</li>
</ul>
</li>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'TasksMenu',
computed: {
...mapState([
'userInfo'
])
}
}
</script>

View File

@ -0,0 +1,32 @@
<template>
<li class="dropdown user user-menu">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<!-- The user image in the navbar-->
<img :src="user.avatar" class="user-image" alt="User Image">
<!-- hidden-xs hides the username on small devices so only the image appears. -->
<span class="hidden-xs">{{user.displayName}}</span>
</a>
<!-- Account Info and Menu -->
<ul class="dropdown-menu">
<li class="user-header" style="height:auto;min-height:85px;padding-bottom:15px;">
<p>
<span>{{user.displayName}}</span>
<small v-for="role in user.roles" :key="role">{{role}}</small>
</p>
</li>
<li class="user-footer">
<a href="javascript:;" class="btn btn-default btn-flat btn-block">
<i class="fa fa-sign-out"></i>
<span>Logout</span>
</a>
</li>
</ul>
</li>
</template>
<script>
export default {
name: 'UserMenu',
props: ['user']
}
</script>

View File

@ -0,0 +1,93 @@
<template>
<section class="content">
<h1 class="text-center">Access</h1>
<h4 class="text-center">Where our users are coming from.</h4>
<div class="row">
<div class="col-md-12">
<!-- MAP & BOX PANE -->
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">Visitors Report</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<!-- /.box-header -->
<div class="box-body no-padding">
<div class="row no-gutters">
<div class="col-md-8">
<!-- Map will be created here -->
<div id="world-map-markers"></div>
</div>
<!-- /.col -->
<div class="col-md-4">
<div class="pad box-pane-right bg-green" style="min-height: 400px">
<div v-for="stat in stats" class="description-block margin-bottom">
<div class="row" data-color="#fff"><i class="fa fa-bar-chart-o fa-3x"></i></div>
<h5 class="description-header">{{stat.header}}</h5>
<span class="description-text">{{stat.text}}</span>
</div>
</div>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</div>
<!-- /.box-body -->
</div>
<link rel="stylesheet" href="/static/js/plugins/jvectormap/jquery-jvectormap-2.0.3.css" >
</div>
</div>
</section>
</template>
<script>
import {stats} from '../../demo'
const pluginURL = '/static/js/plugins/jvectormap/jquery-jvectormap-2.0.3.min.js'
const mapURL = '/static/js/plugins/jvectormap/jquery-jvectormap-world-mill.js'
export default {
name: 'Access',
data () {
return {
stats
}
},
mounted () {
this.$nextTick(() => {
window.jQuery.getScript(pluginURL, () => {
window.jQuery.getScript(mapURL, () => {
window.jQuery('#world-map-markers').vectorMap({
map: 'world_mill'
})
})
})
})
}
}
</script>
<style>
.fake {
color: 'red';
}
#world-map-markers svg {
height: 355px;
}
.row.no-gutters {
margin-right: 0;
margin-left: 0;
}
.row.no-gutters > [class^="col-"],
.row.no-gutters > [class*=" col-"] {
padding-right: 0;
padding-left: 0;
}
</style>

View File

@ -0,0 +1,362 @@
<template>
<section class="content">
<!-- CHPA Crypto Charts START -->
<div class="col-xs-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title"></h3>
<div class="box-body">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Web Traffic Overview</strong>
</p>
<canvas id="trafficBar" ></canvas>
</div>
<hr class="visible-xs-block">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Wallet Pie</strong>
</p>
<canvas id="cryptowalletPie"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- CHPA Crypto Charts END -->
<div class="row center-block">
<h2>Wallet</h2>
<div class="col-md-12">
<div class="box-body no-padding table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<th style="width: 10px">#</th>
<th>Crypto</th>
<th>Amount</th>
<th>Spend</th>
<th>Average</th>
<th>Price</th>
<th>PnL %</th>
<th>PnL </th>
<th style="width: 40px">Pie</th>
</tr>
<!-- Google Sheets Gsheets Data -->
<tr>
<!-- # -->
<td>1.</td>
<!-- Crypto -->
<td>Update software</td>
<!-- Amount -->
<td><div class="progress progress-xs"><div class="progress-bar progress-bar-danger" style="width: 55%"></div></div></td>
<!-- Spend -->
<td></td>
<!-- Average -->
<td></td>
<!-- Price -->
<td></td>
<!-- PnL % -->
<td></td>
<!-- PnL -->
<td></td>
<!-- Pie -->
<td><span class="badge bg-red">55%</span></td>
</tr>
<tr>
<td>2.</td>
<td>Clean database</td>
<td>
<div class="progress progress-xs">
<div class="progress-bar progress-bar-yellow" style="width: 70%"></div>
</div>
</td>
<td><span class="badge bg-yellow">70%</span></td>
</tr>
<tr>
<td>3.</td>
<td>Cron job running</td>
<td>
<div class="progress progress-xs progress-striped active">
<div class="progress-bar progress-bar-primary" style="width: 30%"></div>
</div>
</td>
<td><span class="badge bg-light-blue">30%</span></td>
</tr>
<tr>
<td>4.</td>
<td>Fix and squish bugs</td>
<td>
<div class="progress progress-xs progress-striped active">
<div class="progress-bar progress-bar-success" style="width: 90%"></div>
</div>
</td>
<td><span class="badge bg-green">90%</span></td>
</tr>
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
</div>
<div class="row center-block">
<h2>Crypto Trades</h2>
<div class="col-md-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Last crypto trades</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="dataTables_wrapper form-inline dt-bootstrap" id="example1_wrapper">
<div class="row">
<div class="col-sm-6">
<div id="example1_length" class="dataTables_length">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 table-responsive">
<table aria-describedby="example1_info" role="grid" id="example1" class="table table-bordered table-striped dataTable">
<thead>
<tr role="row">
<th aria-label="Rendering engine: activate to sort column descending" aria-sort="ascending" style="width: 167px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting_asc">Rendering engine</th>
<th aria-label="Browser: activate to sort column ascending" style="width: 207px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Browser</th>
<th aria-label="Platform(s): activate to sort column ascending" style="width: 182px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Platform(s)</th>
<th aria-label="Engine version: activate to sort column ascending" style="width: 142px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Engine version</th>
<th aria-label="CSS grade: activate to sort column ascending" style="width: 101px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">CSS grade</th>
</tr>
</thead>
<tbody>
<tr class="even" role="row">
<td class="sorting_1">Blink</td>
<td>Iridium 54.0</td>
<td>GNU/Linux</td>
<td>54</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.5</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 2.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 3.0</td>
<td>Win 2k+ / OSX.3+</td>
<td>1.9</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.0</td>
<td>OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.5</td>
<td>OSX.3+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape 7.2</td>
<td>Win 95+ / Mac OS 8.6-9.2</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Browser 8</td>
<td>Win 98SE+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Navigator 9</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Mozilla 1.0</td>
<td>Win 95+ / OSX.1+</td>
<td>1</td>
<td>A</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="1" rowspan="1">Rendering engine</th>
<th colspan="1" rowspan="1">Browser</th>
<th colspan="1" rowspan="1">Platform(s)</th>
<th colspan="1" rowspan="1">Engine version</th>
<th colspan="1" rowspan="1">CSS grade</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script>
import Chart from 'chart.js'
import $ from 'jquery'
// Require needed datatables modules
require('datatables.net')
require('datatables.net-bs')
export default {
name: 'Tables',
data () {
return {
generateRandomNumbers (numbers, max, min) {
var a = []
for (var i = 0; i < numbers; i++) {
a.push(Math.floor(Math.random() * (max - min + 1)) + max)
}
return a
}
}
},
computed: {
coPilotNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
personalNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
isMobile () {
return (window.innerWidth <= 800 && window.innerHeight <= 600)
}
},
mounted() {
this.$nextTick(() => {
$('#example1').DataTable()
})
this.$nextTick(() => {
var ctx = document.getElementById('trafficBar').getContext('2d')
var config = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datasets: [{
label: 'Investment',
fill: false,
borderColor: '#284184',
pointBackgroundColor: '#284184',
backgroundColor: '#284184',
data: this.coPilotNumbers
}, {
label: 'If sell Now',
fill: false,
borderColor: '#4BC0C0',
pointBackgroundColor: '#4BC0C0',
backgroundColor: '#4BC0C0',
data: this.personalNumbers
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
},
tooltips: {
mode: 'label',
xPadding: 10,
yPadding: 10,
bodySpacing: 10
}
}
}
new Chart(ctx, config) // eslint-disable-line no-new
var pieChartCanvas = document.getElementById('cryptowalletPie').getContext('2d')
var pieConfig = {
type: 'pie',
data: {
labels: ['BTC', 'ETH', 'LUNA', 'XRP'],
datasets: [{
data: [56.6, 37.7, 4.1, 51],
backgroundColor: ['#00a65a', '#f39c12', '#00c0ef', '#ff6fff'],
hoverBackgroundColor: ['#00a65a', '#f39c12', '#00c0ef', '#ff6fff']
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
}
}
}
new Chart(pieChartCanvas, pieConfig) // eslint-disable-line no-new
})
}
}
</script>
<style>
@import url('/static/js/plugins/datatables/dataTables.bootstrap.css');
table.dataTable thead .sorting:after,
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:after {
font-family: 'FontAwesome';
}
table.dataTable thead .sorting:after {
content: '\f0dc';
}
table.dataTable thead .sorting_asc:after {
content: '\f0dd';
}
table.dataTable thead .sorting_desc:after {
content: '\f0de';
}
</style>

View File

@ -0,0 +1,354 @@
<template>
<!-- Main content -->
<section class="content">
<!-- Info boxes -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-aqua"
:icon-classes="['ion', 'ion-ios-gear-outline']"
text="CPU Traffic"
number="90%"></info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-red"
:icon-classes="['fa', 'fa-google-plus']"
text="Likes"
number="41,410"></info-box>
</div>
<!-- /.col -->
<!-- fix for small devices only -->
<div class="clearfix visible-sm-block"></div>
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-green"
:icon-classes="['ion', 'ion-ios-cart-outline']"
text="Sales"
number="760"></info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-yellow"
:icon-classes="['ion', 'ion-ios-people-outline']"
text="New Members"
number="2,000"></info-box>
</div>
<!-- /.col -->
<div class="row center-block">
<h2>Data tables</h2>
<div class="col-md-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Data Table With Full Features</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="dataTables_wrapper form-inline dt-bootstrap" id="example1_wrapper">
<div class="row">
<div class="col-sm-6">
<div id="example1_length" class="dataTables_length">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 table-responsive">
<table aria-describedby="example1_info" role="grid" id="example1" class="table table-bordered table-striped dataTable">
<thead>
<tr role="row">
<th aria-label="Rendering engine: activate to sort column descending" aria-sort="ascending" style="width: 167px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting_asc">Rendering engine</th>
<th aria-label="Browser: activate to sort column ascending" style="width: 207px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Browser</th>
<th aria-label="Platform(s): activate to sort column ascending" style="width: 182px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Platform(s)</th>
<th aria-label="Engine version: activate to sort column ascending" style="width: 142px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Engine version</th>
<th aria-label="CSS grade: activate to sort column ascending" style="width: 101px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">CSS grade</th>
</tr>
</thead>
<tbody>
<tr class="even" role="row">
<td class="sorting_1">Blink</td>
<td>Iridium 54.0</td>
<td>GNU/Linux</td>
<td>54</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.5</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 2.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 3.0</td>
<td>Win 2k+ / OSX.3+</td>
<td>1.9</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.0</td>
<td>OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.5</td>
<td>OSX.3+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape 7.2</td>
<td>Win 95+ / Mac OS 8.6-9.2</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Browser 8</td>
<td>Win 98SE+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Navigator 9</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Mozilla 1.0</td>
<td>Win 95+ / OSX.1+</td>
<td>1</td>
<td>A</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="1" rowspan="1">Rendering engine</th>
<th colspan="1" rowspan="1">Browser</th>
<th colspan="1" rowspan="1">Platform(s)</th>
<th colspan="1" rowspan="1">Engine version</th>
<th colspan="1" rowspan="1">CSS grade</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</div>
</div>
<!-- /.row -->
<div class="col-xs-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title"></h3>
<div class="box-body">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Web Traffic Overview</strong>
</p>
<canvas id="trafficBar" ></canvas>
</div>
<hr class="visible-xs-block">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Language Overview</strong>
</p>
<canvas id="languagePie"></canvas>
</div>
</div>
</div>
<!-- <div class="text-center">
<small><b>Pro Tip</b> Don't forget to star us on github!</small>
</div> -->
</div>
</div>
<!-- /.row -->
<!-- Main row -->
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-yellow"
:icon-classes="['ion', 'ion-ios-pricetag-outline']"
text="Inventory"
number="5,200"
:progress="50"
description="50% increase since May"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-green"
:icon-classes="['ion', 'ion-ios-heart-outline']"
text="Mentions"
number="92,050"
:progress="20"
description="20% increase in 30 days"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-red"
:icon-classes="['ion', 'ion-ios-cloud-download-outline']"
text="Downloads"
number="114,381"
:progress="70"
description="70% increase since yesterday"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-aqua"
:icon-classes="['ion', 'ion-ios-chatbubble-outline']"
text="Direct Messages"
number="163,921"
:progress="40"
description="40% increase compared to last year"></process-info-box>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
<!-- /.content -->
</template>
<script>
import Chart from 'chart.js'
import Alert from '../widgets/Alert'
import InfoBox from '../widgets/InfoBox'
import ProcessInfoBox from '../widgets/ProcessInfoBox'
export default {
name: 'Dashboard',
components: {
Alert,
InfoBox,
ProcessInfoBox
},
data () {
return {
generateRandomNumbers (numbers, max, min) {
var a = []
for (var i = 0; i < numbers; i++) {
a.push(Math.floor(Math.random() * (max - min + 1)) + max)
}
return a
}
}
},
computed: {
coPilotNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
personalNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
isMobile () {
return (window.innerWidth <= 800 && window.innerHeight <= 600)
}
},
mounted () {
this.$nextTick(() => {
var ctx = document.getElementById('trafficBar').getContext('2d')
var config = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datasets: [{
label: 'CoPilot',
fill: false,
borderColor: '#284184',
pointBackgroundColor: '#284184',
backgroundColor: 'rgba(0, 0, 0, 0)',
data: this.coPilotNumbers
}, {
label: 'Personal Site',
borderColor: '#4BC0C0',
pointBackgroundColor: '#4BC0C0',
backgroundColor: 'rgba(0, 0, 0, 0)',
data: this.personalNumbers
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
},
tooltips: {
mode: 'label',
xPadding: 10,
yPadding: 10,
bodySpacing: 10
}
}
}
new Chart(ctx, config) // eslint-disable-line no-new
var pieChartCanvas = document.getElementById('languagePie').getContext('2d')
var pieConfig = {
type: 'pie',
data: {
labels: ['HTML', 'JavaScript', 'CSS'],
datasets: [{
data: [56.6, 37.7, 4.1],
backgroundColor: ['#00a65a', '#f39c12', '#00c0ef'],
hoverBackgroundColor: ['#00a65a', '#f39c12', '#00c0ef']
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
}
}
}
new Chart(pieChartCanvas, pieConfig) // eslint-disable-line no-new
})
}
}
</script>
<style>
.info-box {
cursor: pointer;
}
.info-box-content {
text-align: center;
vertical-align: middle;
display: inherit;
}
.fullCanvas {
width: 100%;
}
</style>

View File

@ -0,0 +1,227 @@
<template>
<!-- Main content -->
<section class="content">
<!-- Info boxes -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-aqua"
:icon-classes="['ion', 'ion-ios-gear-outline']"
text="CPU Traffic"
number="90%"></info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-red"
:icon-classes="['fa', 'fa-google-plus']"
text="Likes"
number="41,410"></info-box>
</div>
<!-- /.col -->
<!-- fix for small devices only -->
<div class="clearfix visible-sm-block"></div>
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-green"
:icon-classes="['ion', 'ion-ios-cart-outline']"
text="Sales"
number="760"></info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<info-box color-class="bg-yellow"
:icon-classes="['ion', 'ion-ios-people-outline']"
text="New Members"
number="2,000"></info-box>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
<div class="col-xs-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title"></h3>
<div class="box-body">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Web Traffic Overview</strong>
</p>
<canvas id="trafficBar" ></canvas>
</div>
<hr class="visible-xs-block">
<div class="col-sm-6 col-xs-12">
<p class="text-center">
<strong>Language Overview</strong>
</p>
<canvas id="languagePie"></canvas>
</div>
</div>
</div>
<!-- <div class="text-center">
<small><b>Pro Tip</b> Don't forget to star us on github!</small>
</div> -->
</div>
</div>
<!-- /.row -->
<!-- Main row -->
<div class="row">
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-yellow"
:icon-classes="['ion', 'ion-ios-pricetag-outline']"
text="Inventory"
number="5,200"
:progress="50"
description="50% increase since May"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-green"
:icon-classes="['ion', 'ion-ios-heart-outline']"
text="Mentions"
number="92,050"
:progress="20"
description="20% increase in 30 days"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-red"
:icon-classes="['ion', 'ion-ios-cloud-download-outline']"
text="Downloads"
number="114,381"
:progress="70"
description="70% increase since yesterday"></process-info-box>
</div>
<!-- /.col -->
<div class="col-md-3 col-sm-6 col-xs-12">
<process-info-box color-class="bg-aqua"
:icon-classes="['ion', 'ion-ios-chatbubble-outline']"
text="Direct Messages"
number="163,921"
:progress="40"
description="40% increase compared to last year"></process-info-box>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
<!-- /.content -->
</template>
<script>
import Chart from 'chart.js'
import Alert from '../widgets/Alert'
import InfoBox from '../widgets/InfoBox'
import ProcessInfoBox from '../widgets/ProcessInfoBox'
export default {
name: 'Dashboard',
components: {
Alert,
InfoBox,
ProcessInfoBox
},
data () {
return {
generateRandomNumbers (numbers, max, min) {
var a = []
for (var i = 0; i < numbers; i++) {
a.push(Math.floor(Math.random() * (max - min + 1)) + max)
}
return a
}
}
},
computed: {
coPilotNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
personalNumbers () {
return this.generateRandomNumbers(12, 1000000, 10000)
},
isMobile () {
return (window.innerWidth <= 800 && window.innerHeight <= 600)
}
},
mounted () {
this.$nextTick(() => {
var ctx = document.getElementById('trafficBar').getContext('2d')
var config = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datasets: [{
label: 'CoPilot',
fill: false,
borderColor: '#284184',
pointBackgroundColor: '#284184',
backgroundColor: 'rgba(0, 0, 0, 0)',
data: this.coPilotNumbers
}, {
label: 'Personal Site',
borderColor: '#4BC0C0',
pointBackgroundColor: '#4BC0C0',
backgroundColor: 'rgba(0, 0, 0, 0)',
data: this.personalNumbers
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
},
tooltips: {
mode: 'label',
xPadding: 10,
yPadding: 10,
bodySpacing: 10
}
}
}
new Chart(ctx, config) // eslint-disable-line no-new
var pieChartCanvas = document.getElementById('languagePie').getContext('2d')
var pieConfig = {
type: 'pie',
data: {
labels: ['HTML', 'JavaScript', 'CSS'],
datasets: [{
data: [56.6, 37.7, 4.1],
backgroundColor: ['#00a65a', '#f39c12', '#00c0ef'],
hoverBackgroundColor: ['#00a65a', '#f39c12', '#00c0ef']
}]
},
options: {
responsive: true,
maintainAspectRatio: !this.isMobile,
legend: {
position: 'bottom',
display: true
}
}
}
new Chart(pieChartCanvas, pieConfig) // eslint-disable-line no-new
})
}
}
</script>
<style>
.info-box {
cursor: pointer;
}
.info-box-content {
text-align: center;
vertical-align: middle;
display: inherit;
}
.fullCanvas {
width: 100%;
}
</style>

View File

@ -0,0 +1,89 @@
<template>
<div>
<h1 class="text-center">Repos</h1>
<h4 class="text-center">Github Repos</h4>
<section class="content">
<div class="row">
<div v-if="error">
Found an error
</div>
<div v-else>
<div class="col-md-4" v-if="response" v-for="repo in response" >
<div class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active text-center">
<h3 class="widget-user-username center-text">{{repo.name }}</h3>
</div>
<div class="widget-user-image">
<img class="img-circle" v-bind:src="repo.owner.avatar_url" alt="repo.owner.login + ' Avatar'">
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-4 border-right">
<div class="description-block">
<h5 class="description-header">{{repo.stargazers_count}}</h5>
<span class="description-text">Star</span>
</div>
</div>
<div class="col-sm-4 border-right">
<div class="description-block">
<a v-bind:href="repo.owner.html_url" target="_blank">
<button type="button" class="btn btn-default btn-lg">Visit</button>
</a>
</div>
</div>
<div class="col-sm-4">
<div class="description-block">
<h5 class="description-header">{{repo.forks_count}}</h5>
<span class="description-text">Forks</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Repository',
data () {
return {
githubUrl: 'https://api.github.com/search/repositories?q=language%3Ajavascript&sort=stars',
response: null,
error: null
}
},
methods: {
callGitHub () {
axios.get(this.githubUrl)
.then(response => {
console.log('GitHub Response:', response)
if (response.status !== 200) {
this.error = response.statusText
return
}
this.response = response.data.items
})
.catch(error => {
// Request failed.
console.log('error', error.response)
this.error = error.response.statusText
})
}
},
mounted () {
this.callGitHub()
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,36 @@
<template>
<div>
<h1 class="text-center">Our Environment</h1>
<section class="content">
<div class="row" v-if="servers">
<div class="col-md-4" v-for="server in servers">
<div v-bind:class="'box box-' + server.status">
<div class="box-header with-border">
<i v-bind:class="'fa fa-' + server.icon + ' fa-2x'"></i>
<h3 class="box-title">{{server.name}}</h3>
</div>
<div class="box-body">
<span>{{server.description}}</span>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
import {servers} from '../../demo'
export default {
name: 'Servers',
data () {
return {
servers
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,125 @@
<template>
<div>
<h1 class="text-center">Settings</h1>
<section class="content">
<div class="row">
<div class="col-md-12">
<div class="box box-info">
<!-- Input Addons -->
<div class="box-header with-border">
<h3 class="box-title">Inputs</h3>
</div>
<div class="box-body">
<!-- calendar group -->
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-fw fa-calendar"></i>
</span>
<datepicker :readonly="true" format="MMM/D/YYYY" id="dateInput" width="100%"></datepicker>
</div>
<br />
<br />
<!-- with characthers -->
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-fw fa-at" aria-hidden="true"></i>
</span>
<input class="form-control" placeholder="Username" type="text">
</div>
<br />
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-fw fa-usd" aria-hidden="true"></i>
</span>
<input class="form-control" type="text">
<span class="input-group-addon">.00</span>
</div>
<br />
<!-- with icons from font awesome -->
<h4>With icons</h4>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-fw fa-envelope"></i></span>
<input class="form-control" placeholder="Email" type="email">
</div>
<br />
<div class="input-group">
<input class="form-control" type="text">
<span class="input-group-addon"><i class="fa fa-fw fa-check"></i></span>
</div>
<br>
<!-- Success/Error heads up input -->
<h4>With border indicator</h4>
<div class="form-group has-success">
<label class="control-label" for="inputSuccess"><i class="fa fa-fw fa-check"></i> Input with success</label>
<input class="form-control" id="inputSuccess" placeholder="Enter ..." type="text">
<span class="help-block">Help block with success</span>
</div>
<br />
<div class="form-group has-error">
<label class="control-label" for="inputError"><i class="fa fa-fw fa-times-circle-o"></i> Input with error</label>
<input class="form-control" id="inputError" placeholder="Enter ..." type="text">
<span class="help-block">Help block with error</span>
</div>
<!-- select examples -->
<h4>Select Options</h4>
<div class="form-group">
<label>Select</label>
<select class="form-control">
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
<option>option 4</option>
<option>option 5</option>
</select>
</div>
<br />
<div class="form-group">
<label>Select Multiple</label>
<select multiple="" class="form-control">
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
<option>option 4</option>
<option>option 5</option>
</select>
</div>
<!-- /input-group -->
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</section>
</div>
</template>
<script>
require('moment')
import datepicker from 'vue-date-picker'
export default {
name: 'Settings',
components: { datepicker },
computed: {
datetime () {
return new Date()
}
},
methods: {
clearInput (vueModel) {
vueModel = ''
}
}
}
</script>
<style>
.datetime-picker input {
height: 4em !important;
}
</style>

View File

@ -0,0 +1,239 @@
<template>
<section class="content">
<div class="row center-block">
<h2>Simple</h2>
<div class="col-md-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Striped Full Width Table</h3>
</div>
<!-- /.box-header -->
<div class="box-body no-padding table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<th style="width: 10px">#</th>
<th>Task</th>
<th>Progress</th>
<th style="width: 40px">Label</th>
</tr>
<tr>
<td>1.</td>
<td>Update software</td>
<td><div class="progress progress-xs"><div class="progress-bar progress-bar-danger" style="width: 55%"></div></div></td>
<td><span class="badge bg-red">55%</span></td>
</tr>
<tr>
<td>2.</td>
<td>Clean database</td>
<td>
<div class="progress progress-xs">
<div class="progress-bar progress-bar-yellow" style="width: 70%"></div>
</div>
</td>
<td><span class="badge bg-yellow">70%</span></td>
</tr>
<tr>
<td>3.</td>
<td>Cron job running</td>
<td>
<div class="progress progress-xs progress-striped active">
<div class="progress-bar progress-bar-primary" style="width: 30%"></div>
</div>
</td>
<td><span class="badge bg-light-blue">30%</span></td>
</tr>
<tr>
<td>4.</td>
<td>Fix and squish bugs</td>
<td>
<div class="progress progress-xs progress-striped active">
<div class="progress-bar progress-bar-success" style="width: 90%"></div>
</div>
</td>
<td><span class="badge bg-green">90%</span></td>
</tr>
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
<div class="row center-block">
<h2>Data tables</h2>
<div class="col-md-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Data Table With Full Features</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="dataTables_wrapper form-inline dt-bootstrap" id="example1_wrapper">
<div class="row">
<div class="col-sm-6">
<div id="example1_length" class="dataTables_length">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 table-responsive">
<table aria-describedby="example1_info" role="grid" id="example1" class="table table-bordered table-striped dataTable">
<thead>
<tr role="row">
<th aria-label="Rendering engine: activate to sort column descending" aria-sort="ascending" style="width: 167px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting_asc">Rendering engine</th>
<th aria-label="Browser: activate to sort column ascending" style="width: 207px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Browser</th>
<th aria-label="Platform(s): activate to sort column ascending" style="width: 182px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Platform(s)</th>
<th aria-label="Engine version: activate to sort column ascending" style="width: 142px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">Engine version</th>
<th aria-label="CSS grade: activate to sort column ascending" style="width: 101px;" colspan="1" rowspan="1" aria-controls="example1" tabindex="0" class="sorting">CSS grade</th>
</tr>
</thead>
<tbody>
<tr class="even" role="row">
<td class="sorting_1">Blink</td>
<td>Iridium 54.0</td>
<td>GNU/Linux</td>
<td>54</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 1.5</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 2.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Firefox 3.0</td>
<td>Win 2k+ / OSX.3+</td>
<td>1.9</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.0</td>
<td>OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Camino 1.5</td>
<td>OSX.3+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape 7.2</td>
<td>Win 95+ / Mac OS 8.6-9.2</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Browser 8</td>
<td>Win 98SE+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr class="odd" role="row">
<td class="sorting_1">Gecko</td>
<td>Netscape Navigator 9</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr class="even" role="row">
<td class="sorting_1">Gecko</td>
<td>Mozilla 1.0</td>
<td>Win 95+ / OSX.1+</td>
<td>1</td>
<td>A</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="1" rowspan="1">Rendering engine</th>
<th colspan="1" rowspan="1">Browser</th>
<th colspan="1" rowspan="1">Platform(s)</th>
<th colspan="1" rowspan="1">Engine version</th>
<th colspan="1" rowspan="1">CSS grade</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</div>
</section>
</template>
<script>
import $ from 'jquery'
// Require needed datatables modules
require('datatables.net')
require('datatables.net-bs')
export default {
name: 'Tables',
mounted() {
this.$nextTick(() => {
$('#example1').DataTable()
})
}
}
</script>
<style>
/* Using the bootstrap style, but overriding the font to not draw in
the Glyphicons Halflings font as an additional requirement for sorting icons.
An alternative to the solution active below is to use the jquery style
which uses images, but the color on the images does not match adminlte.
@import url('/static/js/plugins/datatables/jquery.dataTables.min.css');
*/
@import url('/static/js/plugins/datatables/dataTables.bootstrap.css');
table.dataTable thead .sorting:after,
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:after {
font-family: 'FontAwesome';
}
table.dataTable thead .sorting:after {
content: '\f0dc';
}
table.dataTable thead .sorting_asc:after {
content: '\f0dd';
}
table.dataTable thead .sorting_desc:after {
content: '\f0de';
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<section class="content">
<div class="row center-block">
<h1 class="text-center">Tasks</h1>
<ul class="timeline">
<!-- timeline time label -->
<li class="time-label">
<span class="bg-green">{{today}}</span>
</li>
<!-- timeline item -->
<li v-for="line in timeline">
<!-- timeline icon -->
<i v-bind:class="'fa ' + line.icon + ' bg-' + line.color"></i>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i>&nbsp;{{line.time}}</span>
<h3 class="timeline-header">{{line.title}}</h3>
<div class="timeline-body" v-if="line.body" v-html="line.body">
</div>
<div class="timeline-footer" v-if="line.buttons">
<a v-for="btn in line.buttons" v-bind:class="'btn btn-' + btn.type + ' btn-xs'" v-bind:href="btn.href" v-bind:target="btn.target">{{btn.message}}</a>
</div>
</div>
</li>
<!-- END timeline item -->
</ul>
</div>
</section>
</template>
<script>
import moment from 'moment'
import {timeline} from '../../demo'
export default {
name: 'Tasks',
computed: {
today () {
return moment().format('MMM Do YY')
},
timeline () {
return timeline
}
}
}
</script>
<style>
.timeline-footer a.btn {
margin-right: 10px;
}
</style>

View File

@ -0,0 +1,36 @@
<template>
<div :class="['alert', 'alert-' + type, {'alert-dismissible': dismissible}]">
<button v-if="dismissible" type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<h4>
<i :class="['icon', iconClasses]"></i>
<span>{{title}}</span>
</h4>
<span>
<slot></slot>
</span>
</div>
</template>
<script>
export default {
name: 'Alert',
props: {
dismissible: {
type: Boolean,
default: true
},
type: {
type: String,
default: 'info'
},
iconClasses: {
type: Array,
default: []
},
title: {
type: String,
required: true
}
}
}
</script>

View File

@ -0,0 +1,35 @@
<template>
<div class="info-box">
<span :class="['info-box-icon', colorClass]">
<i :class="iconClasses"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">{{text}}</span>
<span class="info-box-number">{{number}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'InfoBox',
props: {
text: {
type: String,
required: true
},
number: {
type: String,
default: ''
},
iconClasses: {
type: Array,
default: []
},
colorClass: {
type: String,
default: 'bg-default'
}
}
}
</script>

View File

@ -0,0 +1,50 @@
<template>
<div :class="['info-box', colorClass]">
<span class="info-box-icon">
<i :class="iconClasses"></i>
</span>
<div class="info-box-content">
<span class="info-box-text">{{text}}</span>
<span class="info-box-number">{{number}}</span>
<div class="progress">
<div class="progress-bar" :style="{width: progress + '%'}"></div>
</div>
<span class="progress-description">{{description}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'InfoBox',
props: {
text: {
type: String,
required: true
},
number: {
type: String,
default: ''
},
progress: {
type: Number,
default: 0,
validator(value) {
return value >= 0 && value <= 100
}
},
description: {
type: String,
default: ''
},
iconClasses: {
type: Array,
default: []
},
colorClass: {
type: String,
default: 'bg-default'
}
}
}
</script>

5
src/config/index.js Normal file
View File

@ -0,0 +1,5 @@
export default {
serverURI: '',
fixedLayout: false,
hideLogoOnMobile: false
}

71
src/demo.js Normal file
View File

@ -0,0 +1,71 @@
import moment from 'moment'
export const servers = [{
name: 'www01',
status: 'success',
icon: 'globe',
description: 'Web server that runs our sites'
}, {
name: 'sql01',
status: 'danger',
icon: 'database',
description: 'mySQL server used for reporting'
}, {
name: 'mongoDB01',
status: 'info',
icon: 'file-code-o',
description: 'Main DB server'
}, {
name: 'ldap01',
status: 'success',
icon: 'key',
description: 'Authentication server'
}, {
name: 'mgmt01',
status: 'success',
icon: 'home',
description: 'Management server with all tools'
}, {
name: 'bkup01',
status: 'warning',
icon: 'backward',
description: 'Backup server'
}]
export const stats = [{
header: '8390',
text: 'Visitors'
}, {
header: '30%',
text: 'Referrals'
}, {
header: '70%',
text: 'Organic'
}]
export const timeline = [{
icon: 'fa-envelope',
color: 'blue',
title: 'Write short novel',
time: moment().endOf('day').fromNow(),
body: 'Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles, weebly ning heekya handango imeem plugg dopplr jibjab, movity jajah plickers sifteo edmodo ifttt zimbra. Babblely odeo kaboodle quora plaxo ideeli hulu weebly balihoo...',
buttons: [{
type: 'primary',
message: 'Read more',
href: 'https://github.com/misterGF/CoPilot',
target: '_blank'
}]
},
{
icon: 'fa-user',
color: 'yellow',
title: 'Sarah Young accepted your friend request',
time: moment('20150620', 'MMM Do YY').fromNow()
},
{
icon: 'fa-camera',
color: 'purple',
title: 'Watch a youTube video',
time: moment('20130620', 'YYYYMMDD').fromNow(),
body: '<div class="embed-responsive embed-responsive-16by9"><iframe width="560" height="315" src="https://www.youtube.com/embed/8aGhZQkoFbQ" frameborder="0" allowfullscreen></iframe></div>'
}]

23
src/filters/index.js Normal file
View File

@ -0,0 +1,23 @@
const urlParser = document.createElement('a')
export function domain (url) {
urlParser.href = url
return urlParser.hostname
}
export function count (arr) {
return arr.length
}
export function prettyDate (date) {
var a = new Date(date)
return a.toDateString()
}
export function pluralize (time, label) {
if (time === 1) {
return time + label
}
return time + label + 's'
}

78
src/main.js Normal file
View File

@ -0,0 +1,78 @@
// Import ES6 Promise
import 'es6-promise/auto'
// Import System requirements
import Vue from 'vue'
import VueRouter from 'vue-router'
import { sync } from 'vuex-router-sync'
import routes from './routes'
import store from './store'
// Import Helpers for filters
import { domain, count, prettyDate, pluralize } from './filters'
// Import Views - Top level
import AppView from './components/App.vue'
// Import Install and register helper items
Vue.filter('count', count)
Vue.filter('domain', domain)
Vue.filter('prettyDate', prettyDate)
Vue.filter('pluralize', pluralize)
Vue.use(VueRouter)
// Routing logic
var router = new VueRouter({
routes: routes,
mode: 'history',
linkExactActiveClass: 'active',
scrollBehavior: function(to, from, savedPosition) {
return savedPosition || { x: 0, y: 0 }
}
})
// Some middleware to help us ensure the user is authenticated.
router.beforeEach((to, from, next) => {
if (
to.matched.some(record => record.meta.requiresAuth) &&
(!router.app.$store.state.token || router.app.$store.state.token === 'null')
) {
// this route requires auth, check if logged in
// if not, redirect to login page.
window.console.log('Not authenticated')
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
})
sync(store, router)
// Check local storage to handle refreshes
if (window.localStorage) {
var localUserString = window.localStorage.getItem('user') || 'null'
var localUser = JSON.parse(localUserString)
if (localUser && store.state.user !== localUser) {
store.commit('SET_USER', localUser)
store.commit('SET_TOKEN', window.localStorage.getItem('token'))
}
}
// Start out app!
// eslint-disable-next-line no-new
new Vue({
el: '#root',
router: router,
store: store,
render: h => h(AppView)
})
// change this. demo
window.bugsnagClient = window.bugsnag('02fe1c2caaf5874c50b6ee19534f5932')
window.bugsnagClient.use(window.bugsnag__vue(Vue))

77
src/routes.js Normal file
View File

@ -0,0 +1,77 @@
import DashView from './components/Dash.vue'
import LoginView from './components/Login.vue'
import NotFoundView from './components/404.vue'
// Import Views - Dash
import DashboardView from './components/views/Dashboard.vue'
import TablesView from './components/views/Tables.vue'
import TasksView from './components/views/Tasks.vue'
import SettingView from './components/views/Setting.vue'
import AccessView from './components/views/Access.vue'
import ServerView from './components/views/Server.vue'
import CryptosView from './components/views/Cryptos.vue'
import PersonalFinancesView from './components/views/PersonalFinances.vue'
// Routes
const routes = [
{
path: '/login',
component: LoginView
},
{
path: '/',
component: DashView,
children: [
{
path: 'personalfinances',
alias: '',
component: PersonalFinancesView,
name: 'Personal Finances',
meta: {description: 'Overview of environment'}
},
{
path: 'dashboard',
alias: '',
component: DashboardView,
name: 'Dashboard',
meta: {description: 'Overview of environment'}
}, {
path: 'tables',
component: TablesView,
name: 'Tables',
meta: {description: 'Simple and advance table in CoPilot'}
}, {
path: 'tasks',
component: TasksView,
name: 'Tasks',
meta: {description: 'Tasks page in the form of a timeline'}
}, {
path: 'setting',
component: SettingView,
name: 'Settings',
meta: {description: 'User settings page'}
}, {
path: 'access',
component: AccessView,
name: 'Access',
meta: {description: 'Example of using maps'}
}, {
path: 'server',
component: ServerView,
name: 'Servers',
meta: {description: 'List of our servers', requiresAuth: true}
}, {
path: 'cryptos',
component: CryptosView,
name: 'Cryptos',
meta: {description: 'List of popular javascript repos'}
}
]
}, {
// not found handler
path: '*',
component: NotFoundView
}
]
export default routes

1
src/store/actions.js Normal file
View File

@ -0,0 +1 @@
export default {}

13
src/store/index.js Normal file
View File

@ -0,0 +1,13 @@
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import actions from './actions'
import mutations from './mutations'
Vue.use(Vuex)
export default new Vuex.Store({
state,
actions,
mutations
})

14
src/store/mutations.js Normal file
View File

@ -0,0 +1,14 @@
export default {
TOGGLE_LOADING (state) {
state.callingAPI = !state.callingAPI
},
TOGGLE_SEARCHING (state) {
state.searching = (state.searching === '') ? 'loading' : ''
},
SET_USER (state, user) {
state.user = user
},
SET_TOKEN (state, token) {
state.token = token
}
}

55
src/store/state.js Normal file
View File

@ -0,0 +1,55 @@
export default {
callingAPI: false,
searching: '',
serverURI: 'http://10.110.1.136:8080',
user: null,
token: null,
userInfo: {
messages: [
{
id: 1,
title: 'Support Team',
body: 'Why not consider this a test message?',
createdAt: '17 min ago'
}
],
notifications: [
{
id: 1,
title: 'Birthday Reminder',
body: 'Today is Brians birthday.',
createdAt: 'just now',
readAt: null
},
{
id: 2,
title: 'Bank Holiday in London',
body: 'Our office in London has a bank holiday today. Do not expect them to answer the phone.',
createdAt: '4 hours ago',
readAt: null
},
{
id: 3,
title: 'Birthday Reminder',
body: 'Today is Christians birthday.',
createdAt: '27 days ago',
readAt: '2018-08-12 00:00:00'
},
{
id: 4,
title: 'Birthday Reminder',
body: 'Today is Tanjas birthday.',
createdAt: '29 days ago',
readAt: '2018-08-12 00:00:00'
},
{
id: 5,
title: 'Sales Bonus received',
body: 'You received your monthly sales bonus of 3%. This month you made $2,700 extra!',
createdAt: '7 hours ago',
readAt: null
}
],
tasks: []
}
}