Files
worker/html/point-complaint.html
2025-10-24 11:31:48 +07:00

632 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Khiếu nại Giao dịch điểm - EuroTile Worker</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="page-wrapper">
<!-- Header -->
<div class="header">
<a href="points-history.html" class="back-button">
<i class="fas fa-arrow-left"></i>
</a>
<h1 class="header-title">Khiếu nại Giao dịch điểm</h1>
</div>
<div class="complaint-content">
<!-- Transaction Info Card -->
<div class="transaction-info-card">
<h3><i class="fas fa-receipt"></i> Thông tin giao dịch</h3>
<div class="transaction-details">
<div class="detail-row">
<span class="detail-label">Mã giao dịch:</span>
<span class="detail-value" id="transactionId">TXN123456</span>
</div>
<div class="detail-row">
<span class="detail-label">Loại giao dịch:</span>
<span class="detail-value" id="transactionTitle">Mua hàng tại cửa hàng</span>
</div>
<div class="detail-row">
<span class="detail-label">Ngày giao dịch:</span>
<span class="detail-value" id="transactionDate">22/09/2023 17:23:18</span>
</div>
</div>
</div>
<!-- Complaint Form -->
<div class="complaint-form-card">
<h3><i class="fas fa-edit"></i> Nội dung khiếu nại</h3>
<form id="complaintForm">
<!-- Complaint Type -->
<div class="form-group">
<label class="form-label">Lý do khiếu nại *</label>
<div class="complaint-types">
<label class="complaint-type-option">
<input type="radio" name="complaintType" value="incorrect-points" required>
<span class="radio-custom"></span>
<div class="option-content">
<div class="option-title">Số điểm không chính xác</div>
<div class="option-description">Số điểm được cộng/trừ không đúng</div>
</div>
</label>
<label class="complaint-type-option">
<input type="radio" name="complaintType" value="wrong-transaction" required>
<span class="radio-custom"></span>
<div class="option-content">
<div class="option-title">Giao dịch không phải của tôi</div>
<div class="option-description">Tôi không thực hiện giao dịch này</div>
</div>
</label>
<label class="complaint-type-option">
<input type="radio" name="complaintType" value="missing-points" required>
<span class="radio-custom"></span>
<div class="option-content">
<div class="option-title">Thiếu điểm thưởng</div>
<div class="option-description">Không nhận được điểm sau giao dịch</div>
</div>
</label>
<label class="complaint-type-option">
<input type="radio" name="complaintType" value="other" required>
<span class="radio-custom"></span>
<div class="option-content">
<div class="option-title">Lý do khác</div>
<div class="option-description">Vấn đề khác liên quan đến giao dịch</div>
</div>
</label>
</div>
</div>
<!-- Detailed Description -->
<div class="form-group">
<label class="form-label" for="complaintContent">Mô tả chi tiết vấn đề *</label>
<textarea
id="complaintContent"
class="form-textarea"
rows="5"
placeholder="Vui lòng mô tả chi tiết vấn đề bạn gặp phải với giao dịch này. Thông tin càng chi tiết sẽ giúp chúng tôi xử lý nhanh chóng hơn."
required></textarea>
<div class="form-help">Tối thiểu 20 ký tự</div>
</div>
<!-- Evidence Upload -->
<div class="form-group">
<label class="form-label">Ảnh minh chứng (tùy chọn)</label>
<div class="evidence-upload-section">
<div class="upload-area" onclick="document.getElementById('evidenceFiles').click()">
<div class="upload-placeholder">
<i class="fas fa-camera"></i>
<div class="upload-text">
<div class="upload-title">Tải ảnh minh chứng</div>
<div class="upload-subtitle">Hóa đơn, ảnh chụp màn hình...</div>
</div>
</div>
<input type="file" id="evidenceFiles" multiple accept="image/*" style="display: none;" onchange="handleFileUpload(this)">
</div>
<div class="uploaded-files" id="uploadedFiles"></div>
</div>
<div class="form-help">Tối đa 5 ảnh, mỗi ảnh không quá 10MB</div>
</div>
<!-- Contact Info -->
<div class="form-group">
<label class="form-label" for="contactPhone">Số điện thoại liên hệ</label>
<input
type="tel"
id="contactPhone"
class="form-input"
placeholder="0901234567"
value="0901234567">
<div class="form-help">Để nhận thông báo kết quả xử lý</div>
</div>
</form>
</div>
<!-- Policy Notice -->
<div class="policy-notice">
<div class="notice-content">
<i class="fas fa-info-circle"></i>
<div class="notice-text">
<div class="notice-title">Lưu ý quan trọng</div>
<ul class="notice-list">
<li>Khiếu nại sẽ được xử lý trong vòng 3-5 ngày làm việc</li>
<li>Vui lòng cung cấp thông tin chính xác và đầy đủ</li>
<li>Chúng tôi có thể liên hệ để xác minh thông tin</li>
<li>Kết quả sẽ được thông báo qua SMS và email</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="submit-container">
<button class="submit-btn" onclick="submitComplaint()">
<i class="fas fa-paper-plane"></i>
Gửi Khiếu nại
</button>
</div>
</div>
<style>
.complaint-content {
padding: 0 0 100px 0;
}
/* Transaction Info Card */
.transaction-info-card,
.complaint-form-card {
background: var(--white);
margin: 16px;
padding: 20px;
border-radius: 12px;
box-shadow: var(--shadow-light);
}
.transaction-info-card h3,
.complaint-form-card h3 {
font-size: 16px;
font-weight: 600;
color: var(--text-dark);
margin: 0 0 16px 0;
display: flex;
align-items: center;
gap: 8px;
}
.transaction-details {
background: var(--background-gray);
padding: 16px;
border-radius: 8px;
}
.detail-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
}
.detail-row:last-child {
margin-bottom: 0;
}
.detail-label {
color: var(--text-light);
font-size: 14px;
}
.detail-value {
font-weight: 600;
color: var(--text-dark);
text-align: right;
flex: 1;
margin-left: 12px;
}
/* Complaint Types */
.complaint-types {
display: flex;
flex-direction: column;
gap: 12px;
}
.complaint-type-option {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
border: 2px solid var(--border-color);
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
}
.complaint-type-option:hover {
border-color: var(--primary-blue);
background: var(--background-gray);
}
.complaint-type-option input[type="radio"] {
display: none;
}
.radio-custom {
width: 20px;
height: 20px;
border: 2px solid var(--border-color);
border-radius: 50%;
position: relative;
flex-shrink: 0;
margin-top: 2px;
transition: all 0.3s ease;
}
.complaint-type-option input[type="radio"]:checked + .radio-custom {
border-color: var(--primary-blue);
}
.complaint-type-option input[type="radio"]:checked + .radio-custom::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
background: var(--primary-blue);
border-radius: 50%;
}
.option-content {
flex: 1;
}
.option-title {
font-weight: 600;
color: var(--text-dark);
margin-bottom: 4px;
}
.option-description {
font-size: 13px;
color: var(--text-light);
line-height: 1.4;
}
/* Evidence Upload */
.evidence-upload-section {
border: 2px dashed var(--border-color);
border-radius: 12px;
overflow: hidden;
}
.upload-area {
padding: 24px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
}
.upload-area:hover {
background: var(--background-gray);
border-color: var(--primary-blue);
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.upload-placeholder i {
font-size: 32px;
color: var(--primary-blue);
}
.upload-title {
font-weight: 600;
color: var(--text-dark);
}
.upload-subtitle {
font-size: 13px;
color: var(--text-light);
}
.uploaded-files {
border-top: 1px solid var(--border-color);
background: var(--background-gray);
}
.uploaded-file {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
}
.uploaded-file:last-child {
border-bottom: none;
}
.file-info {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
}
.file-thumbnail {
width: 40px;
height: 40px;
border-radius: 6px;
object-fit: cover;
}
.file-name {
font-weight: 500;
color: var(--text-dark);
font-size: 14px;
}
.file-size {
font-size: 12px;
color: var(--text-light);
}
.file-remove {
width: 32px;
height: 32px;
border: none;
background: var(--danger-color);
color: white;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.file-remove:hover {
background: #c62828;
}
/* Policy Notice */
.policy-notice {
background: linear-gradient(135deg, #fff3e0, #ffeaa7);
border: 1px solid #ffb74d;
border-radius: 12px;
padding: 16px;
margin: 16px;
}
.notice-content {
display: flex;
gap: 12px;
}
.notice-content i {
color: #f57c00;
font-size: 20px;
flex-shrink: 0;
margin-top: 2px;
}
.notice-title {
font-weight: 600;
color: #e65100;
margin-bottom: 8px;
}
.notice-list {
list-style: none;
margin: 0;
padding: 0;
}
.notice-list li {
font-size: 13px;
color: #bf360c;
margin-bottom: 4px;
padding-left: 16px;
position: relative;
}
.notice-list li::before {
content: '•';
position: absolute;
left: 0;
color: #f57c00;
}
/* Submit Container */
.submit-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--white);
padding: 16px;
box-shadow: 0 -4px 15px rgba(0, 0, 0, 0.1);
z-index: 100;
}
.submit-btn {
width: 100%;
background: var(--primary-blue);
color: white;
border: none;
border-radius: 8px;
padding: 14px 20px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: all 0.3s ease;
}
.submit-btn:hover {
background: var(--light-blue);
}
.submit-btn:disabled {
background: var(--text-light);
cursor: not-allowed;
}
/* Mobile Responsiveness */
@media (max-width: 480px) {
.transaction-info-card,
.complaint-form-card,
.policy-notice {
margin: 12px;
padding: 16px;
}
.detail-row {
flex-direction: column;
gap: 4px;
}
.detail-value {
text-align: left;
margin-left: 0;
}
.complaint-type-option {
padding: 12px;
}
.upload-placeholder i {
font-size: 24px;
}
}
</style>
<script>
let uploadedFiles = [];
// Initialize page with transaction details from URL
document.addEventListener('DOMContentLoaded', function() {
const urlParams = new URLSearchParams(window.location.search);
const transactionId = urlParams.get('id') || 'TXN123456';
const transactionTitle = urlParams.get('title') || 'Mua hàng tại cửa hàng';
const transactionDate = urlParams.get('date') || '22/09/2023 17:23:18';
document.getElementById('transactionId').textContent = transactionId;
document.getElementById('transactionTitle').textContent = transactionTitle;
document.getElementById('transactionDate').textContent = transactionDate;
// Update page title
document.title = `Khiếu nại ${transactionId} - EuroTile Worker`;
});
function handleFileUpload(input) {
const files = Array.from(input.files);
files.forEach(file => {
if (uploadedFiles.length >= 5) {
alert('Tối đa 5 ảnh được phép tải lên');
return;
}
if (file.size > 10 * 1024 * 1024) {
alert(`File ${file.name} quá lớn. Vui lòng chọn file nhỏ hơn 10MB.`);
return;
}
if (!file.type.startsWith('image/')) {
alert(`File ${file.name} không phải là ảnh hợp lệ.`);
return;
}
const fileData = {
id: Date.now() + Math.random(),
file: file,
name: file.name,
size: formatFileSize(file.size),
thumbnail: URL.createObjectURL(file)
};
uploadedFiles.push(fileData);
renderUploadedFiles();
});
// Clear input
input.value = '';
}
function renderUploadedFiles() {
const container = document.getElementById('uploadedFiles');
if (uploadedFiles.length === 0) {
container.innerHTML = '';
return;
}
const filesHtml = uploadedFiles.map(file => `
<div class="uploaded-file">
<div class="file-info">
<img src="${file.thumbnail}" alt="${file.name}" class="file-thumbnail">
<div>
<div class="file-name">${file.name}</div>
<div class="file-size">${file.size}</div>
</div>
</div>
<button class="file-remove" onclick="removeFile(${file.id})">
<i class="fas fa-times"></i>
</button>
</div>
`).join('');
container.innerHTML = filesHtml;
}
function removeFile(fileId) {
const fileIndex = uploadedFiles.findIndex(f => f.id === fileId);
if (fileIndex > -1) {
URL.revokeObjectURL(uploadedFiles[fileIndex].thumbnail);
uploadedFiles.splice(fileIndex, 1);
renderUploadedFiles();
}
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function submitComplaint() {
// Validate form
const form = document.getElementById('complaintForm');
if (!form.checkValidity()) {
form.reportValidity();
return;
}
const complaintContent = document.getElementById('complaintContent').value.trim();
if (complaintContent.length < 20) {
alert('Vui lòng mô tả chi tiết hơn (tối thiểu 20 ký tự)');
document.getElementById('complaintContent').focus();
return;
}
// Get form data
const formData = new FormData(form);
const complaintType = formData.get('complaintType');
const contactPhone = document.getElementById('contactPhone').value;
// Show loading state
const submitBtn = document.querySelector('.submit-btn');
const originalContent = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Đang gửi...';
submitBtn.disabled = true;
// Simulate API call
setTimeout(() => {
alert('Khiếu nại đã được gửi thành công!\\n\\nMã khiếu nại: KN' + Date.now() + '\\nChúng tôi sẽ xử lý và phản hồi trong vòng 3-5 ngày làm việc.\\n\\nThông báo kết quả sẽ được gửi qua SMS: ' + contactPhone);
// Navigate back to points history
window.location.href = 'points-history.html';
}, 2000);
}
</script>
</body>
</html>