DONE: remove verified by ajk, fix bug on pagination, improve UI
This commit is contained in:
@@ -2,4 +2,11 @@
|
||||
[x] disable auto trigger tac
|
||||
[x] set the env back to production in prod
|
||||
[x] saham < rm500 cannot vote
|
||||
[x] note/ rujukan cannot be fetch on modal
|
||||
[x] note/ rujukan cannot be fetch on modal
|
||||
[X] butang daftar letak atas
|
||||
[x] pengesahan kehadiran perlu letak di atas (popup)
|
||||
[x] buang "disingikirkan daripada pusingan ..."
|
||||
[X] pindah kod tuntutan elaun ke atas
|
||||
[x] bug on pagination page (kehadiran)
|
||||
[x] hardcode on daftar kehadiran
|
||||
[x] buang flow pengesahan
|
||||
@@ -50,7 +50,7 @@ class VoteController extends Controller
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => 'Voted successfully',
|
||||
'message' => 'Undian anda telah berjaya dihantar.',
|
||||
'result' => Result::where('voter_id', Auth::id())->get()
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -96,9 +96,14 @@ class AttendanceController extends Controller
|
||||
$voter = Voter::findOrFail($id);
|
||||
$voter->fill($request->only(['name', 'no_kp', 'no_anggota', 'unit', 'kehadiran']));
|
||||
|
||||
// Skip admin verification phase for Fizikal.
|
||||
// When Fizikal is selected and (optionally) the counter gate code is valid, we auto-verify.
|
||||
// For non-Fizikal attendance, keep this field cleared.
|
||||
if ((int) $voter->kehadiran === 1) {
|
||||
$voter->fizikal_registration_verified_at = null;
|
||||
}
|
||||
$voter->fizikal_registration_verified_at = now();
|
||||
} else {
|
||||
$voter->fizikal_registration_verified_at = null;
|
||||
}
|
||||
|
||||
$voter->save();
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ class GetController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return $q->paginate(50);
|
||||
// Return all voters with pagination
|
||||
return $q->paginate(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+76383
-2
File diff suppressed because one or more lines are too long
@@ -1,53 +1,53 @@
|
||||
<template>
|
||||
<div>
|
||||
<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="">MyKoPKB</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: 'Kemaskini Jawatan'}" tag="li">
|
||||
<a href="#">Kemaskini Jawatan</a>
|
||||
</router-link>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<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="">MyKoPKB</a>
|
||||
</div>
|
||||
|
||||
<router-view></router-view>
|
||||
</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: 'Kemaskini Sesi' }" tag="li">
|
||||
<a href="#">Kemaskini Sesi</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: 'Log Masuk Admin ==='});
|
||||
return this.$router.push({ name: 'Log Masuk Admin ===' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.navbar-default {
|
||||
box-shadow: 0 1px 10px rgba(0,0,0,.5);
|
||||
background-color: #ffffff;
|
||||
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;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
margin-top: 70px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,57 +1,57 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><b>Tambah Jawatan</b></h3>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="name">Jawatan</label>
|
||||
<input type="text" name="name" class="form-control" required/>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><b>Tambah Sesi</b></h3>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="name">Jawatan</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 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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
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>'}
|
||||
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}
|
||||
{ title: 'ID', field: 'id' },
|
||||
{ title: 'name', field: 'name' },
|
||||
{ title: 'x', field: 'x' },
|
||||
{ title: '', field: 'btn', html: true }
|
||||
],
|
||||
data: [],
|
||||
|
||||
@@ -70,9 +70,9 @@ export default{
|
||||
console.log(this);
|
||||
},
|
||||
|
||||
watch : {
|
||||
watch: {
|
||||
'data.query': {
|
||||
handler (query) {
|
||||
handler(query) {
|
||||
this.data.data = this.xxx;
|
||||
this.data.total = this.yyy.length;
|
||||
},
|
||||
@@ -82,10 +82,10 @@ export default{
|
||||
},
|
||||
|
||||
computed: {
|
||||
xxx : function () {
|
||||
xxx: function () {
|
||||
var offset = this.data.query.offset; //0
|
||||
var limit = this.data.query.limit; //10
|
||||
return this.yyy.slice(offset, offset+limit);
|
||||
return this.yyy.slice(offset, offset + limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
<div class="roulette-elimination" :class="{ 'roulette-elimination--full-width': fullWidth }">
|
||||
<div class="row roulette-main-row">
|
||||
<div class="roulette-wheel-col" :class="wheelColumnClass">
|
||||
<div class="wheel-stage" role="button" :tabindex="wheelStageTabindex"
|
||||
:aria-disabled="!wheelCanSpin"
|
||||
<div class="wheel-stage" role="button" :tabindex="wheelStageTabindex" :aria-disabled="!wheelCanSpin"
|
||||
:aria-label="spinning ? 'Roda sedang berputar' : 'Putar roda — klik pada roda'"
|
||||
:class="{ 'wheel-stage--can-spin': wheelCanSpin }" @click="spin"
|
||||
@keydown.enter.prevent="spin" @keydown.space.prevent="spin">
|
||||
:class="{ 'wheel-stage--can-spin': wheelCanSpin }" @click="spin" @keydown.enter.prevent="spin"
|
||||
@keydown.space.prevent="spin">
|
||||
<div class="pointer" aria-hidden="true"></div>
|
||||
<div class="wheel-wrap" :style="wheelStyle" @transitionend="onSpinEnd">
|
||||
<canvas ref="wheelCanvas" class="wheel-canvas"></canvas>
|
||||
@@ -35,7 +34,7 @@
|
||||
Kurang daripada dua peserta dalam roda — tidak boleh putar lagi.
|
||||
</p>
|
||||
<p v-if="lastWinner && !spinning" class="last-winner">
|
||||
Terpilih: <strong>{{ lastWinner }}</strong> (disingkirkan daripada pusingan seterusnya)
|
||||
Terpilih: <strong>{{ lastWinner }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -21,22 +21,22 @@
|
||||
<router-link v-if="Number(data.user.role) !== 3" :to="{ name: 'Admin Home' }" tag="li"
|
||||
exact><a href="#"><b>Laman
|
||||
Utama</b></a></router-link>
|
||||
<router-link :to="{ name: 'Kemaskini Jawatan' }" v-if="data.user.role == 1" tag="li">
|
||||
<a href="#"><b>Jawatan</b></a>
|
||||
<router-link :to="{ name: 'Kemaskini Sesi' }" v-if="data.user.role == 1" tag="li">
|
||||
<a href="#"><b>Sesi</b></a>
|
||||
</router-link>
|
||||
|
||||
<!-- <router-link :to="{name: 'Manage Partylist'}" v-if="data.user.role==1" tag="li">
|
||||
<a href="#">Manage Partylist</a>
|
||||
</router-link> -->
|
||||
|
||||
<router-link :to="{ name: 'Manage Voter' }" v-if="data.user.role == 1" tag="li" exact>
|
||||
<a href="#"><b>Anggota Koperasi</b></a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{ name: 'Maklumat Calon' }" v-if="data.user.role == 1" tag="li">
|
||||
<a href="#"><b>Calon</b></a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{ name: 'Manage Voter' }" v-if="data.user.role == 1" tag="li" exact>
|
||||
<a href="#"><b>Anggota Koperasi</b></a>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{ name: 'Kehadiran Calon' }"
|
||||
v-if="data.user.role == 1 || Number(data.user.role) === 3" tag="li">
|
||||
<a href="#"><b>Kehadiran</b></a>
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
<h4 class="pull-left nominee-add-page__title">
|
||||
<i class="fa fa-user-plus text-muted"></i> Tambah Calon
|
||||
</h4>
|
||||
<router-link
|
||||
:to="{ name: 'Maklumat Calon', query: { position_id: position_id } }"
|
||||
class="btn btn-default pull-right"
|
||||
>
|
||||
<router-link :to="{ name: 'Maklumat Calon', query: { position_id: position_id } }"
|
||||
class="btn btn-default pull-right">
|
||||
<i class="fa fa-arrow-left"></i> Kembali
|
||||
</router-link>
|
||||
</div>
|
||||
@@ -17,41 +15,24 @@
|
||||
Lengkapkan maklumat calon. Medan bertanda <span class="text-danger">*</span> adalah wajib.
|
||||
</p>
|
||||
|
||||
<form
|
||||
class="nominee-add-form"
|
||||
method="POST"
|
||||
id="add_form"
|
||||
:action="data.API + 'nominee'"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="add()"
|
||||
>
|
||||
<form class="nominee-add-form" method="POST" id="add_form" :action="data.API + 'nominee'"
|
||||
enctype="multipart/form-data" @submit.prevent="add()">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="nominee-name">Nama Calon <span class="text-danger">*</span></label>
|
||||
<input
|
||||
id="nominee-name"
|
||||
type="text"
|
||||
name="name"
|
||||
class="form-control"
|
||||
placeholder="Nama penuh"
|
||||
required
|
||||
/>
|
||||
<input id="nominee-name" type="text" name="name" class="form-control"
|
||||
placeholder="Nama penuh" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="nominee-no-anggota">No. Anggota <span class="text-danger">*</span></label>
|
||||
<input
|
||||
id="nominee-no-anggota"
|
||||
type="text"
|
||||
name="no_anggota"
|
||||
class="form-control"
|
||||
placeholder="No. keahlian"
|
||||
required
|
||||
/>
|
||||
<label for="nominee-no-anggota">No. Anggota <span
|
||||
class="text-danger">*</span></label>
|
||||
<input id="nominee-no-anggota" type="text" name="no_anggota" class="form-control"
|
||||
placeholder="No. keahlian" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,80 +41,43 @@
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="nominee-unit">Unit <span class="text-danger">*</span></label>
|
||||
<input
|
||||
id="nominee-unit"
|
||||
type="text"
|
||||
name="unit"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<input id="nominee-unit" type="text" name="unit" class="form-control" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="nominee-umur">Umur <span class="text-danger">*</span></label>
|
||||
<input
|
||||
id="nominee-umur"
|
||||
type="number"
|
||||
name="umur"
|
||||
class="form-control"
|
||||
min="1"
|
||||
max="120"
|
||||
placeholder="Tahun"
|
||||
required
|
||||
/>
|
||||
<input id="nominee-umur" type="number" name="umur" class="form-control" min="1"
|
||||
max="120" placeholder="Tahun" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nominee-jawatan-sekarang">Jawatan Sekarang <span class="text-danger">*</span></label>
|
||||
<input
|
||||
id="nominee-jawatan-sekarang"
|
||||
type="text"
|
||||
name="jawatan_sekarang"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
<label for="nominee-jawatan-sekarang">Jawatan Sekarang <span
|
||||
class="text-danger">*</span></label>
|
||||
<input id="nominee-jawatan-sekarang" type="text" name="jawatan_sekarang"
|
||||
class="form-control" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nominee-education">Taraf Pendidikan</label>
|
||||
<input
|
||||
id="nominee-education"
|
||||
type="text"
|
||||
name="education"
|
||||
class="form-control"
|
||||
placeholder="Pilihan"
|
||||
/>
|
||||
<input id="nominee-education" type="text" name="education" class="form-control"
|
||||
placeholder="Pilihan" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nominee-experience">Pengalaman Kerja</label>
|
||||
<textarea
|
||||
id="nominee-experience"
|
||||
name="experience"
|
||||
class="form-control"
|
||||
rows="4"
|
||||
placeholder="Pilihan — senaraikan pengalaman relevan"
|
||||
></textarea>
|
||||
<textarea id="nominee-experience" name="experience" class="form-control" rows="4"
|
||||
placeholder="Pilihan — senaraikan pengalaman relevan"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nominee-position-id">Jawatan Dicalonkan <span class="text-danger">*</span></label>
|
||||
<select
|
||||
id="nominee-position-id"
|
||||
class="form-control"
|
||||
v-model="position_id"
|
||||
name="position_id"
|
||||
required
|
||||
>
|
||||
<option value="0" disabled>— Pilih jawatan —</option>
|
||||
<option
|
||||
v-for="position in data.positions"
|
||||
:key="position.id"
|
||||
:value="position.id"
|
||||
>
|
||||
<label for="nominee-position-id">Sesi Dicalonkan <span class="text-danger">*</span></label>
|
||||
<select id="nominee-position-id" class="form-control" v-model="position_id"
|
||||
name="position_id" required>
|
||||
<option value="0" disabled>— Pilih sesi —</option>
|
||||
<option v-for="position in data.positions" :key="position.id" :value="position.id">
|
||||
{{ position.name }}
|
||||
</option>
|
||||
</select>
|
||||
@@ -147,27 +91,20 @@
|
||||
<span class="text-muted small nominee-add-photo__hint">Pilihan</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div
|
||||
class="nominee-add-photo__preview"
|
||||
:class="{ 'nominee-add-photo__preview--empty': !imageUrl }"
|
||||
>
|
||||
<div class="nominee-add-photo__preview"
|
||||
:class="{ 'nominee-add-photo__preview--empty': !imageUrl }">
|
||||
<img v-if="imageUrl" :src="imageUrl" alt="Pratonton gambar calon" />
|
||||
<div v-else class="nominee-add-photo__placeholder">
|
||||
<i class="fa fa-picture-o"></i>
|
||||
<span>Tiada gambar dipilih</span>
|
||||
</div>
|
||||
</div>
|
||||
<label class="btn btn-default btn-block nominee-add-photo__browse" for="nominee-file-input">
|
||||
<label class="btn btn-default btn-block nominee-add-photo__browse"
|
||||
for="nominee-file-input">
|
||||
<i class="fa fa-folder-open"></i> Pilih fail
|
||||
</label>
|
||||
<input
|
||||
id="nominee-file-input"
|
||||
name="photo"
|
||||
type="file"
|
||||
class="nominee-add-photo__input"
|
||||
accept="image/*"
|
||||
@change="handleImageChange"
|
||||
/>
|
||||
<input id="nominee-file-input" name="photo" type="file" class="nominee-add-photo__input"
|
||||
accept="image/*" @change="handleImageChange" />
|
||||
<p class="text-muted small nominee-add-photo__formats">PNG, JPG atau GIF</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,10 +114,8 @@
|
||||
<hr class="nominee-add-form__rule" />
|
||||
|
||||
<div class="clearfix nominee-add-form__actions">
|
||||
<router-link
|
||||
:to="{ name: 'Maklumat Calon', query: { position_id: position_id } }"
|
||||
class="btn btn-default"
|
||||
>
|
||||
<router-link :to="{ name: 'Maklumat Calon', query: { position_id: position_id } }"
|
||||
class="btn btn-default">
|
||||
<i class="fa fa-times"></i> Batal
|
||||
</router-link>
|
||||
<button type="submit" class="btn btn-primary" :disabled="loading">
|
||||
@@ -365,7 +300,7 @@ export default {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.nominee-add-form__actions .btn + .btn {
|
||||
.nominee-add-form__actions .btn+.btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Tambah Jawatan</h4>
|
||||
<form @submit.prevent="add()" id="add-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Nama</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Hantar</button>
|
||||
<router-link :to="{name: 'Kemaskini Jawatan'}" class="btn btn-default">Kembali</router-link>
|
||||
</div>
|
||||
</form>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Tambah Sesi</h4>
|
||||
<form @submit.prevent="add()" id="add-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Nama</label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-success">Hantar</button>
|
||||
<router-link :to="{ name: 'Kemaskini Sesi' }" class="btn btn-default">Kembali</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
@@ -29,15 +29,15 @@ export default{
|
||||
this.loading = true;
|
||||
var vm = this;
|
||||
this.util.notify('Adding Position', 'loading')
|
||||
axios.post(config.API+'position', $('#add-form').serialize())
|
||||
.then(response=>{
|
||||
axios.post(config.API + 'position', $('#add-form').serialize())
|
||||
.then(response => {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
if (vm.util.showResult(response, 'success')) {
|
||||
vm.$router.push({name:'Kemaskini Jawatan', query:{refresh:true}});
|
||||
vm.$router.push({ name: 'Kemaskini Sesi', query: { refresh: true } });
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
.catch(error => {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Edit Jawatan</h4>
|
||||
<form @submit.prevent="edit()" id="edit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Nama</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: 'Kemaskini Jawatan'}" class="btn btn-default">Kembali</router-link>
|
||||
</div>
|
||||
</form>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4>Edit Sesi</h4>
|
||||
<form @submit.prevent="edit()" id="edit-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Nama</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: 'Kemaskini Sesi' }" class="btn btn-default">Kembali</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
loading: false
|
||||
@@ -26,7 +26,7 @@ export default{
|
||||
|
||||
created: function () {
|
||||
if (!this.data.position.id) {
|
||||
this.$router.push({name:'Kemaskini Jawatan'});
|
||||
this.$router.push({ name: 'Kemaskini Sesi' });
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,15 +36,15 @@ export default{
|
||||
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=>{
|
||||
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:'Kemaskini Jawatan', query:{refresh:true}});
|
||||
vm.$router.push({ name: 'Kemaskini Sesi', query: { refresh: true } });
|
||||
}
|
||||
})
|
||||
.catch(error=>{
|
||||
.catch(error => {
|
||||
$.notifyClose();
|
||||
vm.loading = false;
|
||||
vm.util.showResult(error);
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="form-group">
|
||||
<router-link class="btn btn-success" :to="{ name: 'Tambah Jawatan' }">
|
||||
<i class="fa fa-plus"></i> Tambah Jawatan
|
||||
<router-link class="btn btn-success" :to="{ name: 'Tambah Sesi' }">
|
||||
<i class="fa fa-plus"></i> Tambah Sesi
|
||||
</router-link>
|
||||
<button class="btn btn-default" @click="refreshPosition()">
|
||||
<i class="fa fa-refresh"></i> Kemaskini Jawatan
|
||||
<i class="fa fa-refresh"></i> Kemaskini Sesi
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -59,7 +59,7 @@ export default {
|
||||
created: function () {
|
||||
if (this.$route.query.refresh) {
|
||||
this.refreshPosition();
|
||||
this.$router.replace({ name: 'Kemaskini Jawatan' })
|
||||
this.$router.replace({ name: 'Kemaskini Sesi' })
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Kemaskini Jawatan</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<div class="container col-md-8 col-md-offset-2">
|
||||
<h4>Kemaskini Sesi</h4>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
export default {
|
||||
created: function () {
|
||||
this.util.setTitle('MyKoPKB-Kemaskini Jawatan');
|
||||
this.util.setTitle('MyKoPKB-Kemaskini Sesi');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
@@ -1,92 +1,24 @@
|
||||
<template>
|
||||
<div class="attendance-page row col-md-10 col-md-offset-1">
|
||||
<div class="col-md-12">
|
||||
<div class="attendance-hero">
|
||||
<div class="attendance-section-kicker">Pengesahan Kehadiran</div>
|
||||
<h4 class="attendance-page-title">Sahkan Kehadiran Mesyuarat Agung</h4>
|
||||
<p class="attendance-page-subtitle">
|
||||
Sila semak maklumat anda, pilih kaedah kehadiran, dan sahkan penyertaan sebelum meneruskan.
|
||||
</p>
|
||||
<a href="https://drive.google.com/uc?export=download&id=1O5DVDIbGy-w0bejV6RqtJGIty-_5LJD8"
|
||||
target="_blank" class="attendance-download-button">
|
||||
Muat Turun Etika Mesyuarat Agung
|
||||
</a>
|
||||
<div v-if="Number(data.user.kehadiran) === 0" class="attendance-info-top">
|
||||
<div class="attendance-info-top__kicker">Makluman</div>
|
||||
<div class="attendance-info-top__body">
|
||||
<p><strong>*</strong> Pendaftaran akan dibuka dari <strong>jam 7.00 pagi hingga 10.00
|
||||
pagi pada hari pengundian.</strong></p>
|
||||
<p>
|
||||
<strong>*</strong> Elaun kehadiran berjumlah <strong>RM300.00 (secara fizikal)</strong>
|
||||
akan
|
||||
diberikan secara TUNAI selepas mesyuarat. <br />
|
||||
Manakala <strong>RM150.00 (secara atas talian)</strong> akan dikreditkan ke akaun
|
||||
anggota
|
||||
yang
|
||||
hadir penuh.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="edit()" id="edit_form" class="attendance-card">
|
||||
<div class="attendance-card-header">
|
||||
<div>
|
||||
<div class="attendance-section-kicker">Maklumat Anggota</div>
|
||||
<h5 class="attendance-card-title">Butiran Kehadiran</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attendance-info-grid">
|
||||
<div class="form-group attendance-field">
|
||||
<label for="name">Nama</label>
|
||||
<input type="text" name="name" class="form-control attendance-input" readonly
|
||||
:value="data.user.name" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="no_kp">No. Kad Pengenalan</label>
|
||||
<input type="text" name="no_kp" class="form-control attendance-input" readonly
|
||||
:value="data.user.no_kp" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="no_anggota">No. Anggota</label>
|
||||
<input type="text" name="no_anggota" class="form-control attendance-input" readonly
|
||||
:value="data.user.no_anggota" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="unit">Unit</label>
|
||||
<input type="text" name="unit" class="form-control attendance-input" readonly
|
||||
:value="data.user.unit" required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sembunyikan borang pendaftaran selepas kehadiran telah dihantar -->
|
||||
<template v-if="Number(data.user.kehadiran) === 0">
|
||||
<div class="form-group attendance-choice-box">
|
||||
<label for="kehadiran">Kehadiran</label>
|
||||
<select v-model="selectedKehadiran" class="form-control attendance-select" id="kehadiran"
|
||||
name="kehadiran" required>
|
||||
<option value="0">Sila Pilih :</option>
|
||||
<option value="1">Fizikal</option>
|
||||
<option value="2">Maya</option>
|
||||
</select>
|
||||
<small class="form-text text-muted attendance-helper-text">
|
||||
Sila pilih kehadiran (Maya/Fizikal) kemudian klik “SAYA TERIMA”.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedKehadiran === '1'" class="form-group attendance-field">
|
||||
<label for="physical_gate_code">Kod skrin kaunter pendaftaran</label>
|
||||
<input type="text" name="physical_gate_code" id="physical_gate_code"
|
||||
class="form-control attendance-input" autocomplete="off" autocapitalize="characters"
|
||||
inputmode="text" placeholder="8 aksara, semak skrin di kaunter" maxlength="64"
|
||||
@input="onPhysicalGateCodeInput" />
|
||||
<small class="form-text text-muted attendance-helper-text">
|
||||
Kod berputar setiap minit — masukkan kod semasa yang dipaparkan di kaunter sebelum
|
||||
menghantar.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-4 small attendance-info-notice">
|
||||
<p><strong>*</strong> Pendaftaran akan dibuka dari <strong>jam 7.00 pagi hingga 10.00 pagi (25
|
||||
April
|
||||
2025)</strong>.</p>
|
||||
<p>
|
||||
<strong>*</strong> Elaun kehadiran berjumlah <strong>RM300.00 (secara fizikal)</strong> akan
|
||||
diberikan secara TUNAI selepas mesyuarat. <br />
|
||||
Manakala <strong>RM150.00 (secara atas talian)</strong> akan dikreditkan ke akaun anggota
|
||||
yang
|
||||
hadir penuh.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="text-center mt-4 attendance-action-area">
|
||||
<div v-if="data.user.kehadiran != 0 && canProceedToVote" class="attendance-success-card">
|
||||
@@ -128,21 +60,96 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-lg btn-success attendance-submit-button"
|
||||
v-else-if="electionVotingActive">
|
||||
DAFTAR KEHADIRAN
|
||||
</button>
|
||||
<div v-else class="alert alert-info text-left attendance-voting-notice">
|
||||
<p class="attendance-voting-notice__title"><strong>Butang “DAFTAR KEHADIRAN” belum
|
||||
tersedia</strong>
|
||||
</p>
|
||||
<p class="attendance-voting-notice__body">
|
||||
Buat masa ini proses undian / mesyuarat <strong>belum bermula</strong>.
|
||||
</p>
|
||||
<template v-else>
|
||||
<!-- Title -->
|
||||
<h5 class="attendance-section-kicker">Butiran Kehadiran</h5>
|
||||
<div class="attendance-register-box">
|
||||
<p class="attendance-precheck">
|
||||
Sila semak maklumat anda di bawah terlebih dahulu sebelum mendaftar kehadiran.
|
||||
</p>
|
||||
|
||||
<div class="form-group attendance-choice-box">
|
||||
<label for="kehadiran">Kehadiran</label>
|
||||
<select v-model="selectedKehadiran" class="form-control attendance-select"
|
||||
id="kehadiran" name="kehadiran" required>
|
||||
<option value="0">Sila Pilih :</option>
|
||||
<option value="1">Fizikal</option>
|
||||
<option value="2">Maya</option>
|
||||
</select>
|
||||
<small class="form-text text-muted attendance-helper-text">
|
||||
Sila pilih kehadiran (Maya/Fizikal) kemudian klik “SAYA TERIMA”.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedKehadiran === '1'" class="form-group attendance-field">
|
||||
<label for="physical_gate_code">Kod skrin kaunter pendaftaran</label>
|
||||
<input type="text" name="physical_gate_code" id="physical_gate_code"
|
||||
class="form-control attendance-input" autocomplete="off" autocapitalize="characters"
|
||||
inputmode="text" placeholder="8 aksara, semak skrin di kaunter" maxlength="64"
|
||||
@input="onPhysicalGateCodeInput" />
|
||||
<small class="form-text text-muted attendance-helper-text">
|
||||
Kod berputar setiap minit — masukkan kod semasa yang dipaparkan di kaunter sebelum
|
||||
menghantar.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="attendance-register-box__actions">
|
||||
<button type="submit" class="btn btn-lg btn-success attendance-submit-button"
|
||||
v-if="electionVotingActive">
|
||||
DAFTAR KEHADIRAN
|
||||
</button>
|
||||
<div v-else class="alert alert-info attendance-voting-notice">
|
||||
<p class="attendance-voting-notice__title"><strong>Butang “DAFTAR KEHADIRAN” belum
|
||||
tersedia</strong>
|
||||
</p>
|
||||
<p class="attendance-voting-notice__body">
|
||||
Buat masa ini proses undian / mesyuarat <strong>belum bermula</strong>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="attendance-info-grid">
|
||||
<div class="form-group attendance-field">
|
||||
<label for="name">Nama</label>
|
||||
<input type="text" name="name" class="form-control attendance-input" readonly
|
||||
:value="data.user.name" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="no_kp">No. Kad Pengenalan</label>
|
||||
<input type="text" name="no_kp" class="form-control attendance-input" readonly
|
||||
:value="data.user.no_kp" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="no_anggota">No. Anggota</label>
|
||||
<input type="text" name="no_anggota" class="form-control attendance-input" readonly
|
||||
:value="data.user.no_anggota" required />
|
||||
</div>
|
||||
|
||||
<div class="form-group attendance-field">
|
||||
<label for="unit">Unit</label>
|
||||
<input type="text" name="unit" class="form-control attendance-input" readonly
|
||||
:value="data.user.unit" required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div class="attendance-hero">
|
||||
<div class="attendance-section-kicker">Pengesahan Kehadiran</div>
|
||||
<h4 class="attendance-page-title">Sahkan Kehadiran Mesyuarat Agung</h4>
|
||||
<p class="attendance-page-subtitle">
|
||||
Sila semak maklumat anda, pilih kaedah kehadiran, dan sahkan penyertaan sebelum meneruskan.
|
||||
</p>
|
||||
<a href="https://drive.google.com/uc?export=download&id=1O5DVDIbGy-w0bejV6RqtJGIty-_5LJD8"
|
||||
target="_blank" class="attendance-download-button">
|
||||
Muat Turun Etika Mesyuarat Agung
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -155,6 +162,7 @@
|
||||
|
||||
.attendance-hero {
|
||||
margin-bottom: 22px;
|
||||
margin-top: 22px;
|
||||
padding: 26px 28px;
|
||||
border-radius: 22px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #eef6ff 100%);
|
||||
@@ -173,12 +181,6 @@
|
||||
}
|
||||
|
||||
.attendance-page-title,
|
||||
.attendance-card-title {
|
||||
margin: 0 0 8px;
|
||||
color: #17324d;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.attendance-page-subtitle {
|
||||
max-width: 700px;
|
||||
margin: 0 auto 18px;
|
||||
@@ -206,10 +208,6 @@
|
||||
box-shadow: 0 16px 34px rgba(35, 64, 97, 0.08);
|
||||
}
|
||||
|
||||
.attendance-card-header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.attendance-info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -255,6 +253,49 @@
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.attendance-precheck {
|
||||
margin: 0 0 12px;
|
||||
color: #5f7388;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.attendance-register-box {
|
||||
text-align: left;
|
||||
padding: 18px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid #e6edf6;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
|
||||
box-shadow: 0 14px 28px rgba(35, 64, 97, 0.08);
|
||||
}
|
||||
|
||||
.attendance-register-box__actions {
|
||||
margin-top: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.attendance-info-top {
|
||||
margin-bottom: 14px;
|
||||
padding: 16px 18px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #cfe2ff;
|
||||
background: linear-gradient(180deg, #f2f8ff 0%, #ffffff 100%);
|
||||
box-shadow: 0 10px 24px rgba(13, 110, 253, 0.08);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.attendance-info-top__kicker {
|
||||
margin-bottom: 8px;
|
||||
color: #0d6efd;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.attendance-info-top__body p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.attendance-info-notice {
|
||||
margin-bottom: 0;
|
||||
padding: 16px 18px;
|
||||
@@ -422,7 +463,8 @@ export default {
|
||||
},
|
||||
|
||||
/**
|
||||
* Maya (2) can vote once attendance is set. Fizikal (1) needs admin verification timestamp.
|
||||
* Maya (2) can vote once attendance is set. Fizikal (1) can proceed once verified timestamp exists.
|
||||
* (Backend now auto-verifies Fizikal on submit.)
|
||||
*/
|
||||
canProceedToVote: function () {
|
||||
var u = this.data && this.data.user;
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
<div class="home-hero-banner-shine" aria-hidden="true"></div>
|
||||
</div>
|
||||
<div class="hero-banner-caption home-hero-caption">
|
||||
<div class="hero-banner-kicker">Portal Pengundian</div>
|
||||
<h1 class="hero-banner-title">Maklumat Anggota</h1>
|
||||
<h1 class="hero-banner-title">Portal Pengundian</h1>
|
||||
<p class="hero-banner-subtitle">
|
||||
Semak butiran keahlian anda. Gunakan
|
||||
<strong class="home-hero-strong">pautan pantas</strong> di bawah untuk navigasi pantas ke halaman utama
|
||||
portal.
|
||||
Gunakan <strong class="home-hero-strong">pautan pantas</strong> di bawah untuk navigasi pantas ke
|
||||
halaman utama portal.
|
||||
</p>
|
||||
<div class="home-hero-badges">
|
||||
<span class="home-badge home-badge--location">
|
||||
@@ -31,6 +29,88 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Butiran Keahlian and Coupon Claim Code -->
|
||||
<div class="row home-content-row">
|
||||
<div class="col-xs-12 col-md-6 home-column home-column--primary">
|
||||
<!-- Member Information Card -->
|
||||
<div class="home-section-container">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon" aria-hidden="true"><i class="fa fa-list-alt"></i></span>
|
||||
Maklumat Anggota
|
||||
</h2>
|
||||
|
||||
<div v-if="showRegisterCta" class="home-member-cta">
|
||||
<div class="home-member-cta-hint home-member-cta-hint--warning" role="alert">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
<span>Sila semak butiran keahlian anda sebelum mendaftar kehadiran.</span>
|
||||
</div>
|
||||
<div class="home-member-cta-btn-container">
|
||||
<router-link :to="{ name: 'Attendance' }" class="btn btn-primary btn-block home-member-cta-btn">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
Daftar MAT Sekarang
|
||||
</router-link>
|
||||
</div>
|
||||
</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">
|
||||
<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>
|
||||
<span class="member-field-value">{{ row.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Coupon Claim Code Card -->
|
||||
<div class="col-xs-12 col-md-6 home-column home-column--secondary">
|
||||
<div class="home-claim-row">
|
||||
<div class="home-section-container home-section-container--claim">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon home-section-heading-icon--teal" aria-hidden="true"><i
|
||||
class="fa fa-ticket"></i></span>
|
||||
Kod Tuntutan Elaun
|
||||
</h2>
|
||||
<div class="home-claim-card">
|
||||
<div v-if="!canGenerateClaimCode" class="home-claim-locked">
|
||||
<div class="home-claim-locked-icon"><i class="fa fa-lock"></i></div>
|
||||
<p class="home-claim-locked-text">
|
||||
Kod tuntutan hanya tersedia untuk kehadiran <strong>Fizikal</strong> selepas anda
|
||||
<strong>selesai mengundi</strong>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="home-claim-active">
|
||||
<p class="home-claim-hint">
|
||||
Tunjukkan kod ini kepada petugas di kaunter untuk pengesahan bayaran tunai.
|
||||
</p>
|
||||
|
||||
<div v-if="claimError" class="alert alert-danger home-claim-alert">
|
||||
{{ claimError }}
|
||||
</div>
|
||||
|
||||
<div v-if="claimCode" class="home-claim-code-box">
|
||||
<div class="home-claim-code">{{ claimCode }}</div>
|
||||
<div class="home-claim-expiry">
|
||||
Tamat tempoh: <strong>{{ claimExpiresAt || '—' }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary btn-block home-claim-btn" :disabled="claimLoading"
|
||||
@click="generateClaimCode()">
|
||||
<i class="fa fa-refresh" :class="{ 'fa-spin': claimLoading }"></i>
|
||||
{{ claimLoading ? ' Menjana...' : (claimCode ? ' Jana Semula Kod' : ' Jana Kod Tuntutan') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pautan Pantas -->
|
||||
<div class="row home-quick-links-row">
|
||||
<div class="col-xs-12">
|
||||
<div class="home-section-container">
|
||||
@@ -63,6 +143,54 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kad Ahli Digital -->
|
||||
<div class="col-xs-12">
|
||||
<div class="home-section-container home-section-container--kad">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon" aria-hidden="true"><i class="fa fa-credit-card"></i></span>
|
||||
Kad Ahli Digital
|
||||
</h2>
|
||||
<div class="home-kad-wrap">
|
||||
<div class="kad-keahlian">
|
||||
<div class="member-card-vertical">MEMBER CARD</div>
|
||||
|
||||
<div class="kad-logo">
|
||||
<img src="/images/logo_kad.png" alt="Logo" class="kad-logo-img">
|
||||
</div>
|
||||
|
||||
<div class="kad-content">
|
||||
<img src="images/KOPKB_Final.png" class="watermark" alt="">
|
||||
|
||||
<div class="member-details">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NAMA:</span>
|
||||
<span class="detail-value">{{ data.user.name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NO KAD PENGENALAN:</span>
|
||||
<span class="detail-value">{{ data.user.no_kp }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NO ANGGOTA:</span>
|
||||
<span class="detail-value">{{ data.user.no_anggota }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">UNIT:</span>
|
||||
<span class="detail-value">{{ data.user.unit }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-item detail-item--barcode">
|
||||
<svg id="barcode" class="detail-value">{{ data.user.no_kp }}</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Saham Vote Blocked Message -->
|
||||
<div v-if="showSahamVoteBlockedMessage" class="row home-saham-block-row">
|
||||
<div class="col-xs-12">
|
||||
<div class="alert alert-warning home-saham-block-alert" role="alert">
|
||||
@@ -71,112 +199,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row home-content-row">
|
||||
<div class="col-xs-12 col-md-6 home-column home-column--primary">
|
||||
<div class="home-section-container">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon" aria-hidden="true"><i class="fa fa-list-alt"></i></span>
|
||||
Butiran Keahlian
|
||||
</h2>
|
||||
<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">
|
||||
<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>
|
||||
<span class="member-field-value">{{ row.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-6 home-column home-column--secondary">
|
||||
<div class="home-section-container home-section-container--claim">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon home-section-heading-icon--teal" aria-hidden="true"><i
|
||||
class="fa fa-ticket"></i></span>
|
||||
Kod Tuntutan Elaun
|
||||
</h2>
|
||||
<div class="home-claim-card">
|
||||
<div v-if="!canGenerateClaimCode" class="home-claim-locked">
|
||||
<div class="home-claim-locked-icon"><i class="fa fa-lock"></i></div>
|
||||
<p class="home-claim-locked-text">
|
||||
Kod tuntutan hanya tersedia untuk kehadiran <strong>Fizikal</strong> selepas anda
|
||||
<strong>selesai mengundi</strong>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="home-claim-active">
|
||||
<p class="home-claim-hint">
|
||||
Tunjukkan kod ini kepada petugas di kaunter untuk pengesahan bayaran tunai.
|
||||
</p>
|
||||
|
||||
<div v-if="claimError" class="alert alert-danger home-claim-alert">
|
||||
{{ claimError }}
|
||||
</div>
|
||||
|
||||
<div v-if="claimCode" class="home-claim-code-box">
|
||||
<div class="home-claim-code">{{ claimCode }}</div>
|
||||
<div class="home-claim-expiry">
|
||||
Tamat tempoh: <strong>{{ claimExpiresAt || '—' }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary btn-block home-claim-btn" :disabled="claimLoading"
|
||||
@click="generateClaimCode()">
|
||||
<i class="fa fa-refresh" :class="{ 'fa-spin': claimLoading }"></i>
|
||||
{{ claimLoading ? ' Menjana...' : (claimCode ? ' Jana Semula Kod' : ' Jana Kod Tuntutan') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="home-section-container home-section-container--kad">
|
||||
<h2 class="home-section-heading">
|
||||
<span class="home-section-heading-icon" aria-hidden="true"><i class="fa fa-credit-card"></i></span>
|
||||
Kad Ahli Digital
|
||||
</h2>
|
||||
<div class="home-kad-wrap">
|
||||
<div class="kad-keahlian">
|
||||
<div class="member-card-vertical">MEMBER CARD</div>
|
||||
|
||||
<div class="kad-logo">
|
||||
<img src="/images/logo_kad.png" alt="Logo" class="kad-logo-img">
|
||||
</div>
|
||||
|
||||
<div class="kad-content">
|
||||
<img src="images/KOPKB_Final.png" class="watermark" alt="">
|
||||
|
||||
<div class="member-details">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NAMA:</span>
|
||||
<span class="detail-value">{{ data.user.name }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NO KAD PENGENALAN:</span>
|
||||
<span class="detail-value">{{ data.user.no_kp }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">NO ANGGOTA:</span>
|
||||
<span class="detail-value">{{ data.user.no_anggota }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">UNIT:</span>
|
||||
<span class="detail-value">{{ data.user.unit }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-item detail-item--barcode">
|
||||
<svg id="barcode" class="detail-value">{{ data.user.no_kp }}</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -242,6 +264,15 @@ export default {
|
||||
? this.portalSettings.home_mat_label
|
||||
: "MAT KE-29";
|
||||
const links = [
|
||||
{
|
||||
key: "attendance",
|
||||
title: "Daftar MAT",
|
||||
desc: "Daftar kehadiran fizikal atau maya",
|
||||
icon: "fa-pencil-square-o",
|
||||
route: { name: "Attendance" },
|
||||
variant: "home-cta-link--teal",
|
||||
external: false
|
||||
},
|
||||
{
|
||||
key: "calon",
|
||||
title: "Maklumat Calon",
|
||||
@@ -259,15 +290,6 @@ export default {
|
||||
href: this.matLinkUrl,
|
||||
variant: "home-cta-link--violet",
|
||||
external: true
|
||||
},
|
||||
{
|
||||
key: "attendance",
|
||||
title: "Daftar MAT",
|
||||
desc: "Daftar kehadiran fizikal atau maya",
|
||||
icon: "fa-pencil-square-o",
|
||||
route: { name: "Attendance" },
|
||||
variant: "home-cta-link--teal",
|
||||
external: false
|
||||
}
|
||||
];
|
||||
|
||||
@@ -330,6 +352,11 @@ export default {
|
||||
return "Belum daftar kehadiran";
|
||||
},
|
||||
|
||||
showRegisterCta() {
|
||||
// Only show the registration CTA when user hasn't registered attendance yet.
|
||||
return Number(this.data?.user?.kehadiran) === 0;
|
||||
},
|
||||
|
||||
memberRows() {
|
||||
const u = this.data?.user || {};
|
||||
const fmt = (n) => {
|
||||
@@ -438,11 +465,26 @@ export default {
|
||||
}
|
||||
|
||||
.home-content-row {
|
||||
margin-top: 8px;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.home-quick-links-row {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.home-claim-row {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.home-content-row .home-column--secondary .home-claim-row {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.home-column--primary {
|
||||
padding-top: 4px;
|
||||
}
|
||||
@@ -456,6 +498,10 @@ export default {
|
||||
margin-top: 8px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.home-content-row .home-column--secondary .home-claim-row {
|
||||
margin-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
@@ -529,15 +575,6 @@ export default {
|
||||
0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
}
|
||||
|
||||
.hero-banner-kicker {
|
||||
margin-bottom: 10px;
|
||||
color: #2563eb;
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.hero-banner-title {
|
||||
margin: 0 0 10px;
|
||||
color: #0f172a;
|
||||
@@ -567,6 +604,73 @@ export default {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.home-hero-actions {
|
||||
margin: 14px 0 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.home-hero-register-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
font-weight: 800;
|
||||
font-size: 1.35rem;
|
||||
box-shadow: 0 10px 24px rgba(13, 110, 253, 0.35);
|
||||
}
|
||||
|
||||
.home-hero-register-hint {
|
||||
color: #64748b;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.home-member-cta {
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
|
||||
.home-member-cta-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
font-weight: 800;
|
||||
font-size: 1.35rem;
|
||||
box-shadow: 0 10px 24px rgba(13, 110, 253, 0.35);
|
||||
}
|
||||
|
||||
.home-member-cta-hint {
|
||||
margin-top: 8px;
|
||||
color: #64748b;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.home-member-cta-hint--warning {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
background: #fffbeb;
|
||||
border: 1px solid rgba(245, 158, 11, 0.45);
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.home-member-cta-hint--warning .fa {
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.home-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -56,9 +56,6 @@
|
||||
<img :src="nomineeViewed.photo" class="thumbnail nominee-viewed-photo" />
|
||||
<div class="nominee-photo-meta">
|
||||
<div class="nominee-name">{{ nomineeViewed.name }}</div>
|
||||
<div class="nominee-subtitle">
|
||||
Calon No. {{ nomineeViewed.no_calon || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -326,7 +323,8 @@ export default {
|
||||
.nominee-viewed-photo {
|
||||
width: 100%;
|
||||
height: 320px;
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
border: 0;
|
||||
border-radius: 14px;
|
||||
margin: 0 0 16px;
|
||||
@@ -459,11 +457,19 @@ export default {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.nominee-table thead th:nth-child(4),
|
||||
.nominee-table tbody td:nth-child(4),
|
||||
.nominee-table thead th:nth-child(5),
|
||||
.nominee-table tbody td:nth-child(5) {
|
||||
display: none;
|
||||
/* Show all columns on mobile; allow horizontal scroll via table-responsive */
|
||||
.nominee-thumb {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.nominee-table thead th {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.nominee-table tbody td {
|
||||
padding: 10px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,36 +6,6 @@
|
||||
<span>{{ sahamVoteBlockedMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 vote-sidebar-column">
|
||||
<div class="vote-summary-card">
|
||||
<div class="vote-section-kicker">Ringkasan Undian</div>
|
||||
<h4 class="vote-page-title">UNDIAN CALON ANGGOTA LEMBAGA</h4>
|
||||
<p class="vote-page-subtitle">Semak calon yang telah dipilih sebelum menghantar undi anda.</p>
|
||||
<div class="vote-limit-pill">
|
||||
Anda hanya boleh memilih <b>satu (1) orang calon</b> sahaja.
|
||||
</div>
|
||||
|
||||
<ul class="list-group vote-summary-list">
|
||||
<li class="list-group-item vote-summary-item">
|
||||
<div class="vote-position-name">Calon Dipilih</div>
|
||||
<div v-if="allSelectedNomineeIds.length" class="vote-selected-list">
|
||||
<div class="vote-selected-item" v-for="nominee_id in allSelectedNomineeIds" :key="nominee_id">
|
||||
<span class="vote-selected-badge">#{{ getNomineeNo(nominee_id) }}</span>
|
||||
<span>{{ getSelectedNomineeName(nominee_id) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="vote-empty-selection">
|
||||
Belum ada calon dipilih.
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="list-group-item vote-summary-action">
|
||||
<button class="btn btn-success btn-block vote-submit-button" :disabled="!canVoteBySaham"
|
||||
@click="checkUndi()">UNDI</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 vote-content-column">
|
||||
<div class="vote-content-header">
|
||||
<div>
|
||||
@@ -65,11 +35,12 @@
|
||||
<tbody>
|
||||
<tr v-for="(nominee, index) in data.nominees" v-if="nominee.position_id == position.id"
|
||||
:key="nominee.id" class="vote-row">
|
||||
<td class="vote-checkbox-cell"><input type="checkbox" :id="nominee.id" :disabled="disabledCheckboxes[index]"
|
||||
@change="vote(position.id, nominee.id)" />
|
||||
<td class="vote-checkbox-cell"><input type="checkbox" :id="nominee.id"
|
||||
:disabled="disabledCheckboxes[index]" @change="vote(position.id, nominee.id)" />
|
||||
</td>
|
||||
<td>{{ nominee.no_calon }}</td>
|
||||
<td><img @click="view(i)" :src="createBase64ImageUrl(nominee.photo)" class="thumbnail vote-nominee-photo" />
|
||||
<td><img @click="view(i)" :src="createBase64ImageUrl(nominee.photo)"
|
||||
class="thumbnail vote-nominee-photo" />
|
||||
</td>
|
||||
<td>{{ nominee.name }}</td>
|
||||
<td>{{ nominee.unit }}</td>
|
||||
@@ -80,8 +51,54 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade app-modal vote-confirm-modal" id="vote-modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="col-xs-12 vote-summary-bottom">
|
||||
<div class="vote-summary-card">
|
||||
<div class="vote-section-kicker">Ringkasan Undian</div>
|
||||
<h4 class="vote-page-title">UNDIAN CALON ANGGOTA LEMBAGA</h4>
|
||||
<p class="vote-page-subtitle">Semak calon yang telah dipilih sebelum menghantar undi anda.</p>
|
||||
<div class="vote-limit-pill">
|
||||
Anda hanya boleh memilih <b>satu (1) orang calon</b> sahaja.
|
||||
</div>
|
||||
|
||||
<ul class="list-group vote-summary-list">
|
||||
<li class="list-group-item vote-summary-item">
|
||||
<div class="vote-position-name">Calon Dipilih</div>
|
||||
<div v-if="allSelectedNomineeIds.length" class="vote-selected-list">
|
||||
<div class="vote-selected-item" v-for="nominee_id in allSelectedNomineeIds"
|
||||
:key="nominee_id">
|
||||
<span class="vote-selected-badge">#{{ getNomineeNo(nominee_id) }}</span>
|
||||
<span>{{ getSelectedNomineeName(nominee_id) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="vote-empty-selection">
|
||||
Belum ada calon dipilih.
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="list-group-item vote-summary-action">
|
||||
<button class="btn btn-success btn-block vote-submit-button" :disabled="!canVoteBySaham"
|
||||
@click="checkUndi()">UNDI</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vote-mobile-actionbar" v-if="canVoteBySaham">
|
||||
<div class="vote-mobile-actionbar__inner">
|
||||
<div class="vote-mobile-actionbar__meta">
|
||||
<div class="vote-mobile-actionbar__title">Undi</div>
|
||||
<div class="vote-mobile-actionbar__hint">
|
||||
Dipilih: <b>{{ allSelectedNomineeIds.length }}</b> / {{ max }}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-success vote-mobile-actionbar__btn" @click="checkUndi()">
|
||||
UNDI
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade app-modal vote-confirm-modal" id="vote-modal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content vote-modal-content">
|
||||
<div class="modal-header vote-modal-header">
|
||||
@@ -97,7 +114,8 @@
|
||||
<h5 class="vote-modal-note">Nota: Sila pastikan anda telah membuat undian dengan betul.</h5>
|
||||
<div class="vote-modal-selection" v-if="allSelectedNomineeIds.length">
|
||||
<div class="vote-modal-selection-title">Calon dipilih</div>
|
||||
<div class="vote-selected-item" v-for="nominee_id in allSelectedNomineeIds" :key="nominee_id">
|
||||
<div class="vote-selected-item" v-for="nominee_id in allSelectedNomineeIds"
|
||||
:key="nominee_id">
|
||||
<span class="vote-selected-badge">#{{ getNomineeNo(nominee_id) }}</span>
|
||||
<span>{{ getSelectedNomineeName(nominee_id) }}</span>
|
||||
</div>
|
||||
@@ -105,7 +123,8 @@
|
||||
</div>
|
||||
<div class="modal-footer vote-modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
||||
<button type="button" class="btn btn-primary" :disabled="!canVoteBySaham" @click="submit()">Hantar</button>
|
||||
<button type="button" class="btn btn-primary" :disabled="!canVoteBySaham"
|
||||
@click="submit()">Hantar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -371,17 +390,17 @@ export default {
|
||||
|
||||
.vote-sidebar-column,
|
||||
.vote-content-column {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
|
||||
.vote-summary-card {
|
||||
padding: 22px 20px;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
|
||||
border: 1px solid #e2ebf5;
|
||||
box-shadow: 0 16px 34px rgba(35, 64, 97, 0.08);
|
||||
position: sticky;
|
||||
top: 120px;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.vote-section-kicker {
|
||||
@@ -652,9 +671,56 @@ export default {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.vote-table thead th:nth-child(5),
|
||||
.vote-table tbody td:nth-child(5) {
|
||||
/* Keep Unit visible on mobile; hide photo column instead */
|
||||
.vote-table thead th:nth-child(3),
|
||||
.vote-table tbody td:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vote-content-column {
|
||||
padding-bottom: 86px;
|
||||
/* room for sticky action bar */
|
||||
}
|
||||
|
||||
.vote-mobile-actionbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1040;
|
||||
/* below modal (1050), above page */
|
||||
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
backdrop-filter: blur(10px);
|
||||
border-top: 1px solid #e5edf7;
|
||||
box-shadow: 0 -10px 24px rgba(35, 64, 97, 0.12);
|
||||
}
|
||||
|
||||
.vote-mobile-actionbar__inner {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.vote-mobile-actionbar__title {
|
||||
font-weight: 800;
|
||||
color: #17324d;
|
||||
}
|
||||
|
||||
.vote-mobile-actionbar__hint {
|
||||
color: #5f7388;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.vote-mobile-actionbar__btn {
|
||||
min-width: 140px;
|
||||
border-radius: 999px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
box-shadow: 0 12px 24px rgba(40, 167, 69, 0.24);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Vendored
+2
-2
@@ -98,13 +98,13 @@ const routes = [
|
||||
{
|
||||
path: "",
|
||||
component: ManagePositionIndex,
|
||||
name: "Kemaskini Jawatan",
|
||||
name: "Kemaskini Sesi",
|
||||
},
|
||||
|
||||
{
|
||||
path: "add",
|
||||
component: ManagePositionAdd,
|
||||
name: "Tambah Jawatan",
|
||||
name: "Tambah Sesi",
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
Vendored
+2
-2
@@ -198,13 +198,13 @@ export default [
|
||||
{
|
||||
path: "",
|
||||
component: ManagePositionIndex,
|
||||
name: "Kemaskini Jawatan",
|
||||
name: "Kemaskini Sesi",
|
||||
},
|
||||
|
||||
{
|
||||
path: "add",
|
||||
component: ManagePositionAdd,
|
||||
name: "Tambah Jawatan",
|
||||
name: "Tambah Sesi",
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user