feat: add human resource block support, database description column, and image alignment CSS styling
This commit is contained in:
+101
-89
@@ -3,8 +3,8 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Danh sách khóa học / chứng chỉ</title>
|
||||
<!-- Sử dụng Tailwind CSS để dựng giao diện nhanh và đẹp -->
|
||||
<title>Danh sách Bác sĩ</title>
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
body {
|
||||
@@ -13,119 +13,131 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="py-10 px-4 min-h-screen flex items-center justify-center">
|
||||
<body class="min-h-screen py-12 px-4 flex flex-col items-center justify-center">
|
||||
|
||||
<!-- Container chính dạng Grid Responsive -->
|
||||
<div class="max-w-7xl w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<!-- Lưới chứa danh sách card Bác sĩ -->
|
||||
<div id="doctor-grid" class="max-w-6xl w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
|
||||
<!-- THẺ CARD 1 -->
|
||||
<div class="bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden flex flex-col justify-between hover:shadow-lg transition duration-300 p-5">
|
||||
<!-- CARD 1: BS CKII. Nguyễn Viết Hậu -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<!-- Hình ảnh khóa học -->
|
||||
<div class="rounded-lg overflow-hidden mb-4 h-48 bg-gray-100">
|
||||
<img src="https://images.unsplash.com/photo-1551076805-e1869033e561?auto=format&fit=crop&w=600&q=80" alt="Khóa học 1" class="w-full h-full object-cover">
|
||||
<!-- Icon xe cấp cứu góc trên bên phải -->
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
<!-- Icon xe cấp cứu cách điệu -->
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Phần ảnh & Thông tin chính -->
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<!-- Ảnh chân dung với viền xanh lam nhạt -->
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1622253692010-333f2da6031d?auto=format&fit=crop&w=300&q=80" alt="BS CKII. Nguyễn Viết Hậu" class="w-full h-full object-cover">
|
||||
</div>
|
||||
|
||||
<!-- Chức danh & Họ tên -->
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">BS CKII.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Nguyễn Viết Hậu</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Trưởng Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tiêu đề -->
|
||||
<h3 class="font-bold text-blue-900 text-lg mb-2 line-clamp-2">
|
||||
CHỨNG CHỈ ĐÀO Tạo KỸ THUẬT CHUYÊN MÔN: ĐIỆ...
|
||||
</h3>
|
||||
<!-- Mô tả ngắn -->
|
||||
<p class="text-gray-600 text-sm mb-4 line-clamp-3">
|
||||
Phẫu thuật thần kinh luôn đi kèm với những biến chứng nặng nề làm thay đổi cả phần đời còn lại của người...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- Ngày tháng & Nhãn -->
|
||||
<div class="flex items-center justify-between text-sm text-gray-500 border-t border-gray-100 pt-4 mb-4">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
<span>10/08/2026</span>
|
||||
</div>
|
||||
<span class="font-bold text-blue-700 tracking-wide underline decoration-blue-500">SAT</span>
|
||||
</div>
|
||||
<!-- Nút Giá tiền -->
|
||||
<button class="w-full bg-[#1b75bc] hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition duration-200 text-center text-lg shadow-sm">
|
||||
14.999.998 VNĐ
|
||||
</button>
|
||||
<!-- Các nút hành động phía dưới -->
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<!-- Nút Xem hồ sơ -->
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<!-- Nút Đặt lịch khám -->
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- THẺ CARD 2 -->
|
||||
<div class="bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden flex flex-col justify-between hover:shadow-lg transition duration-300 p-5">
|
||||
<!-- CARD 2: BS CKI. Tăng Tuấn Phong -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<!-- Hình ảnh khóa học -->
|
||||
<div class="rounded-lg overflow-hidden mb-4 h-48 bg-gray-100">
|
||||
<img src="https://images.unsplash.com/photo-1576091160399-112ba8d25d1d?auto=format&fit=crop&w=600&q=80" alt="Khóa học 2" class="w-full h-full object-cover">
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1612349317150-e413f6a5b16d?auto=format&fit=crop&w=300&q=80" alt="BS CKI. Tăng Tuấn Phong" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">BS CKI.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Tăng Tuấn Phong</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Phó Trưởng Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tiêu đề -->
|
||||
<h3 class="font-bold text-blue-900 text-lg mb-2 line-clamp-2">
|
||||
CHỨNG CHỈ ĐÀO TẠO KỸ THUẬT CHUYÊN MÔN: KỸ...
|
||||
</h3>
|
||||
<!-- Mô tả ngắn -->
|
||||
<p class="text-gray-600 text-sm mb-4 line-clamp-3">
|
||||
Thăm dò chức năng hô hấp là một phần quan trọng trong chẩn đoán, điều trị và theo dõi các bệnh lý hô...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- Ngày tháng & Nhãn -->
|
||||
<div class="flex items-center justify-between text-sm text-gray-500 border-t border-gray-100 pt-4 mb-4">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
<span>17/08/2026</span>
|
||||
</div>
|
||||
<span class="font-bold text-blue-700 tracking-wide underline decoration-blue-500">SAT</span>
|
||||
</div>
|
||||
<!-- Nút Giá tiền -->
|
||||
<button class="w-full bg-[#1b75bc] hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition duration-200 text-center text-lg shadow-sm">
|
||||
5.000.000 VNĐ
|
||||
</button>
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- THẺ CARD 3 -->
|
||||
<div class="bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden flex flex-col justify-between hover:shadow-lg transition duration-300 p-5">
|
||||
<!-- CARD 3: TS BS. Nguyễn Tuấn Anh -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<!-- Hình ảnh khóa học -->
|
||||
<div class="rounded-lg overflow-hidden mb-4 h-48 bg-gray-100">
|
||||
<img src="https://images.unsplash.com/photo-1584515979956-d9f6e5d09982?auto=format&fit=crop&w=600&q=80" alt="Khóa học 3" class="w-full h-full object-cover">
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1537368910025-700350fe46c7?auto=format&fit=crop&w=300&q=80" alt="TS BS. Nguyễn Tuấn Anh" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">TS BS.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Nguyễn Tuấn Anh</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tiêu đề -->
|
||||
<h3 class="font-bold text-blue-900 text-lg mb-2 line-clamp-2">
|
||||
CHƯƠNG TRÌNH CHỨNG CHỈ ĐÀO TẠO KỸ THUẬT...
|
||||
</h3>
|
||||
<!-- Mô tả ngắn -->
|
||||
<p class="text-gray-600 text-sm mb-4 line-clamp-3">
|
||||
Đột quỵ là bệnh phổ biến với khoảng 200.000 ca đột quỵ mới mỗi năm, theo thống kê của Bộ Y tế. Hơn thế...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- Ngày tháng & Nhãn -->
|
||||
<div class="flex items-center justify-between text-sm text-gray-500 border-t border-gray-100 pt-4 mb-4">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
<span>07/09/2026</span>
|
||||
</div>
|
||||
<span class="font-bold text-blue-700 tracking-wide underline decoration-blue-500">SAT</span>
|
||||
</div>
|
||||
<!-- Nút Giá tiền -->
|
||||
<button class="w-full bg-[#1b75bc] hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition duration-200 text-center text-lg shadow-sm">
|
||||
32.500.000 VNĐ
|
||||
</button>
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- JavaScript tương tác nhẹ (Ví dụ thông báo khi click vào khóa học) -->
|
||||
<!-- Nút Xem thêm ở giữa phía dưới -->
|
||||
<button id="btn-load-more" class="bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-8 rounded-xl transition duration-200 text-sm shadow-md">
|
||||
Xem thêm
|
||||
</button>
|
||||
|
||||
<!-- JavaScript tương tác -->
|
||||
<script>
|
||||
document.querySelectorAll('button').forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const price = this.innerText;
|
||||
alert('Bạn đã chọn đăng ký khóa học với mức giá: ' + price);
|
||||
});
|
||||
document.getElementById('btn-load-more').addEventListener('click', function() {
|
||||
alert('Đang tải thêm danh sách bác sĩ...');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
+371
-155
@@ -1,166 +1,382 @@
|
||||
<!doctype html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Chia sẻ lời tri ân</title>
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
body {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#1e3a8a 0%,
|
||||
#3b82f6 50%,
|
||||
#eff6ff 100%
|
||||
);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="p-4 sm:p-6 md:p-8">
|
||||
<!-- Khung chứa Form: Responsive padding, bo góc và độ rộng -->
|
||||
<section class="xl:py-12 md:py-8 py-4 bg-gray-50" id="chairman-message-section">
|
||||
<div class="container">
|
||||
<h2 class="display-7 text-primary-600 mb-3 text-center">Đội ngũ nhân sự</h2>
|
||||
<div
|
||||
class="bg-white rounded-2xl shadow-2xl w-full max-w-xl p-6 sm:p-8 md:p-10 relative my-auto"
|
||||
class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 xl:gap-4 md:gap-3 gap-2"
|
||||
>
|
||||
<!-- Tiêu đề -->
|
||||
<h2 class="text-xl sm:text-2xl font-bold text-blue-900 mb-6">
|
||||
Chia sẻ lời tri ân
|
||||
</h2>
|
||||
|
||||
<!-- Form chính -->
|
||||
<form
|
||||
onsubmit="
|
||||
event.preventDefault();
|
||||
alert('Gửi thông tin thành công!');
|
||||
"
|
||||
class="space-y-4 sm:space-y-5"
|
||||
<div
|
||||
class="bg-white rounded-xl overview-wrapper-shadow flex flex-col justify-between h-full"
|
||||
>
|
||||
<!-- Họ tên -->
|
||||
<div>
|
||||
<label class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Họ tên <span class="text-red-500">*</span></label
|
||||
<div
|
||||
class="flex gap-4 items-center xl:px-6 px-4 xl:pt-6 pt-4 mb-3 relative"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
placeholder="Nhập họ tên"
|
||||
class="w-full px-3.5 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm placeholder-gray-400"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Bạn là & Chức vụ (Responsive Grid: 1 cột trên mobile, 2 cột từ màn hình sm trở lên) -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label
|
||||
class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Bạn là <span class="text-red-500">*</span></label
|
||||
>
|
||||
<select
|
||||
required
|
||||
class="w-full px-3.5 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm bg-white text-gray-500"
|
||||
>
|
||||
<option value="" disabled selected>Chọn vai trò</option>
|
||||
<option value="bac-si">Bác sĩ / Nhân viên y tế</option>
|
||||
<option value="benh-nhan">Bệnh nhân / Người nhà</option>
|
||||
<option value="khac">Khác</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Chức vụ/ Nơi làm việc của bạn
|
||||
<span class="text-red-500">*</span></label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
placeholder="Nhập chức vụ/ nơi làm việc"
|
||||
class="w-full px-3.5 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm placeholder-gray-400"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Số điện thoại -->
|
||||
<div>
|
||||
<label class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Số điện thoại <span class="text-red-500">*</span></label
|
||||
>
|
||||
<input
|
||||
type="tel"
|
||||
required
|
||||
placeholder="Nhập số điện thoại"
|
||||
class="w-full px-3.5 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm placeholder-gray-400"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Nội dung lời nhắn -->
|
||||
<div>
|
||||
<label class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Nội dung lời nhắn <span class="text-red-500">*</span></label
|
||||
>
|
||||
<textarea
|
||||
rows="3"
|
||||
required
|
||||
placeholder="Nhập nội dung"
|
||||
class="w-full px-3.5 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm placeholder-gray-400 resize-none"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Tải lên hình ảnh -->
|
||||
<div>
|
||||
<label class="block text-xs sm:text-sm font-medium text-gray-700 mb-1"
|
||||
>Hình ảnh <span class="text-red-500">*</span></label
|
||||
>
|
||||
<label
|
||||
class="flex flex-col items-center justify-center w-28 h-28 border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:border-blue-500 bg-gray-50 transition"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center pt-5 pb-6 text-gray-400"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 mb-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
<a
|
||||
class="flex-shrink-0 relative aspect-square overflow-hidden rounded border border-primary-400 bg-gradient-to-tl from-primary-75 to-primary-100 xl:size-[150px] size-[100px]"
|
||||
href="https://bvdaihoc.com.vn/bac-si/tran-huong-giang-id-1534"
|
||||
><img
|
||||
alt="A09-056 (1)"
|
||||
class="lg:hover:scale-105 scale-100 lg:duration-150"
|
||||
data-nimg="fill"
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/images/bac-si/A09-056%20(1).png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA09-056%20(1).png&w=3840&q=80 3840w
|
||||
"
|
||||
style="
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
inset: 0px;
|
||||
object-fit: contain;
|
||||
color: transparent;
|
||||
"
|
||||
/></a>
|
||||
<div class="flex-1">
|
||||
<div
|
||||
class="text-primary-300 label-3 max-md:!text-[14px] !leading-[150%]"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 4v16m8-8H4"
|
||||
></path>
|
||||
</svg>
|
||||
<span class="text-xs">Tải tệp</span>
|
||||
TS BS.
|
||||
</div>
|
||||
<a
|
||||
class="text-[16px] leading-[150%] font-display font-bold text-[#1E293B] lg:hover:text-primary-600 lg:duration-150 mb-1 line-clamp-2"
|
||||
href="https://bvdaihoc.com.vn/bac-si/tran-huong-giang-id-1534"
|
||||
>Trần Hương Giang</a
|
||||
>
|
||||
<div class="text-primary-300 label-3 !leading-[150%]">
|
||||
Trưởng khoa Giải phẫu bệnh
|
||||
</div>
|
||||
</div>
|
||||
<input type="file" class="hidden" accept="image/*" required />
|
||||
</label>
|
||||
<div
|
||||
class="absolute xl:top-4 top-4 xl:right-4 right-4 size-[40px] rounded-lg bg-white card-icon-shadow p-1"
|
||||
>
|
||||
<img
|
||||
alt="library-15"
|
||||
data-nimg="1"
|
||||
decoding="async"
|
||||
height="38"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-15.png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=3840&q=80 3840w
|
||||
"
|
||||
style="color: transparent; object-fit: cover"
|
||||
width="40"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nút gửi (Full width trên điện thoại, kích thước vừa vặn trên desktop) -->
|
||||
<div class="pt-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="w-full sm:w-auto px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium text-sm rounded-lg shadow transition duration-200 text-center"
|
||||
<div
|
||||
class="xl:px-6 px-4 xl:pb-6 pb-4 xl:mt-3 mt-2 flex items-center justify-between gap-x-2"
|
||||
>
|
||||
<a
|
||||
class="btn btn-outline-primary !inline-flex w-[149px] space-x-2 text-center label-2 !px-0 group"
|
||||
href="https://bvdaihoc.com.vn/bac-si/tran-huong-giang-id-1534"
|
||||
><div>Xem hồ sơ</div>
|
||||
<svg
|
||||
fill="none"
|
||||
height="20"
|
||||
viewbox="0 0 21 20"
|
||||
width="21"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_83_448)">
|
||||
<path
|
||||
d="M10.5 20C4.98633 20 0.5 15.5137 0.5 10C0.5 4.48633 4.98633 0 10.5 0C16.0137 0 20.5 4.48633 20.5 10C20.5 15.5137 16.0137 20 10.5 20ZM10.5 1.66602C5.9043 1.66602 2.16602 5.4043 2.16602 10C2.16602 14.5957 5.9043 18.334 10.5 18.334C15.0957 18.334 18.834 14.5957 18.834 10C18.834 5.4043 15.0957 1.66602 10.5 1.66602Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M9.66602 13.75C9.45312 13.75 9.24023 13.668 9.07617 13.5059C8.75 13.1797 8.75 12.6523 9.07617 12.3281L11.4043 10L9.07813 7.67187C8.75195 7.3457 8.75195 6.81836 9.07813 6.49414C9.4043 6.16797 9.93164 6.16797 10.2559 6.49414L13.1719 9.41016C13.498 9.73633 13.498 10.2637 13.1719 10.5879L10.2559 13.5059C10.0937 13.668 9.87891 13.75 9.66602 13.75Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath id="clip0_83_448">
|
||||
<rect
|
||||
fill="white"
|
||||
height="20"
|
||||
transform="translate(0.5)"
|
||||
width="20"
|
||||
></rect>
|
||||
</clippath>
|
||||
</defs></svg
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-xl overview-wrapper-shadow flex flex-col justify-between h-full"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="flex gap-4 items-center xl:px-6 px-4 xl:pt-6 pt-4 mb-3 relative"
|
||||
>
|
||||
Gửi thông tin
|
||||
</button>
|
||||
<a
|
||||
class="flex-shrink-0 relative aspect-square overflow-hidden rounded border border-primary-400 bg-gradient-to-tl from-primary-75 to-primary-100 xl:size-[150px] size-[100px]"
|
||||
href="https://bvdaihoc.com.vn/bac-si/nguyen-sao-trung-id-1359"
|
||||
><img
|
||||
alt="A02-036"
|
||||
class="lg:hover:scale-105 scale-100 lg:duration-150"
|
||||
data-nimg="fill"
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/images/bac-si/A02-036.png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-036.png&w=3840&q=80 3840w
|
||||
"
|
||||
style="
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
inset: 0px;
|
||||
object-fit: contain;
|
||||
color: transparent;
|
||||
"
|
||||
/></a>
|
||||
<div class="flex-1">
|
||||
<div
|
||||
class="text-primary-300 label-3 max-md:!text-[14px] !leading-[150%]"
|
||||
>
|
||||
GS TS BS.
|
||||
</div>
|
||||
<a
|
||||
class="text-[16px] leading-[150%] font-display font-bold text-[#1E293B] lg:hover:text-primary-600 lg:duration-150 mb-1 line-clamp-2"
|
||||
href="https://bvdaihoc.com.vn/bac-si/nguyen-sao-trung-id-1359"
|
||||
>Nguyễn Sào Trung</a
|
||||
>
|
||||
<div class="text-primary-300 label-3 !leading-[150%]">
|
||||
Ban chuyên gia
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="absolute xl:top-4 top-4 xl:right-4 right-4 size-[40px] rounded-lg bg-white card-icon-shadow p-1"
|
||||
>
|
||||
<img
|
||||
alt="library-15"
|
||||
data-nimg="1"
|
||||
decoding="async"
|
||||
height="38"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-15.png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=3840&q=80 3840w
|
||||
"
|
||||
style="color: transparent; object-fit: cover"
|
||||
width="40"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
class="xl:px-6 px-4 xl:pb-6 pb-4 xl:mt-3 mt-2 flex items-center justify-between gap-x-2"
|
||||
>
|
||||
<a
|
||||
class="btn btn-outline-primary !inline-flex w-[149px] space-x-2 text-center label-2 !px-0 group"
|
||||
href="https://bvdaihoc.com.vn/bac-si/nguyen-sao-trung-id-1359"
|
||||
><div>Xem hồ sơ</div>
|
||||
<svg
|
||||
fill="none"
|
||||
height="20"
|
||||
viewbox="0 0 21 20"
|
||||
width="21"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_83_448)">
|
||||
<path
|
||||
d="M10.5 20C4.98633 20 0.5 15.5137 0.5 10C0.5 4.48633 4.98633 0 10.5 0C16.0137 0 20.5 4.48633 20.5 10C20.5 15.5137 16.0137 20 10.5 20ZM10.5 1.66602C5.9043 1.66602 2.16602 5.4043 2.16602 10C2.16602 14.5957 5.9043 18.334 10.5 18.334C15.0957 18.334 18.834 14.5957 18.834 10C18.834 5.4043 15.0957 1.66602 10.5 1.66602Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M9.66602 13.75C9.45312 13.75 9.24023 13.668 9.07617 13.5059C8.75 13.1797 8.75 12.6523 9.07617 12.3281L11.4043 10L9.07813 7.67187C8.75195 7.3457 8.75195 6.81836 9.07813 6.49414C9.4043 6.16797 9.93164 6.16797 10.2559 6.49414L13.1719 9.41016C13.498 9.73633 13.498 10.2637 13.1719 10.5879L10.2559 13.5059C10.0937 13.668 9.87891 13.75 9.66602 13.75Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath id="clip0_83_448">
|
||||
<rect
|
||||
fill="white"
|
||||
height="20"
|
||||
transform="translate(0.5)"
|
||||
width="20"
|
||||
></rect>
|
||||
</clippath>
|
||||
</defs></svg
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-xl overview-wrapper-shadow flex flex-col justify-between h-full"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="flex gap-4 items-center xl:px-6 px-4 xl:pt-6 pt-4 mb-3 relative"
|
||||
>
|
||||
<a
|
||||
class="flex-shrink-0 relative aspect-square overflow-hidden rounded border border-primary-400 bg-gradient-to-tl from-primary-75 to-primary-100 xl:size-[150px] size-[100px]"
|
||||
href="https://bvdaihoc.com.vn/bac-si/doan-thi-phuong-thao-1-id-1357"
|
||||
><img
|
||||
alt="A02-037"
|
||||
class="lg:hover:scale-105 scale-100 lg:duration-150"
|
||||
data-nimg="fill"
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/images/bac-si/A02-037.png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fimages%2Fbac-si%2FA02-037.png&w=3840&q=80 3840w
|
||||
"
|
||||
style="
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
inset: 0px;
|
||||
object-fit: contain;
|
||||
color: transparent;
|
||||
"
|
||||
/></a>
|
||||
<div class="flex-1">
|
||||
<div
|
||||
class="text-primary-300 label-3 max-md:!text-[14px] !leading-[150%]"
|
||||
>
|
||||
TS BS.
|
||||
</div>
|
||||
<a
|
||||
class="text-[16px] leading-[150%] font-display font-bold text-[#1E293B] lg:hover:text-primary-600 lg:duration-150 mb-1 line-clamp-2"
|
||||
href="https://bvdaihoc.com.vn/bac-si/doan-thi-phuong-thao-1-id-1357"
|
||||
>Đoàn Thị Phương Thảo</a
|
||||
>
|
||||
<div class="text-primary-300 label-3 !leading-[150%]">
|
||||
Ban chuyên gia
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="absolute xl:top-4 top-4 xl:right-4 right-4 size-[40px] rounded-lg bg-white card-icon-shadow p-1"
|
||||
>
|
||||
<img
|
||||
alt="library-15"
|
||||
data-nimg="1"
|
||||
decoding="async"
|
||||
height="38"
|
||||
loading="lazy"
|
||||
sizes="100vw"
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-15.png"
|
||||
srcset="
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=640&q=80 640w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=750&q=80 750w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=828&q=80 828w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1080&q=80 1080w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1200&q=80 1200w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=1920&q=80 1920w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=2048&q=80 2048w,
|
||||
/_next/image?url=https%3A%2F%2Fconsole.bvdaihoc.com.vn%2Fuploads%2Fchuyen-khoa%2Flibrary-15.png&w=3840&q=80 3840w
|
||||
"
|
||||
style="color: transparent; object-fit: cover"
|
||||
width="40"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="xl:px-6 px-4 xl:pb-6 pb-4 xl:mt-3 mt-2 flex items-center justify-between gap-x-2"
|
||||
>
|
||||
<a
|
||||
class="btn btn-outline-primary !inline-flex w-[149px] space-x-2 text-center label-2 !px-0 group"
|
||||
href="https://bvdaihoc.com.vn/bac-si/doan-thi-phuong-thao-1-id-1357"
|
||||
><div>Xem hồ sơ</div>
|
||||
<svg
|
||||
fill="none"
|
||||
height="20"
|
||||
viewbox="0 0 21 20"
|
||||
width="21"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_83_448)">
|
||||
<path
|
||||
d="M10.5 20C4.98633 20 0.5 15.5137 0.5 10C0.5 4.48633 4.98633 0 10.5 0C16.0137 0 20.5 4.48633 20.5 10C20.5 15.5137 16.0137 20 10.5 20ZM10.5 1.66602C5.9043 1.66602 2.16602 5.4043 2.16602 10C2.16602 14.5957 5.9043 18.334 10.5 18.334C15.0957 18.334 18.834 14.5957 18.834 10C18.834 5.4043 15.0957 1.66602 10.5 1.66602Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M9.66602 13.75C9.45312 13.75 9.24023 13.668 9.07617 13.5059C8.75 13.1797 8.75 12.6523 9.07617 12.3281L11.4043 10L9.07813 7.67187C8.75195 7.3457 8.75195 6.81836 9.07813 6.49414C9.4043 6.16797 9.93164 6.16797 10.2559 6.49414L13.1719 9.41016C13.498 9.73633 13.498 10.2637 13.1719 10.5879L10.2559 13.5059C10.0937 13.668 9.87891 13.75 9.66602 13.75Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath id="clip0_83_448">
|
||||
<rect
|
||||
fill="white"
|
||||
height="20"
|
||||
transform="translate(0.5)"
|
||||
width="20"
|
||||
></rect>
|
||||
</clippath>
|
||||
</defs></svg></a
|
||||
><a
|
||||
class="btn btn-light space-x-2 text-center label-2 !px-0 w-[149px]"
|
||||
href="https://bvdaihoc.com.vn/dat-lich-kham"
|
||||
><div>Đặt lịch khám</div>
|
||||
<svg
|
||||
fill="none"
|
||||
height="20"
|
||||
viewbox="0 0 20 20"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_83_297)">
|
||||
<path
|
||||
d="M0 16.26C0 17.3 0.366667 18.18 1.1 18.9C1.83333 19.62 2.72 19.9867 3.76 20H16.26C17.2867 20 18.1667 19.6333 18.9 18.9C19.6333 18.1667 20 17.2867 20 16.26V3.76C20 2.94667 19.7667 2.22 19.3 1.58C18.8333 0.94 18.2333 0.493333 17.5 0.24V1.88C17.5 2.4 17.32 2.84667 16.96 3.22C16.6 3.59333 16.1533 3.77333 15.62 3.76C15.0867 3.74667 14.6467 3.56667 14.3 3.22C13.9533 2.87333 13.7733 2.42667 13.76 1.88V0H6.26V1.88C6.26 2.4 6.07333 2.84667 5.7 3.22C5.32667 3.59333 4.88667 3.77333 4.38 3.76C3.87333 3.74667 3.42667 3.56667 3.04 3.22C2.65333 2.87333 2.47333 2.42667 2.5 1.88V0.24C1.76667 0.506667 1.16667 0.953333 0.7 1.58C0.233333 2.20667 0 2.93333 0 3.76L0 16.26ZM2.5 16.26V6.26H17.5V16.26C17.5 16.6067 17.38 16.9 17.14 17.14C16.9 17.38 16.6067 17.5 16.26 17.5H3.76C3.41333 17.5 3.11333 17.38 2.86 17.14C2.60667 16.9 2.48667 16.6067 2.5 16.26ZM3.76 1.88C3.76 2.05333 3.82 2.2 3.94 2.32C4.06 2.44 4.20667 2.5 4.38 2.5C4.55333 2.5 4.7 2.44 4.82 2.32C4.94 2.2 5 2.05333 5 1.88V0H3.76V1.88ZM5 15H7.5V12.5H5V15ZM5 11.26H7.5V8.76H5V11.26ZM8.76 15H11.26V12.5H8.76V15ZM8.76 11.26H11.26V8.76H8.76V11.26ZM12.5 15H15V12.5H12.5V15ZM12.5 11.26H15V8.76H12.5V11.26ZM15 1.88C15 2.05333 15.06 2.2 15.18 2.32C15.3 2.44 15.4467 2.5 15.62 2.5C15.7933 2.5 15.94 2.44 16.06 2.32C16.18 2.2 16.2467 2.05333 16.26 1.88V0H15V1.88Z"
|
||||
fill="white"
|
||||
></path>
|
||||
</g>
|
||||
<defs>
|
||||
<clippath id="clip0_83_297">
|
||||
<rect fill="white" height="20" width="20"></rect>
|
||||
</clippath>
|
||||
</defs></svg
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<div class="flex justify-center xl:mt-8 md:mt-6 mt-4">
|
||||
<button class="btn btn-light label-2">Xem thêm</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+4
-2
@@ -51,13 +51,14 @@ public class ManageMenuController {
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/items/add")
|
||||
public String addMenuItem(@PathVariable Long id, @RequestParam String label, @RequestParam String url, @RequestParam(required = false) Long parentId, @RequestParam(required = false) String title, @RequestParam(required = false) String imageUrl, RedirectAttributes redirectAttributes) {
|
||||
public String addMenuItem(@PathVariable Long id, @RequestParam String label, @RequestParam String url, @RequestParam(required = false) Long parentId, @RequestParam(required = false) String title, @RequestParam(required = false) String imageUrl, @RequestParam(required = false) String description, RedirectAttributes redirectAttributes) {
|
||||
Menu menu = menuService.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid menu Id"));
|
||||
MenuItem item = new MenuItem();
|
||||
item.setLabel(label);
|
||||
item.setUrl(url);
|
||||
item.setTitle(title);
|
||||
item.setImageUrl(imageUrl);
|
||||
item.setDescription(description);
|
||||
item.setMenu(menu);
|
||||
item.setDisplayOrder(menu.getItems().size());
|
||||
|
||||
@@ -94,12 +95,13 @@ public class ManageMenuController {
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/items/{itemId}/update")
|
||||
public String updateMenuItem(@PathVariable Long id, @PathVariable Long itemId, @RequestParam String label, @RequestParam String url, @RequestParam(required = false) Long parentId, @RequestParam(required = false) Integer displayOrder, @RequestParam(required = false) String title, @RequestParam(required = false) String imageUrl, RedirectAttributes redirectAttributes) {
|
||||
public String updateMenuItem(@PathVariable Long id, @PathVariable Long itemId, @RequestParam String label, @RequestParam String url, @RequestParam(required = false) Long parentId, @RequestParam(required = false) Integer displayOrder, @RequestParam(required = false) String title, @RequestParam(required = false) String imageUrl, @RequestParam(required = false) String description, RedirectAttributes redirectAttributes) {
|
||||
MenuItem item = menuItemRepository.findById(itemId).orElseThrow(() -> new IllegalArgumentException("Invalid item Id"));
|
||||
item.setLabel(label);
|
||||
item.setUrl(url);
|
||||
item.setTitle(title);
|
||||
item.setImageUrl(imageUrl);
|
||||
item.setDescription(description);
|
||||
if (displayOrder != null) {
|
||||
item.setDisplayOrder(displayOrder);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ public class MenuItem extends AbstractAuditingEntity<Long> {
|
||||
@Column(name = "image_url", length = 500)
|
||||
private String imageUrl;
|
||||
|
||||
@Size(max = 1000)
|
||||
@Column(name = "description", length = 1000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "display_order")
|
||||
private Integer displayOrder = 0;
|
||||
|
||||
@@ -127,6 +131,14 @@ public class MenuItem extends AbstractAuditingEntity<Long> {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<changeSet id="20260811031000-1" author="antigravity">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not>
|
||||
<columnExists tableName="sis_menu_item" columnName="description"/>
|
||||
</not>
|
||||
</preConditions>
|
||||
<addColumn tableName="sis_menu_item">
|
||||
<column name="description" type="varchar(1000)">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -59,4 +59,5 @@
|
||||
<include file="config/liquibase/changelog/20260728173000_fix_xml_specialties.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260729104200_add_page_tag.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260810093000_add_price_to_post.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260811031000_add_description_to_menu_item.xml" relativeToChangelogFile="false"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -660,6 +660,114 @@ figure.table table tr:hover {
|
||||
height: stretch;
|
||||
}
|
||||
|
||||
.card-icon-shadow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Image Alignment Rules (Rich Text / Editor / CMS Content)
|
||||
Supports display: inline-block !important in element.style
|
||||
========================================================================== */
|
||||
|
||||
/* 1. Force parent elements containing centered images to text-align: center !important */
|
||||
p[style*="text-align: center"],
|
||||
p[style*="text-align:center"],
|
||||
div[style*="text-align: center"],
|
||||
div[style*="text-align:center"],
|
||||
figure[style*="text-align: center"],
|
||||
figure[style*="text-align:center"],
|
||||
section[style*="text-align: center"],
|
||||
section[style*="text-align:center"],
|
||||
.text-center,
|
||||
.ce-block--align-center {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* 2. Parent containers auto-center if child img has auto-margin or center styles in element.style */
|
||||
p:has(> img[style*="margin-left: auto"]),
|
||||
p:has(> img[style*="margin-left:auto"]),
|
||||
div:has(> img[style*="margin-left: auto"]),
|
||||
div:has(> img[style*="margin-left:auto"]),
|
||||
figure:has(> img[style*="margin-left: auto"]),
|
||||
figure:has(> img[style*="margin-left:auto"]),
|
||||
p:has(> img[style*="text-align: center"]),
|
||||
p:has(> img[style*="text-align:center"]),
|
||||
div:has(> img[style*="text-align: center"]),
|
||||
div:has(> img[style*="text-align:center"]),
|
||||
p:has(> img.aligncenter),
|
||||
div:has(> img.aligncenter),
|
||||
figure:has(> img.aligncenter) {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* 3. Center Aligned Images (Works for both block and inline-block) */
|
||||
p[style*="text-align: center"] img,
|
||||
p[style*="text-align:center"] img,
|
||||
div[style*="text-align: center"] img,
|
||||
div[style*="text-align:center"] img,
|
||||
figure[style*="text-align: center"] img,
|
||||
figure[style*="text-align:center"] img,
|
||||
section[style*="text-align: center"] img,
|
||||
section[style*="text-align:center"] img,
|
||||
[style*="text-align: center"] > img,
|
||||
[style*="text-align:center"] > img,
|
||||
img[style*="text-align: center"],
|
||||
img[style*="text-align:center"],
|
||||
img[style*="margin-left: auto"][style*="margin-right: auto"],
|
||||
img[style*="margin-left:auto"][style*="margin-right:auto"],
|
||||
img.aligncenter,
|
||||
figure.aligncenter,
|
||||
figure.aligncenter img,
|
||||
figure.image-style-align-center,
|
||||
figure.image-style-align-center img,
|
||||
.text-center img,
|
||||
.text-center > img,
|
||||
p.text-center img,
|
||||
div.text-center img {
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
/* Left Aligned Images */
|
||||
p[style*="text-align: left"] img,
|
||||
p[style*="text-align:left"] img,
|
||||
div[style*="text-align: left"] img,
|
||||
div[style*="text-align:left"] img,
|
||||
figure[style*="text-align: left"] img,
|
||||
figure[style*="text-align:left"] img,
|
||||
[style*="text-align: left"] > img,
|
||||
[style*="text-align:left"] > img,
|
||||
img[style*="text-align: left"],
|
||||
img[style*="text-align:left"],
|
||||
img.alignleft,
|
||||
figure.alignleft,
|
||||
figure.alignleft img,
|
||||
.text-left img,
|
||||
.text-left > img {
|
||||
margin-left: 0 !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
/* Right Aligned Images */
|
||||
p[style*="text-align: right"] img,
|
||||
p[style*="text-align:right"] img,
|
||||
div[style*="text-align: right"] img,
|
||||
div[style*="text-align:right"] img,
|
||||
figure[style*="text-align: right"] img,
|
||||
figure[style*="text-align:right"] img,
|
||||
[style*="text-align: right"] > img,
|
||||
[style*="text-align:right"] > img,
|
||||
img[style*="text-align: right"],
|
||||
img[style*="text-align:right"],
|
||||
img.alignright,
|
||||
figure.alignright,
|
||||
figure.alignright img,
|
||||
.text-right img,
|
||||
.text-right > img {
|
||||
margin-left: auto !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
5. Responsive Breakpoints — 3 Groups Only
|
||||
========================================================================== */
|
||||
|
||||
@@ -325,13 +325,8 @@ class SISAccordionTool {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SISHeroBannerTool extracted to /js/manage/editor-plugins/hero-banner.js
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the SIS Block Editor on a given holder element.
|
||||
*
|
||||
@@ -457,7 +452,22 @@ function initSISEditor(holderId, hiddenInputId, initialData, skipSubmitHandler =
|
||||
if (Object.prototype.hasOwnProperty.call(sourceTools, key)) {
|
||||
var toolDef = sourceTools[key];
|
||||
if (toolDef) {
|
||||
allTools[key] = toolDef;
|
||||
var toolClass = toolDef.class || toolDef;
|
||||
if (typeof toolClass === 'function') {
|
||||
if (registeredClasses.has(toolClass)) {
|
||||
// Mark alias keys with toolbox: false so Editor.js parses the block type without adding duplicate menu items
|
||||
if (typeof toolDef === 'function') {
|
||||
allTools[key] = { class: toolDef, toolbox: false };
|
||||
} else {
|
||||
allTools[key] = Object.assign({}, toolDef, { toolbox: false });
|
||||
}
|
||||
} else {
|
||||
registeredClasses.add(toolClass);
|
||||
allTools[key] = toolDef;
|
||||
}
|
||||
} else {
|
||||
allTools[key] = toolDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+418
@@ -0,0 +1,418 @@
|
||||
/**
|
||||
* SISHumanResourceTool — Dedicated Human Resources / Doctor List Block Tool for Editor.js
|
||||
* Allows content managers to easily manage doctor cards, degrees, names, positions, avatars, specialty icons, and booking/profile action links.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
class SISHumanResourceTool {
|
||||
static get toolbox() {
|
||||
return {
|
||||
title: 'Đội ngũ nhân sự / Bác sĩ',
|
||||
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 1-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>'
|
||||
};
|
||||
}
|
||||
|
||||
constructor({ data, api, readOnly }) {
|
||||
this.api = api;
|
||||
this.readOnly = readOnly;
|
||||
this.instanceId = 'hr_' + Math.random().toString(36).substring(7);
|
||||
|
||||
this.data = {
|
||||
title: (data && data.title !== undefined) ? data.title : 'Đội ngũ nhân sự',
|
||||
cols: parseInt(data && data.cols) || 3,
|
||||
globalClass: (data && data.globalClass) || '',
|
||||
globalId: (data && data.globalId) || '',
|
||||
globalAttributes: (data && data.globalAttributes) || (data && data.attributes) || '',
|
||||
showMoreBtn: (data && (data.showMoreBtn === true || data.showMoreBtn === 'true')),
|
||||
showMoreText: (data && data.showMoreText) || 'Xem thêm',
|
||||
showMoreUrl: (data && data.showMoreUrl) || '#',
|
||||
items: (data && data.items && Array.isArray(data.items)) ? data.items : []
|
||||
};
|
||||
|
||||
// Populate default items if empty
|
||||
if (this.data.items.length === 0) {
|
||||
this.data.items.push({
|
||||
degree: 'BS CKII.',
|
||||
name: 'Nguyễn Viết Hậu',
|
||||
position: 'Trưởng Khoa Cấp cứu',
|
||||
avatarUrl: 'https://images.unsplash.com/photo-1622253692010-333f2da6031d?auto=format&fit=crop&w=300&q=80',
|
||||
specialtyIconUrl: '',
|
||||
profileUrl: '#',
|
||||
profileBtnText: 'Xem hồ sơ',
|
||||
bookingUrl: '#',
|
||||
bookingBtnText: 'Đặt lịch khám',
|
||||
active: true
|
||||
});
|
||||
}
|
||||
this.wrapper = undefined;
|
||||
}
|
||||
|
||||
render() {
|
||||
this.wrapper = document.createElement('div');
|
||||
this.wrapper.className = 'p-3 bg-light border rounded mb-3 ce-hr-tool-wrapper';
|
||||
this.wrapper.style.fontFamily = 'inherit';
|
||||
|
||||
const titleLabel = document.createElement('div');
|
||||
titleLabel.className = 'font-weight-bold text-primary small mb-3 d-flex align-items-center justify-content-between';
|
||||
titleLabel.innerHTML = '<span><i class="fas fa-user-md mr-1"></i> Quản lý Đội ngũ Nhân sự / Danh sách Bác sĩ</span>';
|
||||
this.wrapper.appendChild(titleLabel);
|
||||
|
||||
// Global Block Settings
|
||||
const settingsRow = document.createElement('div');
|
||||
settingsRow.className = 'form-row mb-3 pb-2 border-bottom';
|
||||
|
||||
// 1. Block Title
|
||||
const titleDiv = document.createElement('div');
|
||||
titleDiv.className = 'col-md-4 mb-2';
|
||||
titleDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Tiêu đề Khối</label>';
|
||||
this.titleInput = document.createElement('input');
|
||||
this.titleInput.type = 'text';
|
||||
this.titleInput.className = 'form-control form-control-sm';
|
||||
this.titleInput.placeholder = 'Đội ngũ nhân sự...';
|
||||
this.titleInput.value = this.data.title;
|
||||
titleDiv.appendChild(this.titleInput);
|
||||
|
||||
// 2. Columns Select
|
||||
const colDiv = document.createElement('div');
|
||||
colDiv.className = 'col-md-2 mb-2';
|
||||
colDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Số cột</label>';
|
||||
this.colsSelect = document.createElement('select');
|
||||
this.colsSelect.className = 'form-control form-control-sm';
|
||||
[1, 2, 3, 4].forEach(num => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = num;
|
||||
opt.textContent = num + ' cột';
|
||||
if (num === this.data.cols) opt.selected = true;
|
||||
this.colsSelect.appendChild(opt);
|
||||
});
|
||||
colDiv.appendChild(this.colsSelect);
|
||||
|
||||
// 3. CSS Class & Global ID
|
||||
const cssDiv = document.createElement('div');
|
||||
cssDiv.className = 'col-md-3 mb-2';
|
||||
cssDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">CSS Class (tùy chọn)</label>';
|
||||
this.globalClassInput = document.createElement('input');
|
||||
this.globalClassInput.type = 'text';
|
||||
this.globalClassInput.className = 'form-control form-control-sm';
|
||||
this.globalClassInput.placeholder = 'sis-doctor-section';
|
||||
this.globalClassInput.value = this.data.globalClass;
|
||||
cssDiv.appendChild(this.globalClassInput);
|
||||
|
||||
const idDiv = document.createElement('div');
|
||||
idDiv.className = 'col-md-3 mb-2';
|
||||
idDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Element ID</label>';
|
||||
this.globalIdInput = document.createElement('input');
|
||||
this.globalIdInput.type = 'text';
|
||||
this.globalIdInput.className = 'form-control form-control-sm';
|
||||
this.globalIdInput.placeholder = 'doctor-list-section';
|
||||
this.globalIdInput.value = this.data.globalId;
|
||||
idDiv.appendChild(this.globalIdInput);
|
||||
|
||||
settingsRow.appendChild(titleDiv);
|
||||
settingsRow.appendChild(colDiv);
|
||||
settingsRow.appendChild(cssDiv);
|
||||
settingsRow.appendChild(idDiv);
|
||||
this.wrapper.appendChild(settingsRow);
|
||||
|
||||
// Show More Button Settings Row
|
||||
const moreRow = document.createElement('div');
|
||||
moreRow.className = 'form-row mb-3 pb-2 border-bottom align-items-center';
|
||||
|
||||
const showMoreToggleDiv = document.createElement('div');
|
||||
showMoreToggleDiv.className = 'col-md-3 mb-2';
|
||||
const showMoreCheckbox = document.createElement('div');
|
||||
showMoreCheckbox.className = 'custom-control custom-switch';
|
||||
const checkId = 'hr_sm_' + Math.random().toString(36).substring(7);
|
||||
this.showMoreCheck = document.createElement('input');
|
||||
this.showMoreCheck.type = 'checkbox';
|
||||
this.showMoreCheck.className = 'custom-control-input';
|
||||
this.showMoreCheck.id = checkId;
|
||||
this.showMoreCheck.checked = !!this.data.showMoreBtn;
|
||||
|
||||
const checkLabel = document.createElement('label');
|
||||
checkLabel.className = 'custom-control-label small font-weight-bold text-secondary';
|
||||
checkLabel.htmlFor = checkId;
|
||||
checkLabel.textContent = 'Hiển thị nút "Xem thêm"';
|
||||
|
||||
showMoreCheckbox.appendChild(this.showMoreCheck);
|
||||
showMoreCheckbox.appendChild(checkLabel);
|
||||
showMoreToggleDiv.appendChild(showMoreCheckbox);
|
||||
|
||||
const showMoreTextDiv = document.createElement('div');
|
||||
showMoreTextDiv.className = 'col-md-4 mb-2';
|
||||
showMoreTextDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Tên nút Xem thêm</label>';
|
||||
this.showMoreTextInput = document.createElement('input');
|
||||
this.showMoreTextInput.type = 'text';
|
||||
this.showMoreTextInput.className = 'form-control form-control-sm';
|
||||
this.showMoreTextInput.value = this.data.showMoreText;
|
||||
showMoreTextDiv.appendChild(this.showMoreTextInput);
|
||||
|
||||
const showMoreUrlDiv = document.createElement('div');
|
||||
showMoreUrlDiv.className = 'col-md-5 mb-2';
|
||||
showMoreUrlDiv.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Đường dẫn Xem thêm (URL)</label>';
|
||||
this.showMoreUrlInput = document.createElement('input');
|
||||
this.showMoreUrlInput.type = 'text';
|
||||
this.showMoreUrlInput.className = 'form-control form-control-sm';
|
||||
this.showMoreUrlInput.value = this.data.showMoreUrl;
|
||||
showMoreUrlDiv.appendChild(this.showMoreUrlInput);
|
||||
|
||||
moreRow.appendChild(showMoreToggleDiv);
|
||||
moreRow.appendChild(showMoreTextDiv);
|
||||
moreRow.appendChild(showMoreUrlDiv);
|
||||
this.wrapper.appendChild(moreRow);
|
||||
|
||||
// Items Container
|
||||
this.itemsContainer = document.createElement('div');
|
||||
this.itemsContainer.className = 'hr-items-list mb-3';
|
||||
this.wrapper.appendChild(this.itemsContainer);
|
||||
|
||||
this.data.items.forEach((item, index) => {
|
||||
this._renderItemRow(item, index);
|
||||
});
|
||||
|
||||
// Add New Item Button
|
||||
const addBtn = document.createElement('button');
|
||||
addBtn.type = 'button';
|
||||
addBtn.className = 'btn btn-sm btn-outline-primary font-weight-bold mt-2';
|
||||
addBtn.innerHTML = '<i class="fas fa-plus mr-1"></i> Thêm Bác sĩ / Nhân sự';
|
||||
addBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const newItem = {
|
||||
degree: 'BS.',
|
||||
name: 'Họ và Tên Bác sĩ',
|
||||
position: 'Chức danh / Chuyên khoa',
|
||||
avatarUrl: '',
|
||||
specialtyIconUrl: '',
|
||||
profileUrl: '#',
|
||||
profileBtnText: 'Xem hồ sơ',
|
||||
bookingUrl: '#',
|
||||
bookingBtnText: 'Đặt lịch khám',
|
||||
active: true
|
||||
};
|
||||
this.data.items.push(newItem);
|
||||
this._renderItemRow(newItem, this.data.items.length - 1);
|
||||
});
|
||||
|
||||
this.wrapper.appendChild(addBtn);
|
||||
|
||||
return this.wrapper;
|
||||
}
|
||||
|
||||
_openPicker(currentUrl, onSelect) {
|
||||
if (window.SISMediaPicker && typeof window.SISMediaPicker.open === 'function') {
|
||||
window.SISMediaPicker.open(function (url) {
|
||||
if (url) onSelect(url);
|
||||
}, currentUrl);
|
||||
} else {
|
||||
const url = prompt('Nhập URL hình ảnh:', currentUrl || '');
|
||||
if (url !== null) onSelect(url.trim());
|
||||
}
|
||||
}
|
||||
|
||||
_renderItemRow(item, index) {
|
||||
const self = this;
|
||||
const card = document.createElement('div');
|
||||
card.className = 'card mb-3 shadow-sm border hr-item-card';
|
||||
|
||||
const cardHeader = document.createElement('div');
|
||||
cardHeader.className = 'card-header bg-white py-2 px-3 d-flex align-items-center justify-content-between';
|
||||
cardHeader.innerHTML = `
|
||||
<span class="font-weight-bold text-dark small">#${index + 1}: ${item.degree ? item.degree + ' ' : ''}${item.name || 'Bác sĩ'}</span>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-light btn-sm move-up-btn" title="Di chuyển lên"><i class="fas fa-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-light btn-sm move-down-btn" title="Di chuyển xuống"><i class="fas fa-arrow-down"></i></button>
|
||||
<button type="button" class="btn btn-danger btn-sm delete-btn" title="Xóa thẻ"><i class="fas fa-trash"></i></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const cardBody = document.createElement('div');
|
||||
cardBody.className = 'card-body p-3';
|
||||
|
||||
// Row 1: Degree, Name, Position
|
||||
const row1 = document.createElement('div');
|
||||
row1.className = 'form-row mb-2';
|
||||
|
||||
const degreeCol = document.createElement('div'); degreeCol.className = 'col-md-2 mb-2';
|
||||
degreeCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Học hàm/học vị</label>';
|
||||
const degreeInput = document.createElement('input'); degreeInput.type = 'text'; degreeInput.className = 'form-control form-control-sm';
|
||||
degreeInput.value = item.degree || '';
|
||||
degreeInput.placeholder = 'BS CKII., TS BS...';
|
||||
degreeInput.addEventListener('input', () => { item.degree = degreeInput.value; });
|
||||
degreeCol.appendChild(degreeInput);
|
||||
|
||||
const nameCol = document.createElement('div'); nameCol.className = 'col-md-5 mb-2';
|
||||
nameCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Họ và tên</label>';
|
||||
const nameInput = document.createElement('input'); nameInput.type = 'text'; nameInput.className = 'form-control form-control-sm';
|
||||
nameInput.value = item.name || '';
|
||||
nameInput.placeholder = 'Nguyễn Viết Hậu...';
|
||||
nameInput.addEventListener('input', () => {
|
||||
item.name = nameInput.value;
|
||||
const headerText = cardHeader.querySelector('.font-weight-bold');
|
||||
if (headerText) headerText.textContent = `#${index + 1}: ${item.degree ? item.degree + ' ' : ''}${item.name}`;
|
||||
});
|
||||
nameCol.appendChild(nameInput);
|
||||
|
||||
const posCol = document.createElement('div'); posCol.className = 'col-md-5 mb-2';
|
||||
posCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Chức vụ / Chuyên khoa</label>';
|
||||
const posInput = document.createElement('input'); posInput.type = 'text'; posInput.className = 'form-control form-control-sm';
|
||||
posInput.value = item.position || '';
|
||||
posInput.placeholder = 'Trưởng Khoa Cấp cứu...';
|
||||
posInput.addEventListener('input', () => { item.position = posInput.value; });
|
||||
posCol.appendChild(posInput);
|
||||
|
||||
row1.appendChild(degreeCol); row1.appendChild(nameCol); row1.appendChild(posCol);
|
||||
cardBody.appendChild(row1);
|
||||
|
||||
// Row 2: Avatar Image (with SISMediaPicker), Specialty Icon (with SISMediaPicker)
|
||||
const row2 = document.createElement('div');
|
||||
row2.className = 'form-row mb-2';
|
||||
|
||||
// Avatar
|
||||
const avatarCol = document.createElement('div'); avatarCol.className = 'col-md-6 mb-2';
|
||||
avatarCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Ảnh chân dung (Avatar)</label>';
|
||||
const avatarGroup = document.createElement('div'); avatarGroup.className = 'input-group input-group-sm';
|
||||
const avatarInput = document.createElement('input'); avatarInput.type = 'text'; avatarInput.className = 'form-control';
|
||||
avatarInput.value = item.avatarUrl || '';
|
||||
avatarInput.placeholder = '/uploads/... hoặc URL ảnh';
|
||||
avatarInput.addEventListener('input', () => { item.avatarUrl = avatarInput.value.trim(); });
|
||||
|
||||
const avatarAppend = document.createElement('div'); avatarAppend.className = 'input-group-append';
|
||||
const avatarPickBtn = document.createElement('button'); avatarPickBtn.type = 'button'; avatarPickBtn.className = 'btn btn-outline-secondary';
|
||||
avatarPickBtn.innerHTML = '<i class="fas fa-image mr-1"></i> Thư viện';
|
||||
avatarPickBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
self._openPicker(item.avatarUrl, (selectedUrl) => {
|
||||
item.avatarUrl = selectedUrl;
|
||||
avatarInput.value = selectedUrl;
|
||||
});
|
||||
});
|
||||
avatarAppend.appendChild(avatarPickBtn);
|
||||
avatarGroup.appendChild(avatarInput); avatarGroup.appendChild(avatarAppend);
|
||||
avatarCol.appendChild(avatarGroup);
|
||||
|
||||
// Specialty Icon
|
||||
const iconCol = document.createElement('div'); iconCol.className = 'col-md-6 mb-2';
|
||||
iconCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Icon chuyên khoa (Góc trên phải)</label>';
|
||||
const iconGroup = document.createElement('div'); iconGroup.className = 'input-group input-group-sm';
|
||||
const iconInput = document.createElement('input'); iconInput.type = 'text'; iconInput.className = 'form-control';
|
||||
iconInput.value = item.specialtyIconUrl || '';
|
||||
iconInput.placeholder = '/uploads/icon.png hoặc URL';
|
||||
iconInput.addEventListener('input', () => { item.specialtyIconUrl = iconInput.value.trim(); });
|
||||
|
||||
const iconAppend = document.createElement('div'); iconAppend.className = 'input-group-append';
|
||||
const iconPickBtn = document.createElement('button'); iconPickBtn.type = 'button'; iconPickBtn.className = 'btn btn-outline-secondary';
|
||||
iconPickBtn.innerHTML = '<i class="fas fa-image mr-1"></i> Thư viện';
|
||||
iconPickBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
self._openPicker(item.specialtyIconUrl, (selectedUrl) => {
|
||||
item.specialtyIconUrl = selectedUrl;
|
||||
iconInput.value = selectedUrl;
|
||||
});
|
||||
});
|
||||
iconAppend.appendChild(iconPickBtn);
|
||||
iconGroup.appendChild(iconInput); iconGroup.appendChild(iconAppend);
|
||||
iconCol.appendChild(iconGroup);
|
||||
|
||||
row2.appendChild(avatarCol); row2.appendChild(iconCol);
|
||||
cardBody.appendChild(row2);
|
||||
|
||||
// Row 3: Action Buttons (Profile URL, Profile Btn Text, Booking URL, Booking Btn Text)
|
||||
const row3 = document.createElement('div');
|
||||
row3.className = 'form-row mb-2';
|
||||
|
||||
const profUrlCol = document.createElement('div'); profUrlCol.className = 'col-md-3 mb-2';
|
||||
profUrlCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Link Xem Hồ Sơ</label>';
|
||||
const profUrlInput = document.createElement('input'); profUrlInput.type = 'text'; profUrlInput.className = 'form-control form-control-sm';
|
||||
profUrlInput.value = item.profileUrl || '#';
|
||||
profUrlInput.addEventListener('input', () => { item.profileUrl = profUrlInput.value.trim(); });
|
||||
profUrlCol.appendChild(profUrlInput);
|
||||
|
||||
const profTextCol = document.createElement('div'); profTextCol.className = 'col-md-3 mb-2';
|
||||
profTextCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Tên nút Hồ Sơ</label>';
|
||||
const profTextInput = document.createElement('input'); profTextInput.type = 'text'; profTextInput.className = 'form-control form-control-sm';
|
||||
profTextInput.value = item.profileBtnText || 'Xem hồ sơ';
|
||||
profTextInput.addEventListener('input', () => { item.profileBtnText = profTextInput.value; });
|
||||
profTextCol.appendChild(profTextInput);
|
||||
|
||||
const bookUrlCol = document.createElement('div'); bookUrlCol.className = 'col-md-3 mb-2';
|
||||
bookUrlCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Link Đặt Lịch</label>';
|
||||
const bookUrlInput = document.createElement('input'); bookUrlInput.type = 'text'; bookUrlInput.className = 'form-control form-control-sm';
|
||||
bookUrlInput.value = item.bookingUrl || '#';
|
||||
bookUrlInput.addEventListener('input', () => { item.bookingUrl = bookUrlInput.value.trim(); });
|
||||
bookUrlCol.appendChild(bookUrlInput);
|
||||
|
||||
const bookTextCol = document.createElement('div'); bookTextCol.className = 'col-md-3 mb-2';
|
||||
bookTextCol.innerHTML = '<label class="small font-weight-bold text-secondary mb-1">Tên nút Đặt Lịch</label>';
|
||||
const bookTextInput = document.createElement('input'); bookTextInput.type = 'text'; bookTextInput.className = 'form-control form-control-sm';
|
||||
bookTextInput.value = item.bookingBtnText || 'Đặt lịch khám';
|
||||
bookTextInput.addEventListener('input', () => { item.bookingBtnText = bookTextInput.value; });
|
||||
bookTextCol.appendChild(bookTextInput);
|
||||
|
||||
row3.appendChild(profUrlCol); row3.appendChild(profTextCol);
|
||||
row3.appendChild(bookUrlCol); row3.appendChild(bookTextCol);
|
||||
cardBody.appendChild(row3);
|
||||
|
||||
card.appendChild(cardHeader);
|
||||
card.appendChild(cardBody);
|
||||
|
||||
// Event handlers for move/delete
|
||||
cardHeader.querySelector('.move-up-btn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (index > 0) {
|
||||
const temp = this.data.items[index];
|
||||
this.data.items[index] = this.data.items[index - 1];
|
||||
this.data.items[index - 1] = temp;
|
||||
this._refreshItemsUI();
|
||||
}
|
||||
});
|
||||
|
||||
cardHeader.querySelector('.move-down-btn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (index < this.data.items.length - 1) {
|
||||
const temp = this.data.items[index];
|
||||
this.data.items[index] = this.data.items[index + 1];
|
||||
this.data.items[index + 1] = temp;
|
||||
this._refreshItemsUI();
|
||||
}
|
||||
});
|
||||
|
||||
cardHeader.querySelector('.delete-btn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (confirm('Bạn có chắc muốn xóa bác sĩ này?')) {
|
||||
this.data.items.splice(index, 1);
|
||||
this._refreshItemsUI();
|
||||
}
|
||||
});
|
||||
|
||||
this.itemsContainer.appendChild(card);
|
||||
}
|
||||
|
||||
_refreshItemsUI() {
|
||||
this.itemsContainer.innerHTML = '';
|
||||
this.data.items.forEach((item, idx) => {
|
||||
this._renderItemRow(item, idx);
|
||||
});
|
||||
}
|
||||
|
||||
save() {
|
||||
return {
|
||||
title: this.titleInput ? this.titleInput.value.trim() : (this.data.title || 'Đội ngũ nhân sự'),
|
||||
cols: this.colsSelect ? parseInt(this.colsSelect.value) : (this.data.cols || 3),
|
||||
globalClass: this.globalClassInput ? this.globalClassInput.value.trim() : (this.data.globalClass || ''),
|
||||
globalId: this.globalIdInput ? this.globalIdInput.value.trim() : (this.data.globalId || ''),
|
||||
globalAttributes: this.data.globalAttributes || '',
|
||||
showMoreBtn: this.showMoreCheck ? this.showMoreCheck.checked : !!this.data.showMoreBtn,
|
||||
showMoreText: this.showMoreTextInput ? this.showMoreTextInput.value.trim() : (this.data.showMoreText || 'Xem thêm'),
|
||||
showMoreUrl: this.showMoreUrlInput ? this.showMoreUrlInput.value.trim() : (this.data.showMoreUrl || '#'),
|
||||
items: this.data.items || []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Register the plugin globally
|
||||
window.SISEditorPlugins = window.SISEditorPlugins || {};
|
||||
window.SISEditorPlugins['human_resource'] = { class: SISHumanResourceTool };
|
||||
window.SISEditorPlugins['humanResource'] = { class: SISHumanResourceTool };
|
||||
window.SISEditorPlugins['human-resource'] = { class: SISHumanResourceTool };
|
||||
})();
|
||||
@@ -194,7 +194,7 @@
|
||||
},
|
||||
image_dimensions: true,
|
||||
object_resizing: 'img',
|
||||
content_style: 'body { font-family: Roboto, ui-sans-serif, sans-serif; font-size: 14px; color: #333; } img { max-width: 100%; height: auto; cursor: pointer; display: inline-block; }',
|
||||
content_style: 'body { font-family: Roboto, ui-sans-serif, sans-serif; font-size: 14px; color: #333; } img { max-width: 100%; height: auto; cursor: pointer; display: inline-block; } p[style*="text-align: center"] img, p[style*="text-align:center"] img, div[style*="text-align: center"] img, div[style*="text-align:center"] img, figure[style*="text-align: center"] img, figure[style*="text-align:center"] img, img[style*="text-align: center"], img[style*="text-align:center"], img.aligncenter, figure.aligncenter img { display: block !important; margin-left: auto !important; margin-right: auto !important; }',
|
||||
paste_postprocess: function(plugin, args) {
|
||||
if (args && args.node) {
|
||||
args.node.querySelectorAll('img').forEach(function(img) {
|
||||
|
||||
@@ -66,7 +66,11 @@
|
||||
<input type="text" class="form-control" id="title" name="title" placeholder="VD: BỆNH VIỆN...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="imageUrl">Image URL (Tùy chọn - Dùng cho Mega Menu)</label>
|
||||
<label for="description">Mô tả (Tùy chọn - Dùng cho Mega Menu Cột 1)</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="2" placeholder="VD: Khám phá các dịch vụ..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="imageUrl">Image URL (Tùy chọn - Dùng cho Mega Menu Cột 4)</label>
|
||||
<input type="text" class="form-control" id="imageUrl" name="imageUrl" placeholder="VD: /images/banner.jpg">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -79,6 +83,9 @@
|
||||
<option th:value="${childOpt.id}" th:text="'-- ' + ${childOpt.label}"></option>
|
||||
<th:block th:each="grandChildOpt : ${childOpt.children}">
|
||||
<option th:value="${grandChildOpt.id}" th:text="'---- ' + ${grandChildOpt.label}"></option>
|
||||
<th:block th:each="greatGrandChildOpt : ${grandChildOpt.children}">
|
||||
<option th:value="${greatGrandChildOpt.id}" th:text="'------ ' + ${greatGrandChildOpt.label}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
@@ -114,6 +121,7 @@
|
||||
th:data-label="${topItem.label}"
|
||||
th:data-url="${topItem.url}"
|
||||
th:data-title="${topItem.title}"
|
||||
th:data-description="${topItem.description}"
|
||||
th:data-image-url="${topItem.imageUrl}"
|
||||
th:data-parent-id="${topItem.parent != null ? topItem.parent.id : ''}"
|
||||
th:data-display-order="${topItem.displayOrder}">Edit</button>
|
||||
@@ -139,6 +147,7 @@
|
||||
th:data-label="${child.label}"
|
||||
th:data-url="${child.url}"
|
||||
th:data-title="${child.title}"
|
||||
th:data-description="${child.description}"
|
||||
th:data-image-url="${child.imageUrl}"
|
||||
th:data-parent-id="${child.parent != null ? child.parent.id : ''}"
|
||||
th:data-display-order="${child.displayOrder}">Edit</button>
|
||||
@@ -163,6 +172,7 @@
|
||||
th:data-label="${grandchild.label}"
|
||||
th:data-url="${grandchild.url}"
|
||||
th:data-title="${grandchild.title}"
|
||||
th:data-description="${grandchild.description}"
|
||||
th:data-image-url="${grandchild.imageUrl}"
|
||||
th:data-parent-id="${grandchild.parent != null ? grandchild.parent.id : ''}"
|
||||
th:data-display-order="${grandchild.displayOrder}">Edit</button>
|
||||
@@ -170,6 +180,32 @@
|
||||
th:data-action="@{/manage/menus/{menuId}/items/{itemId}/delete(menuId=${menu.id}, itemId=${grandchild.id})}">Delete</button>
|
||||
</div>
|
||||
</li>
|
||||
<!-- Great-Grandchildren Items -->
|
||||
<th:block th:each="greatgrandchild : ${grandchild.children}">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center bg-light" style="margin-left: 6rem; border-left: 4px solid #f6c23e;">
|
||||
<div>
|
||||
<strong th:text="${greatgrandchild.label}">Link Text</strong>
|
||||
<span class="badge badge-warning ml-2">Tier 4</span>
|
||||
<br>
|
||||
<small class="text-muted" th:text="${greatgrandchild.url}">URL</small>
|
||||
</div>
|
||||
<div>
|
||||
<span class="badge badge-primary badge-pill mr-2" th:text="'Order: ' + ${greatgrandchild.displayOrder}">0</span>
|
||||
<button type="button" class="btn btn-sm btn-info edit-item-btn"
|
||||
data-toggle="modal" data-target="#editItemModal"
|
||||
th:data-id="${greatgrandchild.id}"
|
||||
th:data-label="${greatgrandchild.label}"
|
||||
th:data-url="${greatgrandchild.url}"
|
||||
th:data-title="${greatgrandchild.title}"
|
||||
th:data-description="${greatgrandchild.description}"
|
||||
th:data-image-url="${greatgrandchild.imageUrl}"
|
||||
th:data-parent-id="${greatgrandchild.parent != null ? greatgrandchild.parent.id : ''}"
|
||||
th:data-display-order="${greatgrandchild.displayOrder}">Edit</button>
|
||||
<button type="button" class="btn btn-sm btn-danger delete-item-btn"
|
||||
th:data-action="@{/manage/menus/{menuId}/items/{itemId}/delete(menuId=${menu.id}, itemId=${greatgrandchild.id})}">Delete</button>
|
||||
</div>
|
||||
</li>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
@@ -208,7 +244,11 @@
|
||||
<input type="text" class="form-control" id="modalTitle" name="title">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Image URL (Tùy chọn)</label>
|
||||
<label>Mô tả / Description (Tùy chọn - Dùng cho Mega Menu Cột 1)</label>
|
||||
<textarea class="form-control" id="modalDescription" name="description" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Image URL (Tùy chọn - Dùng cho Mega Menu Cột 4)</label>
|
||||
<input type="text" class="form-control" id="modalImageUrl" name="imageUrl">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -221,6 +261,9 @@
|
||||
<option th:value="${childOpt.id}" th:text="'-- ' + ${childOpt.label}"></option>
|
||||
<th:block th:each="grandChildOpt : ${childOpt.children}">
|
||||
<option th:value="${grandChildOpt.id}" th:text="'---- ' + ${grandChildOpt.label}"></option>
|
||||
<th:block th:each="greatGrandChildOpt : ${grandChildOpt.children}">
|
||||
<option th:value="${greatGrandChildOpt.id}" th:text="'------ ' + ${greatGrandChildOpt.label}"></option>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
@@ -277,6 +320,7 @@
|
||||
var label = $btn.data('label') || '';
|
||||
var url = $btn.data('url') || '';
|
||||
var title = $btn.data('title') || '';
|
||||
var description = $btn.data('description') || '';
|
||||
var imageUrl = $btn.data('image-url') || '';
|
||||
var parentId = $btn.data('parent-id') || '';
|
||||
var displayOrder = $btn.data('display-order') || '0';
|
||||
@@ -285,6 +329,7 @@
|
||||
$('#modalLabel').val(label);
|
||||
$('#modalUrl').val(url);
|
||||
$('#modalTitle').val(title);
|
||||
$('#modalDescription').val(description);
|
||||
$('#modalImageUrl').val(imageUrl);
|
||||
$('#modalParentId').val(parentId);
|
||||
$('#modalDisplayOrder').val(displayOrder);
|
||||
|
||||
@@ -472,6 +472,7 @@
|
||||
<script th:src="@{/js/manage/editor-plugins/googleForm.js}"></script>
|
||||
<script th:src="@{/js/manage/editor-plugins/cards.js}"></script>
|
||||
<script th:src="@{/js/manage/editor-plugins/tab-livestream.js}"></script>
|
||||
<script th:src="@{/js/manage/editor-plugins/human-resource.js}"></script>
|
||||
|
||||
<!-- SIS Standalone Media Picker Library -->
|
||||
<script th:src="@{/js/manage/sis-media-picker.js}"></script>
|
||||
|
||||
@@ -570,6 +570,83 @@
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
<!-- Dedicated Human Resource / Doctor List Block (Untitled-6.html) -->
|
||||
<th:block th:if="${block['type'] == 'human_resource' or block['type'] == 'humanResource' or block['type'] == 'human-resource'}">
|
||||
<div th:id="${block.data['globalId'] != null and !#strings.isEmpty(block.data['globalId']) ? block.data['globalId'] : (block['elementId'] != null ? block['elementId'] : null)}"
|
||||
th:class="${block.data['globalClass'] != null and !#strings.isEmpty(block.data['globalClass']) ? block.data['globalClass'] : 'sis-doctor-section'}"
|
||||
th:classappend="${block['cssClass']}"
|
||||
th:styleappend="${(block['customStyle'] != null ? block['customStyle'] : '') + (block['alignment'] != null ? '; text-align: ' + block['alignment'] + ';' : '')}"
|
||||
th:attr="data-custom-attrs=${block['customAttrs']}"
|
||||
th:data-custom-attrs-original="${block.data['globalAttributes'] != null and !#strings.isEmpty(block.data['globalAttributes']) ? block.data['globalAttributes'] : null}">
|
||||
<div class="container py-4">
|
||||
<h2 class="display-7 text-primary-600 mb-4 text-center font-weight-bold"
|
||||
th:if="${block.data['title'] != null and !#strings.isEmpty(block.data['title'])}"
|
||||
th:utext="${block.data['title']}">Đội ngũ nhân sự</h2>
|
||||
|
||||
<div class="row align-items-stretch">
|
||||
<th:block th:each="doctor : ${block.data['items']}">
|
||||
<div th:if="${doctor['active'] == null or doctor['active'] == true or doctor['active'] == 'true'}"
|
||||
th:class="${block.data['cols'] == 1 ? 'col-12 mb-4' : (block.data['cols'] == 2 ? 'col-md-6 col-12 mb-4' : (block.data['cols'] == 4 ? 'col-lg-3 col-md-6 col-12 mb-4' : 'col-lg-4 col-md-6 col-12 mb-4'))}">
|
||||
<div class="bg-white rounded-2xl p-4 overview-wrapper-shadow border flex flex-col justify-between h-100 position-relative" style="border-radius: 16px; border: 1px solid #f1f5f9;">
|
||||
<div>
|
||||
<!-- Corner Specialty Icon -->
|
||||
<div class="position-absolute" style="top: 1rem; right: 1rem; background: rgba(239, 246, 255, 0.6); padding: 0.5rem; border-radius: 12px; border: 1px solid #dbeafe;"
|
||||
th:if="${doctor['specialtyIconUrl'] != null and !#strings.isEmpty(doctor['specialtyIconUrl'])}">
|
||||
<img th:src="${doctor['specialtyIconUrl']}" alt="Specialty Icon" style="width: 24px; height: 24px; object-fit: contain;" />
|
||||
</div>
|
||||
|
||||
<!-- Avatar & Info -->
|
||||
<div class="d-flex align-items-start mb-4" style="gap: 1rem;">
|
||||
<div class="flex-shrink-0" style="width: 112px; height: 128px; border-radius: 12px; overflow: hidden; border: 2px solid #a5f3fc; background-color: #f0f9ff;">
|
||||
<img th:src="${(doctor['avatarUrl'] != null and !#strings.isEmpty(doctor['avatarUrl'])) ? doctor['avatarUrl'] : 'https://images.unsplash.com/photo-1622253692010-333f2da6031d?auto=format&fit=crop&w=300&q=80'}"
|
||||
th:alt="${doctor['name']}"
|
||||
style="width: 100%; height: 100%; object-fit: cover;" />
|
||||
</div>
|
||||
<div class="pt-1 pr-4">
|
||||
<span class="text-xs font-weight-bold text-cyan-600 d-block mb-1" style="font-size: 0.75rem; color: #0891b2;"
|
||||
th:if="${doctor['degree'] != null and !#strings.isEmpty(doctor['degree'])}"
|
||||
th:utext="${doctor['degree']}"></span>
|
||||
<h3 class="font-weight-bold text-dark mb-1" style="font-size: 1.125rem; line-height: 1.375;"
|
||||
th:utext="${doctor['name']}">Doctor Name</h3>
|
||||
<p class="text-sm font-weight-bold" style="font-size: 0.875rem; color: #0891b2;"
|
||||
th:if="${doctor['position'] != null and !#strings.isEmpty(doctor['position'])}"
|
||||
th:utext="${doctor['position']}"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Links -->
|
||||
<div class="d-flex align-items-center mt-3" style="gap: 0.75rem;">
|
||||
<a th:if="${doctor['profileUrl'] != null and !#strings.isEmpty(doctor['profileUrl'])}"
|
||||
th:href="${doctor['profileUrl']}"
|
||||
class="btn btn-outline-primary flex-fill font-weight-bold d-inline-flex align-items-center justify-content-center"
|
||||
style="border-radius: 12px; padding: 8px 12px; font-size: 0.875rem; border-color: #0073b7; color: #0073b7; gap: 6px;">
|
||||
<span th:utext="${(doctor['profileBtnText'] != null and !#strings.isEmpty(doctor['profileBtnText'])) ? doctor['profileBtnText'] : 'Xem hồ sơ'}">Xem hồ sơ</span>
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<a th:if="${doctor['bookingUrl'] != null and !#strings.isEmpty(doctor['bookingUrl'])}"
|
||||
th:href="${doctor['bookingUrl']}"
|
||||
class="btn btn-primary flex-fill font-weight-bold d-inline-flex align-items-center justify-content-center shadow-sm"
|
||||
style="border-radius: 12px; padding: 8px 12px; font-size: 0.875rem; background-color: #0073b7; border-color: #0073b7; color: #ffffff; gap: 6px;">
|
||||
<span th:utext="${(doctor['bookingBtnText'] != null and !#strings.isEmpty(doctor['bookingBtnText'])) ? doctor['bookingBtnText'] : 'Đặt lịch khám'}">Đặt lịch khám</span>
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<!-- Show More Button -->
|
||||
<div class="d-flex justify-content-center mt-4" th:if="${block.data['showMoreBtn'] == true or block.data['showMoreBtn'] == 'true'}">
|
||||
<a th:href="${(block.data['showMoreUrl'] != null and !#strings.isEmpty(block.data['showMoreUrl'])) ? block.data['showMoreUrl'] : '#'}"
|
||||
class="btn btn-primary font-weight-bold px-4 py-2 shadow-sm" style="border-radius: 12px; background-color: #0073b7; border-color: #0073b7;"
|
||||
th:utext="${(block.data['showMoreText'] != null and !#strings.isEmpty(block.data['showMoreText'])) ? block.data['showMoreText'] : 'Xem thêm'}">Xem thêm</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
<!-- Practice Cards Block (Untitled-5.html) -->
|
||||
<th:block th:if="${block['type'] == 'cards' or block['type'] == 'practiceCards' or block['type'] == 'practice-cards'}">
|
||||
<div th:id="${block.data['globalId'] != null and !#strings.isEmpty(block.data['globalId']) ? block.data['globalId'] : (block['elementId'] != null ? block['elementId'] : null)}"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -223,14 +223,14 @@
|
||||
padding-left: 8px; /* Layout indent animation */
|
||||
}
|
||||
|
||||
/* Right Column: Image */
|
||||
/* Column 4: Image */
|
||||
.mega-col-image {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-left: 1px solid #d1d5db;
|
||||
padding-left: 30px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.mega-col-image img {
|
||||
width: 100%;
|
||||
@@ -240,11 +240,11 @@
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* Middle Column for Tabbed Level 2 */
|
||||
/* Column 2: Level 2 */
|
||||
.mega-col-level2 {
|
||||
flex: 1.2;
|
||||
flex: 1;
|
||||
border-left: 1px solid #d1d5db;
|
||||
padding-left: 30px;
|
||||
padding-left: 20px;
|
||||
max-height: 245px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -281,11 +281,11 @@
|
||||
color: #111827 !important;
|
||||
}
|
||||
|
||||
/* Right Column for Level 3 Links */
|
||||
/* Column 3: Level 3 */
|
||||
.mega-col-level3-container {
|
||||
flex: 1;
|
||||
border-left: 1px solid #d1d5db;
|
||||
padding-left: 30px;
|
||||
padding-left: 20px;
|
||||
max-height: 245px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -378,9 +378,12 @@
|
||||
<!-- Column 1: Info (Title and Text) -->
|
||||
<div class="mega-col-info">
|
||||
<h3 th:utext="${not #strings.isEmpty(item.title) ? item.title : item.label}">BỆNH VIỆN ĐA KHOA QUỐC TẾ S.I.S CẦN THƠ</h3>
|
||||
<p th:if="${item.label == 'Về Bệnh viện' or item.label == 'VỀ BỆNH VIỆN'}" style="text-transform: math-auto;">Bệnh viện Đa Khoa Quốc Tế S.I.S Cần Thơ tự hào là đơn vị tiên phong trong việc cung cấp dịch vụ khám chữa bệnh chất lượng cao, mang lại sự tin cậy và an tâm cho bệnh nhân.</p>
|
||||
<p th:if="${item.label == 'Chuyên khoa' or item.label == 'CHUYÊN KHOA'}" style="text-transform: math-auto;">Khám phá các chuyên khoa hàng đầu với đội ngũ bác sĩ chuyên môn cao, trang thiết bị y tế hiện đại đạt tiêu chuẩn quốc tế.</p>
|
||||
<p th:if="${item.label != 'Về Bệnh viện' and item.label != 'VỀ BỆNH VIỆN' and item.label != 'Chuyên khoa' and item.label != 'CHUYÊN KHOA'}" style="text-transform: math-auto;">Khám phá thêm thông tin chi tiết về các dịch vụ, chuyên gia và hoạt động của chúng tôi để bảo vệ sức khỏe của bạn.</p>
|
||||
<p th:if="${not #strings.isEmpty(item.description)}" th:utext="${item.description}" style="text-transform: math-auto;"></p>
|
||||
<th:block th:if="${#strings.isEmpty(item.description)}">
|
||||
<p th:if="${item.label == 'Về Bệnh viện' or item.label == 'VỀ BỆNH VIỆN'}" style="text-transform: math-auto;">Bệnh viện Đa Khoa Quốc Tế S.I.S Cần Thơ tự hào là đơn vị tiên phong trong việc cung cấp dịch vụ khám chữa bệnh chất lượng cao, mang lại sự tin cậy và an tâm cho bệnh nhân.</p>
|
||||
<p th:if="${item.label == 'Chuyên khoa' or item.label == 'CHUYÊN KHOA'}" style="text-transform: math-auto;">Khám phá các chuyên khoa hàng đầu với đội ngũ bác sĩ chuyên môn cao, trang thiết bị y tế hiện đại đạt tiêu chuẩn quốc tế.</p>
|
||||
<p th:if="${item.label != 'Về Bệnh viện' and item.label != 'VỀ BỆNH VIỆN' and item.label != 'Chuyên khoa' and item.label != 'CHUYÊN KHOA'}" style="text-transform: math-auto;">Khám phá thêm thông tin chi tiết về các dịch vụ, chuyên gia và hoạt động của chúng tôi để bảo vệ sức khỏe của bạn.</p>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<!-- Column 2: Level 2 Links -->
|
||||
@@ -392,25 +395,30 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Column 3: Level 3 Links OR Fallback Image -->
|
||||
<div class="mega-col-level3-container" th:if="${not #lists.isEmpty(item.children)}">
|
||||
<!-- Column 3: Level 3 Links -->
|
||||
<div class="mega-col-level3-container" th:if="${not #lists.isEmpty(item.children) and item.children.![children != null and !children.isEmpty()].contains(true)}">
|
||||
<!-- Render each Level 3 target content -->
|
||||
<th:block th:each="child : ${item.children}">
|
||||
<ul th:id="'l3-' + ${item.id} + '-' + ${child.id}" class="submenu-l3 l3-content" style="display: none;">
|
||||
<th:block th:if="${not #lists.isEmpty(child.children)}">
|
||||
<li class="menu-item-l3" th:each="grandchild : ${child.children}">
|
||||
<a th:href="${grandchild.url}" th:text="${grandchild.label}">Grandchild Item</a>
|
||||
<a th:href="${grandchild.url}" th:text="${grandchild.label}" th:classappend="${not #lists.isEmpty(grandchild.children) ? 'font-weight-bold' : ''}">Grandchild Item</a>
|
||||
<ul th:if="${not #lists.isEmpty(grandchild.children)}" class="submenu-l4" style="padding-left: 15px; margin-top: 5px; list-style-type: none;">
|
||||
<li class="menu-item-l4" th:each="greatgrandchild : ${grandchild.children}" style="margin-bottom: 5px;">
|
||||
<a th:href="${greatgrandchild.url}" th:text="${greatgrandchild.label}" style="font-size: 13px; font-weight: normal; color: #555; text-transform: none;">Great-Grandchild Item</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</th:block>
|
||||
<th:block th:if="${#lists.isEmpty(child.children)}">
|
||||
<div class="mega-col-image" style="padding-left: 0; border: none; flex: 1;">
|
||||
<img th:if="${not #strings.isEmpty(item.imageUrl)}" th:src="${item.imageUrl}" style="object-fit: cover; border-radius: 8px; width: 100%;"/>
|
||||
<img th:if="${#strings.isEmpty(item.imageUrl)}" th:src="@{/theme-assets/umass/images/logo.png}" style="object-fit: contain; background: white; padding: 20px; width: 100%;"/>
|
||||
</div>
|
||||
</th:block>
|
||||
</ul>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<!-- Column 4: Featured Image / Media Banner -->
|
||||
<div class="mega-col-image">
|
||||
<img th:if="${not #strings.isEmpty(item.imageUrl)}" th:src="${item.imageUrl}" style="object-fit: cover; border-radius: 8px; width: 100%; max-height: 245px;"/>
|
||||
<img th:if="${#strings.isEmpty(item.imageUrl)}" th:src="@{/theme-assets/umass/images/logo.png}" style="object-fit: contain; background: white; padding: 20px; width: 100%; max-height: 245px;"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Mega Menu Layout -->
|
||||
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Cơ Hội Nghề Nghiệp - S.I.S</title>
|
||||
<style>
|
||||
/* ===================================================
|
||||
1. RESET & VARIABLES
|
||||
=================================================== */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Roboto, ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f8fafc;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* ===================================================
|
||||
2. HERO SECTION LAYOUT
|
||||
=================================================== */
|
||||
.career-hero {
|
||||
position: relative;
|
||||
padding: 40px 0;
|
||||
min-height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Lớp phủ Background Gradient */
|
||||
.hero-bg-1 {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(360deg, #f0faff 65.38%, rgba(253, 254, 255, 0) 100%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-bg-2 {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(360deg, #b7eaff 29.33%, rgba(253, 254, 255, 0) 100%);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Container chứa nội dung chính */
|
||||
.hero-container {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
/* Tiêu đề H1 chính */
|
||||
.hero-title {
|
||||
font-size: 42px;
|
||||
font-weight: 700;
|
||||
color: #0d71ba; /* Màu xanh y tế chuẩn */
|
||||
line-height: 1.2;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
/* Khung chứa hình chứng nhận và các danh hiệu */
|
||||
.awards-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
/* Hình Bằng khen / Chứng nhận */
|
||||
.certificate-box {
|
||||
position: relative;
|
||||
width: 313px;
|
||||
aspect-ratio: 2 / 3;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.certificate-box img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* Danh sách giải thưởng */
|
||||
.awards-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.award-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.award-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.trophy-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.award-badge {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #0d68aa;
|
||||
border-bottom: 2px solid #0d68aa;
|
||||
display: inline-block;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.award-desc {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #0d68aa;
|
||||
line-height: 1.4;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Hình ảnh Bác sĩ bên phải */
|
||||
.doctor-image-box {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 32px;
|
||||
width: 630px;
|
||||
aspect-ratio: 630 / 480;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.doctor-image-box img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* ===================================================
|
||||
3. RESPONSIVE DESIGN (Cho Mobile & Tablet)
|
||||
=================================================== */
|
||||
@media (max-width: 1200px) {
|
||||
.hero-title {
|
||||
font-size: 34px;
|
||||
}
|
||||
.certificate-box {
|
||||
width: 220px;
|
||||
}
|
||||
.doctor-image-box {
|
||||
width: 450px;
|
||||
}
|
||||
.award-badge {
|
||||
font-size: 20px;
|
||||
}
|
||||
.award-desc {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.doctor-image-box {
|
||||
width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
/* Ẩn hình ảnh bác sĩ lớn trên điện thoại */
|
||||
.doctor-image-box {
|
||||
display: none;
|
||||
}
|
||||
.certificate-box {
|
||||
width: 140px;
|
||||
}
|
||||
.trophy-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.award-badge {
|
||||
font-size: 16px;
|
||||
}
|
||||
.award-desc {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<section class="career-hero">
|
||||
<!-- Lớp phủ Gradient mờ -->
|
||||
<div class="hero-bg-1"></div>
|
||||
<div class="hero-bg-2"></div>
|
||||
|
||||
<!-- Nội dung chính Banner -->
|
||||
<div class="hero-container">
|
||||
<!-- Tiêu đề -->
|
||||
<h1 class="hero-title">Cơ hội nghề nghiệp</h1>
|
||||
|
||||
<!-- Cột Nội dung Bằng khen & Cúp danh hiệu -->
|
||||
<div class="awards-wrapper">
|
||||
<!-- Ảnh Chứng nhận/Bằng khen bên trái -->
|
||||
<div class="certificate-box">
|
||||
<img src="/_next/image?url=%2Fimages%2Fcareer%2Fcertificate.webp&w=1200&q=80" alt="Bằng khen S.I.S" />
|
||||
</div>
|
||||
|
||||
<!-- Khối danh hiệu Top 10 & Top 50 -->
|
||||
<div class="awards-list">
|
||||
<!-- TOP 10 -->
|
||||
<div class="award-item">
|
||||
<div class="award-header">
|
||||
<img src="/_next/image?url=%2Fimages%2Fcareer%2Ftrophy.png&w=640&q=80" alt="Cúp danh hiệu" class="trophy-icon" />
|
||||
<span class="award-badge">TOP 10</span>
|
||||
</div>
|
||||
<p class="award-desc">NƠI LÀM VIỆC TỐT NHẤT NGÀNH Y DƯỢC - CHĂM SÓC SỨC KHOẺ</p>
|
||||
</div>
|
||||
|
||||
<!-- TOP 50 -->
|
||||
<div class="award-item">
|
||||
<div class="award-header">
|
||||
<img src="/_next/image?url=%2Fimages%2Fcareer%2Ftrophy.png&w=640&q=80" alt="Cúp danh hiệu" class="trophy-icon" />
|
||||
<span class="award-badge">TOP 50</span>
|
||||
</div>
|
||||
<p class="award-desc">NƠI LÀM VIỆC TỐT NHẤT VIỆT NAM</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ảnh Bác sĩ định vị góc phải (Tự động ẩn trên Mobile) -->
|
||||
<div class="doctor-image-box">
|
||||
<img src="/_next/image?url=%2Fimages%2Fcareer%2Fhero-doctor.webp&w=1200&q=80" alt="Đội ngũ Y Bác sĩ S.I.S" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Danh sách Bác sĩ</title>
|
||||
<!-- Tailwind CSS CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen py-12 px-4 flex flex-col items-center justify-center">
|
||||
|
||||
<!-- Lưới chứa danh sách card Bác sĩ -->
|
||||
<div id="doctor-grid" class="max-w-6xl w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
|
||||
<!-- CARD 1: BS CKII. Nguyễn Viết Hậu -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<!-- Icon xe cấp cứu góc trên bên phải -->
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
<!-- Icon xe cấp cứu cách điệu -->
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Phần ảnh & Thông tin chính -->
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<!-- Ảnh chân dung với viền xanh lam nhạt -->
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1622253692010-333f2da6031d?auto=format&fit=crop&w=300&q=80" alt="BS CKII. Nguyễn Viết Hậu" class="w-full h-full object-cover">
|
||||
</div>
|
||||
|
||||
<!-- Chức danh & Họ tên -->
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">BS CKII.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Nguyễn Viết Hậu</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Trưởng Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Các nút hành động phía dưới -->
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<!-- Nút Xem hồ sơ -->
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<!-- Nút Đặt lịch khám -->
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CARD 2: BS CKI. Tăng Tuấn Phong -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1612349317150-e413f6a5b16d?auto=format&fit=crop&w=300&q=80" alt="BS CKI. Tăng Tuấn Phong" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">BS CKI.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Tăng Tuấn Phong</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Phó Trưởng Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CARD 3: TS BS. Nguyễn Tuấn Anh -->
|
||||
<div class="bg-white rounded-2xl p-5 shadow-lg border border-gray-100 flex flex-col justify-between hover:shadow-xl transition duration-300 relative">
|
||||
<div>
|
||||
<div class="absolute top-4 right-4 bg-blue-50/60 p-2 rounded-xl border border-blue-100">
|
||||
<svg class="w-6 h-6 text-[#0073b7]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" d="M8 17h1m8 0h1M3 9l2-4h10l2 4m-14 0h16v7a1 1 0 01-1 1H4a1 1 0 01-1-1V9z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<div class="w-28 h-32 rounded-lg overflow-hidden border-2 border-cyan-200 flex-shrink-0 bg-blue-50">
|
||||
<img src="https://images.unsplash.com/photo-1537368910025-700350fe46c7?auto=format&fit=crop&w=300&q=80" alt="TS BS. Nguyễn Tuấn Anh" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="pt-2 pr-8">
|
||||
<span class="text-xs font-semibold text-cyan-600 block mb-1">TS BS.</span>
|
||||
<h3 class="font-bold text-gray-900 text-lg leading-snug mb-1">Nguyễn Tuấn Anh</h3>
|
||||
<p class="text-cyan-600 text-sm font-medium">Khoa Cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3 pt-2">
|
||||
<a href="#" class="flex-1 border-2 border-[#0073b7] text-[#0073b7] hover:bg-blue-50 font-semibold py-2 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5">
|
||||
<span>Xem hồ sơ</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
|
||||
</a>
|
||||
<a href="#" class="flex-1 bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-3 rounded-xl transition duration-200 text-center text-sm flex items-center justify-center gap-1.5 shadow-sm">
|
||||
<span>Đặt lịch khám</span>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Nút Xem thêm ở giữa phía dưới -->
|
||||
<button id="btn-load-more" class="bg-[#0073b7] hover:bg-blue-700 text-white font-semibold py-2.5 px-8 rounded-xl transition duration-200 text-sm shadow-md">
|
||||
Xem thêm
|
||||
</button>
|
||||
|
||||
<!-- JavaScript tương tác -->
|
||||
<script>
|
||||
document.getElementById('btn-load-more').addEventListener('click', function() {
|
||||
alert('Đang tải thêm danh sách bác sĩ...');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user