Feature/standardize ui display
This commit is contained in:
Vendored
+30
-3
@@ -19,16 +19,34 @@ const router = new VueRouter({
|
||||
routes
|
||||
});
|
||||
|
||||
var publicVoterRouteNames = {
|
||||
'Voter Login': true,
|
||||
'Voter Verify': true,
|
||||
'Physical Gate Display': true,
|
||||
'Roulette Wheel Demo': true,
|
||||
'penyata': true
|
||||
};
|
||||
|
||||
router.beforeEach(function (to, from, next) {
|
||||
if (to.name === 'Voter Login' && utilMethods.isAdminPortalSession()) {
|
||||
var dest = utilMethods.getAdminEntryRoute();
|
||||
return next(Object.assign({}, dest, { replace: true }));
|
||||
}
|
||||
if (!to.path.startsWith('/admin') || to.name === 'Admin Login') {
|
||||
|
||||
var isAdminRoute = to.path.indexOf('/admin') === 0;
|
||||
var isPublicVoterRoute = !!publicVoterRouteNames[to.name]
|
||||
|| to.path.indexOf('/display/') === 0
|
||||
|| to.path.indexOf('/demo/') === 0;
|
||||
|
||||
if (!isAdminRoute && !isPublicVoterRoute && !utilMethods.isLogin()) {
|
||||
return next({ name: 'Voter Login', replace: true });
|
||||
}
|
||||
|
||||
if (!isAdminRoute || to.name === 'Admin Login') {
|
||||
return next();
|
||||
}
|
||||
if (!localStorage.getItem('Access Token')) {
|
||||
return next();
|
||||
if (!utilMethods.isLogin()) {
|
||||
return next({ name: 'Admin Login', replace: true });
|
||||
}
|
||||
var role = localStorage.getItem('admin_role');
|
||||
if (role === '3' && to.name !== 'Kehadiran Calon') {
|
||||
@@ -37,6 +55,15 @@ router.beforeEach(function (to, from, next) {
|
||||
next();
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(function (response) {
|
||||
return response;
|
||||
}, function (error) {
|
||||
if (error.response && error.response.status === 401) {
|
||||
utilMethods.handleUnauthorized(router);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
const app = new Vue({
|
||||
router
|
||||
}).$mount('#app');
|
||||
|
||||
@@ -139,15 +139,14 @@ export default {
|
||||
// Swap admin token + user in local state.
|
||||
var token = response.data.token;
|
||||
if (token) {
|
||||
localStorage['Access Token'] = 'Bearer ' + token;
|
||||
vm.util.persistLoginSession(token, response.data.token_expires_at, {
|
||||
adminSession: true,
|
||||
adminRole: response.data.user && response.data.user.role
|
||||
});
|
||||
localStorage.setItem('is_impersonating', '1');
|
||||
if (vm.util && vm.util.setAuthorization) vm.util.setAuthorization();
|
||||
}
|
||||
if (response.data.user) {
|
||||
vm.data.user = response.data.user;
|
||||
if (response.data.user.role !== undefined && response.data.user.role !== null) {
|
||||
localStorage.setItem('admin_role', String(response.data.user.role));
|
||||
}
|
||||
}
|
||||
|
||||
vm.util.notify('Menyamar berjaya', 'success');
|
||||
|
||||
@@ -146,9 +146,14 @@ export default {
|
||||
})
|
||||
.catch(error => {
|
||||
$.notifyClose();
|
||||
if (this.util.showResult(error) == 401) {
|
||||
vm.logout();
|
||||
var status = error.response ? error.response.status : 500;
|
||||
if (status === 401) {
|
||||
vm.util.clearSession();
|
||||
vm.$router.replace({ name: 'Admin Login' });
|
||||
return;
|
||||
}
|
||||
vm.util.showResult(error, 'error');
|
||||
vm.loading = false;
|
||||
})
|
||||
} else {
|
||||
this.$router.push({ name: 'Admin Login' });
|
||||
@@ -186,15 +191,14 @@ export default {
|
||||
return;
|
||||
}
|
||||
if (response.data.token) {
|
||||
localStorage['Access Token'] = 'Bearer ' + response.data.token;
|
||||
if (vm.util && vm.util.setAuthorization) vm.util.setAuthorization();
|
||||
vm.util.persistLoginSession(response.data.token, response.data.token_expires_at, {
|
||||
adminSession: true,
|
||||
adminRole: response.data.user && response.data.user.role
|
||||
});
|
||||
}
|
||||
localStorage.removeItem('is_impersonating');
|
||||
if (response.data.user) {
|
||||
vm.data.user = response.data.user;
|
||||
if (response.data.user.role !== undefined && response.data.user.role !== null) {
|
||||
localStorage.setItem('admin_role', String(response.data.user.role));
|
||||
}
|
||||
}
|
||||
vm.util.notify('Berjaya kembali', 'success');
|
||||
if (vm.$router) vm.$router.go(0);
|
||||
@@ -206,9 +210,7 @@ export default {
|
||||
},
|
||||
|
||||
logout: function () {
|
||||
localStorage.removeItem('admin_role');
|
||||
localStorage.removeItem('is_impersonating');
|
||||
localStorage.clear();
|
||||
this.util.clearSession();
|
||||
this.$router.push({ name: 'Admin Login' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +84,10 @@ export default {
|
||||
.then(response => {
|
||||
vm.stopLoading();
|
||||
if (this.util.showResult(response, 'success')) {
|
||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||
localStorage.setItem('admin_session', '1');
|
||||
if (response.data.user && response.data.user.role !== undefined && response.data.user.role !== null) {
|
||||
localStorage.setItem('admin_role', String(response.data.user.role));
|
||||
}
|
||||
this.util.setAuthorization();
|
||||
this.util.persistLoginSession(response.data.token, response.data.token_expires_at, {
|
||||
adminSession: true,
|
||||
adminRole: response.data.user && response.data.user.role
|
||||
});
|
||||
if (Number(response.data.user && response.data.user.role) === 3) {
|
||||
vm.$router.push({ name: 'Kehadiran Calon' });
|
||||
} else {
|
||||
|
||||
@@ -53,13 +53,21 @@
|
||||
</div>
|
||||
|
||||
<div class="member-info-card home-member-card home-member-card--in-section">
|
||||
<div v-for="row in memberRows" :key="row.label" class="member-field">
|
||||
<div v-for="row in memberRows" :key="row.key || row.label" class="member-field">
|
||||
<span class="member-field-icon" aria-hidden="true"><i class="fa" :class="row.icon"></i></span>
|
||||
<div class="member-field-body">
|
||||
<span class="member-field-label">{{ row.label }}</span>
|
||||
<div class="member-field-value-wrap">
|
||||
<span class="member-field-value">{{ row.value }}</span>
|
||||
<span v-if="row.subvalue" class="member-field-subvalue">{{ row.subvalue }}</span>
|
||||
<template v-if="row.entries">
|
||||
<div v-for="(entry, entryIdx) in row.entries" :key="entryIdx" class="member-field-entry">
|
||||
<span class="member-field-value">{{ entry.period }}: {{ entry.value }}</span>
|
||||
<span v-if="entry.subvalue" class="member-field-subvalue">{{ entry.subvalue }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="member-field-value">{{ row.value }}</span>
|
||||
<span v-if="row.subvalue" class="member-field-subvalue">{{ row.subvalue }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -399,19 +407,43 @@ export default {
|
||||
{ icon: "fa-barcode", label: "No. Anggota", value: u.no_anggota || "—" },
|
||||
{ icon: "fa-building", label: "Unit", value: u.unit || "—" },
|
||||
{
|
||||
key: "saham",
|
||||
icon: "fa-line-chart",
|
||||
label: "Saham",
|
||||
value: "RM " + fmt(u.saham),
|
||||
subvalue: dividendSub(u.saham, u.dividen_saham, 40)
|
||||
entries: [
|
||||
{
|
||||
period: "Sehingga Jun 2025",
|
||||
value: "RM " + fmt(u.saham),
|
||||
subvalue: dividendSub(u.saham, u.dividen_saham, 40)
|
||||
},
|
||||
{
|
||||
period: "Terkumpul Sehingga Mei 2026",
|
||||
value: "RM " + fmt(u.saham_terkini)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "yuran",
|
||||
icon: "fa-money",
|
||||
label: "Yuran",
|
||||
value: "RM " + fmt(u.yuran),
|
||||
subvalue: dividendSub(u.yuran, u.dividen_yuran, 8)
|
||||
entries: [
|
||||
{
|
||||
period: "Sehingga Jun 2025",
|
||||
value: "RM " + fmt(u.yuran),
|
||||
subvalue: dividendSub(u.yuran, u.dividen_yuran, 8)
|
||||
},
|
||||
{
|
||||
period: "Terkumpul Sehingga Mei 2026",
|
||||
value: "RM " + fmt(u.yuran_terkini)
|
||||
}
|
||||
]
|
||||
},
|
||||
{ icon: "fa-bank", label: "Simpanan Khas (Tabung 1) - (Sehingga Dis 2025)", value: "RM " + fmt(u.accumulated_amount) },
|
||||
{ icon: "fa-percent", label: "Dividen Simpanan Khas (Tabung 1) Tahun 2025", value: "RM " + fmt(u.pelaburan) }
|
||||
{
|
||||
icon: "fa-bank",
|
||||
label: "Simpanan Khas (Tabung 1) - (Sehingga Dis 2025)",
|
||||
value: "RM " + fmt(u.accumulated_amount),
|
||||
subvalue: dividendSub(u.accumulated_amount, u.pelaburan, 12)
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
@@ -1043,6 +1075,20 @@ export default {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.member-field-entry {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.member-field-entry+.member-field-entry {
|
||||
margin-top: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px dashed #e2e8f0;
|
||||
}
|
||||
|
||||
.member-field-value {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
|
||||
@@ -47,6 +47,10 @@ export default {
|
||||
}),
|
||||
|
||||
created: function () {
|
||||
if (!this.util.isLogin()) {
|
||||
this.$router.replace({ name: 'Voter Login' });
|
||||
return;
|
||||
}
|
||||
this.refreshInfo();
|
||||
},
|
||||
|
||||
@@ -81,7 +85,7 @@ export default {
|
||||
axios.post(config.API + 'voter/logout')
|
||||
.catch(function () { })
|
||||
.finally(function () {
|
||||
localStorage.clear();
|
||||
vm.util.clearSession();
|
||||
vm.$router.push({ name: 'Voter Login' });
|
||||
});
|
||||
},
|
||||
@@ -105,10 +109,14 @@ export default {
|
||||
vm.data.result = response.data.result;
|
||||
})
|
||||
.catch(error => {
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(error, 'error') == 401) {
|
||||
vm.$router.push({ name: 'Voter Login' });
|
||||
var status = error.response ? error.response.status : 500;
|
||||
if (status === 401) {
|
||||
vm.util.clearSession();
|
||||
vm.$router.replace({ name: 'Voter Login' });
|
||||
return;
|
||||
}
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error, 'error');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +157,9 @@ export default {
|
||||
.then(response => {
|
||||
vm.stopLoading();
|
||||
if (this.util.showResult(response, 'success')) {
|
||||
localStorage.removeItem('admin_role');
|
||||
localStorage.removeItem('admin_session');
|
||||
localStorage['Access Token'] = `Bearer ${response.data.token}`;
|
||||
this.util.setAuthorization();
|
||||
this.util.persistLoginSession(response.data.token, response.data.token_expires_at, {
|
||||
clearAdminSession: true
|
||||
});
|
||||
vm.$router.push({ name: 'Voter Home' });
|
||||
}
|
||||
})
|
||||
|
||||
Vendored
+72
-1
@@ -14,7 +14,78 @@ const methods = {
|
||||
* @return {Boolean} isLogin
|
||||
*/
|
||||
isLogin: function () {
|
||||
return localStorage['Access Token'] ? true : false;
|
||||
if (!localStorage['Access Token']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isSessionExpired()) {
|
||||
this.clearSession();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
isSessionExpired: function () {
|
||||
var expiresAt = localStorage.getItem('token_expires_at');
|
||||
if (!expiresAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Date.now() >= new Date(expiresAt).getTime();
|
||||
},
|
||||
|
||||
clearSession: function () {
|
||||
localStorage.removeItem('Access Token');
|
||||
localStorage.removeItem('token_expires_at');
|
||||
localStorage.removeItem('admin_role');
|
||||
localStorage.removeItem('admin_session');
|
||||
localStorage.removeItem('is_impersonating');
|
||||
delete axios.defaults.headers.common['Authorization'];
|
||||
},
|
||||
|
||||
persistLoginSession: function (token, expiresAt, options) {
|
||||
options = options || {};
|
||||
var bearer = token.indexOf('Bearer ') === 0 ? token : 'Bearer ' + token;
|
||||
localStorage['Access Token'] = bearer;
|
||||
|
||||
if (expiresAt) {
|
||||
localStorage.setItem('token_expires_at', expiresAt);
|
||||
} else {
|
||||
localStorage.removeItem('token_expires_at');
|
||||
}
|
||||
|
||||
if (options.adminRole !== undefined && options.adminRole !== null) {
|
||||
localStorage.setItem('admin_role', String(options.adminRole));
|
||||
}
|
||||
|
||||
if (options.adminSession) {
|
||||
localStorage.setItem('admin_session', '1');
|
||||
}
|
||||
|
||||
if (options.clearAdminSession) {
|
||||
localStorage.removeItem('admin_role');
|
||||
localStorage.removeItem('admin_session');
|
||||
}
|
||||
|
||||
this.setAuthorization();
|
||||
},
|
||||
|
||||
handleUnauthorized: function (router) {
|
||||
var isAdminPath = window.location.pathname.indexOf('/admin') === 0;
|
||||
this.clearSession();
|
||||
|
||||
if (!router || !router.currentRoute) {
|
||||
window.location.href = isAdminPath ? '/admin/login' : '/login';
|
||||
return;
|
||||
}
|
||||
|
||||
var routeName = router.currentRoute.name;
|
||||
if (routeName === 'Voter Login' || routeName === 'Admin Login') {
|
||||
return;
|
||||
}
|
||||
|
||||
router.replace({ name: isAdminPath ? 'Admin Login' : 'Voter Login' });
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user