Files
worker/html/chat-list.html
2025-11-03 11:20:09 +07:00

805 lines
29 KiB
HTML

<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tin nhắn - 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="index.html" class="back-button">
<i class="fas fa-arrow-left"></i>
</a>
<h1 class="header-title">Tin nhắn</h1>
<div class="header-actions">
<button class="header-action-btn" onclick="searchConversations()">
<i class="fas fa-search"></i>
</button>
<button class="header-action-btn" onclick="newConversation()">
<i class="fas fa-plus"></i>
</button>
</div>
</div>
<div class="chat-list-content">
<!-- Search Bar (Hidden by default) -->
<div class="search-container" id="searchContainer" style="display: none;">
<div class="search-bar">
<i class="fas fa-search search-icon"></i>
<input type="text" class="search-input" placeholder="Tìm kiếm cuộc trò chuyện..." id="searchInput">
<button class="search-clear" onclick="clearSearch()" style="display: none;">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- Chat Filter Tabs -->
<!-- <div class="chat-filter-tabs">
<button class="filter-tab active" onclick="filterChats('all')">
Tất cả
<span class="tab-count">12</span>
</button>
<button class="filter-tab" onclick="filterChats('unread')">
Chưa đọc
<span class="tab-count">3</span>
</button>
<button class="filter-tab" onclick="filterChats('customers')">
Khách hàng
<span class="tab-count">8</span>
</button>
<button class="filter-tab" onclick="filterChats('support')">
Hỗ trợ
<span class="tab-count">4</span>
</button>
</div>-->
<!-- Conversation List -->
<div class="conversations-list" id="conversationsList">
<!-- Conversation Item 1 - Order Reference -->
<div class="conversation-item unread customer" onclick="openChat('order001')">
<div class="avatar-container">
<div class="avatar support-avatar">
<i class="fas fa-box"></i>
</div>
<div class="online-indicator online"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Đơn hàng #SO001234</h3>
<span class="message-time">14:30</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<i class="fas fa-shipping-fast"></i>
Đơn hàng đang được giao - Dự kiến đến 16:00
</div>
<div class="message-indicators">
<span class="unread-count">2</span>
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Về: Đơn hàng #SO001234</span>
<span class="separator"></span>
<span class="last-seen">Cập nhật mới</span>
</div>
</div>
</div>
<!-- Conversation Item 3 - Product Reference -->
<div class="conversation-item unread customer" onclick="openChat('product001')">
<div class="avatar-container">
<div class="avatar customer-avatar">
<i class="fas fa-cube" style="color: #005B9A; font-size: 20px;"></i>
</div>
<div class="online-indicator away"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Sản phẩm PR0123</h3>
<span class="message-time">12:20</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<i class="fas fa-info-circle"></i>
Thông tin bổ sung về gạch Granite 60x60
</div>
<div class="message-indicators">
<span class="unread-count">1</span>
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Đơn hàng #DH001233</span>
<span class="separator"></span>
<span class="last-seen">2 giờ trước</span>
</div>
</div>
</div>
<!-- Conversation Item 2 - Support Team -->
<div class="conversation-item support" onclick="openChat('support001')">
<div class="avatar-container">
<div class="avatar support-avatar">
<i class="fas fa-headset"></i>
</div>
<div class="online-indicator online"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Tổng đài hỗ trợ</h3>
<span class="message-time">13:45</span>
</div>
<div class="conversation-preview">
<div class="last-message">
Thông tin về quy trình đổi trả sản phẩm
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Bộ phận hỗ trợ</span>
<span class="separator"></span>
<span class="last-seen">Đang hoạt động</span>
</div>
</div>
</div>
<!-- Conversation Item 4 - Architect -->
<!--<div class="conversation-item customer" onclick="openChat('conv003')">
<div class="avatar-container">
<div class="avatar architect-avatar">
<img src="https://placehold.co/50x50/F0F8FF/4169E1/png?text=LVC" alt="Lê Văn C">
</div>
<div class="online-indicator offline"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">KTS. Lê Văn C</h3>
<span class="message-time">Hôm qua</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<i class="fas fa-check-double delivered"></i>
Cảm ơn bạn! Tư vấn rất hữu ích.
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Kiến trúc sư</span>
<span class="separator">•</span>
<span class="last-seen">1 ngày trước</span>
</div>
</div>
</div>-->
<!-- Conversation Item 5 - Product Inquiry -->
<!-- <div class="conversation-item customer" onclick="openChat('conv004')">
<div class="avatar-container">
<div class="avatar customer-avatar">
<img src="https://placehold.co/50x50/FFF8DC/8B4513/png?text=PTD" alt="Phạm Thị D">
</div>
<div class="online-indicator offline"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Phạm Thị D</h3>
<span class="message-time">2 ngày</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<i class="fas fa-check-double delivered"></i>
Có thể xem thêm mẫu gạch 80x80 không?
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Tư vấn sản phẩm</span>
<span class="separator">•</span>
<span class="last-seen">2 ngày trước</span>
</div>
</div>
</div> -->
<!-- Conversation Item 6 - Group Support -->
<!--<div class="conversation-item support" onclick="openChat('group001')">
<div class="avatar-container">
<div class="avatar group-avatar">
<i class="fas fa-users"></i>
</div>
<div class="online-indicator online"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Nhóm bán hàng miền Nam</h3>
<span class="message-time">3 ngày</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<strong>Quản lý:</strong> Cập nhật bảng giá tháng 8
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Nhóm làm việc</span>
<span class="separator">•</span>
<span class="last-seen">15 thành viên</span>
</div>
</div>
</div>-->
<!-- Conversation Item 7 - Technical Question -->
<!--<div class="conversation-item customer" onclick="openChat('conv005')">
<div class="avatar-container">
<div class="avatar customer-avatar">
<img src="https://placehold.co/50x50/E0FFFF/008B8B/png?text=HVE" alt="Hoàng Văn E">
</div>
<div class="online-indicator offline"></div>
</div>
<div class="conversation-content">
<div class="conversation-header">
<h3 class="contact-name">Hoàng Văn E</h3>
<span class="message-time">1 tuần</span>
</div>
<div class="conversation-preview">
<div class="last-message">
<i class="fas fa-check-double read"></i>
Hướng dẫn lắp đặt rất chi tiết, cảm ơn!
</div>
</div>
<div class="conversation-meta">
<span class="contact-type">Hướng dẫn lắp đặt</span>
<span class="separator">•</span>
<span class="last-seen">1 tuần trước</span>
</div>
</div>
</div>-->
<!-- More conversations would be loaded with pagination -->
<div class="load-more-section">
<button class="load-more-btn" onclick="loadMoreConversations()">
<i class="fas fa-chevron-down"></i>
Tải thêm cuộc trò chuyện
</button>
</div>
</div>
</div>
</div>
<style>
.chat-list-content {
padding: 0 0 80px 0;
}
/* Search Container */
.search-container {
padding: 12px 16px;
background: var(--white);
border-bottom: 1px solid var(--border-color);
}
/* Chat Filter Tabs */
.chat-filter-tabs {
display: flex;
background: var(--white);
border-bottom: 1px solid var(--border-color);
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.chat-filter-tabs::-webkit-scrollbar {
display: none;
}
.filter-tab {
flex-shrink: 0;
padding: 12px 16px;
border: none;
background: none;
color: var(--text-light);
font-size: 14px;
font-weight: 500;
cursor: pointer;
position: relative;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.3s ease;
white-space: nowrap;
}
.filter-tab.active {
color: var(--primary-blue);
}
.filter-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 2px;
background: var(--primary-blue);
}
.tab-count {
background: var(--primary-blue);
color: white;
font-size: 11px;
padding: 2px 6px;
border-radius: 10px;
font-weight: 600;
}
.filter-tab:not(.active) .tab-count {
background: var(--text-light);
}
/* Conversations List */
.conversations-list {
background: var(--background-gray);
}
.conversation-item {
display: flex;
padding: 16px;
background: var(--white);
border-bottom: 1px solid var(--border-color);
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.conversation-item:hover {
background: #f8f9fa;
}
.conversation-item.unread {
background: #f0f9ff;
}
.conversation-item.unread:hover {
background: #e0f2fe;
}
/* Avatar */
.avatar-container {
position: relative;
margin-right: 12px;
flex-shrink: 0;
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.customer-avatar {
background: var(--background-gray);
}
.support-avatar {
background: linear-gradient(135deg, var(--primary-blue), var(--light-blue));
color: white;
font-size: 20px;
}
.architect-avatar {
background: var(--background-gray);
}
.group-avatar {
background: linear-gradient(135deg, var(--success-color), #4CAF50);
color: white;
font-size: 18px;
}
.online-indicator {
position: absolute;
bottom: 2px;
right: 2px;
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid var(--white);
}
.online-indicator.online {
background: var(--success-color);
}
.online-indicator.away {
background: var(--warning-color);
}
.online-indicator.offline {
background: var(--text-light);
}
/* Conversation Content */
.conversation-content {
flex: 1;
min-width: 0;
}
.conversation-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.contact-name {
font-size: 16px;
font-weight: 600;
color: var(--text-dark);
margin: 0;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.message-time {
color: var(--text-light);
font-size: 12px;
flex-shrink: 0;
margin-left: 8px;
}
.conversation-preview {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.last-message {
flex: 1;
font-size: 14px;
color: var(--text-light);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
align-items: center;
gap: 6px;
}
.last-message i {
flex-shrink: 0;
}
.last-message .fa-check-double.delivered {
color: var(--primary-blue);
}
.last-message .fa-check-double.read {
color: var(--success-color);
}
.message-indicators {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
margin-left: 8px;
}
.unread-count {
background: var(--danger-color);
color: white;
font-size: 11px;
font-weight: 600;
padding: 2px 6px;
border-radius: 10px;
min-width: 18px;
text-align: center;
}
.conversation-meta {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--text-light);
}
.contact-type {
font-weight: 500;
}
.separator {
color: var(--border-color);
}
/* Load More */
.load-more-section {
padding: 20px;
text-align: center;
background: var(--white);
}
.load-more-btn {
background: var(--border-color);
color: var(--text-dark);
border: none;
border-radius: 8px;
padding: 12px 24px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
margin: 0 auto;
transition: all 0.3s ease;
}
.load-more-btn:hover {
background: #ddd;
}
/* Sharing Header */
.sharing-header {
background: linear-gradient(135deg, var(--primary-blue), var(--light-blue));
color: white;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.sharing-product-info {
display: flex;
align-items: center;
gap: 12px;
flex: 1;
min-width: 0;
}
.sharing-product-info i {
font-size: 20px;
flex-shrink: 0;
}
.sharing-details {
min-width: 0;
flex: 1;
}
.sharing-title {
font-size: 12px;
opacity: 0.9;
margin-bottom: 2px;
}
.sharing-product {
font-size: 14px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cancel-sharing {
width: 32px;
height: 32px;
border-radius: 50%;
border: none;
background: rgba(255, 255, 255, 0.2);
color: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.cancel-sharing:hover {
background: rgba(255, 255, 255, 0.3);
}
/* Responsive Design */
@media (max-width: 480px) {
.conversation-item {
padding: 12px 16px;
}
.avatar {
width: 45px;
height: 45px;
}
.contact-name {
font-size: 15px;
}
.last-message {
font-size: 13px;
}
.filter-tab {
padding: 10px 12px;
font-size: 13px;
}
}
</style>
<script>
let currentFilter = 'all';
function searchConversations() {
const container = document.getElementById('searchContainer');
const input = document.getElementById('searchInput');
if (container.style.display === 'none') {
container.style.display = 'block';
input.focus();
} else {
container.style.display = 'none';
input.value = '';
clearSearch();
}
}
function clearSearch() {
const input = document.getElementById('searchInput');
input.value = '';
filterConversations('');
}
function filterChats(type) {
currentFilter = type;
// Update tab states
document.querySelectorAll('.filter-tab').forEach(tab => {
tab.classList.remove('active');
});
event.target.classList.add('active');
// Filter conversations
const conversations = document.querySelectorAll('.conversation-item');
conversations.forEach(conv => {
const shouldShow = shouldShowConversation(conv, type);
conv.style.display = shouldShow ? 'flex' : 'none';
});
}
function shouldShowConversation(conversation, filter) {
switch(filter) {
case 'all':
return true;
case 'unread':
return conversation.classList.contains('unread');
case 'customers':
return conversation.classList.contains('customer');
case 'support':
return conversation.classList.contains('support');
default:
return true;
}
}
function filterConversations(searchTerm) {
const conversations = document.querySelectorAll('.conversation-item');
conversations.forEach(conv => {
const name = conv.querySelector('.contact-name').textContent.toLowerCase();
const message = conv.querySelector('.last-message').textContent.toLowerCase();
const matches = searchTerm === '' ||
name.includes(searchTerm.toLowerCase()) ||
message.includes(searchTerm.toLowerCase());
const shouldShow = matches && shouldShowConversation(conv, currentFilter);
conv.style.display = shouldShow ? 'flex' : 'none';
});
}
function openChat(conversationId) {
window.location.href = `chat-detail.html?id=${conversationId}`;
}
function newConversation() {
// In a real app, this would open a contact selection modal
alert('Chức năng tạo cuộc trò chuyện mới sẽ được triển khai trong phiên bản tiếp theo.');
}
function loadMoreConversations() {
// In a real app, this would load more conversations via API
alert('Đang tải thêm cuộc trò chuyện...');
}
// Check for sharing mode
function checkSharingMode() {
const urlParams = new URLSearchParams(window.location.search);
const mode = urlParams.get('mode');
if (mode === 'share') {
const productId = urlParams.get('product');
const productName = urlParams.get('name');
const productPrice = urlParams.get('price');
// Show sharing header
showSharingHeader(productName, productPrice);
// Add click handler for conversations
document.querySelectorAll('.conversation-item').forEach(item => {
const originalOnclick = item.getAttribute('onclick');
if (originalOnclick) {
const conversationId = originalOnclick.match(/'([^']+)'/)[1];
item.setAttribute('onclick', `shareProductToConversation('${productId}', '${productName}', '${productPrice}', '${conversationId}')`);
}
});
}
}
function showSharingHeader(productName, productPrice) {
const header = document.querySelector('.header');
const sharingHeader = document.createElement('div');
sharingHeader.className = 'sharing-header';
sharingHeader.innerHTML = `
<div class="sharing-product-info">
<i class="fas fa-share"></i>
<div class="sharing-details">
<div class="sharing-title">Chia sẻ sản phẩm</div>
<div class="sharing-product">${decodeURIComponent(productName)}</div>
</div>
</div>
<button class="cancel-sharing" onclick="cancelSharing()">
<i class="fas fa-times"></i>
</button>
`;
header.parentNode.insertBefore(sharingHeader, header.nextSibling);
}
function shareProductToConversation(productId, productName, productPrice, conversationId) {
const confirmMsg = `Chia sẻ "${decodeURIComponent(productName)}" đến cuộc trò chuyện này?`;
if (confirm(confirmMsg)) {
// Navigate to chat detail with shared product info
window.location.href = `chat-detail.html?id=${conversationId}&share=true&product=${productId}&name=${productName}&price=${productPrice}`;
}
}
function cancelSharing() {
window.location.href = 'product-detail.html';
}
// Search input event listener
document.addEventListener('DOMContentLoaded', function() {
// Check for sharing mode on page load
checkSharingMode();
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', function(e) {
filterConversations(e.target.value);
// Show/hide clear button
const clearBtn = document.querySelector('.search-clear');
if (e.target.value) {
clearBtn.style.display = 'block';
} else {
clearBtn.style.display = 'none';
}
});
});
</script>
</body>
</html>