diff --git a/src/components/ImportReceiptHistoryModal.vue b/src/components/ImportReceiptHistoryModal.vue new file mode 100644 index 0000000..9c5f642 --- /dev/null +++ b/src/components/ImportReceiptHistoryModal.vue @@ -0,0 +1,371 @@ + + + + + diff --git a/src/services/importReceiptService.js b/src/services/importReceiptService.js index a05d43b..4a5b50b 100644 --- a/src/services/importReceiptService.js +++ b/src/services/importReceiptService.js @@ -145,6 +145,17 @@ export async function rejectImportReceipt(receiptId, reason) { } } +export async function getImportReceiptHistory(receiptId) { + try { + const { data } = await importReceiptClient.get(`/api/import-receipts/${receiptId}/history`, { + headers: getAuthorizationHeader(), + }) + return data + } catch (error) { + throw normalizeImportReceiptError(error, 'Không thể tải lịch sử duyệt.') + } +} + // ===== Các chức năng xử lý hàng về & kiểm hàng từ dev ===== export async function confirmArrival(receiptId) { diff --git a/src/style.css b/src/style.css index 46c6298..be1cf8d 100644 --- a/src/style.css +++ b/src/style.css @@ -59,6 +59,8 @@ a { color: inherit; text-decoration: none; } .btn-ghost { border-color: transparent; background: transparent; color: var(--primary); } .btn-icon { width: 36px; padding: 0; } .btn-sm { min-height: 32px; padding: 6px 10px; font-size: 13px; } +.btn-secondary { border-color: #6366f1; background: #6366f1; color: #fff; } +.btn-secondary:hover { background: #4f46e5; border-color: #4f46e5; } .input, .select, .textarea { width: 100%; min-height: 40px; border: 1px solid var(--border); border-radius: 8px; background: #fff; padding: 9px 12px; color: var(--text); outline: none; } .textarea { min-height: 88px; resize: vertical; } diff --git a/src/views/ApprovalsView.vue b/src/views/ApprovalsView.vue index 00026ec..c65c4b6 100644 --- a/src/views/ApprovalsView.vue +++ b/src/views/ApprovalsView.vue @@ -3,6 +3,7 @@ import { computed, onMounted, reactive, ref } from 'vue' import { useRouter } from 'vue-router' import PageHeader from '../components/PageHeader.vue' import DataTable from '../components/DataTable.vue' +import ImportReceiptHistoryModal from '../components/ImportReceiptHistoryModal.vue' import { approveImportReceipt, getApprovalDetail, @@ -33,6 +34,9 @@ const detailState = reactive({ open: false, loading: false, error: '', receipt: // Modal từ chối (T98) const rejectState = reactive({ open: false, receiptId: null, reason: '', error: '', submitting: false }) +// Modal Lịch sử duyệt +const historyState = reactive({ open: false, receiptId: null, receiptCode: '' }) + const REJECT_REASON_MAX = 500 const columns = [ @@ -213,6 +217,18 @@ function isAnyActionRunning(receipt) { return actionState.receiptId === receipt.id } +function openHistory(receipt) { + historyState.receiptId = receipt.id + historyState.receiptCode = receipt.code + historyState.open = true +} + +function closeHistory() { + historyState.open = false + historyState.receiptId = null + historyState.receiptCode = '' +} + function statusLabel(status) { return statusLabels[status] || status || '-' } @@ -264,6 +280,7 @@ function formatCurrency(value) {