164 lines
6.0 KiB
Plaintext
164 lines
6.0 KiB
Plaintext
@{
|
|
ViewData["Title"] = "Overtime Pending Approval";
|
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
|
}
|
|
|
|
<style>
|
|
body {
|
|
background-color: #f3f4f6;
|
|
font-family: Arial, sans-serif;
|
|
}
|
|
|
|
.table-layer {
|
|
background-color: #fff;
|
|
border-radius: 10px;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
padding: 25px;
|
|
margin-top: 30px;
|
|
border: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.table-container table {
|
|
width: 100%;
|
|
}
|
|
|
|
.header {
|
|
background-color: #007bff;
|
|
color: white;
|
|
text-align: center;
|
|
}
|
|
|
|
.btn-sm {
|
|
font-size: 0.75rem;
|
|
}
|
|
</style>
|
|
|
|
<div id="app" style="max-width: 1300px; margin: auto; font-size: 13px;">
|
|
<div class="mb-3 d-flex flex-wrap">
|
|
<div class="me-2 mb-2">
|
|
<label>Month</label>
|
|
<select class="form-control form-control-sm" v-model="selectedMonth" v-on:change="loadData">
|
|
<option v-for="(m, i) in months" :value="i + 1">{{ m }}</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-2">
|
|
<label>Year</label>
|
|
<select class="form-control form-control-sm" v-model="selectedYear" v-on:change="loadData">
|
|
<option v-for="y in years" :value="y">{{ y }}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-layer">
|
|
<div class="table-container table-responsive">
|
|
<table class="table table-bordered table-sm table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th class="header">Staff Name</th>
|
|
<th class="header">Date Submit</th>
|
|
<th class="header" v-if="userRoles.includes('HoU')">HoU Status</th>
|
|
<th class="header" v-if="userRoles.includes('HoD')">HoD Status</th>
|
|
<th class="header" v-if="userRoles.includes('Manager')">Manager Status</th>
|
|
<th class="header" v-if="userRoles.includes('HR')">HR Status</th>
|
|
<th class="header">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="row in otStatusList" :key="row.statusId">
|
|
<td>{{ row.fullName }}</td>
|
|
<td>{{ formatDate(row.submitDate) }}</td>
|
|
<td v-if="userRoles.includes('HoU')">{{ row.houStatus }}</td>
|
|
<td v-if="userRoles.includes('HoD')">{{ row.hodStatus }}</td>
|
|
<td v-if="userRoles.includes('Manager')">{{ row.managerStatus }}</td>
|
|
<td v-if="userRoles.includes('HR')">{{ row.hrStatus }}</td>
|
|
<td>
|
|
<button class="btn btn-success btn-sm me-1" v-on:click="updateStatus(row.statusId, 'Approved')">Approve</button>
|
|
<button class="btn btn-danger btn-sm me-1" v-on:click="updateStatus(row.statusId, 'Rejected')">Reject</button>
|
|
<button class="btn btn-primary btn-sm" v-on:click="viewOtData(row.statusId)">View</button>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
</tbody>
|
|
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const app = Vue.createApp({
|
|
data() {
|
|
return {
|
|
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
|
years: Array.from({ length: 10 }, (_, i) => new Date().getFullYear() - 5 + i),
|
|
selectedMonth: new Date().getMonth() + 1,
|
|
selectedYear: new Date().getFullYear(),
|
|
otStatusList: [],
|
|
userRoles: []
|
|
};
|
|
},
|
|
methods: {
|
|
loadData() {
|
|
fetch(`/OvertimeAPI/GetPendingApproval?month=${this.selectedMonth}&year=${this.selectedYear}`)
|
|
.then(res => {
|
|
if (!res.ok) throw new Error("Network response was not OK");
|
|
return res.json();
|
|
})
|
|
.then(result => {
|
|
this.userRoles = result.roles;
|
|
this.otStatusList = result.data;
|
|
})
|
|
.catch(err => {
|
|
console.error("Error loading data:", err);
|
|
});
|
|
},
|
|
formatDate(dateStr) {
|
|
const d = new Date(dateStr);
|
|
return d.toLocaleDateString();
|
|
},
|
|
updateStatus(statusId, decision) {
|
|
console.log('statusId received:', statusId); // Add this for immediate inspection
|
|
if (!statusId) {
|
|
console.error("Invalid statusId passed to updateStatus.");
|
|
return;
|
|
}
|
|
|
|
const actionText = decision === 'Approved' ? 'approve' : 'reject';
|
|
const confirmed = confirm(`Are you sure you want to ${actionText} this request?`);
|
|
|
|
if (!confirmed) return;
|
|
|
|
fetch('/OvertimeAPI/UpdateApprovalStatus', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ statusId: statusId, decision: decision })
|
|
})
|
|
.then(res => {
|
|
if (!res.ok) throw new Error("Failed to update status");
|
|
return res.json();
|
|
})
|
|
.then(() => {
|
|
this.loadData(); // Refresh table
|
|
})
|
|
.catch(err => {
|
|
console.error("Error updating status:", err);
|
|
});
|
|
},
|
|
viewOtData(statusId) {
|
|
// Navigate to another page with the statusId in query string
|
|
window.location.href = `/OTcalculate/ApprovalDashboard/OtReview?statusId=${statusId}`;
|
|
|
|
}
|
|
|
|
},
|
|
mounted() {
|
|
this.loadData();
|
|
}
|
|
});
|
|
|
|
app.mount('#app');
|
|
</script>
|
|
|
|
|