feat: [equipment] 설비 목록에 관리자 정/부 열 분리 및 QR 코드 열 추가
- 담당자 단일 열 → 관리자 정, 관리자 부 2열로 분리 - QR 코드 아이콘 열 추가 (클릭 시 모달로 QR 표시) - QR PNG 다운로드 기능 포함
This commit is contained in:
@@ -79,9 +79,29 @@ class="bg-white rounded-lg shadow-sm">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- QR 코드 모달 -->
|
||||
<div id="qrModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50" onclick="if(event.target===this)closeQrModal()">
|
||||
<div class="bg-white rounded-xl shadow-xl p-6 mx-4" style="max-width: 320px; width: 100%;">
|
||||
<div class="text-center mb-4">
|
||||
<p id="qrEquipCode" class="text-sm text-blue-600 font-mono"></p>
|
||||
<p id="qrEquipName" class="text-lg font-semibold text-gray-800"></p>
|
||||
</div>
|
||||
<div id="qrCanvas" class="flex justify-center mb-4"></div>
|
||||
<div class="flex gap-2">
|
||||
<button onclick="downloadQr()" class="flex-1 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-sm transition">
|
||||
PNG 다운로드
|
||||
</button>
|
||||
<button onclick="closeQrModal()" class="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg text-sm transition">
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
|
||||
<script>
|
||||
const FILTER_KEY = 'equipment_filter';
|
||||
const filterForm = document.getElementById('filterForm');
|
||||
@@ -127,6 +147,52 @@ function saveFilter() {
|
||||
saveFilter();
|
||||
});
|
||||
|
||||
let currentQrCode = null;
|
||||
let currentQrFileName = '';
|
||||
|
||||
function showQr(equipmentId, equipCode, equipName) {
|
||||
document.getElementById('qrEquipCode').textContent = equipCode;
|
||||
document.getElementById('qrEquipName').textContent = equipName;
|
||||
|
||||
const container = document.getElementById('qrCanvas');
|
||||
container.innerHTML = '';
|
||||
|
||||
const baseUrl = '{{ rtrim(config("app.url"), "/") }}';
|
||||
const url = baseUrl + '/m/inspect/' + equipmentId;
|
||||
|
||||
currentQrCode = new QRCode(container, {
|
||||
text: url,
|
||||
width: 200,
|
||||
height: 200,
|
||||
colorDark: '#000000',
|
||||
colorLight: '#ffffff',
|
||||
correctLevel: QRCode.CorrectLevel.M,
|
||||
});
|
||||
currentQrFileName = equipCode + '_' + equipName;
|
||||
|
||||
const modal = document.getElementById('qrModal');
|
||||
modal.classList.remove('hidden');
|
||||
modal.classList.add('flex');
|
||||
}
|
||||
|
||||
function closeQrModal() {
|
||||
const modal = document.getElementById('qrModal');
|
||||
modal.classList.add('hidden');
|
||||
modal.classList.remove('flex');
|
||||
}
|
||||
|
||||
function downloadQr() {
|
||||
const canvas = document.querySelector('#qrCanvas canvas');
|
||||
if (!canvas) return;
|
||||
canvas.toBlob(function(blob) {
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = 'QR_' + currentQrFileName + '.png';
|
||||
a.click();
|
||||
URL.revokeObjectURL(a.href);
|
||||
});
|
||||
}
|
||||
|
||||
function confirmDelete(id, name) {
|
||||
showDeleteConfirm(name, () => {
|
||||
fetch(`/api/admin/equipment/${id}`, {
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">위치</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">생산라인</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">상태</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">담당자</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">관리자 정</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">관리자 부</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">구입일</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">QR</th>
|
||||
<th class="px-3 py-2 text-center text-sm font-semibold text-gray-700">액션</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -40,9 +42,20 @@
|
||||
<td class="px-3 py-3 whitespace-nowrap text-sm text-center text-gray-600">
|
||||
{{ $eq->manager?->name ?? '-' }}
|
||||
</td>
|
||||
<td class="px-3 py-3 whitespace-nowrap text-sm text-center text-gray-600">
|
||||
{{ $eq->subManager?->name ?? '-' }}
|
||||
</td>
|
||||
<td class="px-3 py-3 whitespace-nowrap text-sm text-center text-gray-600">
|
||||
{{ $eq->purchase_date?->format('Y-m-d') ?? '-' }}
|
||||
</td>
|
||||
<td class="px-3 py-3 whitespace-nowrap text-sm text-center" onclick="event.stopPropagation()">
|
||||
<button type="button" onclick="showQr({{ $eq->id }}, '{{ addslashes($eq->equipment_code) }}', '{{ addslashes($eq->name) }}')"
|
||||
class="text-gray-500 hover:text-blue-600 transition" title="QR 코드">
|
||||
<svg class="w-5 h-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h7v7H3V3zm11 0h7v7h-7V3zM3 14h7v7H3v-7zm14 3h.01M17 14h3v3h-3v-3zm0 4h3v3h-3v-3zm-4 0h3v3h-3v-3z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</td>
|
||||
<td class="px-3 py-3 whitespace-nowrap text-sm text-center" onclick="event.stopPropagation()">
|
||||
<a href="{{ route('equipment.edit', $eq->id) }}" class="text-blue-600 hover:text-blue-900 mr-2">수정</a>
|
||||
<button onclick="confirmDelete({{ $eq->id }}, '{{ $eq->name }}')"
|
||||
@@ -51,7 +64,7 @@ class="text-red-600 hover:text-red-900">삭제</button>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-6 py-12 text-center text-gray-500">
|
||||
<td colspan="11" class="px-6 py-12 text-center text-gray-500">
|
||||
등록된 설비가 없습니다.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user