522 lines
24 KiB
HTML
522 lines
24 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êm địa chỉ mới - 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 class="bg-gray-50">
|
|
<div class="page-wrapper">
|
|
<!-- Header -->
|
|
<div class="header">
|
|
<a href="addresses.html" class="back-button">
|
|
<i class="fas fa-arrow-left"></i>
|
|
</a>
|
|
<h1 class="header-title">Thêm địa chỉ mới</h1>
|
|
<button class="back-button" onclick="openInfoModal()">
|
|
<i class="fas fa-info-circle"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="container max-w-3xl mx-auto px-4 py-6" style="padding-bottom: 100px;">
|
|
<form id="addressForm" onsubmit="handleSubmit(event)">
|
|
|
|
<!-- Contact Information -->
|
|
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
|
|
<h3 class="text-base font-semibold text-gray-900 mb-4 flex items-center gap-2">
|
|
<i class="fas fa-user text-blue-600"></i>
|
|
Thông tin liên hệ
|
|
</h3>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Họ và tên <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<i class="fas fa-user absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
|
<input type="text"
|
|
id="fullName"
|
|
class="form-input w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
|
placeholder="Nhập họ và tên người nhận"
|
|
required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Số điện thoại <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<i class="fas fa-phone absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
|
<input type="tel"
|
|
id="phone"
|
|
class="form-input w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
|
placeholder="Nhập số điện thoại"
|
|
pattern="[0-9]{10,11}"
|
|
required>
|
|
</div>
|
|
<p class="text-xs text-gray-500 mt-1">Định dạng: 10-11 số</p>
|
|
</div>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Email <span class="text-red-500"></span>
|
|
</label>
|
|
<div class="relative">
|
|
<i class="fas fa-phone absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
|
<input type="tel"
|
|
id="phone"
|
|
class="form-input w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
|
placeholder="Nhập email"
|
|
pattern="[0-9]{10,11}"
|
|
required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Mã số thuế <span class="text-red-500"></span>
|
|
</label>
|
|
<div class="relative">
|
|
<i class="fas fa-phone absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
|
|
<input type="tel"
|
|
id="phone"
|
|
class="form-input w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
|
|
placeholder="Nhập mã số thuế"
|
|
pattern="[0-9]{10,11}"
|
|
required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Address Information -->
|
|
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
|
|
<h3 class="text-base font-semibold text-gray-900 mb-4 flex items-center gap-2">
|
|
<i class="fas fa-map-marker-alt text-blue-600"></i>
|
|
Địa chỉ giao hàng
|
|
</h3>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Tỉnh/Thành phố <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<select id="province"
|
|
class="form-select w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition appearance-none bg-white"
|
|
onchange="updateDistricts()"
|
|
required>
|
|
<option value="">-- Chọn Tỉnh/Thành phố --</option>
|
|
<option value="hanoi">Hà Nội</option>
|
|
<option value="hcm">TP. Hồ Chí Minh</option>
|
|
<option value="danang">Đà Nẵng</option>
|
|
<option value="haiphong">Hải Phòng</option>
|
|
<option value="cantho">Cần Thơ</option>
|
|
<option value="binhduong">Bình Dương</option>
|
|
<option value="dongnai">Đồng Nai</option>
|
|
<option value="vungtau">Bà Rịa - Vũng Tàu</option>
|
|
<option value="nhatrang">Khánh Hòa</option>
|
|
</select>
|
|
<i class="fas fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Phường/Xã <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<select id="district"
|
|
class="form-select w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition appearance-none bg-white"
|
|
onchange="updateWards()"
|
|
required
|
|
disabled>
|
|
<option value="">-- Chọn Phường/Xã --</option>
|
|
</select>
|
|
<i class="fas fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<!--<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Phường/Xã <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="relative">
|
|
<select id="ward"
|
|
class="form-select w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition appearance-none bg-white"
|
|
required
|
|
disabled>
|
|
<option value="">-- Chọn Phường/Xã --</option>
|
|
</select>
|
|
<i class="fas fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"></i>
|
|
</div>
|
|
</div>-->
|
|
|
|
<div class="form-group mb-4">
|
|
<label class="form-label block text-sm font-medium text-gray-700 mb-2">
|
|
Địa chỉ cụ thể <span class="text-red-500">*</span>
|
|
</label>
|
|
<textarea id="addressDetail"
|
|
class="form-textarea w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition resize-none"
|
|
rows="3"
|
|
placeholder="Số nhà, tên đường, khu vực..."
|
|
required></textarea>
|
|
<p class="text-xs text-gray-500 mt-1">Ví dụ: 123 Nguyễn Huệ, Khu phố 5</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Default Address Option -->
|
|
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
|
|
<label class="flex items-center cursor-pointer">
|
|
<input type="checkbox"
|
|
id="isDefault"
|
|
class="form-checkbox h-5 w-5 text-blue-600 rounded border-gray-300 focus:ring-2 focus:ring-blue-500">
|
|
<span class="ml-3 text-sm font-medium text-gray-900">Đặt làm địa chỉ mặc định</span>
|
|
</label>
|
|
<p class="text-xs text-gray-500 mt-2 ml-8">
|
|
Địa chỉ này sẽ được sử dụng làm mặc định khi đặt hàng
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Info Note -->
|
|
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4">
|
|
<div class="flex gap-3">
|
|
<i class="fas fa-info-circle text-blue-600 text-lg flex-shrink-0 mt-0.5"></i>
|
|
<div class="text-sm text-blue-800">
|
|
<strong>Lưu ý:</strong> Vui lòng kiểm tra kỹ thông tin địa chỉ để đảm bảo giao hàng chính xác.
|
|
Bạn có thể chỉnh sửa hoặc xóa địa chỉ này sau khi lưu.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Sticky Footer with Save Button -->
|
|
<div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 shadow-lg z-50">
|
|
<div class="max-w-3xl mx-auto px-4 py-4">
|
|
<button type="submit"
|
|
form="addressForm"
|
|
id="saveBtn"
|
|
class="w-full bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 text-white font-semibold py-4 px-6 rounded-lg shadow-lg transition-all duration-200 hover:shadow-xl hover:-translate-y-0.5 flex items-center justify-center gap-2">
|
|
<i class="fas fa-save"></i>
|
|
<span>Lưu địa chỉ</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
/* Custom form styles */
|
|
.form-input:focus,
|
|
.form-select:focus,
|
|
.form-textarea:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.form-select {
|
|
background-image: none;
|
|
}
|
|
|
|
.form-checkbox:checked {
|
|
background-color: #2563eb;
|
|
/*border-color: #2563eb;*/
|
|
}
|
|
|
|
/* Disabled state */
|
|
.form-select:disabled {
|
|
background-color: #f3f4f6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Animation */
|
|
@keyframes slideDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.form-group {
|
|
animation: slideDown 0.3s ease-out;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Address data structure (simulated - in real app this comes from API)
|
|
const addressData = {
|
|
hanoi: {
|
|
name: "Hà Nội",
|
|
districts: {
|
|
"hoan-kiem": {
|
|
name: "Hoàn Kiếm",
|
|
wards: ["Hàng Bạc", "Hàng Bài", "Hàng Bồ", "Hàng Đào", "Hàng Gai"]
|
|
},
|
|
"ba-dinh": {
|
|
name: "Ba Đình",
|
|
wards: ["Điện Biên", "Đội Cấn", "Giảng Võ", "Kim Mã", "Ngọc Hà"]
|
|
},
|
|
"dong-da": {
|
|
name: "Đống Đa",
|
|
wards: ["Cát Linh", "Hàng Bột", "Khâm Thiên", "Láng Hạ", "Ô Chợ Dừa"]
|
|
},
|
|
"cau-giay": {
|
|
name: "Cầu Giấy",
|
|
wards: ["Dịch Vọng", "Mai Dịch", "Nghĩa Đô", "Quan Hoa", "Yên Hòa"]
|
|
}
|
|
}
|
|
},
|
|
hcm: {
|
|
name: "TP. Hồ Chí Minh",
|
|
districts: {
|
|
"quan-1": {
|
|
name: "Quận 1",
|
|
wards: ["Bến Nghé", "Bến Thành", "Cô Giang", "Đa Kao", "Nguyễn Thái Bình"]
|
|
},
|
|
"quan-3": {
|
|
name: "Quận 3",
|
|
wards: ["Võ Thị Sáu", "Phường 1", "Phường 2", "Phường 3", "Phường 4"]
|
|
},
|
|
"quan-5": {
|
|
name: "Quận 5",
|
|
wards: ["Phường 1", "Phường 2", "Phường 3", "Phường 4", "Phường 5"]
|
|
},
|
|
"quan-7": {
|
|
name: "Quận 7",
|
|
wards: ["Tân Phong", "Tân Phú", "Tân Quy", "Tân Thuận Đông", "Tân Thuận Tây"]
|
|
},
|
|
"binh-thanh": {
|
|
name: "Bình Thạnh",
|
|
wards: ["Phường 1", "Phường 2", "Phường 3", "Phường 5", "Phường 7"]
|
|
}
|
|
}
|
|
},
|
|
danang: {
|
|
name: "Đà Nẵng",
|
|
districts: {
|
|
"hai-chau": {
|
|
name: "Hải Châu",
|
|
wards: ["Hải Châu 1", "Hải Châu 2", "Nam Dương", "Phước Ninh", "Thạch Thang"]
|
|
},
|
|
"thanh-khe": {
|
|
name: "Thanh Khê",
|
|
wards: ["An Khê", "Chính Gián", "Tam Thuận", "Tân Chính", "Thạc Gián"]
|
|
},
|
|
"son-tra": {
|
|
name: "Sơn Trà",
|
|
wards: ["An Hải Bắc", "An Hải Đông", "Mân Thái", "Nại Hiên Đông", "Phước Mỹ"]
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// Update districts when province changes
|
|
function updateDistricts() {
|
|
const provinceSelect = document.getElementById('province');
|
|
const districtSelect = document.getElementById('district');
|
|
const wardSelect = document.getElementById('ward');
|
|
|
|
const selectedProvince = provinceSelect.value;
|
|
|
|
// Reset district and ward
|
|
districtSelect.innerHTML = '<option value="">-- Chọn Quận/Huyện --</option>';
|
|
wardSelect.innerHTML = '<option value="">-- Chọn Phường/Xã --</option>';
|
|
wardSelect.disabled = true;
|
|
|
|
if (selectedProvince && addressData[selectedProvince]) {
|
|
const districts = addressData[selectedProvince].districts;
|
|
|
|
// Enable district select
|
|
districtSelect.disabled = false;
|
|
|
|
// Populate districts
|
|
Object.keys(districts).forEach(districtKey => {
|
|
const option = document.createElement('option');
|
|
option.value = districtKey;
|
|
option.textContent = districts[districtKey].name;
|
|
districtSelect.appendChild(option);
|
|
});
|
|
} else {
|
|
districtSelect.disabled = true;
|
|
}
|
|
}
|
|
|
|
// Update wards when district changes
|
|
function updateWards() {
|
|
const provinceSelect = document.getElementById('province');
|
|
const districtSelect = document.getElementById('district');
|
|
const wardSelect = document.getElementById('ward');
|
|
|
|
const selectedProvince = provinceSelect.value;
|
|
const selectedDistrict = districtSelect.value;
|
|
|
|
// Reset ward
|
|
wardSelect.innerHTML = '<option value="">-- Chọn Phường/Xã --</option>';
|
|
|
|
if (selectedProvince && selectedDistrict && addressData[selectedProvince]) {
|
|
const district = addressData[selectedProvince].districts[selectedDistrict];
|
|
|
|
if (district && district.wards) {
|
|
// Enable ward select
|
|
wardSelect.disabled = false;
|
|
|
|
// Populate wards
|
|
district.wards.forEach(ward => {
|
|
const option = document.createElement('option');
|
|
option.value = ward.toLowerCase().replace(/\s+/g, '-');
|
|
option.textContent = ward;
|
|
wardSelect.appendChild(option);
|
|
});
|
|
}
|
|
} else {
|
|
wardSelect.disabled = true;
|
|
}
|
|
}
|
|
|
|
// Handle form submission
|
|
function handleSubmit(event) {
|
|
event.preventDefault();
|
|
|
|
// Get form values
|
|
const formData = {
|
|
fullName: document.getElementById('fullName').value,
|
|
phone: document.getElementById('phone').value,
|
|
province: document.getElementById('province').value,
|
|
provinceName: document.getElementById('province').selectedOptions[0].text,
|
|
district: document.getElementById('district').value,
|
|
districtName: document.getElementById('district').selectedOptions[0].text,
|
|
ward: document.getElementById('ward').value,
|
|
wardName: document.getElementById('ward').selectedOptions[0].text,
|
|
addressDetail: document.getElementById('addressDetail').value,
|
|
isDefault: document.getElementById('isDefault').checked
|
|
};
|
|
|
|
// Validate
|
|
if (!formData.province || !formData.district || !formData.ward) {
|
|
showToast('Vui lòng chọn đầy đủ Tỉnh/Thành phố, Quận/Huyện, Phường/Xã', 'error');
|
|
return;
|
|
}
|
|
|
|
// Show loading
|
|
const saveBtn = document.getElementById('saveBtn');
|
|
const originalContent = saveBtn.innerHTML;
|
|
saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <span>Đang lưu...</span>';
|
|
saveBtn.disabled = true;
|
|
|
|
// Simulate API call
|
|
setTimeout(() => {
|
|
// Save to localStorage (simulated)
|
|
let addresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]');
|
|
|
|
// If this is default, remove default from others
|
|
if (formData.isDefault) {
|
|
addresses = addresses.map(addr => ({...addr, isDefault: false}));
|
|
}
|
|
|
|
// Add new address
|
|
addresses.push({
|
|
id: Date.now(),
|
|
...formData,
|
|
createdAt: new Date().toISOString()
|
|
});
|
|
|
|
localStorage.setItem('savedAddresses', JSON.stringify(addresses));
|
|
|
|
// Reset button
|
|
saveBtn.innerHTML = originalContent;
|
|
saveBtn.disabled = false;
|
|
|
|
// Show success and redirect
|
|
showToast('Đã lưu địa chỉ thành công!', 'success');
|
|
|
|
setTimeout(() => {
|
|
window.location.href = 'addresses.html';
|
|
}, 1000);
|
|
}, 1500);
|
|
}
|
|
|
|
// Toast notification
|
|
function showToast(message, type = 'success') {
|
|
const colors = {
|
|
success: '#10b981',
|
|
error: '#ef4444',
|
|
warning: '#f59e0b',
|
|
info: '#3b82f6'
|
|
};
|
|
|
|
const icons = {
|
|
success: 'fa-check-circle',
|
|
error: 'fa-exclamation-circle',
|
|
warning: 'fa-exclamation-triangle',
|
|
info: 'fa-info-circle'
|
|
};
|
|
|
|
const toast = document.createElement('div');
|
|
toast.innerHTML = `
|
|
<i class="fas ${icons[type]}"></i>
|
|
<span>${message}</span>
|
|
`;
|
|
toast.style.cssText = `
|
|
position: fixed;
|
|
top: 80px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: ${colors[type]};
|
|
color: white;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
z-index: 10000;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
animation: slideDown 0.3s ease;
|
|
max-width: 90%;
|
|
`;
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.style.animation = 'slideUp 0.3s ease';
|
|
setTimeout(() => {
|
|
document.body.removeChild(toast);
|
|
}, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// Add animation styles
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@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);
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
</script>
|
|
</body>
|
|
</html>
|