update database

This commit is contained in:
Phuoc Nguyen
2025-10-24 11:31:48 +07:00
parent f95fa9d0a6
commit c4272f9a21
126 changed files with 23528 additions and 2234 deletions

757
html/my-gift-detail.html Normal file
View File

@@ -0,0 +1,757 @@
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chi tiết Quà tặng - 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">
<style>
.gift-detail-container {
min-height: calc(100vh - 120px);
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
}
.gift-card {
background: white;
border-radius: 20px;
padding: 30px 20px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
text-align: center;
position: relative;
overflow: hidden;
}
.gift-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
}
.gift-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
color: white;
font-size: 2rem;
}
.gift-title {
font-size: 1.5rem;
font-weight: 700;
color: #2d3748;
margin-bottom: 10px;
}
.gift-description {
color: #718096;
margin-bottom: 20px;
line-height: 1.5;
}
.voucher-code-section {
background: #f7fafc;
border: 2px dashed #e2e8f0;
border-radius: 12px;
padding: 20px;
margin: 20px 0;
position: relative;
}
.voucher-code {
font-size: 2rem;
font-weight: 800;
color: #2d3748;
font-family: 'Courier New', monospace;
letter-spacing: 2px;
margin-bottom: 10px;
text-align: center;
}
.copy-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
padding: 10px 20px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
margin: 0 auto;
}
.copy-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.qr-code-section {
background: white;
border-radius: 16px;
padding: 20px;
text-align: center;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
}
.qr-code-container {
background: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 12px;
padding: 20px;
margin: 15px 0;
display: inline-block;
}
.qr-code-placeholder {
width: 200px;
height: 200px;
background: #ffffff;
border: 2px dashed #dee2e6;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #6c757d;
font-size: 0.9rem;
margin: 0 auto;
}
.qr-code-placeholder i {
font-size: 3rem;
margin-bottom: 10px;
color: #adb5bd;
}
.gift-info-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin: 20px 0;
}
.info-item {
background: #f8f9fa;
padding: 15px;
border-radius: 12px;
text-align: center;
}
.info-label {
font-size: 0.8rem;
color: #6c757d;
margin-bottom: 5px;
font-weight: 500;
}
.info-value {
font-weight: 700;
color: #2d3748;
}
.status-badge {
display: inline-block;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
margin-bottom: 15px;
}
.status-valid {
background: #d4edda;
color: #155724;
}
.status-used {
background: #d1ecf1;
color: #0c5460;
}
.status-expired {
background: #f8d7da;
color: #721c24;
}
.action-buttons {
display: flex;
gap: 10px;
margin-top: 20px;
}
.btn-use {
flex: 1;
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
color: white;
border: none;
border-radius: 12px;
padding: 15px;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-use:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(40, 167, 69, 0.4);
}
.btn-use:disabled {
background: #6c757d;
cursor: not-allowed;
}
.btn-share {
background: #ffffff;
color: #667eea;
border: 2px solid #667eea;
border-radius: 12px;
padding: 15px 20px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-share:hover {
background: #667eea;
color: white;
}
.terms-section {
background: white;
border-radius: 16px;
padding: 20px;
margin-top: 20px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
}
.terms-title {
font-weight: 700;
color: #2d3748;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.terms-list {
color: #4a5568;
line-height: 1.6;
}
.terms-list li {
margin-bottom: 8px;
padding-left: 10px;
position: relative;
}
.terms-list li::before {
content: '•';
color: #667eea;
font-weight: bold;
position: absolute;
left: 0;
}
.usage-history {
background: white;
border-radius: 16px;
padding: 20px;
margin-top: 20px;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
}
.history-title {
font-weight: 700;
color: #2d3748;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.history-empty {
text-align: center;
color: #9ca3af;
padding: 20px;
font-style: italic;
}
.toast {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: #28a745;
color: white;
padding: 12px 24px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 1000;
display: none;
align-items: center;
gap: 8px;
font-weight: 500;
}
.toast.show {
display: flex;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateX(-50%) translateY(-20px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
@media (max-width: 768px) {
.gift-detail-container {
padding: 10px;
}
.gift-card {
padding: 20px 15px;
margin-bottom: 15px;
}
.voucher-code {
font-size: 1.5rem;
}
.qr-code-placeholder {
width: 150px;
height: 150px;
}
.gift-info-grid {
grid-template-columns: 1fr;
gap: 10px;
}
}
</style>
</head>
<body>
<div class="page-wrapper">
<!-- Header -->
<div class="header">
<a href="my-gifts.html" class="back-button">
<i class="fas fa-arrow-left"></i>
</a>
<h1 class="header-title">Chi tiết Quà tặng</h1>
<button class="icon-button" onclick="shareGift()">
<i class="fas fa-share-alt"></i>
</button>
</div>
<div class="gift-detail-container">
<!-- Gift Card -->
<div class="gift-card">
<div class="gift-icon">
<i class="fas fa-gift" id="giftIcon"></i>
</div>
<div class="status-badge" id="statusBadge">
Còn hạn sử dụng
</div>
<h2 class="gift-title" id="giftTitle">
Voucher giảm 100.000đ
</h2>
<p class="gift-description" id="giftDescription">
Áp dụng cho đơn hàng từ 2.000.000đ
</p>
<!-- Voucher Code Section -->
<div class="voucher-code-section">
<div class="voucher-code" id="voucherCode">
SAVE100K
</div>
<button class="copy-button" onclick="copyVoucherCode()">
<i class="fas fa-copy"></i>
Sao chép mã
</button>
</div>
<!-- Gift Info Grid -->
<div class="gift-info-grid">
<div class="info-item">
<div class="info-label">Hạn sử dụng</div>
<div class="info-value" id="expiryDate">31/12/2023</div>
</div>
<div class="info-item">
<div class="info-label">Giá trị</div>
<div class="info-value" id="giftValue">100.000đ</div>
</div>
</div>
<!-- Action Buttons -->
<div class="action-buttons">
<button class="btn-use" id="useButton" onclick="useGift()">
<i class="fas fa-check"></i>
Sử dụng ngay
</button>
<button class="btn-share" onclick="shareGift()">
<i class="fas fa-share-alt"></i>
</button>
</div>
</div>
<!-- QR Code Section -->
<div class="qr-code-section">
<h3 style="font-weight: 700; color: #2d3748; margin-bottom: 15px; text-align: center;">
<i class="fas fa-qrcode"></i>
Mã QR Code
</h3>
<p style="color: #6c757d; font-size: 0.9rem; margin-bottom: 15px;">
Đưa mã QR này cho nhân viên để quét tại cửa hàng
</p>
<div class="qr-code-container">
<div class="qr-code-placeholder" id="qrCodePlaceholder">
<i class="fas fa-qrcode"></i>
<div>Mã QR Code</div>
<div style="font-size: 0.8rem;" id="qrCodeValue">SAVE100K</div>
</div>
</div>
<p style="color: #6c757d; font-size: 0.8rem; margin-top: 10px;">
<i class="fas fa-info-circle"></i>
Mã QR sẽ tự động cập nhật khi bạn sử dụng voucher
</p>
</div>
<!-- Terms and Conditions -->
<div class="terms-section">
<h3 class="terms-title">
<i class="fas fa-list-check"></i>
Điều kiện sử dụng
</h3>
<ul class="terms-list" id="termsList">
<li>Áp dụng cho đơn hàng từ 2.000.000đ</li>
<li>Không áp dụng cùng với khuyến mãi khác</li>
<li>Chỉ sử dụng 1 lần duy nhất</li>
<li>Không hoàn trả hoặc đổi thành tiền mặt</li>
<li>Có thể sử dụng cho cả mua hàng online và offline</li>
</ul>
</div>
<!-- Usage History -->
<div class="usage-history">
<h3 class="history-title">
<i class="fas fa-history"></i>
Lịch sử sử dụng
</h3>
<div class="history-empty" id="usageHistory">
Chưa có lịch sử sử dụng
</div>
</div>
</div>
</div>
<!-- Toast Notification -->
<div class="toast" id="toast">
<i class="fas fa-check-circle"></i>
<span id="toastMessage">Đã sao chép mã voucher!</span>
</div>
<script>
// Gift data mapping
const giftDatabase = {
'SAVE100K': {
name: 'Voucher giảm 100.000đ',
description: 'Áp dụng cho đơn hàng từ 2.000.000đ',
icon: 'fas fa-percentage',
value: '100.000đ',
expiry: '31/12/2023',
minOrder: '2.000.000đ',
terms: [
'Áp dụng cho đơn hàng từ 2.000.000đ',
'Không áp dụng cùng với khuyến mãi khác',
'Chỉ sử dụng 1 lần duy nhất',
'Không hoàn trả hoặc đổi thành tiền mặt',
'Có thể sử dụng cho cả mua hàng online và offline'
]
},
'FREECERAMIC': {
name: 'Gạch ceramic miễn phí',
description: '1m² gạch ceramic 30x30 cao cấp',
icon: 'fas fa-gift',
value: '1m²',
expiry: '15/01/2024',
minOrder: 'Không có',
terms: [
'Áp dụng cho gạch ceramic 30x30 cao cấp',
'Tối đa 1m² mỗi voucher',
'Chỉ sử dụng 1 lần duy nhất',
'Phải đến cửa hàng để nhận hàng',
'Không áp dụng cùng với khuyến mãi khác'
]
},
'FREEDESIGN': {
name: 'Tư vấn thiết kế miễn phí',
description: 'Dịch vụ tư vấn thiết kế chuyên nghiệp',
icon: 'fas fa-star',
value: 'Miễn phí',
expiry: '28/02/2024',
minOrder: 'Không có',
terms: [
'Dịch vụ tư vấn thiết kế chuyên nghiệp',
'Thời gian tư vấn: 60 phút',
'Đặt lịch hẹn trước 24h',
'Áp dụng cho dự án từ 20m² trở lên',
'Bao gồm bản vẽ 2D cơ bản'
]
}
};
// Initialize page with gift data
document.addEventListener('DOMContentLoaded', function() {
const savedGift = localStorage.getItem('selectedGift');
if (savedGift) {
const giftData = JSON.parse(savedGift);
loadGiftDetails(giftData.code, giftData.status);
} else {
// Fallback to default gift
loadGiftDetails('SAVE100K', 'valid');
}
});
function loadGiftDetails(giftCode, status) {
const gift = giftDatabase[giftCode];
if (!gift) return;
// Update gift information
document.getElementById('giftTitle').textContent = gift.name;
document.getElementById('giftDescription').textContent = gift.description;
document.getElementById('voucherCode').textContent = giftCode;
document.getElementById('qrCodeValue').textContent = giftCode;
document.getElementById('giftValue').textContent = gift.value;
document.getElementById('expiryDate').textContent = gift.expiry;
// Update icon
const iconElement = document.getElementById('giftIcon');
iconElement.className = gift.icon;
// Update status
const statusBadge = document.getElementById('statusBadge');
const useButton = document.getElementById('useButton');
switch(status) {
case 'valid':
statusBadge.textContent = 'Còn hạn sử dụng';
statusBadge.className = 'status-badge status-valid';
useButton.disabled = false;
useButton.innerHTML = '<i class="fas fa-check"></i> Sử dụng ngay';
break;
case 'used':
statusBadge.textContent = 'Đã sử dụng';
statusBadge.className = 'status-badge status-used';
useButton.disabled = true;
useButton.innerHTML = '<i class="fas fa-check-circle"></i> Đã sử dụng';
updateUsageHistory();
break;
case 'expired':
statusBadge.textContent = 'Đã hết hạn';
statusBadge.className = 'status-badge status-expired';
useButton.disabled = true;
useButton.innerHTML = '<i class="fas fa-times-circle"></i> Hết hạn';
break;
}
// Update terms
const termsList = document.getElementById('termsList');
termsList.innerHTML = '';
gift.terms.forEach(term => {
const li = document.createElement('li');
li.textContent = term;
termsList.appendChild(li);
});
// Generate QR code placeholder (in a real app, this would be an actual QR code)
generateQRCodePlaceholder(giftCode);
}
function generateQRCodePlaceholder(code) {
const qrPlaceholder = document.getElementById('qrCodePlaceholder');
// In a real application, you would integrate with a QR code library
// For now, we'll create a styled placeholder
qrPlaceholder.innerHTML = `
<div style="
width: 100%;
height: 100%;
background: linear-gradient(45deg, #f8f9fa 25%, transparent 25%, transparent 75%, #f8f9fa 75%, #f8f9fa),
linear-gradient(45deg, #f8f9fa 25%, transparent 25%, transparent 75%, #f8f9fa 75%, #f8f9fa);
background-size: 10px 10px;
background-position: 0 0, 5px 5px;
border: 2px solid #333;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #333;
font-weight: bold;
">
<i class="fas fa-qrcode" style="font-size: 2rem; margin-bottom: 10px;"></i>
<div style="font-size: 0.8rem;">${code}</div>
</div>
`;
}
function copyVoucherCode() {
const voucherCode = document.getElementById('voucherCode').textContent;
// Copy to clipboard
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(voucherCode).then(() => {
showToast('Đã sao chép mã voucher!');
}).catch(() => {
fallbackCopyTextToClipboard(voucherCode);
});
} else {
fallbackCopyTextToClipboard(voucherCode);
}
}
function fallbackCopyTextToClipboard(text) {
const textArea = document.createElement("textarea");
textArea.value = text;
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
showToast('Đã sao chép mã voucher!');
} catch (err) {
showToast('Không thể sao chép. Vui lòng sao chép thủ công.', 'error');
}
document.body.removeChild(textArea);
}
function useGift() {
const useButton = document.getElementById('useButton');
if (useButton.disabled) return;
// Confirm usage
if (confirm('Bạn có chắc chắn muốn sử dụng voucher này? Hành động này không thể hoàn tác.')) {
// Update gift status to used
const giftCode = document.getElementById('voucherCode').textContent;
// Update localStorage
const giftData = {
code: giftCode,
name: document.getElementById('giftTitle').textContent,
status: 'used'
};
localStorage.setItem('selectedGift', JSON.stringify(giftData));
// Reload page with used status
loadGiftDetails(giftCode, 'used');
showToast('Voucher đã được sử dụng thành công!');
// Redirect to store or cart page after 2 seconds
setTimeout(() => {
window.location.href = 'cart.html';
}, 2000);
}
}
function shareGift() {
const giftName = document.getElementById('giftTitle').textContent;
const giftCode = document.getElementById('voucherCode').textContent;
const shareText = `Xem voucher ${giftName} - Mã: ${giftCode}`;
if (navigator.share) {
navigator.share({
title: giftName,
text: shareText,
url: window.location.href,
}).catch((error) => {
console.log('Error sharing:', error);
fallbackShare(shareText);
});
} else {
fallbackShare(shareText);
}
}
function fallbackShare(text) {
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => {
showToast('Đã sao chép thông tin để chia sẻ!');
});
} else {
showToast('Sao chép thủ công: ' + text);
}
}
function updateUsageHistory() {
const historyElement = document.getElementById('usageHistory');
const currentDate = new Date().toLocaleDateString('vi-VN');
historyElement.innerHTML = `
<div style="text-align: left; color: #4a5568;">
<div style="display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid #e2e8f0;">
<div>
<div style="font-weight: 600;">Đã sử dụng voucher</div>
<div style="font-size: 0.8rem; color: #718096;">Đơn hàng #DH${Date.now().toString().slice(-6)}</div>
</div>
<div style="text-align: right;">
<div style="color: #28a745; font-weight: 600;">${currentDate}</div>
<div style="font-size: 0.8rem; color: #718096;">Thành công</div>
</div>
</div>
</div>
`;
}
function showToast(message, type = 'success') {
const toast = document.getElementById('toast');
const toastMessage = document.getElementById('toastMessage');
toastMessage.textContent = message;
if (type === 'error') {
toast.style.background = '#dc3545';
} else {
toast.style.background = '#28a745';
}
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
</script>
</body>
</html>