trangshopeeaffiliate/resources/views/history/index.blade.php
2026-07-11 22:56:22 +07:00

248 lines
13 KiB
PHP

@extends('layouts.app')
@section('title', 'Lịch sử chuyển đổi')
@section('content')
<div class="row">
<div class="col-12">
<!-- Bulk Action Header -->
<div class="mb-3 d-flex align-items-center justify-content-between">
<div>
<p class="m-0 text-muted small">Chọn các dòng cần xóa hoặc quản link</p>
</div>
<div>
<button type="button" id="btn-bulk-delete" class="btn btn-danger btn-sm d-none shadow-sm fw-bold" onclick="submitBulkDelete()">
<i class="bi bi-trash3-fill me-1"></i> Xóa mục đã chọn (<span id="select-count">0</span>)
</button>
</div>
</div>
<div class="card shadow-sm">
<div class="card-body table-responsive p-0">
<table class="table table-hover align-middle text-nowrap">
<thead>
<tr>
<th style="width: 40px;" class="px-3">
<input type="checkbox" id="select-all" class="form-check-input">
</th>
<th>Thời gian</th>
<th>Kênh Zalo</th>
<th>Khách hàng</th>
<th>Link gốc</th>
<th>Link rút gọn</th>
<th>Lượt click</th>
<th>Trạng thái</th>
<th class="text-end px-3">Hành động</th>
</tr>
</thead>
<tbody>
@forelse($histories as $history)
<tr>
<td class="px-3">
<input type="checkbox" value="{{ $history->id }}" class="form-check-input history-checkbox">
</td>
<td>{{ $history->created_at->format('H:i:s d/m/Y') }}</td>
<td>
@if($history->zalo_thread_id)
<div class="d-flex align-items-center gap-3">
<div>
<span class="d-block fw-bold text-primary" title="Thread ID: {{ $history->zalo_thread_id }}">
<i class="bi bi-chat-dots-fill me-1"></i> {{ $history->zalo_chat_name ?? 'Nhóm Zalo' }}
</span>
<small class="text-muted" style="font-size: 0.75rem;">ID: {{ $history->zalo_thread_id }}</small>
</div>
<div>
<form action="{{ route('zalo_channels.quick_toggle') }}" method="POST" class="d-inline">
@csrf
<input type="hidden" name="thread_id" value="{{ $history->zalo_thread_id }}">
<input type="hidden" name="name" value="{{ $history->zalo_chat_name }}">
@if(in_array($history->zalo_thread_id, $allowedThreadIds))
<button type="submit" class="btn btn-danger btn-sm py-0 px-2 fw-bold text-white shadow-sm" style="font-size: 0.75rem;" title="Ngắt kết nối Bot với nhóm này">
<i class="bi bi-slash-circle-fill"></i> Chặn
</button>
@else
<button type="submit" class="btn btn-success btn-sm py-0 px-2 fw-bold text-white shadow-sm" style="font-size: 0.75rem;" title="Cho phép Bot phản hồi nhóm này">
<i class="bi bi-check-circle-fill"></i> Cho phép
</button>
@endif
</form>
</div>
</div>
@else
<span class="badge text-bg-secondary px-2"><i class="bi bi-globe me-1"></i> Web Rút Gọn</span>
@endif
</td>
<td>
@if($history->customer_name || $history->customer_phone)
<span class="d-block fw-bold text-dark">{{ $history->customer_name ?: 'Ẩn danh' }}</span>
@if($history->customer_phone)
<small class="text-muted"><i class="bi bi-telephone-fill me-1" style="font-size: 0.7rem;"></i>{{ $history->customer_phone }}</small>
@endif
@else
<span class="text-muted">-</span>
@endif
</td>
<td>
<a href="{{ $history->original_url }}" target="_blank" class="text-truncate d-inline-block" style="max-width: 250px;" title="{{ $history->original_url }}">{{ $history->original_url }}</a>
</td>
<td>
@if($history->code)
@php
$domainSetting = app(\App\Services\SettingService::class)->get('short_link_domain');
if ($domainSetting) {
$shortUrl = rtrim($domainSetting, '/') . '/aff/s/' . $history->code;
} else {
$shortUrl = route('short_link.redirect', ['code' => $history->code]);
}
@endphp
<div class="d-inline-flex align-items-center gap-2">
<a href="{{ $shortUrl }}" target="_blank" class="fw-bold text-success">{{ $shortUrl }}</a>
<button type="button" onclick="copyToClipboard('{{ $shortUrl }}', this)" class="btn btn-outline-primary btn-sm py-0 px-1 border-0" title="Copy Link">
<i class="bi bi-clipboard"></i>
</button>
</div>
@elseif($history->affiliate_url)
<a href="{{ $history->affiliate_url }}" target="_blank" class="text-truncate d-inline-block" style="max-width: 250px;">{{ $history->affiliate_url }}</a>
@else
<span class="text-muted">-</span>
@endif
</td>
<td>
<span class="badge text-bg-info px-2 py-1 text-white" style="font-weight: 600;"><i class="bi bi-eye-fill me-1"></i> {{ number_format($history->clicks) }}</span>
</td>
<td>
@if($history->status === 'success')
<span class="badge text-bg-success"><i class="bi bi-check-circle me-1"></i> Thành công</span>
@elseif($history->zalo_thread_id && $history->status === 'failed' && str_contains($history->error_message, 'restricted'))
<span class="badge text-bg-warning text-dark" title="{{ $history->error_message }}"><i class="bi bi-slash-circle me-1"></i> Bị chặn (Whitelist)</span>
@else
<span class="badge text-bg-danger" title="{{ $history->error_message }}"><i class="bi bi-exclamation-triangle me-1"></i> Thất bại</span>
@endif
</td>
<td class="text-end px-3">
<button type="button" onclick="deleteSingle({{ $history->id }})" class="btn btn-outline-danger btn-sm py-1 px-2 border-0" title="Xóa lịch sử">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
@empty
<tr>
<td colspan="9" class="text-center py-4 text-muted">Không tìm thấy lịch sử nào.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@if($histories->hasPages())
<div class="card-footer clearfix bg-light">
{{ $histories->links() }}
</div>
@endif
</div>
</div>
</div>
<!-- Hidden Bulk & Single Delete Forms -->
<form id="bulk-delete-form" action="{{ route('history.bulk_destroy') }}" method="POST" style="display:none;">
@csrf
@method('DELETE')
</form>
<form id="single-delete-form" method="POST" style="display:none;">
@csrf
@method('DELETE')
</form>
@endsection
@push('scripts')
<script>
const selectAllCheckbox = document.getElementById('select-all');
const checkboxes = document.querySelectorAll('.history-checkbox');
const bulkDeleteBtn = document.getElementById('btn-bulk-delete');
const selectCountSpan = document.getElementById('select-count');
const bulkDeleteForm = document.getElementById('bulk-delete-form');
const singleDeleteForm = document.getElementById('single-delete-form');
// Toggle select all checkboxes
if (selectAllCheckbox) {
selectAllCheckbox.addEventListener('change', function() {
checkboxes.forEach(cb => {
cb.checked = this.checked;
});
updateBulkDeleteButton();
});
}
// Toggle single checkbox
checkboxes.forEach(cb => {
cb.addEventListener('change', function() {
if (!this.checked) {
selectAllCheckbox.checked = false;
} else {
const allChecked = Array.from(checkboxes).every(c => c.checked);
selectAllCheckbox.checked = allChecked;
}
updateBulkDeleteButton();
});
});
// Update bulk action button visibility
function updateBulkDeleteButton() {
const checkedCount = Array.from(checkboxes).filter(c => c.checked).length;
if (selectCountSpan) selectCountSpan.textContent = checkedCount;
if (checkedCount > 0) {
bulkDeleteBtn.classList.remove('d-none');
} else {
bulkDeleteBtn.classList.add('d-none');
}
}
// Trigger Bulk Delete Submit (append checked IDs dynamically)
function submitBulkDelete() {
const checkedBoxes = Array.from(checkboxes).filter(c => c.checked);
if (checkedBoxes.length === 0) return;
if (confirm(`Bạn có chắc chắn muốn xóa ${checkedBoxes.length} lịch sử đã chọn không?`)) {
// Remove old dynamic ID inputs from form if any
const existingInputs = bulkDeleteForm.querySelectorAll('input[name="ids[]"]');
existingInputs.forEach(input => input.remove());
// Create and append dynamic input fields for each checked item ID
checkedBoxes.forEach(cb => {
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = 'ids[]';
hiddenInput.value = cb.value;
bulkDeleteForm.appendChild(hiddenInput);
});
bulkDeleteForm.submit();
}
}
// Trigger Single Delete
function deleteSingle(id) {
if (confirm('Bạn có chắc muốn xóa lịch sử chuyển đổi này không?')) {
singleDeleteForm.action = `/history/${id}`;
singleDeleteForm.submit();
}
}
// Clipboard copy helper
function copyToClipboard(text, button) {
navigator.clipboard.writeText(text).then(() => {
const icon = button.querySelector('i');
icon.className = 'bi bi-check-lg';
button.className = 'btn btn-success btn-sm py-0 px-1 border-0';
setTimeout(() => {
icon.className = 'bi bi-clipboard';
button.className = 'btn btn-outline-primary btn-sm py-0 px-1 border-0';
}, 1500);
}).catch(err => {
console.error('Không thể copy link:', err);
});
}
</script>
@endpush