all feature

This commit is contained in:
antv
2026-06-29 11:55:33 +07:00
parent 08d13336cd
commit 8a77324f89
59 changed files with 5587 additions and 145 deletions
+146
View File
@@ -0,0 +1,146 @@
@extends('layouts.app')
@section('title', 'Gửi Thank Card')
@section('content')
<div class="form-container">
<div class="form-header">
<h3 class="form-header-title">Gửi Thank Card Tới Đồng Nghiệp</h3>
</div>
<form id="sendCardForm">
@csrf
<div class="form-body">
<div class="form-group">
<label class="form-label" for="receiver">Chọn người nhận <span class="text-red-500">*</span></label>
<select name="receiver" id="receiver" class="form-input" required>
<option value="" disabled selected>-- Chọn đồng nghiệp --</option>
@foreach($users as $u)
<option value="{{ $u->msnv }}">{{ $u->msnv }} ({{ $u->mail }})</option>
@endforeach
</select>
</div>
<div class="form-group">
<label class="form-label" for="amount">Số lượng thẻ <span class="text-red-500">*</span></label>
<select name="amount" id="amount" class="form-input" required>
<option value="1">1 Thẻ</option>
<option value="2">2 Thẻ</option>
<option value="3">3 Thẻ</option>
<option value="4">4 Thẻ</option>
<option value="{{ \App\Models\Administration::MAX_SEND_CARD_PER_MONTH }}">{{ \App\Models\Administration::MAX_SEND_CARD_PER_MONTH }} Thẻ (Tối đa)</option>
</select>
<p class="helper-text">Lưu ý: Chỉ được gửi tối đa {{ \App\Models\Administration::MAX_SEND_CARD_PER_MONTH }} thẻ cho cùng 1 người trong 1 tháng.</p>
</div>
</div>
<div class="form-footer">
<a href="{{ route('user.dashboard') }}" class="btn-secondary">Hủy bỏ</a>
<button type="button" id="btnSubmitSend" class="btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5 mr-2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5" />
</svg>
Gửi Card
</button>
</div>
</form>
</div>
<!-- Custom Popup Modal -->
<x-modal id="customModal" title="Thông báo" maxWidth="md">
<p id="modalMessage" class="text-sm text-gray-600 leading-relaxed"></p>
<x-slot name="footer">
<div id="modalActions" class="w-full flex flex-col sm:flex-row-reverse gap-3">
<!-- Buttons injected by JS -->
</div>
</x-slot>
</x-modal>
@endsection
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function () {
const btnSubmit = document.getElementById('btnSubmitSend');
const form = document.getElementById('sendCardForm');
const modalTitle = document.getElementById('modal-title-customModal');
const modalMessage = document.getElementById('modalMessage');
const modalActions = document.getElementById('modalActions');
const showModal = (title, message, isConfirm, confirmCallback) => {
modalTitle.textContent = title;
modalMessage.innerHTML = message;
if(isConfirm) {
modalTitle.className = "text-lg font-bold text-primary";
modalActions.innerHTML = `
<button id="btnConfirmOk" class="w-full sm:w-auto btn-primary !px-6 shadow-sm">Xác nhận gửi</button>
<button id="btnCancel" class="w-full sm:w-auto btn-secondary !px-6 shadow-sm">Hủy</button>
`;
document.getElementById('btnCancel').addEventListener('click', () => window.closeModal('customModal'));
document.getElementById('btnConfirmOk').addEventListener('click', function() {
this.disabled = true;
this.innerHTML = '<span class="flex items-center gap-2"><svg class="animate-spin h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> Đang xử lý...</span>';
confirmCallback();
});
} else {
modalTitle.className = "text-lg font-bold text-red-600";
modalActions.innerHTML = `
<button id="btnOkOnly" class="w-full sm:w-auto btn-secondary !px-6 shadow-sm">Đóng</button>
`;
document.getElementById('btnOkOnly').addEventListener('click', () => window.closeModal('customModal'));
}
window.openModal('customModal');
};
btnSubmit.addEventListener('click', function() {
if(!form.checkValidity()) {
form.reportValidity();
return;
}
const receiver = document.getElementById('receiver').value;
const amount = document.getElementById('amount').value;
showModal(
'Xác nhận gửi Thank Card',
`Bạn có chắc chắn muốn gửi <b>${amount} thẻ</b> cho nhân viên <span class="font-bold text-primary">${receiver}</span> không? <br><br><span class="text-xs text-text-light">Hành động này không thể hoàn tác, tin nhắn CO sẽ được gửi đi!</span>`,
true,
() => {
fetch('{{ route('user.store_send') }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({
receiver: receiver,
amount: amount
})
})
.then(response => response.json().then(data => ({status: response.status, body: data})))
.then(res => {
if (res.status === 200 && res.body.success) {
alert(res.body.message);
window.location.href = '{{ route('user.dashboard') }}';
} else {
window.closeModal('customModal');
setTimeout(() => {
showModal('Lỗi Giao Dịch', res.body.message || 'Có lỗi xảy ra, vui lòng thử lại.', false, null);
}, 350);
}
})
.catch(err => {
window.closeModal('customModal');
setTimeout(() => {
showModal('Lỗi Hệ Thống', 'Không thể kết nối đến máy chủ.', false, null);
}, 350);
});
}
);
});
});
</script>
@endpush