397 lines
21 KiB
HTML
397 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="vi">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Thông tin cá nhân - EuroTile Worker</title>
|
|
<script src="https://cdn.tailwindcss.com/3.4.1"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<style>
|
|
body {
|
|
background-color: #f7fafc;
|
|
}
|
|
.form-input, .form-select {
|
|
border: 1px solid #e2e8f0;
|
|
transition: border-color 0.2s ease-in-out;
|
|
}
|
|
.form-input:focus, .form-select:focus {
|
|
border-color: #3b82f6;
|
|
outline: none;
|
|
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
}
|
|
.readonly-input {
|
|
background-color: #f1f5f9;
|
|
cursor: not-allowed;
|
|
color: #64748b;
|
|
}
|
|
.nav-item.active {
|
|
color: #3b82f6;
|
|
}
|
|
.header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 50;
|
|
background-color: white;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
@keyframes slideDown {
|
|
from { opacity: 0; transform: translate(-50%, -20px); }
|
|
to { opacity: 1; transform: translate(-50%, 0); }
|
|
}
|
|
@keyframes slideUp {
|
|
from { opacity: 1; transform: translate(-50%, 0); }
|
|
to { opacity: 0; transform: translate(-50%, -20px); }
|
|
}
|
|
.upload-card.has-file {
|
|
border-color: #22c55e;
|
|
background-color: #f0fdf4;
|
|
}
|
|
.upload-card.readonly {
|
|
cursor: not-allowed;
|
|
opacity: 0.7;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="text-gray-800">
|
|
|
|
<div class="page-wrapper">
|
|
<!-- Header -->
|
|
<div class="header flex items-center justify-between p-4 border-b border-gray-200">
|
|
<a href="account.html" class="text-gray-600">
|
|
<i class="fas fa-arrow-left text-xl"></i>
|
|
</a>
|
|
<h1 class="text-lg font-bold" style="margin-right: 97px;">Thông tin cá nhân</h1>
|
|
</div>
|
|
|
|
<div class="container p-4 pb-24">
|
|
<form id="profileForm" onsubmit="handleSubmit(event)">
|
|
|
|
<!-- Avatar Section -->
|
|
<div class="bg-white rounded-xl shadow-sm p-6 flex flex-col items-center">
|
|
<div class="relative">
|
|
<img src="https://ui-avatars.com/api/?name=Nguyen+Van+A&background=3b82f6&color=fff&size=128"
|
|
alt="Avatar"
|
|
id="avatarImage"
|
|
class="w-24 h-24 rounded-full border-4 border-white shadow-lg">
|
|
<label for="avatarInput" class="absolute -bottom-2 -right-2 w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white cursor-pointer shadow">
|
|
<i class="fas fa-camera text-sm"></i>
|
|
</label>
|
|
<input type="file" id="avatarInput" accept="image/*" class="hidden" onchange="handleAvatarChange(this)">
|
|
</div>
|
|
<h2 id="fullNameDisplay" class="text-xl font-bold mt-4">Nguyễn Văn A</h2>
|
|
<p class="text-gray-500">Thầu thợ</p>
|
|
<div id="accountStatusCard" class="mt-4">
|
|
<!-- Dynamic content based on status -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Verification Form (Hidden by default) -->
|
|
<div id="verificationFormContainer" class="bg-white rounded-xl shadow-sm mt-4 p-5" style="display: none;">
|
|
<div class="flex items-center gap-3 border-b pb-3 mb-4">
|
|
<i class="fas fa-file-check text-blue-500"></i>
|
|
<h3 class="font-bold text-base">Thông tin xác thực</h3>
|
|
</div>
|
|
|
|
<div class="info-note bg-blue-50 border-l-4 border-blue-400 text-blue-700 p-4 rounded-md mb-4 text-sm">
|
|
<i class="fas fa-info-circle mr-2"></i>
|
|
<strong>Lưu ý:</strong> Vui lòng cung cấp ảnh chụp rõ ràng các giấy tờ xác thực để được phê duyệt nhanh chóng.
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div class="form-group">
|
|
<label class="form-label font-semibold text-sm mb-2 block">Ảnh mặt trước CCCD/CMND <span class="text-red-500">*</span></label>
|
|
<div id="idCardUploadCard" class="upload-card border-2 border-dashed rounded-lg p-6 text-center cursor-pointer bg-gray-50 hover:bg-gray-100" onclick="handleUploadClick('idCardInput')">
|
|
<div id="idCardPreview" class="upload-content text-gray-500">
|
|
<i class="fas fa-camera text-2xl"></i>
|
|
<span class="mt-2 text-sm font-semibold">Chụp ảnh hoặc chọn file</span>
|
|
<span class="text-xs">JPG, PNG tối đa 5MB</span>
|
|
</div>
|
|
</div>
|
|
<input type="file" id="idCardInput" accept="image/*" class="hidden" onchange="handleVerificationFileUpload(this, 'idCardPreview')">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label font-semibold text-sm mb-2 block">Ảnh chứng chỉ hành nghề hoặc GPKD <span class="text-red-500">*</span></label>
|
|
<div id="certificateUploadCard" class="upload-card border-2 border-dashed rounded-lg p-6 text-center cursor-pointer bg-gray-50 hover:bg-gray-100" onclick="handleUploadClick('certificateInput')">
|
|
<div id="certificatePreview" class="upload-content text-gray-500">
|
|
<i class="fas fa-file-certificate text-2xl"></i>
|
|
<span class="mt-2 text-sm font-semibold">Chụp ảnh hoặc chọn file</span>
|
|
<span class="text-xs">JPG, PNG tối đa 5MB</span>
|
|
</div>
|
|
</div>
|
|
<input type="file" id="certificateInput" accept="image/*" class="hidden" onchange="handleVerificationFileUpload(this, 'certificatePreview')">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-3 mt-6" id="verificationSubmitBtn" style="display: none;">
|
|
<button type="button" class="w-full bg-gray-200 text-gray-700 font-bold py-2.5 px-4 rounded-lg" onclick="cancelVerification()">Hủy</button>
|
|
<button type="button" class="w-full bg-blue-500 text-white font-bold py-2.5 px-4 rounded-lg" onclick="submitVerification()">Gửi xác thực</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Combined Personal Information Section -->
|
|
<div class="bg-white rounded-xl shadow-sm mt-4 p-5">
|
|
<div class="flex items-center gap-3 border-b pb-3 mb-4">
|
|
<i class="fas fa-user-circle text-blue-500"></i>
|
|
<h3 class="font-bold text-base">Thông tin cá nhân</h3>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Họ và tên <span class="text-red-500">*</span></label>
|
|
<input type="text" id="fullName" class="form-input w-full p-2.5 rounded-lg" value="Nguyễn Văn A" placeholder="Nhập họ và tên" required onkeyup="document.getElementById('fullNameDisplay').textContent = this.value">
|
|
</div>
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Số điện thoại</label>
|
|
<input type="tel" class="form-input readonly-input w-full p-2.5 rounded-lg" value="0983 441 099" readonly>
|
|
</div>
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Email</label>
|
|
<input type="email" class="form-input readonly-input w-full p-2.5 rounded-lg" value="nguyenvana@email.com" readonly>
|
|
</div>
|
|
<!--<div>
|
|
<label class="font-semibold text-sm mb-1 block">Vai trò</label>
|
|
<input class="form-input readonly-input w-full p-2.5 rounded-lg" value="Thầu thợ" disabled>
|
|
</div>-->
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Ngày sinh</label>
|
|
<input type="date" id="birthDate" class="form-input w-full p-2.5 rounded-lg" value="1990-05-15">
|
|
</div>
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Giới tính</label>
|
|
<select id="gender" class="form-select w-full p-2.5 rounded-lg bg-white">
|
|
<option value="">Chọn giới tính</option>
|
|
<option value="male" selected>Nam</option>
|
|
<option value="female">Nữ</option>
|
|
<option value="other">Khác</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Tên công ty/Cửa hàng</label>
|
|
<input type="text" id="companyName" class="form-input w-full p-2.5 rounded-lg" value="Gạch ốp lát Phương Nam" placeholder="Nhập tên (không bắt buộc)">
|
|
</div>
|
|
<div>
|
|
<label class="font-semibold text-sm mb-1 block">Mã số thuế</label>
|
|
<input type="text" id="taxCode" class="form-input w-full p-2.5 rounded-lg" value="0312345678" placeholder="Nhập mã số thuế (không bắt buộc)">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Read-only Fields -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="bg-blue-50 border-l-4 border-blue-400 text-blue-700 p-3 rounded text-xs">
|
|
<i class="fas fa-info-circle mr-2"></i>
|
|
Để thay đổi số điện thoại, email hoặc vai trò, vui lòng liên hệ bộ phận hỗ trợ.
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="mt-6">
|
|
<button id="submit-btn" type="submit" class="w-full bg-blue-500 text-white font-bold py-3 px-4 rounded-lg shadow-md hover:bg-blue-600 transition-colors">
|
|
Lưu thay đổi
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
let accountStatus = 'chua_xac_thuc';
|
|
let verificationData = {
|
|
idNumber: '079123456789',
|
|
taxCode: '0312345678',
|
|
idCardFile: null,
|
|
certificateFile: null
|
|
};
|
|
|
|
function initializeAccountStatus() {
|
|
const statusContainer = document.getElementById('accountStatusCard');
|
|
const verificationFormContainer = document.getElementById('verificationFormContainer');
|
|
statusContainer.innerHTML = '';
|
|
|
|
if (accountStatus === 'chua_xac_thuc') {
|
|
const unverifiedBadge = document.createElement('div');
|
|
unverifiedBadge.className = 'flex items-center gap-4';
|
|
unverifiedBadge.innerHTML = `
|
|
<div class="inline-flex items-center gap-1.5 bg-red-100 text-red-700 text-xs font-semibold px-2.5 py-1 rounded-full">
|
|
<i class="fas fa-exclamation-circle"></i>
|
|
<span>Chưa xác thực</span>
|
|
</div>
|
|
<button class="text-blue-500 font-semibold text-sm" onclick="showVerificationForm()">
|
|
Xác thực ngay <i class="fas fa-arrow-right text-xs"></i>
|
|
</button>
|
|
`;
|
|
statusContainer.appendChild(unverifiedBadge);
|
|
verificationFormContainer.style.display = 'none';
|
|
} else if (accountStatus === 'cho_xac_thuc') {
|
|
statusContainer.innerHTML = `
|
|
<div class="inline-flex items-center gap-1.5 bg-yellow-100 text-yellow-800 text-xs font-semibold px-2.5 py-1 rounded-full cursor-pointer" onclick="viewVerificationInfo()">
|
|
<i class="fas fa-clock"></i>
|
|
<span>Đang chờ xác thực</span>
|
|
</div>`;
|
|
verificationFormContainer.style.display = 'none';
|
|
} else if (accountStatus === 'da_xac_thuc') {
|
|
statusContainer.innerHTML = `
|
|
<div class="inline-flex items-center gap-1.5 bg-green-100 text-green-700 text-xs font-semibold px-2.5 py-1 rounded-full cursor-pointer" onclick="viewVerificationInfo()">
|
|
<i class="fas fa-check-circle"></i>
|
|
<span>Đã xác thực</span>
|
|
</div>`;
|
|
verificationFormContainer.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function showVerificationForm() {
|
|
const verificationFormContainer = document.getElementById('verificationFormContainer');
|
|
const verificationSubmitBtn = document.getElementById('verificationSubmitBtn');
|
|
|
|
// Clear upload previews
|
|
document.getElementById('idCardPreview').innerHTML = `<i class="fas fa-camera text-2xl"></i><span class="mt-2 text-sm font-semibold">Chụp ảnh hoặc chọn file</span><span class="text-xs">JPG, PNG tối đa 5MB</span>`;
|
|
document.getElementById('certificatePreview').innerHTML = `<i class="fas fa-file-certificate text-2xl"></i><span class="mt-2 text-sm font-semibold">Chụp ảnh hoặc chọn file</span><span class="text-xs">JPG, PNG tối đa 5MB</span>`;
|
|
|
|
const idCard = document.getElementById('idCardUploadCard');
|
|
const certCard = document.getElementById('certificateUploadCard');
|
|
idCard.classList.remove('has-file', 'readonly');
|
|
certCard.classList.remove('has-file', 'readonly');
|
|
idCard.onclick = () => handleUploadClick('idCardInput');
|
|
certCard.onclick = () => handleUploadClick('certificateInput');
|
|
|
|
verificationFormContainer.style.display = 'block';
|
|
verificationSubmitBtn.style.display = 'grid';
|
|
|
|
setTimeout(() => verificationFormContainer.scrollIntoView({ behavior: 'smooth', block: 'center' }), 100);
|
|
}
|
|
|
|
function viewVerificationInfo() {
|
|
const verificationFormContainer = document.getElementById('verificationFormContainer');
|
|
const verificationSubmitBtn = document.getElementById('verificationSubmitBtn');
|
|
|
|
const idCard = document.getElementById('idCardUploadCard');
|
|
const certCard = document.getElementById('certificateUploadCard');
|
|
|
|
if (verificationData.idCardFile) {
|
|
document.getElementById('idCardPreview').innerHTML = `<i class="fas fa-check-circle text-3xl text-green-500"></i><span class="mt-2 text-sm font-semibold text-green-600">CCCD_front.jpg</span>`;
|
|
idCard.classList.add('has-file', 'readonly');
|
|
idCard.onclick = null;
|
|
}
|
|
|
|
if (verificationData.certificateFile) {
|
|
document.getElementById('certificatePreview').innerHTML = `<i class="fas fa-check-circle text-3xl text-green-500"></i><span class="mt-2 text-sm font-semibold text-green-600">certificate.jpg</span>`;
|
|
certCard.classList.add('has-file', 'readonly');
|
|
certCard.onclick = null;
|
|
}
|
|
|
|
verificationFormContainer.style.display = 'block';
|
|
verificationSubmitBtn.style.display = 'none';
|
|
|
|
setTimeout(() => verificationFormContainer.scrollIntoView({ behavior: 'smooth', block: 'center' }), 100);
|
|
}
|
|
|
|
function cancelVerification() {
|
|
document.getElementById('verificationFormContainer').style.display = 'none';
|
|
}
|
|
|
|
function submitVerification() {
|
|
if (!document.getElementById('idCardInput').files.length) return showToast('Vui lòng upload ảnh CCCD/CMND', 'error');
|
|
if (!document.getElementById('certificateInput').files.length) return showToast('Vui lòng upload ảnh chứng chỉ', 'error');
|
|
|
|
verificationData.idCardFile = document.getElementById('idCardInput').files[0];
|
|
verificationData.certificateFile = document.getElementById('certificateInput').files[0];
|
|
|
|
showToast('Đang gửi thông tin xác thực...', 'info');
|
|
|
|
setTimeout(() => {
|
|
accountStatus = 'cho_xac_thuc';
|
|
initializeAccountStatus();
|
|
document.getElementById('verificationFormContainer').style.display = 'none';
|
|
showToast('Đã gửi thông tin thành công! Vui lòng chờ duyệt.', 'success');
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}, 1500);
|
|
}
|
|
|
|
function handleUploadClick(inputId) {
|
|
// Add readonly check
|
|
const uploadCard = document.getElementById(inputId).parentElement;
|
|
if (uploadCard.classList.contains('readonly')) return;
|
|
document.getElementById(inputId).click();
|
|
}
|
|
|
|
function handleAvatarChange(input) {
|
|
const file = input.files[0];
|
|
if (file) {
|
|
if (!file.type.startsWith('image/')) return showToast('Vui lòng chọn file hình ảnh (JPG, PNG)', 'error');
|
|
if (file.size > 5 * 1024 * 1024) return showToast('File không được vượt quá 5MB', 'error');
|
|
|
|
const reader = new FileReader();
|
|
reader.onload = e => document.getElementById('avatarImage').src = e.target.result;
|
|
reader.readAsDataURL(file);
|
|
showToast('Đã chọn ảnh đại diện mới', 'success');
|
|
}
|
|
}
|
|
|
|
function handleVerificationFileUpload(input, previewId) {
|
|
const file = input.files[0];
|
|
const previewContainer = document.getElementById(previewId);
|
|
const uploadCard = previewContainer.parentElement;
|
|
|
|
if (file) {
|
|
if (!file.type.startsWith('image/')) return showToast('Vui lòng chọn file hình ảnh (JPG, PNG)', 'error');
|
|
if (file.size > 5 * 1024 * 1024) return showToast('File không được vượt quá 5MB', 'error');
|
|
|
|
const reader = new FileReader();
|
|
reader.onload = e => {
|
|
previewContainer.innerHTML = `
|
|
<img src="${e.target.result}" alt="Preview" class="w-full h-24 object-contain rounded-md mb-2">
|
|
<div class="text-sm font-semibold text-green-600 truncate">${file.name}</div>
|
|
<div class="text-xs text-gray-500">Nhấn để thay đổi</div>
|
|
`;
|
|
uploadCard.classList.add('has-file');
|
|
};
|
|
reader.readAsDataURL(file);
|
|
showToast('Đã upload file thành công', 'success');
|
|
}
|
|
}
|
|
|
|
function handleSubmit(event) {
|
|
event.preventDefault();
|
|
if (!document.getElementById('fullName').value) return showToast('Vui lòng nhập họ và tên', 'error');
|
|
saveProfile();
|
|
}
|
|
|
|
function saveProfile() {
|
|
const submitBtn = document.getElementById('submit-btn');
|
|
const originalText = submitBtn.innerHTML;
|
|
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Đang lưu...';
|
|
submitBtn.disabled = true;
|
|
|
|
}
|
|
|
|
function showToast(message, type = 'success') {
|
|
const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500' };
|
|
const icons = { success: 'fa-check-circle', error: 'fa-exclamation-circle', info: 'fa-info-circle' };
|
|
|
|
const toast = document.createElement('div');
|
|
toast.className = `fixed top-5 left-1/2 -translate-x-1/2 ${colors[type]} text-white py-2 px-5 rounded-lg shadow-lg flex items-center gap-2 text-sm z-[100]`;
|
|
toast.innerHTML = `<i class="fas ${icons[type]}"></i><span>${message}</span>`;
|
|
toast.style.animation = 'slideDown 0.3s ease';
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.style.animation = 'slideUp 0.3s ease forwards';
|
|
setTimeout(() => toast.remove(), 300);
|
|
}, 3000);
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
initializeAccountStatus();
|
|
|
|
// FOR TESTING:
|
|
// accountStatus = 'chua_xac_thuc';
|
|
// accountStatus = 'cho_xac_thuc';
|
|
// accountStatus = 'da_xac_thuc';
|
|
// initializeAccountStatus();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |