PSTW_CentralizeSystem/Areas/OTcalculate/Views/Overtime/OtStatus.cshtml
2025-05-13 17:13:30 +08:00

150 lines
5.9 KiB
Plaintext

@{
ViewData["Title"] = "Overtime Status";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
.white-box {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-top: 20px;
}
</style>
<div id="app" style="max-width: 1300px; margin: auto; font-size: 13px;">
<div class="table-layer">
<div class="white-box">
<div class="table-container table-responsive">
<table id="otStatusTable" class="table table-bordered table-sm table-striped">
<thead>
<tr>
<th>Month/Year</th>
<th>Submit Date</th>
<th v-if="includeHou">HoU Status</th>
<th v-if="includeHod">HoD Status</th>
<th v-if="includeManager">Manager Status</th>
<th v-if="includeHr">HR Status</th>
<th>Updated</th>
<th>File</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in otRecords" :key="index">
<td>{{ formatMonthYear(item.month, item.year) }}</td>
<td>{{ formatDate(item.submitDate) }}</td>
<td v-if="includeHou">{{ item.houStatus ?? '-' }}</td>
<td v-if="includeHod">{{ item.hodStatus ?? '-' }}</td>
<td v-if="includeManager">{{ item.managerStatus ?? '-' }}</td>
<td v-if="includeHr">{{ item.hrStatus ?? '-' }}</td>
<td>{{ item.updated ? 'Yes' : 'No' }}</td>
<td>
<button v-if="item.filePath" class="btn btn-sm btn-primary" v-on:click ="previewFile(item.filePath)">
View
</button>
<span v-else>-</span>
</td>
</tr>
<tr v-if="otRecords.length === 0">
<td :colspan="columnCount" class="text-center">No records found.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div v-if="showPreview" class="modal-backdrop">
<div class="modal-dialog-box">
<div class="modal-header" style="background-color: white;">
<h5 class="modal-title">File Preview</h5>
<button type="button" class="btn-close" aria-label="Close Preview" v-on:click ="closePreview"></button>
</div>
<div class="modal-body">
<iframe :src="previewUrl" width="100%" height="650px" style="border: none;"></iframe>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
const app = Vue.createApp({
data() {
return {
otRecords: [],
includeHou: false,
includeHod: false,
includeManager: false,
includeHr: false,
showPreview: false,
previewUrl: ''
};
},
computed: {
columnCount() {
let count = 3; // Month/Year, SubmitDate, Updated
if (this.includeHou) count++;
if (this.includeHod) count++;
if (this.includeManager) count++;
if (this.includeHr) count++;
return count + 1; // File column
}
},
mounted() {
fetch('/OvertimeAPI/GetUserOtStatus')
.then(res => res.json())
.then(data => {
this.includeHou = data.includeHou;
this.includeHod = data.includeHod;
this.includeManager = data.includeManager;
this.includeHr = data.includeHr;
this.otRecords = (data.otStatuses || []).sort((a, b) => {
// Sort in descending order of SubmitDate (latest first)
return new Date(b.submitDate) - new Date(a.submitDate);
});
this.$nextTick(() => {
// Delay to ensure table is rendered
if ($.fn.dataTable.isDataTable('#otStatusTable')) {
$('#otStatusTable').DataTable().destroy();
}
$('#otStatusTable').DataTable({
responsive: true,
pageLength: 10,
order: []
});
});
})
.catch(err => {
console.error("Error fetching OT records:", err);
});
},
methods: {
formatDate(dateStr) {
const date = new Date(dateStr);
return date.toLocaleDateString();
},
formatMonthYear(month, year) {
if (!month || !year) return '-';
return `${month.toString().padStart(2, '0')}/${year}`;
},
previewFile(path) {
this.previewUrl = '/' + path.replace(/^\/+/, '');
this.showPreview = true;
document.body.style.overflow = 'hidden';
},
closePreview() {
this.previewUrl = '';
this.showPreview = false;
document.body.style.overflow = '';
}
}
});
app.mount('#app');
</script>
}