initialize project
This commit is contained in:
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
require('./bootstrap.js');
|
||||
|
||||
import VueRouter from 'vue-router';
|
||||
import Util from './util.js';
|
||||
import routes from './routes.js';
|
||||
|
||||
Vue.use(VueRouter);
|
||||
Vue.mixin(Util);
|
||||
|
||||
const router = new VueRouter({
|
||||
linkActiveClass: 'active',
|
||||
routes
|
||||
});
|
||||
|
||||
const app = new Vue({
|
||||
router
|
||||
}).$mount('#app');
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
require('./bootstrap.js');
|
||||
//window.VueRouter = require('vue-router').default;
|
||||
//import VueRouter from 'vue-router';
|
||||
import Util from './util.js';
|
||||
import routes from './routesIndex.js';
|
||||
|
||||
|
||||
Vue.use(VueRouter);
|
||||
Vue.mixin(Util);
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
linkActiveClass: 'active',
|
||||
routes
|
||||
});
|
||||
|
||||
const app = new Vue({
|
||||
router
|
||||
}).$mount('#app');
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
// window.$ = window.jQuery = require('jquery'); //Library for dom Manipulation
|
||||
|
||||
|
||||
//require('bootstrap-sass'); //Bootstrap for design
|
||||
|
||||
|
||||
// Axios - Ajax Library
|
||||
//window.axios = require('axios');
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
|
||||
// window.Vue = require('vue'); // JS Framework
|
||||
|
||||
|
||||
// require('bootstrap-notify'); //Notify
|
||||
|
||||
|
||||
// require('jquery-form'); //Alternative to Axios
|
||||
|
||||
|
||||
require('./customComponents.js'); // My components
|
||||
|
||||
//Pie Chart for Vote Result
|
||||
// require('jquery-flot');
|
||||
// require('../../../node_modules/jquery-flot/jquery.flot.pie.js');
|
||||
|
||||
|
||||
//Date and Time Management
|
||||
// window.moment = require('moment');
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Example Component</div>
|
||||
|
||||
<div class="panel-body">
|
||||
I'm an example component!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
console.log('Component mounted.')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<nav class="nav navbar-default navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="">Voting System</a>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="myNavbar">
|
||||
<ul class="nav navbar-nav">
|
||||
<router-link :to="{name: 'Admin Home'}" tag="li" exact>
|
||||
<a href="#"><span class="fa fa-home"></span></a>
|
||||
</router-link>
|
||||
<router-link :to="{name: 'Manage Position'}" tag="li">
|
||||
<a href="#">Manage Position</a>
|
||||
</router-link>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
created: function () {
|
||||
if (!this.util.isLogin())
|
||||
return this.$router.push({name: 'Admin Login'});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.navbar-default {
|
||||
box-shadow: 0 1px 10px rgba(0,0,0,.5);
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
color: #000000;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
margin-top: 70px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="col-md-5 col-md-offset-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Admin Login</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form @submit.prevent="login" id="login_form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">E-mail</label>
|
||||
<input type="email" name="email" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" class="form-control" id="password" required/>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="visibility"
|
||||
onclick=" $(this)[0].checked ?
|
||||
$('#password').attr('type','text'):
|
||||
$('#password').attr('type','password')"/> Show Password
|
||||
</label>
|
||||
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="submit"
|
||||
class="btn btn-primary form-control"
|
||||
:class="{'disabled': loading.isLoading}"
|
||||
:value="loading.value"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
loading: {
|
||||
value: 'Login',
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (this.util.isLogin())
|
||||
return this.$router.push('Admin Home')
|
||||
this.util.setTitle('Admin Login');
|
||||
},
|
||||
|
||||
methods: {
|
||||
login: function () {
|
||||
if (this.loading.isLoading) return;
|
||||
|
||||
let vm = this;
|
||||
|
||||
this.startLoading();
|
||||
|
||||
axios.post('api/v1/admin/login', $('#login_form').serialize())
|
||||
.then(response => {
|
||||
vm.stopLoading();
|
||||
if (this.util.showResult(response, 'success')) {
|
||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||
localStorage['User'] = JSON.stringify(response.data.user);
|
||||
window.axios.defaults.headers.common['Authorization'] = localStorage['Access Token'];
|
||||
vm.$router.push({name: 'Admin Home'});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
vm.stopLoading();
|
||||
this.util.showResult(error, 'error');
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
startLoading: function () {
|
||||
this.util.notify('Logging in', 'loading');
|
||||
this.loading = {
|
||||
value: 'Loading...',
|
||||
isLoading: true
|
||||
}
|
||||
},
|
||||
|
||||
stopLoading: function () {
|
||||
$.notifyClose();
|
||||
this.loading = {
|
||||
value: 'Login',
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 50px 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><b>Add Position</b></h3>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="name">Position</label>
|
||||
<input type="text" name="name" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="button" value="Submit" class="btn btn-info"/>
|
||||
<input type="reset" value="Reset" class="btn btn-default"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<datatable v-bind="data" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: () => ({
|
||||
yyy : [
|
||||
{id: 1, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 2, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 3, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 4, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 5, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 6, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 7, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 8, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 9, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 10, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 11, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 12, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 13, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 14, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 15, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 16, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 17, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'},
|
||||
{id: 18, name: 'Sample Data', x: 'Sample Data', btn: '<button @click="log" class="btn btn-info">Click me</button>'}
|
||||
],
|
||||
|
||||
data: {
|
||||
columns: [
|
||||
{title:'ID', field: 'id'},
|
||||
{title:'name', field: 'name'},
|
||||
{title:'x', field:'x'},
|
||||
{title:'', field:'btn', html: true}
|
||||
],
|
||||
data: [],
|
||||
|
||||
total: 0,
|
||||
|
||||
query: {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
sort: '',
|
||||
order: ''
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
created: function () {
|
||||
console.log(this);
|
||||
},
|
||||
|
||||
watch : {
|
||||
'data.query': {
|
||||
handler (query) {
|
||||
this.data.data = this.xxx;
|
||||
this.data.total = this.yyy.length;
|
||||
},
|
||||
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
xxx : function () {
|
||||
var offset = this.data.query.offset; //0
|
||||
var limit = this.data.query.limit; //10
|
||||
return this.yyy.slice(offset, offset+limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<form id="add_form" @submit.prevent="add()">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" name="email" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirm_password">Confirm Password</label>
|
||||
<input type="password" name="confirm_password" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-info"/>
|
||||
<router-link :to="{name: 'Manage Account'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: () => ({
|
||||
loading: false
|
||||
}),
|
||||
|
||||
methods:{
|
||||
add: function () {
|
||||
if (this.loading || !this.isPasswordMatch()) return;
|
||||
var vm = this;
|
||||
this.loading = true;
|
||||
this.util.notify('Adding Admin', 'loading');
|
||||
axios.post(config.API+'admin', $('#add_form').serialize())
|
||||
.then(response=>{
|
||||
vm.loading = false;
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name: 'Manage Account'});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
vm.loading = false;
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error')
|
||||
})
|
||||
},
|
||||
|
||||
isPasswordMatch: function () {
|
||||
var isMatch = $('[name=password]').val() == $('[name=confirm_password]').val();
|
||||
if (!isMatch) this.util.notify('Password not match', 'error');
|
||||
return isMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Manage Account</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Account');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Update Account</h4>
|
||||
<form @submit.prevent="edit()" id="edit_form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" :value="data.user.name" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">E-mail</label>
|
||||
<input type="email" name="email" class="form-control" :value="data.user.email" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-info"/>
|
||||
<router-link :to="{name: 'Update Password'}" class="btn btn-default">Change Password</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods:{
|
||||
refreshUser: function () {
|
||||
var vm = this;
|
||||
axios.get(config.API+'admin/'+this.data.user.id)
|
||||
.then(response=>{
|
||||
vm.data.user = response.data;
|
||||
})
|
||||
},
|
||||
|
||||
edit: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Updating account', 'loading');
|
||||
axios.put(config.API+'admin/'+this.data.user.id, $('#edit_form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.refreshUser();
|
||||
vm.$router.push({name:'Admin Home'});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error, 'error')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body table-responsive">
|
||||
|
||||
<div class="form-group">
|
||||
<router-link :to="{name: 'Add Account'}" class="btn btn-success">
|
||||
<i class="fa fa-plus"></i> Add Account</router-link>
|
||||
<button class="btn btn-default" @click="refreshAdmin()">
|
||||
<i class="fa fa-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="admin in data.admins">
|
||||
<td>{{ admin.id }}</td>
|
||||
<td>{{ admin.name }}</td>
|
||||
<td>{{ admin.email }}</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" @click="id=admin.id;util.showModal('#delete-admin-modal')">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<modal id="delete-admin-modal">
|
||||
<modal-header>Delete Admin</modal-header>
|
||||
<modal-body>
|
||||
<h3>Are you sure to delete this admin?</h3>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button @click="deleteAdmin()" class="btn btn-danger">Delete</button>
|
||||
<button @click="util.hideModal('#delete-admin-modal')" class="btn btn-default">Cancel</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
data: () => ({
|
||||
id:0
|
||||
}),
|
||||
|
||||
created: function () {
|
||||
this.refreshAdmin();
|
||||
},
|
||||
|
||||
methods: {
|
||||
deleteAdmin: function () {
|
||||
this.util.hideModal('#delete-admin-modal');
|
||||
this.util.notify('Deleting admin', 'loading');
|
||||
var vm = this;
|
||||
axios.delete(config.API+'admin/'+this.id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success'))
|
||||
vm.refreshAdmin();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
refreshAdmin: function () {
|
||||
this.util.notify('Refreshing admin', 'loading');
|
||||
var vm = this;
|
||||
axios.get(config.API+'admin')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (response.data.status == 'failed')
|
||||
vm.util.showResult(response, 'success');
|
||||
else
|
||||
vm.data.admins = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Update Password</h4>
|
||||
<form @submit.prevent="edit()" id="edit_form">
|
||||
<div class="form-group">
|
||||
<label for="old_password">Old Password</label>
|
||||
<input type="password" name="old_password" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">New Password</label>
|
||||
<input type="password" name="password" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirm_password">Confirm Password</label>
|
||||
<input type="password" name="confirm_password" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-info"/>
|
||||
<router-link :to="{name: 'Update Account'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit: function () {
|
||||
if (this.loading || !this.checkPassword()) return;
|
||||
var vm = this;
|
||||
vm.loading = true;
|
||||
vm.util.notify('Updating Password', 'loading');
|
||||
axios.put(config.API+'admin/password/'+this.data.user.id, $('#edit_form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(response, 'success');
|
||||
vm.$router.push({name:'Admin Home'});
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
checkPassword: function () {
|
||||
var isMatch = $("[name=password]").val() == $("[name=confirm_password]").val();
|
||||
if (!isMatch) {
|
||||
this.util.notify('Password not match', 'error');
|
||||
}
|
||||
return isMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div v-for="position in positions">
|
||||
<h5>{{ position.name }}</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="10%">Student ID</th>
|
||||
<th width="30%">Name</th>
|
||||
<th width="20%">Partylist</th>
|
||||
<th width="20%">Course</th>
|
||||
<th width="20%">Votes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="result in results" v-if="result.position_id==position.id">
|
||||
<td>{{ getNominee(result.nominee_id)['student_id'] }}</td>
|
||||
<td>{{ getNominee(result.nominee_id)['name'] }}</td>
|
||||
<td>{{ getPartylist(getNominee(result.nominee_id)['partylist_id']) }}</td>
|
||||
<td>{{ getNominee(result.nominee_id)['course'] }}</td>
|
||||
<td>{{ result.votes}}</td>
|
||||
</tr>
|
||||
<tr v-for="no_vote in no_votes" v-if="no_vote.position_id==position.id">
|
||||
<td>{{ no_vote.student_id }}</td>
|
||||
<td>{{ no_vote.name }}</td>
|
||||
<td>{{ getPartylist(no_vote.partylist_id) }}</td>
|
||||
<td>{{ no_vote.course }}</td>
|
||||
<td>0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function() {
|
||||
return {
|
||||
nominees: [],
|
||||
results: [],
|
||||
partylists: [],
|
||||
positions: []
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getNominee: function (id) {
|
||||
let nominees = this.nominees;
|
||||
for (var i in nominees)
|
||||
if (id == nominees[i]['id'])
|
||||
return nominees[i];
|
||||
return {};
|
||||
},
|
||||
|
||||
getPartylist: function (id) {
|
||||
let partylists = this.partylists;
|
||||
for (var i in partylists)
|
||||
if (id == partylists[i]['id'])
|
||||
return partylists[i]['name'];
|
||||
return 'No Partylist';
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
this.util.notify('Loading please wait...', 'loading');
|
||||
var vm = this;
|
||||
axios.get(config.API+'election/result/'+this.election_id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.nominees = response.data.nominee;
|
||||
vm.results = response.data.result;
|
||||
vm.partylists = response.data.partylist;
|
||||
vm.positions = response.data.position;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
computed: {
|
||||
election_id: function () {
|
||||
return this.$route.params.election_id;
|
||||
},
|
||||
|
||||
no_votes: function () {
|
||||
let nominees = this.nominees;
|
||||
let results = this.results;
|
||||
let no_votes = [];
|
||||
for (var i in nominees) {
|
||||
var hasvote = false;
|
||||
for (var y in results) {
|
||||
if (results[y]['nominee_id'] == nominees[i]['id'])
|
||||
hasvote = true;
|
||||
}
|
||||
if (!hasvote)
|
||||
no_votes.push(nominees[i]);
|
||||
}
|
||||
return no_votes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Manage Election</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Election');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4> Recent Elections</h4>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-success" v-if="data.election.status == 1" @click="util.showModal('#start-election-modal')">Start Election</button>
|
||||
|
||||
<router-link :to="{name: 'Current Result'}" class="btn btn-info" v-if="data.election.status == 2">
|
||||
View Results
|
||||
</router-link>
|
||||
|
||||
<button class="btn btn-danger" v-if="data.election.status == 2" @click="util.showModal('#stop-election-modal')">End Election</button>
|
||||
|
||||
<label v-if="data.election.status == 2">Election has Started {{ start_date }}</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Election Name</th>
|
||||
<th>Election Start</th>
|
||||
<th>Election End</th>
|
||||
<th>View</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="election in data.elections">
|
||||
<td>{{ election.id }}</td>
|
||||
<td>{{ election.name }}</td>
|
||||
<td>{{ election.start}}</td>
|
||||
<td>{{ election.end}}</td>
|
||||
<td>
|
||||
<router-link :to="{name: 'Election Result', params:{election_id:election.id}}" class="btn btn-info">View Result</router-link></td>
|
||||
</tr>
|
||||
<tr v-if="data.elections.length < 1">
|
||||
<td colspan="5">No elections yet</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="start" id="start_form">
|
||||
<modal id="start-election-modal">
|
||||
<modal-header>Start Election</modal-header>
|
||||
<modal-body>
|
||||
<div class="form-group">
|
||||
<label for="name">Election Name</label>
|
||||
<input type="text" name="name" class="form-control" placeholder="(Optional)"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Confirm Password</label>
|
||||
<input type="password" name="password" class="form-control" required/>
|
||||
</div>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<input type="submit" class="btn btn-info" value="Start"/>
|
||||
<input type="button" data-dismiss="modal" class="btn btn-default" value="Cancel"/>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
</form>
|
||||
|
||||
<form @submit.prevent="stop" id="stop_form">
|
||||
<modal id="stop-election-modal">
|
||||
<modal-header>Stop Election</modal-header>
|
||||
<modal-body>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Election Name</label>
|
||||
<input type="text" name="name" :value="data.election.name" class="form-control" placeholder="(Optional)"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Confirm Password</label>
|
||||
<input type="password" name="password" class="form-control" required/>
|
||||
</div>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<input type="submit" class="btn btn-danger" value="Stop Election"/>
|
||||
<input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel"/>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: ()=>({
|
||||
start_date: null
|
||||
}),
|
||||
created: function () {
|
||||
this.refreshElection();
|
||||
var vm = this;
|
||||
setInterval(()=>{
|
||||
vm.start_date = moment(vm.data.election.start).fromNow();
|
||||
},1000);
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
stop: function () {
|
||||
var vm = this;
|
||||
this.util.hideModal('#stop-election-modal');
|
||||
this.util.notify('Stopping Election', 'loading');
|
||||
axios.post(config.API+'election/stop', $('#stop_form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response,'success')) {
|
||||
vm.refreshElection();
|
||||
vm.data.election =response.data.election;
|
||||
vm.data.positions = [];
|
||||
vm.data.partylists = [];
|
||||
vm.data.voters = [];
|
||||
vm.data.nominees = [];
|
||||
vm.data.results = [];
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var vm = this;
|
||||
this.util.hideModal('#start-election-modal');
|
||||
this.util.notify('Loading please wait', 'loading');
|
||||
axios.post(config.API+'election/start', $('#start_form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if(vm.util.showResult(response, 'success')){
|
||||
vm.refreshElection();
|
||||
vm.data.election = response.data.election;
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
refreshElection: function(){
|
||||
this.util.notify('Refreshing Election', 'loading');
|
||||
var vm = this;
|
||||
axios.get(config.API+'election')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.data.elections = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h4>Positions</h4><hr/>
|
||||
<ul class="list-group">
|
||||
<router-link :key="position.id" v-for="position in data.positions" class="list-group-item" :class="{'active':position.id==position_id}" tag="li" :to="{query:{position_id:position.id}}" exact replace>
|
||||
{{ position.name }}
|
||||
</router-link>
|
||||
<li class="list-group-item">
|
||||
<center>
|
||||
<button class="btn btn-info" @click="refreshNominees()">
|
||||
Refresh results <i class="fa fa-refresh"></i>
|
||||
</button>
|
||||
</center>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h4>Results</h4><hr/>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">{{ getPosition(position_id) }} - Results as of : {{ last_update }}</div>
|
||||
<div class="panel-body">
|
||||
<div id="chart" style="height: 300px; width: 300px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
created: function () {
|
||||
console.log(this)
|
||||
this.refreshNominees();
|
||||
this.$nextTick(function(){
|
||||
this.initChart();
|
||||
});
|
||||
},
|
||||
|
||||
watch: {
|
||||
position_id : function () {
|
||||
this.initChart();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
refreshNominees: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing results', 'loading');
|
||||
axios.get(config.API+'nominee')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.data.nominees = response.data;
|
||||
vm.refreshResults();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
refreshResults: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing results', 'loading');
|
||||
axios.get(config.API+'election/results')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.data.results = response.data;
|
||||
vm.data.last_update= new Date();
|
||||
vm.initChart();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
initChart: function () {
|
||||
$.plot($('#chart'), this.datas, {
|
||||
series: {
|
||||
pie: {
|
||||
show: true,
|
||||
innerRadius: 0.5
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getPosition: function (id) {
|
||||
let positions = this.data.positions;
|
||||
for (var i in positions)
|
||||
if (id == positions[i]['id']) return positions[i]['name'];
|
||||
return '';
|
||||
},
|
||||
|
||||
getNominee: function (id) {
|
||||
let nominees = this.data.nominees;
|
||||
for (var i in nominees)
|
||||
if (id == nominees[i]['id']) return nominees[i]['name'];
|
||||
return '';
|
||||
},
|
||||
|
||||
getVotes: function (id) {
|
||||
let results = this.data.results;
|
||||
for (var i in results) {
|
||||
if (results[i]['nominee_id'] == id) return results[i]['votes'];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
last_update: function () {
|
||||
let x = this.data.last_update;
|
||||
return x.toDateString() +' '+x.toLocaleTimeString();
|
||||
},
|
||||
|
||||
position_id: function () {
|
||||
return this.$route.query.position_id ?
|
||||
this.$route.query.position_id :
|
||||
this.data.positions[0]['id'];
|
||||
},
|
||||
|
||||
datas: function () {
|
||||
//var results =
|
||||
var data = [];
|
||||
var nominees = this.data.nominees;
|
||||
for (var i in nominees) {
|
||||
if (nominees[i]['position_id']== this.position_id){
|
||||
let row = [];
|
||||
row['label'] = nominees[i]['name'];
|
||||
row['data'] = [[1, this.getVotes(nominees[i]['id'])]];
|
||||
data.push(row);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="!loading">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" id="nav">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" :href="data.baseURL" >Voting System</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="myNavbar">
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<router-link :to="{name: 'Admin Home'}" tag="li" exact><a href="#">Home</a></router-link>
|
||||
|
||||
<router-link :to="{name: 'Manage Position'}" tag="li">
|
||||
<a href="#">Jawatan</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Manage Partylist'}" tag="li">
|
||||
<a href="#">Manage Partylist</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Manage Voter'}" tag="li">
|
||||
<a href="#">Ahli Koperasi</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Manage Nominee'}" tag="li">
|
||||
<a href="#">Calon</a>
|
||||
</router-link>
|
||||
|
||||
</ul>
|
||||
<ul class="nav navbar-right navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a
|
||||
href="#"
|
||||
class="dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
role="button" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="fa fa-user"></span> {{ data.user.name }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<router-link :to="{name:'Update Account'}" tag="li" exact>
|
||||
<a href="#">Update Account</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Manage Account'}" tag="li" v-if="data.user.id==1">
|
||||
<a href="#">Manage Account</a>
|
||||
</router-link>
|
||||
|
||||
<li @click="logout()"><a>Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<div v-if="loading" class="container">
|
||||
<div class="jumbotron">
|
||||
<h1>Loading <i class="fa fa-refresh fa-spin"></i></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
data: () =>({
|
||||
loading: true
|
||||
}),
|
||||
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Administrator');
|
||||
var vm = this;
|
||||
if (this.util.isLogin()) {
|
||||
this.util.setAuthorization();
|
||||
axios.get(config.API+'admin/information')
|
||||
.then(response=>{
|
||||
console.log(response);
|
||||
vm.data.user = response.data.user;
|
||||
vm.data.election = response.data.election;
|
||||
vm.data.partylists = response.data.partylist;
|
||||
vm.data.positions = response.data.position;
|
||||
vm.loading = false;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
if (this.util.showResult(error) == 401) {
|
||||
vm.logout();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$router.push({name:'Admin Login'});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
logout: function () {
|
||||
localStorage.clear();
|
||||
this.$router.push({name: 'Admin Login'});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body{
|
||||
padding: 70px 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div class="col-md-5 col-md-offset-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Admin Login</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form @submit.prevent="login" id="login_form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">E-mail</label>
|
||||
<input type="email" name="email" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" class="form-control" id="password" required/>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="visibility"
|
||||
onclick=" $(this)[0].checked ?
|
||||
$('#password').attr('type','text'):
|
||||
$('#password').attr('type','password')"/> Show Password
|
||||
</label>
|
||||
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="submit"
|
||||
class="btn btn-primary form-control"
|
||||
:class="{'disabled': loading.isLoading}"
|
||||
:value="loading.value"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
loading: {
|
||||
value: 'Login',
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (this.util.isLogin())
|
||||
return this.$router.push({name:'Admin Home'})
|
||||
this.util.setTitle('Admin Login');
|
||||
},
|
||||
|
||||
methods: {
|
||||
login: function () {
|
||||
if (this.loading.isLoading) return;
|
||||
|
||||
let vm = this;
|
||||
|
||||
this.startLoading();
|
||||
|
||||
axios.post(config.API+'admin/login', $('#login_form').serialize())
|
||||
.then(response => {
|
||||
vm.stopLoading();
|
||||
if (this.util.showResult(response, 'success')) {
|
||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||
this.util.setAuthorization();
|
||||
vm.$router.push({name: 'Admin Home'});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
vm.stopLoading();
|
||||
this.util.showResult(error, 'error');
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
startLoading: function () {
|
||||
this.util.notify('Logging in', 'loading');
|
||||
this.loading = {
|
||||
value: 'Loading...',
|
||||
isLoading: true
|
||||
}
|
||||
},
|
||||
|
||||
stopLoading: function () {
|
||||
$.notifyClose();
|
||||
this.loading = {
|
||||
value: 'Login',
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 50px 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<form
|
||||
class="row"
|
||||
method="POST"
|
||||
id="add_form"
|
||||
:action="data.API+'nominee'"
|
||||
enctype="mutlipart/formdata"
|
||||
@submit.prevent="add()">
|
||||
<div class="col-md-4">
|
||||
<uploader file-name="image" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="student_id">Student ID</label>
|
||||
<input type="text" name="student_id" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="course">Course</label>
|
||||
<input type="text" name="course" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="motto">Motto</label>
|
||||
<input type="text" name="motto" class="form-control" placeholder="(Optional)" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea name="description" class="form-control" placeholder="(Optional)"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="position_id">Position</label>
|
||||
<select class="form-control" v-model="position_id" name="position_id" required>
|
||||
<option value="0" disabled>--- Select Position ---</option>
|
||||
<option v-for="position in data.positions" :value="position.id">{{ position.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="partylist_id">Partylist</label>
|
||||
<select class="form-control" name="partylist_id">
|
||||
<option value="">--- Select Partylist (Optional) ---</option>
|
||||
<option v-for="partylist in data.partylists" :value="partylist.id">{{ partylist.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group pull-right">
|
||||
<input type="submit" value="Submit" class="btn btn-info">
|
||||
<router-link
|
||||
:to="{name:'Manage Nominee', query:{position_id:position_id}}"
|
||||
class="btn btn-default">
|
||||
Submit
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add: function () {
|
||||
if (this.loading) return;
|
||||
var vm = this;
|
||||
this.loading = true;
|
||||
this.util.notify('Adding Nominee', 'progress', 0);
|
||||
$('#add_form').ajaxSubmit({
|
||||
success: function (response) {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success', 'ajax'))
|
||||
vm.$router.push({name: 'Manage Nominee'});
|
||||
},
|
||||
error: function (error) {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error, 'error', 'ajax');
|
||||
},
|
||||
uploadProgress: function (a, b, c, progress) {
|
||||
vm.util.notify('Adding Nominee', 'progress', progress);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
position_id: {
|
||||
get: function () {
|
||||
return this.$route.query.position_id;
|
||||
},
|
||||
|
||||
set: function (id) {
|
||||
this.$router.replace({query: {position_id: id}});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<form
|
||||
method="POST"
|
||||
class="row"
|
||||
id="edit_form"
|
||||
:action="data.API+'nominee/'+id"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="edit()">
|
||||
<input type="hidden" name="_method" value="PUT"/>
|
||||
|
||||
<div class="col-md-4">
|
||||
<uploader file-name="image" :image-src="data.storageURL+nominee.image"/>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" :value="nominee.name" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="student_id">Student ID</label>
|
||||
<input type="text" name="student_id" class="form-control" :value="nominee.student_id" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="course">Course</label>
|
||||
<input type="text" name="course" class="form-control" :value="nominee.course" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="motto">Motto</label>
|
||||
<input type="text" name="motto" class="form-control" :value="nominee.motto" placeholder="(Optional)" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea name="description" class="form-control" placeholder="(Optional)">{{ nominee.description}}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="position_id">Position</label>
|
||||
<select class="form-control" name="position_id" :value="nominee.position_id" required>
|
||||
<option value="0" disabled>--- Select Position ---</option>
|
||||
<option v-for="position in data.positions" :value="position.id">{{ position.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="partylist_id">Partylist</label>
|
||||
<select class="form-control" name="partylist_id" :value="nominee.partylist_id">
|
||||
<option value="">--- Select Partylist (Optional) ---</option>
|
||||
<option v-for="partylist in data.partylists" :value="partylist.id">{{ partylist.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group pull-right">
|
||||
<input type="submit" value="Submit" class="btn btn-info">
|
||||
<router-link
|
||||
:to="{name:'Manage Nominee'}"
|
||||
class="btn btn-default">
|
||||
Back
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (!this.nominee.id)
|
||||
this.$router.push({name:'Manage Nominee'});
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit: function () {
|
||||
if (this.loading) return;
|
||||
var vm = this;
|
||||
this.loading = true;
|
||||
this.util.notify('Updating nominee', 'progress', 0);
|
||||
$('#edit_form').ajaxSubmit({
|
||||
success: function (response) {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success', 'ajax'))
|
||||
vm.$router.push({name: 'Manage Nominee'});
|
||||
},
|
||||
error: function (error) {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error, 'error', 'ajax');
|
||||
},
|
||||
uploadProgress: function (a, b, c, progress) {
|
||||
vm.util.notify('Updating Nominee', 'progress', progress);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
id: function () {
|
||||
return this.$route.params.id;
|
||||
},
|
||||
|
||||
nominee: function () {
|
||||
for (var i in this.data.nominees)
|
||||
if(this.data.nominees[i].id == this.id)
|
||||
return this.data.nominees[i];
|
||||
return {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-3" style="max-width: 250px;">
|
||||
<ul class="list-group">
|
||||
<router-link
|
||||
tag="li"
|
||||
class="list-group-item"
|
||||
:to="{name: 'Manage Nominee'}"
|
||||
exact
|
||||
replace
|
||||
:class="{'active':position_id==0}">
|
||||
All Position
|
||||
</router-link>
|
||||
<router-link
|
||||
v-for="position in data.positions"
|
||||
:key="position.id"
|
||||
tag="li"
|
||||
class="list-group-item"
|
||||
:to="{query: {position_id:position.id}}"
|
||||
exact
|
||||
replace>
|
||||
{{ position.name }}
|
||||
</router-link>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-9 panel panel-default">
|
||||
<div class="panel-body table-responsive">
|
||||
<div class="form-group">
|
||||
<router-link :to="{name: 'Add Nominee', query:{position_id:position_id}}" class="btn btn-success"><i class="fa fa-plus"></i> Add Nominee</router-link>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>No. Anggota</th>
|
||||
<th>Course</th>
|
||||
<th>Position</th>
|
||||
<th>Partylist</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="nominee in nominees">
|
||||
<td>
|
||||
<img :alt="nominee.name" :src="data.storageURL+nominee.image" class="thumbnail" style="height: 60px;width: 60px;">
|
||||
</td>
|
||||
<td>{{ nominee.name}}</td>
|
||||
<td>{{ nominee.student_id}}</td>
|
||||
<td>{{ nominee.course}}</td>
|
||||
<td>{{ nominee.position}}</td>
|
||||
<td>{{ nominee.partylist}}</td>
|
||||
<td>
|
||||
<router-link :to="{name: 'Edit Nominee', params:{id:nominee.id}}" class="btn btn-info">
|
||||
<i class="fa fa-edit"></i> Edit
|
||||
</router-link>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
@click="util.showModal('#delete-nominee-modal');id=nominee.id">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="nominees.length < 1">
|
||||
<td colspan="7">No nominees</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="delete-nominee-modal">
|
||||
<modal-header>Delete Nominee</modal-header>
|
||||
<modal-body>
|
||||
<h3>Are you sure to delete this nominee?</h3>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button class="btn btn-danger" @click="deleteNominee()">Delete</button>
|
||||
<button class="btn btn-default" @click="util.hideModal('#delete-nominee-modal')">
|
||||
Back
|
||||
</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
id: 0
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
this.refreshNominee();
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
deleteNominee: function () {
|
||||
this.util.hideModal('#delete-nominee-modal');
|
||||
var vm = this;
|
||||
this.util.notify('Deleting nominee', 'loading');
|
||||
axios.delete(config.API+'nominee/'+this.id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if(vm.util.showResult(response, 'success'))
|
||||
vm.refreshNominee();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
},
|
||||
|
||||
refreshNominee: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing Nominees', 'loading');
|
||||
axios.get(config.API+'nominee')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
console.log(response);
|
||||
vm.data.nominees = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
getPosition: function (id) {
|
||||
var positions = this.data.positions;
|
||||
for (var i in positions)
|
||||
if (positions[i].id == id)
|
||||
return positions[i]['name'];
|
||||
},
|
||||
|
||||
getPartylist: function (id) {
|
||||
var partylists = this.data.partylists;
|
||||
for (var i in partylists)
|
||||
if (partylists[i].id == id)
|
||||
return partylists[i]['name'];
|
||||
return 'No partylists';
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
nominees: function () {
|
||||
var nominees = [];
|
||||
var y = this.data.nominees;
|
||||
for (var nominee in this.data.nominees) {
|
||||
if (y[nominee].position_id == this.position_id || this.position_id == 0) {
|
||||
var x = y[nominee];
|
||||
x.position = this.getPosition(y[nominee].position_id);
|
||||
x.partylist = this.getPartylist(y[nominee].partylist_id);
|
||||
nominees.push(x);
|
||||
}
|
||||
}
|
||||
return nominees;
|
||||
},
|
||||
|
||||
position_id: function () {
|
||||
return this.$route.query.position_id ? this.$route.query.position_id : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-10 col-md-offset-1">
|
||||
<h4>Manage Nominee</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Nominee');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Add Partylist</h4>
|
||||
<form @submit.prevent="add()" id="add-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
<router-link :to="{name: 'Manage Partylist'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Adding Partylist', 'loading')
|
||||
axios.post(config.API+'partylist', $('#add-form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Partylist', query: {refresh:true}});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Edit Partylist</h4>
|
||||
<form @submit.prevent="edit()" id="edit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" :value="data.partylist.name" required/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-success"/>
|
||||
<router-link :to="{name: 'Manage Partylist'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (!this.data.partylist.id) {
|
||||
this.$router.push({name:'Manage Partylist'});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Updating partylist', 'loading');
|
||||
axios.put(config.API+'partylist/'+this.data.partylist.id, $('#edit-form').serialize())
|
||||
.then(response=>{
|
||||
vm.loading = false;
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Partylist', query: {refresh:true}});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="form-group">
|
||||
<router-link class="btn btn-success" :to="{name:'Add Partylist'}">
|
||||
<i class="fa fa-plus"></i> Add Partylist
|
||||
</router-link>
|
||||
<button class="btn btn-default" @click="refreshPartylist()">
|
||||
<i class="fa fa-refresh"></i> Refresh Partylist
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="partylist_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(partylist,i) in data.partylists">
|
||||
<td>{{ partylist.id }}</td>
|
||||
<td>{{ partylist.name }}</td>
|
||||
<td>
|
||||
<button class="btn btn-info" @click="edit(i)">
|
||||
<i class="fa fa-edit"></i> Edit
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
@click="util.showModal('#delete-partylist-modal');id=partylist.id">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="data.partylists.length < 1">
|
||||
<td colspan="3">No Partylist</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="delete-partylist-modal">
|
||||
<modal-header>Delete Partylist</modal-header>
|
||||
<modal-body>
|
||||
<h2>Are you sure to delete Partylist?</h2>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button class="btn btn-danger" @click="deletePartylist()">Delete</button>
|
||||
<button class="btn btn-default" @click="util.hideModal('#delete-partylist-modal')">Cancel</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
id: 0
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (this.$route.query.refresh) {
|
||||
this.refreshPartylist();
|
||||
this.$router.replace({name: 'Manage Partylist'});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
refreshPartylist: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing Partylist', 'loading');
|
||||
axios.get(config.API+'partylist')
|
||||
.then(response=>{
|
||||
console.log(response)
|
||||
$.notifyClose();
|
||||
vm.data.partylists = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
edit: function (i) {
|
||||
var vm = this;
|
||||
this.data.partylist = this.data.partylists[i];
|
||||
this.$router.push({name: 'Edit Partylist', params:{id:vm.data.partylist.id}})
|
||||
},
|
||||
|
||||
deletePartylist: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Deleting partylist', 'loading');
|
||||
this.util.hideModal('#delete-partylist-modal');
|
||||
axios.delete(config.API+'partylist/'+this.id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) vm.refreshPartylist();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Manage Partylist</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Partylist');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Add Position</h4>
|
||||
<form @submit.prevent="add()" id="add-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
<router-link :to="{name: 'Manage Position'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Adding Position', 'loading')
|
||||
axios.post(config.API+'position', $('#add-form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Position', query:{refresh:true}});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Edit Position</h4>
|
||||
<form @submit.prevent="edit()" id="edit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" :value="data.position.name" required/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-success"/>
|
||||
<router-link :to="{name: 'Manage Position'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (!this.data.position.id) {
|
||||
this.$router.push({name:'Manage Position'});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Updating position', 'loading');
|
||||
axios.put(config.API+'position/'+this.data.position.id, $('#edit-form').serialize())
|
||||
.then(response=>{
|
||||
vm.loading = false;
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Position', query:{refresh:true}});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="form-group">
|
||||
<router-link class="btn btn-success" :to="{name:'Add Position'}">
|
||||
<i class="fa fa-plus"></i> Add Position
|
||||
</router-link>
|
||||
<button class="btn btn-default" @click="refreshPosition()">
|
||||
<i class="fa fa-refresh"></i> Refresh Position
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="position_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(position,i) in data.positions">
|
||||
<td>{{ position.id }}</td>
|
||||
<td>{{ position.name }}</td>
|
||||
<td>
|
||||
<button class="btn btn-info" @click="edit(i)">
|
||||
<i class="fa fa-edit"></i> Edit
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
@click="util.showModal('#delete-position-modal');id=position.id">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="data.positions.length < 1">
|
||||
<td colspan="3">No Positions</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="delete-position-modal">
|
||||
<modal-header>Delete Position</modal-header>
|
||||
<modal-body>
|
||||
<h2>Are you sure to delete Position?</h2>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button class="btn btn-danger" @click="deletePosition()">Delete</button>
|
||||
<button class="btn btn-default" @click="util.hideModal('#delete-position-modal')">Cancel</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
id: 0
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (this.$route.query.refresh) {
|
||||
this.refreshPosition();
|
||||
this.$router.replace({name: 'Manage Position'})
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
refreshPosition: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing Position', 'loading');
|
||||
axios.get(config.API+'position')
|
||||
.then(response=>{
|
||||
console.log(response)
|
||||
$.notifyClose();
|
||||
vm.data.positions = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
initDatatable: function () {
|
||||
var vm = this;
|
||||
$('#position_table').DataTable({
|
||||
destroy: true,
|
||||
searching: false,
|
||||
info: false,
|
||||
autoWidth: false,
|
||||
dom: 'Bfrtip'
|
||||
});
|
||||
},
|
||||
|
||||
edit: function (i) {
|
||||
var vm = this;
|
||||
this.data.position = this.data.positions[i];
|
||||
this.$router.push({name: 'Edit Position', params:{id:vm.data.position.id}})
|
||||
},
|
||||
|
||||
deletePosition: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Deleting position', 'loading');
|
||||
this.util.hideModal('#delete-position-modal');
|
||||
axios.delete(config.API+'position/'+this.id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) vm.refreshPosition();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Manage Position</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Position');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<table id="sample_table" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
let fakeData = [
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>'],
|
||||
['Column1', 'Column2', '<button v-on:click="x()">click me</button>']
|
||||
]
|
||||
this.$nextTick(()=>{
|
||||
$('#sample_table').dataTable({
|
||||
aaData: fakeData
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
x: function () {
|
||||
console.log('clicked');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Add Voter</h4>
|
||||
<form @submit.prevent="add()" id="add-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="student_id">Student ID</label>
|
||||
<input type="text" name="student_id" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="course">Course</label>
|
||||
<input type="text" name="course" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
<router-link :to="{name: 'Manage Voter'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Adding Voter', 'loading')
|
||||
axios.post(config.API+'voter', $('#add-form').serialize())
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Voter'});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Edit Voter</h4>
|
||||
<form @submit.prevent="edit()" id="edit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" class="form-control" :value="data.voter.name" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="student_id">Student ID</label>
|
||||
<input type="text" name="student_id" class="form-control" :value="data.voter.student_id" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="course">Course</label>
|
||||
<input type="text" name="course" class="form-control" :value="data.voter.course" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Submit" class="btn btn-success"/>
|
||||
<router-link :to="{name: 'Manage Voter'}" class="btn btn-default">Back</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (!this.data.voter.id) {
|
||||
this.$router.push({name:'Manage Voter'});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit: function () {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Updating voter', 'loading');
|
||||
axios.put(config.API+'voter/'+this.data.voter.id, $('#edit-form').serialize())
|
||||
.then(response=>{
|
||||
vm.loading = false;
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Manage Voter'});
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="form-group">
|
||||
<router-link class="btn btn-success" :to="{name:'Add Voter'}">
|
||||
<i class="fa fa-plus"></i> Add Voter
|
||||
</router-link>
|
||||
<button class="btn btn-default" @click="refreshVoter()">
|
||||
<i class="fa fa-refresh"></i> Refresh Voter
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="position_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Student ID</th>
|
||||
<th>Course</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(voter,i) in data.voters.data">
|
||||
<td>{{ voter.name }}</td>
|
||||
<td>{{ voter.student_id }}</td>
|
||||
<td>{{ voter.course }}</td>
|
||||
<td>
|
||||
<button class="btn btn-info" @click="edit(i)">
|
||||
<i class="fa fa-edit"></i> Edit
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger"
|
||||
@click="util.showModal('#delete-voter-modal');id=voter.id">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="data.voters.data && data.voters.data.length < 1">
|
||||
<td colspan="3">No Voters</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<ul class="pagination" v-if="pages.length > 1">
|
||||
<router-link
|
||||
tag="li"
|
||||
v-for="page in pages"
|
||||
:key="page['pages']"
|
||||
:to="{query:{page:page['page']}}"
|
||||
:class="{'active':current_page==page['page']}"
|
||||
exact>
|
||||
<a href="#">{{ page['page'] }}</a>
|
||||
</router-link>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="delete-voter-modal">
|
||||
<modal-header>Delete Voter</modal-header>
|
||||
<modal-body>
|
||||
<h2>Are you sure to delete voter?</h2>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button class="btn btn-danger" @click="deleteVoter()">Delete</button>
|
||||
<button class="btn btn-default" @click="util.hideModal('#delete-voter-modal')">Cancel</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
id: 0
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
this.refreshVoter();
|
||||
},
|
||||
|
||||
methods: {
|
||||
search: function () {
|
||||
|
||||
},
|
||||
|
||||
refreshVoter: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing Voter', 'loading');
|
||||
axios.get(config.API+'voter?page='+this.current_page)
|
||||
.then(response=>{
|
||||
console.log(response)
|
||||
$.notifyClose();
|
||||
vm.data.voters = response.data;
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
edit: function (i) {
|
||||
var vm = this;
|
||||
this.data.voter = this.data.voters.data[i];
|
||||
this.$router.push({name: 'Edit Voter', params:{id:vm.data.voter.id}})
|
||||
},
|
||||
|
||||
deleteVoter: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Deleting voter', 'loading');
|
||||
this.util.hideModal('#delete-voter-modal');
|
||||
axios.delete(config.API+'voter/'+this.id)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')) vm.refreshVoter();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route.query.page': function () {
|
||||
$.notifyClose();
|
||||
this.refreshVoter();
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
pages: function () {
|
||||
var pages = [];
|
||||
if (this.data.voters.last_page)
|
||||
for (var i = 1; i <= this.data.voters.last_page;i++) {
|
||||
let x = {};
|
||||
x['page'] = i;
|
||||
pages.push(x);
|
||||
}
|
||||
return pages;
|
||||
},
|
||||
|
||||
current_page: function () {
|
||||
return this.$route.query.page ? this.$route.query.page : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Manage Voters</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
this.util.setTitle('Voting System - Manage Voters');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="row col-md-10 col-md-offset-1">
|
||||
<div class="col-md-4">
|
||||
<h4>Voter's Information</h4><hr/>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item"><b>Student ID : </b>{{ data.user.student_id }}</li>
|
||||
<li class="list-group-item"><b>Name : </b>{{ data.user.name }}</li>
|
||||
<li class="list-group-item"><b>Course : </b>{{ data.user.course }}</li>
|
||||
<li class="list-group-item" v-if="data.election.status==1">
|
||||
<center>Election hasn't started yet</center>
|
||||
</li>
|
||||
<li class="list-group-item" v-if="data.election.status==2">
|
||||
<center>
|
||||
<router-link v-if="!hasVoted()" :to="{name: 'Vote'}" class="btn btn-info">
|
||||
Vote Now
|
||||
</router-link>
|
||||
<router-link v-else :to="{name: 'Result'}" class="btn btn-info">
|
||||
View Result
|
||||
</router-link>
|
||||
</center>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-if="hasVoted()">
|
||||
<hr/>
|
||||
<h4>Your votes information</h4><hr/>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item" v-for="result in data.result">
|
||||
<b>{{ getPosition(result.position_id) }} : </b>{{ getNominee(result.nominee_id) }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<h4>Candidates Information</h4><hr/>
|
||||
<small>Click Picture to see details</small>
|
||||
<div class="panel panel-primary" v-for="position in data.positions">
|
||||
<div class="panel-heading">{{ position.name }}</div>
|
||||
<div class="panel-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>Partylist</th>
|
||||
<th>Course</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(nominee,i) in data.nominees" v-if="nominee.position_id==position.id">
|
||||
<td><img
|
||||
@click="view(i)"
|
||||
:src="data.storageURL+nominee.image"
|
||||
class="thumbnail"
|
||||
style="height: 60px;width: 60px;" />
|
||||
</td>
|
||||
<td>{{ nominee.name }}</td>
|
||||
<td>{{ getPartylist(nominee.partylist_id) }}</td>
|
||||
<td>{{ nominee.course }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="nominee-information-modal" aClass="primary">
|
||||
<modal-header>{{ header }}</modal-header>
|
||||
<modal-body>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<img :src="data.storageURL+x.image" style="height: 150px; width: 150px" class="thumbnail"/>
|
||||
</div>
|
||||
<div class="col-md-9" style="margin-left: 5px;">
|
||||
<h3><strong><em>"{{ x.motto }}"</em></strong></h3>
|
||||
<b> Name : </b>{{ x.name }}<br/>
|
||||
<b> Course : </b>{{ x.course }}<br/>
|
||||
<b> Partylist : </b>{{ getPartylist(x.partylist_id) }}<br/><hr/>
|
||||
{{ x.description }}
|
||||
</div>
|
||||
</div>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button data-dismiss="modal" class="btn btn-default">Close</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
//console.log(this)
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
x: {}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
hasVoted: function () {
|
||||
return this.data.result.length > 0;
|
||||
},
|
||||
|
||||
getPartylist: function(id) {
|
||||
let partylists = this.data.partylists;
|
||||
for (var i in partylists)
|
||||
if (partylists[i]['id'] == id) return partylists[i]['name'];
|
||||
return 'No Partylist';
|
||||
},
|
||||
|
||||
getPosition: function (id) {
|
||||
let positions = this.data.positions;
|
||||
for (var i in positions)
|
||||
if (positions[i].id == id) return positions[i].name;
|
||||
return '';
|
||||
},
|
||||
|
||||
getNominee: function (id) {
|
||||
let nominees = this.data.nominees;
|
||||
for (var i in nominees)
|
||||
if (nominees[i]['id']==id) return nominees[i].name;
|
||||
return '';
|
||||
},
|
||||
|
||||
view: function (index) {
|
||||
this.x = this.data.nominees[index];
|
||||
this.util.showModal('#nominee-information-modal');
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
header: function () {
|
||||
return this.x.name+' for '+this.getPosition(this.x.position_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div class="row col-md-10 col-md-offset-1">
|
||||
<div class="col-md-4">
|
||||
<h4>Positions</h4><hr/>
|
||||
<ul class="list-group">
|
||||
<router-link :key="position.id" v-for="position in data.positions" class="list-group-item" :class="{'active':position.id==position_id}" tag="li" :to="{query:{position_id:position.id}}" exact replace>
|
||||
{{ position.name }}
|
||||
</router-link>
|
||||
<li class="list-group-item">
|
||||
<center>
|
||||
<button class="btn btn-info" @click="refreshResults()">
|
||||
Refresh results <i class="fa fa-refresh"></i>
|
||||
</button>
|
||||
</center>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h4>Results</h4><hr/>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">{{ getPosition(position_id) }} - Results as of : {{ last_update }}</div>
|
||||
<div class="panel-body">
|
||||
<div id="chart" style="height: 300px; width: 300px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: function () {
|
||||
return {
|
||||
results: [{
|
||||
"position_id": 6,
|
||||
"nominee_id": 1,
|
||||
"votes": 2
|
||||
}, {
|
||||
"position_id": 8,
|
||||
"nominee_id": 6,
|
||||
"votes": 2
|
||||
}, {
|
||||
"position_id": 7,
|
||||
"nominee_id": 5,
|
||||
"votes": 2
|
||||
}, {
|
||||
"position_id": 7,
|
||||
"nominee_id": 4,
|
||||
"votes": 1
|
||||
}, {
|
||||
"position_id": 6,
|
||||
"nominee_id": 2,
|
||||
"votes": 1
|
||||
}, {
|
||||
"position_id": 8,
|
||||
"nominee_id": 7,
|
||||
"votes": 1
|
||||
}]
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
this.refreshResults();
|
||||
this.$nextTick(function(){
|
||||
this.initChart();
|
||||
});
|
||||
},
|
||||
|
||||
watch: {
|
||||
position_id : function () {
|
||||
this.initChart();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
refreshResults: function () {
|
||||
var vm = this;
|
||||
this.util.notify('Refreshing results', 'loading');
|
||||
axios.get(config.API+'election/result')
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
console.log(response)
|
||||
vm.data.results = response.data;
|
||||
vm.data.last_update= new Date();
|
||||
vm.initChart();
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error);
|
||||
})
|
||||
},
|
||||
|
||||
initChart: function () {
|
||||
$.plot($('#chart'), this.datas, {
|
||||
series: {
|
||||
pie: {
|
||||
show: true,
|
||||
innerRadius: 0.5
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getPosition: function (id) {
|
||||
let positions = this.data.positions;
|
||||
for (var i in positions)
|
||||
if (id == positions[i]['id']) return positions[i]['name'];
|
||||
return '';
|
||||
},
|
||||
|
||||
getNominee: function (id) {
|
||||
let nominees = this.data.nominees;
|
||||
for (var i in nominees)
|
||||
if (id == nominees[i]['id']) return nominees[i]['name'];
|
||||
return '';
|
||||
},
|
||||
|
||||
getVotes: function (id) {
|
||||
let results = this.data.results;
|
||||
for (var i in results) {
|
||||
if (results[i]['nominee_id'] == id) return results[i]['votes'];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
last_update: function () {
|
||||
let x = this.data.last_update;
|
||||
return x.toDateString() +' '+x.toLocaleTimeString();
|
||||
},
|
||||
|
||||
position_id: function () {
|
||||
return this.$route.query.position_id ?
|
||||
this.$route.query.position_id :
|
||||
this.data.positions[0]['id'];
|
||||
},
|
||||
|
||||
datas: function () {
|
||||
//var results =
|
||||
var data = [];
|
||||
var nominees = this.data.nominees;
|
||||
for (var i in nominees) {
|
||||
if (nominees[i]['position_id']== this.position_id){
|
||||
let row = [];
|
||||
row['label'] = nominees[i]['name'];
|
||||
row['data'] = [[1, this.getVotes(nominees[i]['id'])]];
|
||||
data.push(row);
|
||||
}
|
||||
}
|
||||
/*let positions = this.data.positions;
|
||||
for (var i in positions) {
|
||||
if (positions[i]['id'] == this.position_id) {
|
||||
var row = [];
|
||||
row['label'] = this.getNominee()
|
||||
}
|
||||
}
|
||||
for (var i in results) {
|
||||
if (results[i]['position_id'] != this.position_id) continue;
|
||||
var row = [];
|
||||
row['label'] = this.getNominee(results[i]['nominee_id']);
|
||||
row['data'] = [[1, results[i]['votes']]];
|
||||
data.push(row);
|
||||
}*/
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="row col-md-10 col-md-offset-1">
|
||||
<div class="col-md-4">
|
||||
<h4>Vote Information</h4><hr/>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item" v-for="position in data.positions">
|
||||
<b>{{ position.name }} : </b>{{ getName(position.id) }}
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<center>
|
||||
<button class="btn btn-success" @click="util.showModal('#vote-modal')">Submit Vote</button>
|
||||
<button class="btn btn-default" @click="reset()">Reset</button>
|
||||
</center>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h4>Select Candidates</h4><hr/>
|
||||
<div class="panel panel-info" v-for="position in data.positions">
|
||||
<div class="panel-heading">{{ position.name }}</div>
|
||||
<div class="panel-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>Partylist</th>
|
||||
<th>Unit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="nominee in data.nominees" v-if="nominee.position_id==position.id" @click="vote(position.id,nominee.id)">
|
||||
<td><input type="radio" :name="position.id" :id="nominee.id"/></td>
|
||||
<td>{{ nominee.name }}</td>
|
||||
<td>{{ getPartylist(nominee.partylist_id) }}</td>
|
||||
<td>{{ nominee.course }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="vote-modal">
|
||||
<modal-header>Vote</modal-header>
|
||||
<modal-body>
|
||||
<h3>Note: You can only vote once, so vote wisely.</h3>
|
||||
</modal-body>
|
||||
<modal-footer>
|
||||
<button class="btn btn-success" @click="submit()">Submit Vote</button>
|
||||
<button class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
</modal-footer>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
created: function () {
|
||||
if (this.data.result.length > 0 || this.data.election.status != 2)
|
||||
this.$router.push({name: 'Voter Home'})
|
||||
for (var i in this.data.positions) {
|
||||
this.selected.push({
|
||||
position_id: this.data.positions[i]['id'],
|
||||
nominee_id: null,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
selected: [],
|
||||
name: {}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
submit: function () {
|
||||
this.util.hideModal('#vote-modal');
|
||||
if (this.hasNullVote()) return;
|
||||
var vm = this;
|
||||
this.util.notify('Submitting your vote, please wait...', 'loading');
|
||||
let data = {};
|
||||
data['vote'] = this.selected;
|
||||
axios.post(config.API+'election/vote', data)
|
||||
.then(response=>{
|
||||
$.notifyClose();
|
||||
if (vm.util.showResult(response, 'success')){
|
||||
vm.data.result = response.data.result;
|
||||
vm.$router.push({name: 'Voter Home'});
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error=>{
|
||||
$.notifyClose();
|
||||
vm.util.showResult(error, 'error');
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
hasNullVote: function () {
|
||||
let selected = this.selected;
|
||||
for (var i in selected)
|
||||
if (selected[i]['nominee_id'] == null){
|
||||
this.util.notify('You must vote on all position', 'error');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
let selected = this.selected;
|
||||
for (var i in selected){
|
||||
$('#'+selected[i]['nominee_id']).selected(false);
|
||||
selected[i]['nominee_id'] = null;
|
||||
}
|
||||
},
|
||||
|
||||
vote: function (position_id, nominee_id) {
|
||||
$('#'+nominee_id).selected();
|
||||
for (var i in this.selected)
|
||||
if (this.selected[i]['position_id'] == position_id) {
|
||||
this.selected[i]['nominee_id'] = nominee_id;
|
||||
}
|
||||
},
|
||||
|
||||
getName: function (id) {
|
||||
let positions = this.data.positions;
|
||||
let selected = this.selected;
|
||||
for (var i in selected)
|
||||
if (selected[i]['position_id'] == id)
|
||||
return this.getNominee(selected[i]['nominee_id']);
|
||||
return '';
|
||||
},
|
||||
|
||||
getNominee: function (id) {
|
||||
let nominees = this.data.nominees;
|
||||
for (var i in nominees)
|
||||
if (nominees[i]['id'] == id) return nominees[i]['name'];
|
||||
},
|
||||
|
||||
getPartylist: function (id) {
|
||||
let partylists = this.data.partylists;
|
||||
for (var i in partylists)
|
||||
if (partylists[i]['id']==id) return partylists[i]['name'];
|
||||
return 'No Partylist';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="!loading">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" id="nav">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" :href="data.baseURL" >Voting System</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="myNavbar">
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<router-link :to="{name: 'Voter Home'}" tag="li" exact>
|
||||
<a href="#">Home</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Vote'}" v-if="data.election.status==2 && !hasVoted()" tag="li" exact>
|
||||
<a href="#">Vote</a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Result'}" v-if="data.election.status==2 && hasVoted()" tag="li">
|
||||
<a href="#">Results</a>
|
||||
</router-link>
|
||||
|
||||
</ul>
|
||||
<ul class="nav navbar-right navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a
|
||||
href="#"
|
||||
class="dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
role="button" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="fa fa-user"></span> {{ data.user.name }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li @click="logout()"><a>Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<div v-else class="container">
|
||||
<div class="jumbotron">
|
||||
<h1>Loading <i class="fa fa-refresh fa-spin"></i></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data: () => ({
|
||||
loading: true
|
||||
}),
|
||||
|
||||
created: function(){
|
||||
this.refreshInfo();
|
||||
},
|
||||
|
||||
methods: {
|
||||
logout: function () {
|
||||
localStorage.clear();
|
||||
this.$router.push({name: 'Voter Login'});
|
||||
},
|
||||
|
||||
hasVoted: function () {
|
||||
return this.data.result.length > 0;
|
||||
},
|
||||
|
||||
refreshInfo: function () {
|
||||
var vm = this;
|
||||
this.util.setAuthorization();
|
||||
axios.get(config.API+'election/information')
|
||||
.then(response=>{
|
||||
console.log(response);
|
||||
vm.loading = false;
|
||||
vm.data.election = response.data.election;
|
||||
vm.data.nominees = response.data.nominee;
|
||||
vm.data.partylists = response.data.partylist;
|
||||
vm.data.positions = response.data.position;
|
||||
vm.data.user = response.data.voter;
|
||||
vm.data.result = response.data.result;
|
||||
})
|
||||
.catch(error=>{
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(error, 'error') == 401) {
|
||||
vm.$router.push({name: 'Voter Login'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body{
|
||||
padding: 70px 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="col-md-5 col-md-offset-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4>Voter Login</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<form @submit.prevent="login" id="login_form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Masukkan No. Anggota</label>
|
||||
<input type="text" name="student_id" class="form-control" required/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="submit"
|
||||
class="btn btn-primary form-control"
|
||||
value="Login"/>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
if (this.util.isLogin())
|
||||
//return this.$router.push({name:'Admin Home'})
|
||||
this.util.setTitle('Voter Login');
|
||||
},
|
||||
|
||||
methods: {
|
||||
login: function () {
|
||||
if (this.loading) return;
|
||||
|
||||
let vm = this;
|
||||
|
||||
this.startLoading();
|
||||
|
||||
axios.post(config.API+'voter/login', $('#login_form').serialize())
|
||||
.then(response => {
|
||||
vm.stopLoading();
|
||||
if (this.util.showResult(response, 'success')) {
|
||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||
this.util.setAuthorization();
|
||||
vm.$router.push({name: 'Voter Home'});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
vm.stopLoading();
|
||||
this.util.showResult(error, 'error');
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
startLoading: function () {
|
||||
this.util.notify('Logging in', 'loading');
|
||||
this.loading = true;
|
||||
},
|
||||
|
||||
stopLoading: function () {
|
||||
$.notifyClose();
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 50px 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="modal-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="modal-footer">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4><slot></slot></h4>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="modal fade" v-bind:id="id" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" :class="aClass">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:['id', 'aClass']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.primary{
|
||||
background-color: #337ab7;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.primary .modal-body{
|
||||
background-color: #fff;
|
||||
border-left: solid 1px #337ab7;
|
||||
border-right: solid 1px #337ab7;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.primary .modal-footer{
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
border-left: solid 1px #337ab7;
|
||||
border-right: solid 1px #337ab7;
|
||||
border-bottom: solid 1px #337ab7;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<center>
|
||||
<div class="imgContainer">
|
||||
<input
|
||||
type="file"
|
||||
:id="fileId"
|
||||
class="file"
|
||||
:name="fileName"
|
||||
v-on:change="readFile(fileId, imageId)" />
|
||||
<img
|
||||
:src="imageSrc"
|
||||
height="100%"
|
||||
width="100%"
|
||||
class="imgUpload img-rounded"
|
||||
:id="imageId"/>
|
||||
<span class="imgText">Select Image</span>
|
||||
</div>
|
||||
</center>
|
||||
</template>
|
||||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: {
|
||||
fileId: {default:'fileId'},
|
||||
fileName: {default:'file_name'},
|
||||
imageId: {default:'imageId'},
|
||||
imageSrc:{default:'#'}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Print the selected file into image
|
||||
* @param String fileID, String imageId
|
||||
*
|
||||
*/
|
||||
readFile: function(fileId, imageId) {
|
||||
var inputFile = $('#'+fileId)[0];
|
||||
var inputImage = $('#'+imageId);
|
||||
if (inputFile.files && inputFile.files[0]) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) { inputImage.attr('src', e.target.result)};
|
||||
reader.readAsDataURL(inputFile.files[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.imgContainer {
|
||||
position: relative;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
|
||||
}
|
||||
|
||||
.file {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.imgUpload {
|
||||
background-color: #ffffff;
|
||||
border:2px black solid;
|
||||
}
|
||||
|
||||
.imgText {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 45%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,111 @@
|
||||
<style scoped>
|
||||
.action-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m-b-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="tokens.length > 0">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Authorized Applications</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<!-- Authorized Tokens -->
|
||||
<table class="table table-borderless m-b-none">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Scopes</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="token in tokens">
|
||||
<!-- Client Name -->
|
||||
<td style="vertical-align: middle;">
|
||||
{{ token.client.name }}
|
||||
</td>
|
||||
|
||||
<!-- Scopes -->
|
||||
<td style="vertical-align: middle;">
|
||||
<span v-if="token.scopes.length > 0">
|
||||
{{ token.scopes.join(', ') }}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<!-- Revoke Button -->
|
||||
<td style="vertical-align: middle;">
|
||||
<a class="action-link text-danger" @click="revoke(token)">
|
||||
Revoke
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
/*
|
||||
* The component's data.
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
tokens: []
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 1.x).
|
||||
*/
|
||||
ready() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 2.x).
|
||||
*/
|
||||
mounted() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Prepare the component (Vue 2.x).
|
||||
*/
|
||||
prepareComponent() {
|
||||
this.getTokens();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all of the authorized tokens for the user.
|
||||
*/
|
||||
getTokens() {
|
||||
axios.get('/oauth/tokens')
|
||||
.then(response => {
|
||||
this.tokens = response.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Revoke the given token.
|
||||
*/
|
||||
revoke(token) {
|
||||
axios.delete('/oauth/tokens/' + token.id)
|
||||
.then(response => {
|
||||
this.getTokens();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,354 @@
|
||||
<style scoped>
|
||||
.action-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m-b-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>
|
||||
OAuth Clients
|
||||
</span>
|
||||
|
||||
<a class="action-link" @click="showCreateClientForm">
|
||||
Create New Client
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<!-- Current Clients -->
|
||||
<p class="m-b-none" v-if="clients.length === 0">
|
||||
You have not created any OAuth clients.
|
||||
</p>
|
||||
|
||||
<table class="table table-borderless m-b-none" v-if="clients.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client ID</th>
|
||||
<th>Name</th>
|
||||
<th>Secret</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="client in clients">
|
||||
<!-- ID -->
|
||||
<td style="vertical-align: middle;">
|
||||
{{ client.id }}
|
||||
</td>
|
||||
|
||||
<!-- Name -->
|
||||
<td style="vertical-align: middle;">
|
||||
{{ client.name }}
|
||||
</td>
|
||||
|
||||
<!-- Secret -->
|
||||
<td style="vertical-align: middle;">
|
||||
<code>{{ client.secret }}</code>
|
||||
</td>
|
||||
|
||||
<!-- Edit Button -->
|
||||
<td style="vertical-align: middle;">
|
||||
<a class="action-link" @click="edit(client)">
|
||||
Edit
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<!-- Delete Button -->
|
||||
<td style="vertical-align: middle;">
|
||||
<a class="action-link text-danger" @click="destroy(client)">
|
||||
Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Client Modal -->
|
||||
<div class="modal fade" id="modal-create-client" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h4 class="modal-title">
|
||||
Create Client
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Form Errors -->
|
||||
<div class="alert alert-danger" v-if="createForm.errors.length > 0">
|
||||
<p><strong>Whoops!</strong> Something went wrong!</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li v-for="error in createForm.errors">
|
||||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Create Client Form -->
|
||||
<form class="form-horizontal" role="form">
|
||||
<!-- Name -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Name</label>
|
||||
|
||||
<div class="col-md-7">
|
||||
<input id="create-client-name" type="text" class="form-control"
|
||||
@keyup.enter="store" v-model="createForm.name">
|
||||
|
||||
<span class="help-block">
|
||||
Something your users will recognize and trust.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Redirect URL -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Redirect URL</label>
|
||||
|
||||
<div class="col-md-7">
|
||||
<input type="text" class="form-control" name="redirect"
|
||||
@keyup.enter="store" v-model="createForm.redirect">
|
||||
|
||||
<span class="help-block">
|
||||
Your application's authorization callback URL.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Modal Actions -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
||||
<button type="button" class="btn btn-primary" @click="store">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Client Modal -->
|
||||
<div class="modal fade" id="modal-edit-client" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h4 class="modal-title">
|
||||
Edit Client
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Form Errors -->
|
||||
<div class="alert alert-danger" v-if="editForm.errors.length > 0">
|
||||
<p><strong>Whoops!</strong> Something went wrong!</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li v-for="error in editForm.errors">
|
||||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Edit Client Form -->
|
||||
<form class="form-horizontal" role="form">
|
||||
<!-- Name -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Name</label>
|
||||
|
||||
<div class="col-md-7">
|
||||
<input id="edit-client-name" type="text" class="form-control"
|
||||
@keyup.enter="update" v-model="editForm.name">
|
||||
|
||||
<span class="help-block">
|
||||
Something your users will recognize and trust.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Redirect URL -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Redirect URL</label>
|
||||
|
||||
<div class="col-md-7">
|
||||
<input type="text" class="form-control" name="redirect"
|
||||
@keyup.enter="update" v-model="editForm.redirect">
|
||||
|
||||
<span class="help-block">
|
||||
Your application's authorization callback URL.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Modal Actions -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
||||
<button type="button" class="btn btn-primary" @click="update">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
/*
|
||||
* The component's data.
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
clients: [],
|
||||
|
||||
createForm: {
|
||||
errors: [],
|
||||
name: '',
|
||||
redirect: ''
|
||||
},
|
||||
|
||||
editForm: {
|
||||
errors: [],
|
||||
name: '',
|
||||
redirect: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 1.x).
|
||||
*/
|
||||
ready() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 2.x).
|
||||
*/
|
||||
mounted() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Prepare the component.
|
||||
*/
|
||||
prepareComponent() {
|
||||
this.getClients();
|
||||
|
||||
$('#modal-create-client').on('shown.bs.modal', () => {
|
||||
$('#create-client-name').focus();
|
||||
});
|
||||
|
||||
$('#modal-edit-client').on('shown.bs.modal', () => {
|
||||
$('#edit-client-name').focus();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all of the OAuth clients for the user.
|
||||
*/
|
||||
getClients() {
|
||||
axios.get('/oauth/clients')
|
||||
.then(response => {
|
||||
this.clients = response.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the form for creating new clients.
|
||||
*/
|
||||
showCreateClientForm() {
|
||||
$('#modal-create-client').modal('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new OAuth client for the user.
|
||||
*/
|
||||
store() {
|
||||
this.persistClient(
|
||||
'post', '/oauth/clients',
|
||||
this.createForm, '#modal-create-client'
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Edit the given client.
|
||||
*/
|
||||
edit(client) {
|
||||
this.editForm.id = client.id;
|
||||
this.editForm.name = client.name;
|
||||
this.editForm.redirect = client.redirect;
|
||||
|
||||
$('#modal-edit-client').modal('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the client being edited.
|
||||
*/
|
||||
update() {
|
||||
this.persistClient(
|
||||
'put', '/oauth/clients/' + this.editForm.id,
|
||||
this.editForm, '#modal-edit-client'
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Persist the client to storage using the given form.
|
||||
*/
|
||||
persistClient(method, uri, form, modal) {
|
||||
form.errors = [];
|
||||
|
||||
axios[method](uri, form)
|
||||
.then(response => {
|
||||
this.getClients();
|
||||
|
||||
form.name = '';
|
||||
form.redirect = '';
|
||||
form.errors = [];
|
||||
|
||||
$(modal).modal('hide');
|
||||
})
|
||||
.catch(error => {
|
||||
if (typeof error.response.data === 'object') {
|
||||
form.errors = _.flatten(_.toArray(error.response.data));
|
||||
} else {
|
||||
form.errors = ['Something went wrong. Please try again.'];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the given client.
|
||||
*/
|
||||
destroy(client) {
|
||||
axios.delete('/oauth/clients/' + client.id)
|
||||
.then(response => {
|
||||
this.getClients();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,302 @@
|
||||
<style scoped>
|
||||
.action-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m-b-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>
|
||||
Personal Access Tokens
|
||||
</span>
|
||||
|
||||
<a class="action-link" @click="showCreateTokenForm">
|
||||
Create New Token
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<!-- No Tokens Notice -->
|
||||
<p class="m-b-none" v-if="tokens.length === 0">
|
||||
You have not created any personal access tokens.
|
||||
</p>
|
||||
|
||||
<!-- Personal Access Tokens -->
|
||||
<table class="table table-borderless m-b-none" v-if="tokens.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="token in tokens">
|
||||
<!-- Client Name -->
|
||||
<td style="vertical-align: middle;">
|
||||
{{ token.name }}
|
||||
</td>
|
||||
|
||||
<!-- Delete Button -->
|
||||
<td style="vertical-align: middle;">
|
||||
<a class="action-link text-danger" @click="revoke(token)">
|
||||
Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Token Modal -->
|
||||
<div class="modal fade" id="modal-create-token" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h4 class="modal-title">
|
||||
Create Token
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Form Errors -->
|
||||
<div class="alert alert-danger" v-if="form.errors.length > 0">
|
||||
<p><strong>Whoops!</strong> Something went wrong!</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li v-for="error in form.errors">
|
||||
{{ error }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Create Token Form -->
|
||||
<form class="form-horizontal" role="form" @submit.prevent="store">
|
||||
<!-- Name -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-4 control-label">Name</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="create-token-name" type="text" class="form-control" name="name" v-model="form.name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scopes -->
|
||||
<div class="form-group" v-if="scopes.length > 0">
|
||||
<label class="col-md-4 control-label">Scopes</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div v-for="scope in scopes">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
@click="toggleScope(scope.id)"
|
||||
:checked="scopeIsAssigned(scope.id)">
|
||||
|
||||
{{ scope.id }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Modal Actions -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
||||
<button type="button" class="btn btn-primary" @click="store">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Access Token Modal -->
|
||||
<div class="modal fade" id="modal-access-token" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h4 class="modal-title">
|
||||
Personal Access Token
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Here is your new personal access token. This is the only time it will be shown so don't lose it!
|
||||
You may now use this token to make API requests.
|
||||
</p>
|
||||
|
||||
<pre><code>{{ accessToken }}</code></pre>
|
||||
</div>
|
||||
|
||||
<!-- Modal Actions -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
/*
|
||||
* The component's data.
|
||||
*/
|
||||
data() {
|
||||
return {
|
||||
accessToken: null,
|
||||
|
||||
tokens: [],
|
||||
scopes: [],
|
||||
|
||||
form: {
|
||||
name: '',
|
||||
scopes: [],
|
||||
errors: []
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 1.x).
|
||||
*/
|
||||
ready() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the component (Vue 2.x).
|
||||
*/
|
||||
mounted() {
|
||||
this.prepareComponent();
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Prepare the component.
|
||||
*/
|
||||
prepareComponent() {
|
||||
this.getTokens();
|
||||
this.getScopes();
|
||||
|
||||
$('#modal-create-token').on('shown.bs.modal', () => {
|
||||
$('#create-token-name').focus();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all of the personal access tokens for the user.
|
||||
*/
|
||||
getTokens() {
|
||||
axios.get('/oauth/personal-access-tokens')
|
||||
.then(response => {
|
||||
this.tokens = response.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all of the available scopes.
|
||||
*/
|
||||
getScopes() {
|
||||
axios.get('/oauth/scopes')
|
||||
.then(response => {
|
||||
this.scopes = response.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the form for creating new tokens.
|
||||
*/
|
||||
showCreateTokenForm() {
|
||||
$('#modal-create-token').modal('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new personal access token.
|
||||
*/
|
||||
store() {
|
||||
this.accessToken = null;
|
||||
|
||||
this.form.errors = [];
|
||||
|
||||
axios.post('/oauth/personal-access-tokens', this.form)
|
||||
.then(response => {
|
||||
this.form.name = '';
|
||||
this.form.scopes = [];
|
||||
this.form.errors = [];
|
||||
|
||||
this.tokens.push(response.data.token);
|
||||
|
||||
this.showAccessToken(response.data.accessToken);
|
||||
})
|
||||
.catch(error => {
|
||||
if (typeof error.response.data === 'object') {
|
||||
this.form.errors = _.flatten(_.toArray(error.response.data));
|
||||
} else {
|
||||
this.form.errors = ['Something went wrong. Please try again.'];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the given scope in the list of assigned scopes.
|
||||
*/
|
||||
toggleScope(scope) {
|
||||
if (this.scopeIsAssigned(scope)) {
|
||||
this.form.scopes = _.reject(this.form.scopes, s => s == scope);
|
||||
} else {
|
||||
this.form.scopes.push(scope);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the given scope has been assigned to the token.
|
||||
*/
|
||||
scopeIsAssigned(scope) {
|
||||
return _.indexOf(this.form.scopes, scope) >= 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the given access token to the user.
|
||||
*/
|
||||
showAccessToken(accessToken) {
|
||||
$('#modal-create-token').modal('hide');
|
||||
|
||||
this.accessToken = accessToken;
|
||||
|
||||
$('#modal-access-token').modal('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Revoke the given token.
|
||||
*/
|
||||
revoke(token) {
|
||||
axios.delete('/oauth/personal-access-tokens/' + token.id)
|
||||
.then(response => {
|
||||
this.getTokens();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
//Global Components
|
||||
Vue.component('modal', require('./components/mycomponents/modal/modal.vue'))
|
||||
Vue.component('modal-header', require('./components/mycomponents/modal/header.vue'));
|
||||
Vue.component('modal-body', require('./components/mycomponents/modal/body.vue'));
|
||||
Vue.component('modal-footer', require('./components/mycomponents/modal/footer.vue'));
|
||||
|
||||
Vue.component('uploader', require('./components/mycomponents/uploader.vue'));
|
||||
Vendored
+223
@@ -0,0 +1,223 @@
|
||||
import AdminIndex from './components/demo/admin/index.vue';
|
||||
import AdminLogin from './components/demo/admin/login.vue';
|
||||
|
||||
import test from './components/demo/admin/position/test.vue';
|
||||
import FinalResult from './components/demo/admin/home/final.vue';
|
||||
|
||||
import ManageElection from './components/demo/admin/home/home.vue';
|
||||
import ManageElectionIndex from './components/demo/admin/home/index.vue';
|
||||
import ManageElectionResult from './components/demo/admin/home/result.vue';
|
||||
|
||||
import ManagePosition from './components/demo/admin/position/position.vue';
|
||||
import ManagePositionIndex from './components/demo/admin/position/index.vue';
|
||||
import ManagePositionAdd from './components/demo/admin/position/add.vue';
|
||||
import ManagePositionEdit from './components/demo/admin/position/edit.vue';
|
||||
|
||||
import ManagePartylist from './components/demo/admin/partylist/partylist.vue';
|
||||
import ManagePartylistIndex from './components/demo/admin/partylist/index.vue';
|
||||
import ManagePartylistAdd from './components/demo/admin/partylist/add.vue';
|
||||
import ManagePartylistEdit from './components/demo/admin/partylist/edit.vue';
|
||||
|
||||
import ManageVoter from './components/demo/admin/voter/voter.vue';
|
||||
import ManageVoterIndex from './components/demo/admin/voter/index.vue';
|
||||
import ManageVoterAdd from './components/demo/admin/voter/add.vue';
|
||||
import ManageVoterEdit from './components/demo/admin/voter/edit.vue';
|
||||
|
||||
import ManageNominee from './components/demo/admin/nominee/nominee.vue';
|
||||
import ManageNomineeIndex from './components/demo/admin/nominee/index.vue';
|
||||
import ManageNomineeAdd from './components/demo/admin/nominee/add.vue';
|
||||
import ManageNomineeEdit from './components/demo/admin/nominee/edit.vue';
|
||||
|
||||
import ManageAccount from './components/demo/admin/admin/admin.vue';
|
||||
import ManageAccountIndex from './components/demo/admin/admin/index.vue';
|
||||
import ManageAccountEdit from './components/demo/admin/admin/edit.vue';
|
||||
import ManageAccountPassword from './components/demo/admin/admin/password.vue';
|
||||
import ManageAccountAdd from './components/demo/admin/admin/add.vue';
|
||||
|
||||
const default_component = {
|
||||
template: '<div>Not found: {{ $route.path }}</div>'
|
||||
}
|
||||
|
||||
const routes = [
|
||||
|
||||
{
|
||||
path: '/',
|
||||
component: AdminIndex,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: 'result/:election_id',
|
||||
component: FinalResult,
|
||||
name: 'Election Result'
|
||||
},
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageElection,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageElectionIndex,
|
||||
name: 'Admin Home'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'result',
|
||||
component: ManageElectionResult,
|
||||
name: 'Result'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'position',
|
||||
component: ManagePosition,
|
||||
children: [
|
||||
|
||||
{
|
||||
path:'',
|
||||
component: ManagePositionIndex,
|
||||
name: 'Manage Position'
|
||||
},
|
||||
|
||||
{
|
||||
path:'add',
|
||||
component: ManagePositionAdd,
|
||||
name: 'Add Position'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManagePositionEdit,
|
||||
name: 'Edit Position'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'partylist',
|
||||
component: ManagePartylist,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManagePartylistIndex,
|
||||
name: 'Manage Partylist'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManagePartylistAdd,
|
||||
name: 'Add Partylist'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManagePartylistEdit,
|
||||
name: 'Edit Partylist'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'voter',
|
||||
component: ManageVoter,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageVoterIndex,
|
||||
name: 'Manage Voter'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageVoterAdd,
|
||||
name: 'Add Voter'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManageVoterEdit,
|
||||
name: 'Edit Voter'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'nominee',
|
||||
component: ManageNominee,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageNomineeIndex,
|
||||
name: 'Manage Nominee'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageNomineeAdd,
|
||||
name: 'Add Nominee'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManageNomineeEdit,
|
||||
name: 'Edit Nominee'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/account',
|
||||
component: ManageAccount,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageAccountIndex,
|
||||
name: 'Manage Account'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'update',
|
||||
component: ManageAccountEdit,
|
||||
name: 'Update Account'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'password',
|
||||
component: ManageAccountPassword,
|
||||
name: 'Update Password'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageAccountAdd,
|
||||
name: 'Add Account'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/login',
|
||||
component: AdminLogin,
|
||||
name: 'Admin Login'
|
||||
},
|
||||
|
||||
{
|
||||
path: '/test',
|
||||
component: test
|
||||
}
|
||||
];
|
||||
|
||||
export default routes;
|
||||
Vendored
+253
@@ -0,0 +1,253 @@
|
||||
import VoterLogin from './components/demo/voter/login.vue';
|
||||
import VoterHome from './components/demo/voter/index.vue';
|
||||
|
||||
import Home from './components/demo/voter/home/index.vue';
|
||||
import Vote from './components/demo/voter/home/vote.vue';
|
||||
import Result from './components/demo/voter/home/result.vue';
|
||||
|
||||
import AdminLogin from './components/demo/admin/login.vue';
|
||||
import AdminIndex from './components/demo/admin/index.vue';
|
||||
|
||||
import FinalResult from './components/demo/admin/home/final.vue';
|
||||
|
||||
import ManageElection from './components/demo/admin/home/home.vue';
|
||||
import ManageElectionIndex from './components/demo/admin/home/index.vue';
|
||||
import ManageElectionResult from './components/demo/admin/home/result.vue';
|
||||
|
||||
import ManagePosition from './components/demo/admin/position/position.vue';
|
||||
import ManagePositionIndex from './components/demo/admin/position/index.vue';
|
||||
import ManagePositionAdd from './components/demo/admin/position/add.vue';
|
||||
import ManagePositionEdit from './components/demo/admin/position/edit.vue';
|
||||
|
||||
import ManagePartylist from './components/demo/admin/partylist/partylist.vue';
|
||||
import ManagePartylistIndex from './components/demo/admin/partylist/index.vue';
|
||||
import ManagePartylistAdd from './components/demo/admin/partylist/add.vue';
|
||||
import ManagePartylistEdit from './components/demo/admin/partylist/edit.vue';
|
||||
|
||||
import ManageVoter from './components/demo/admin/voter/voter.vue';
|
||||
import ManageVoterIndex from './components/demo/admin/voter/index.vue';
|
||||
import ManageVoterAdd from './components/demo/admin/voter/add.vue';
|
||||
import ManageVoterEdit from './components/demo/admin/voter/edit.vue';
|
||||
|
||||
import ManageNominee from './components/demo/admin/nominee/nominee.vue';
|
||||
import ManageNomineeIndex from './components/demo/admin/nominee/index.vue';
|
||||
import ManageNomineeAdd from './components/demo/admin/nominee/add.vue';
|
||||
import ManageNomineeEdit from './components/demo/admin/nominee/edit.vue';
|
||||
|
||||
import ManageAccount from './components/demo/admin/admin/admin.vue';
|
||||
import ManageAccountIndex from './components/demo/admin/admin/index.vue';
|
||||
import ManageAccountEdit from './components/demo/admin/admin/edit.vue';
|
||||
import ManageAccountPassword from './components/demo/admin/admin/password.vue';
|
||||
import ManageAccountAdd from './components/demo/admin/admin/add.vue';
|
||||
|
||||
const default_component = {
|
||||
template: '<div>Not found: {{ $route.path }}</div>'
|
||||
}
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/',
|
||||
component: VoterHome,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: Home,
|
||||
name: 'Voter Home'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'vote',
|
||||
component: Vote,
|
||||
name: 'Vote'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'result',
|
||||
component: Result,
|
||||
name: 'Result'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/login',
|
||||
component: VoterLogin,
|
||||
name: 'Voter Login'
|
||||
},
|
||||
|
||||
{
|
||||
path: '/admin/login',
|
||||
component: AdminLogin,
|
||||
name: 'Admin Login'
|
||||
},
|
||||
|
||||
{
|
||||
path: '/admin',
|
||||
component: AdminIndex,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: 'result/:election_id',
|
||||
component: FinalResult,
|
||||
name: 'Election Result'
|
||||
},
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageElection,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageElectionIndex,
|
||||
name: 'Admin Home'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'result',
|
||||
component: ManageElectionResult,
|
||||
name: 'Current Result'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'position',
|
||||
component: ManagePosition,
|
||||
children: [
|
||||
|
||||
{
|
||||
path:'',
|
||||
component: ManagePositionIndex,
|
||||
name: 'Manage Position'
|
||||
},
|
||||
|
||||
{
|
||||
path:'add',
|
||||
component: ManagePositionAdd,
|
||||
name: 'Add Position'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManagePositionEdit,
|
||||
name: 'Edit Position'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'partylist',
|
||||
component: ManagePartylist,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManagePartylistIndex,
|
||||
name: 'Manage Partylist'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManagePartylistAdd,
|
||||
name: 'Add Partylist'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManagePartylistEdit,
|
||||
name: 'Edit Partylist'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'voter',
|
||||
component: ManageVoter,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageVoterIndex,
|
||||
name: 'Manage Voter'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageVoterAdd,
|
||||
name: 'Add Voter'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManageVoterEdit,
|
||||
name: 'Edit Voter'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: 'nominee',
|
||||
component: ManageNominee,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageNomineeIndex,
|
||||
name: 'Manage Nominee'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageNomineeAdd,
|
||||
name: 'Add Nominee'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'edit/:id',
|
||||
component: ManageNomineeEdit,
|
||||
name: 'Edit Nominee'
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/account',
|
||||
component: ManageAccount,
|
||||
children: [
|
||||
|
||||
{
|
||||
path: '',
|
||||
component: ManageAccountIndex,
|
||||
name: 'Manage Account'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'update',
|
||||
component: ManageAccountEdit,
|
||||
name: 'Update Account'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'password',
|
||||
component: ManageAccountPassword,
|
||||
name: 'Update Password'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'add',
|
||||
component: ManageAccountAdd,
|
||||
name: 'Add Account'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Vendored
+204
@@ -0,0 +1,204 @@
|
||||
const methods = {
|
||||
/**
|
||||
* Hide Modal
|
||||
* @param {String} Modal ID
|
||||
*
|
||||
*/
|
||||
hideModal: function (id) {
|
||||
$(id).modal('hide');
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if Login
|
||||
*
|
||||
* @return {Boolean} isLogin
|
||||
*/
|
||||
isLogin: function () {
|
||||
return localStorage['Access Token'] ? true : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a messages
|
||||
* @param {String} Message
|
||||
*
|
||||
*/
|
||||
log: function (message) {
|
||||
if (config.debug) console.log(message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show an alert message
|
||||
* @param {String} message to be Shown
|
||||
* @param {String} type of message (info|error|loading|success)
|
||||
* @param {Boolean} if message will be closed imediately (true|false)
|
||||
* @return {Notify}
|
||||
*/
|
||||
notify: function (message, label = 'info', progress) {
|
||||
|
||||
let delay = 5000;
|
||||
let type = 'info';
|
||||
let icon = 'fa fa-info';
|
||||
|
||||
switch (label) {
|
||||
case 'error':
|
||||
type = 'danger';
|
||||
icon = 'fa fa-warning';
|
||||
break;
|
||||
case 'loading':
|
||||
delay = 0;
|
||||
icon = 'fa fa-refresh fa-spin';
|
||||
break;
|
||||
case 'success':
|
||||
type = 'success';
|
||||
icon = 'fa fa-check';
|
||||
break;
|
||||
case 'progress':
|
||||
$.notifyClose();
|
||||
delay = 0;
|
||||
message = `<label>${message}</label>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-green" role="progressbar" aria-valuenow="${progress}" aria-valuemin="0" aria-valuemax="100" style="width: ${progress}%">
|
||||
</div>
|
||||
</div>`;
|
||||
icon = 'fa fa-refresh fa-spin';
|
||||
break;
|
||||
}
|
||||
|
||||
return $.notify({
|
||||
message: message,
|
||||
icon: icon
|
||||
}, {
|
||||
type: type,
|
||||
delay: delay,
|
||||
placement: {from: 'top', align: 'center'}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set Authorization for all outgoing request
|
||||
*
|
||||
*/
|
||||
setAuthorization: function () {
|
||||
axios.defaults.headers.common['Authorization'] = localStorage['Access Token'];
|
||||
$.ajaxSetup({headers:{'Authorization': localStorage['Access Token']}});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set the title of the webpage
|
||||
* @param {String} Title
|
||||
*
|
||||
*/
|
||||
setTitle: function (title) {
|
||||
$('title').text(title);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the error Message
|
||||
* @param {String} Data
|
||||
* @param {Int} Response Status
|
||||
* @return {String} Error Message
|
||||
*/
|
||||
getErrorMessage: function (data, status)
|
||||
{
|
||||
var message = '';
|
||||
switch (status) {
|
||||
case 200:
|
||||
message = data.message;
|
||||
break;
|
||||
case 422:
|
||||
data = typeof data == 'string' ? JSON.parse(data) : data;
|
||||
for (var i in data)
|
||||
data[i].map(y=>{message+=y+'<br/>';});
|
||||
break;
|
||||
case 401:
|
||||
message = 'You need to login first.';
|
||||
break;
|
||||
default:
|
||||
message = 'An error occured.';
|
||||
break;
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the modal
|
||||
* @param {String} Modal ID
|
||||
*
|
||||
*/
|
||||
showModal: function (id) {
|
||||
$(id).modal('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* Show result from an http request
|
||||
* @param {Response} response
|
||||
* @param {Type} responseType (error|success)
|
||||
* @param {library} Library used (ajax|axios) Default : axios
|
||||
*/
|
||||
showResult: function (response, type, library = 'axios') {
|
||||
this.log (response);
|
||||
var isSuccess = data => data.status == 'success';
|
||||
if (library == 'axios') {
|
||||
if (type == 'success') {
|
||||
if (isSuccess(response.data)) {
|
||||
this.notify(response.data.message, 'success');
|
||||
return true;
|
||||
} else {
|
||||
this.notify(response.data.message, 'error');
|
||||
}
|
||||
} else {
|
||||
var status = response.response ? response.response.status : 500;
|
||||
var message = this.getErrorMessage(response.response.data, status);
|
||||
this.notify(message, 'error');
|
||||
return status;
|
||||
}
|
||||
} else if (library == 'ajax') {
|
||||
if (type == 'success') {
|
||||
if (isSuccess(response)) {
|
||||
this.notify(response.message, 'success');
|
||||
return true;
|
||||
} else {
|
||||
this.notify(response.message, 'error');
|
||||
}
|
||||
} else if (type == 'error') {
|
||||
var status = response.status;
|
||||
var message = this.getErrorMessage(response.responseText, status);
|
||||
this.notify(message, 'error');
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const data = {
|
||||
baseURL: config.baseURL,
|
||||
API: config.API,
|
||||
storageURL: config.storageURL,
|
||||
elections: [],
|
||||
election: {},
|
||||
user: {},
|
||||
positions: [],
|
||||
position: {},
|
||||
partylists: [],
|
||||
partylist:{},
|
||||
voters:{},
|
||||
voter:{},
|
||||
nominees:[],
|
||||
nominee:{},
|
||||
admins:[],
|
||||
information: {},
|
||||
result: [],
|
||||
results: [],
|
||||
last_update: new Date()
|
||||
}
|
||||
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
util: methods,
|
||||
data: data
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
// Body
|
||||
$body-bg: #f5f8fa;
|
||||
|
||||
// Borders
|
||||
$laravel-border-color: darken($body-bg, 10%);
|
||||
$list-group-border: $laravel-border-color;
|
||||
$navbar-default-border: $laravel-border-color;
|
||||
$panel-default-border: $laravel-border-color;
|
||||
$panel-inner-border: $laravel-border-color;
|
||||
|
||||
// Brands
|
||||
$brand-primary: #3097D1;
|
||||
$brand-info: #8eb4cb;
|
||||
$brand-success: #2ab27b;
|
||||
$brand-warning: #cbb956;
|
||||
$brand-danger: #bf5329;
|
||||
|
||||
// Typography
|
||||
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
|
||||
$font-family-sans-serif: "Raleway", sans-serif;
|
||||
$font-size-base: 14px;
|
||||
$line-height-base: 1.6;
|
||||
$text-color: #636b6f;
|
||||
|
||||
// Navbar
|
||||
$navbar-default-bg: #fff;
|
||||
|
||||
// Buttons
|
||||
$btn-default-color: $text-color;
|
||||
|
||||
// Inputs
|
||||
$input-border: lighten($text-color, 40%);
|
||||
$input-border-focus: lighten($brand-primary, 25%);
|
||||
$input-color-placeholder: lighten($text-color, 30%);
|
||||
|
||||
// Panels
|
||||
$panel-default-heading-bg: #fff;
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
//fontawesome
|
||||
//@import "node_modules/font-awesome/scss/font-awesome.scss";
|
||||
|
||||
// Variables
|
||||
//@import "variables";
|
||||
|
||||
// Bootstrap
|
||||
//@import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
@import "./font-awesome/scss/font-awesome.scss";
|
||||
@import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
|
||||
];
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Previous',
|
||||
'next' => 'Next »',
|
||||
|
||||
];
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Passwords must be at least six characters and match the confirmation.',
|
||||
'reset' => 'Your password has been reset!',
|
||||
'sent' => 'We have e-mailed your password reset link!',
|
||||
'token' => 'This password reset token is invalid.',
|
||||
'user' => "We can't find a user with that e-mail address.",
|
||||
|
||||
];
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute must be accepted.',
|
||||
'active_url' => 'The :attribute is not a valid URL.',
|
||||
'after' => 'The :attribute must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
'alpha' => 'The :attribute may only contain letters.',
|
||||
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
|
||||
'alpha_num' => 'The :attribute may only contain letters and numbers.',
|
||||
'array' => 'The :attribute must be an array.',
|
||||
'before' => 'The :attribute must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
'array' => 'The :attribute must have between :min and :max items.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'The :attribute confirmation does not match.',
|
||||
'date' => 'The :attribute is not a valid date.',
|
||||
'date_format' => 'The :attribute does not match the format :format.',
|
||||
'different' => 'The :attribute and :other must be different.',
|
||||
'digits' => 'The :attribute must be :digits digits.',
|
||||
'digits_between' => 'The :attribute must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'filled' => 'The :attribute field must have a value.',
|
||||
'image' => 'The :attribute must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
'in_array' => 'The :attribute field does not exist in :other.',
|
||||
'integer' => 'The :attribute must be an integer.',
|
||||
'ip' => 'The :attribute must be a valid IP address.',
|
||||
'ipv4' => 'The :attribute must be a valid IPv4 address.',
|
||||
'ipv6' => 'The :attribute must be a valid IPv6 address.',
|
||||
'json' => 'The :attribute must be a valid JSON string.',
|
||||
'max' => [
|
||||
'numeric' => 'The :attribute may not be greater than :max.',
|
||||
'file' => 'The :attribute may not be greater than :max kilobytes.',
|
||||
'string' => 'The :attribute may not be greater than :max characters.',
|
||||
'array' => 'The :attribute may not have more than :max items.',
|
||||
],
|
||||
'mimes' => 'The :attribute must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute must be a file of type: :values.',
|
||||
'min' => [
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
],
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_with_all' => 'The :attribute field is required when :values is present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
||||
'same' => 'The :attribute and :other must match.',
|
||||
'size' => [
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
'array' => 'The :attribute must contain :size items.',
|
||||
],
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'timezone' => 'The :attribute must be a valid zone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'url' => 'The :attribute format is invalid.',
|
||||
'password' => 'Wrong password.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Voting System - Administrator</title>
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.config = {
|
||||
"API":"{{ url('api/v1') }}/", //URL OF YOUR API LOCATED
|
||||
"baseURL":"{{ url('') }}/", //URL OF YOUR WEBSITE
|
||||
"storageURL":"{{ url('storage') }}/", //URL WHERE YOUR IMAGES and OTHER FILEs stored
|
||||
"debug": {{ env('APP_DEBUG') }}
|
||||
}
|
||||
</script>
|
||||
<script src="{{ asset('js/admin.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Voting System</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="/css/app.css">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
|
||||
<div id="error"></div>
|
||||
|
||||
<script>
|
||||
window.config = {
|
||||
"API":"/api/v1/", //URL OF YOUR API LOCATED
|
||||
"baseURL":"/", //URL OF YOUR WEBSITE
|
||||
"storageURL":"{{ config('app.cloudinary_enabled') ? '' : '/storage/' }}", //URL WHERE YOUR IMAGES and OTHER FILEs stored
|
||||
"debug": {{ env('APP_DEBUG') }}
|
||||
}
|
||||
</script>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js" integrity="sha512-bZS47S7sPOxkjU/4Bt0zrhEtWx0y0CRkhEp8IckzK+ltifIIE9EMIMTuT/mEzoIMewUINruDBIR/jJnbguonqQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-notify@3.1.3/bootstrap-notify.min.js" integrity="sha256-DRllCE/8rrevSAnSMWB4XO3zpr+3WaSuqUSNLD5NAzg=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-form@4.3.0/dist/jquery.form.min.js" integrity="sha256-3TKcZElR88BBIA6CeePJAGOsW1yIYf4lP8pI333YuZw=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-flot@0.8.3/jquery.flot.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-flot@0.8.3/jquery.flot.pie.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.9/dist/vue-router.min.js"></script>
|
||||
<script src="/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user