feat: implement responsive tab plugin and new hover card v3 component, and add admin controllers for price and recruiting tables.

This commit is contained in:
2026-08-04 21:44:13 +07:00
parent 89c18f20fd
commit 373ee63716
42 changed files with 6148 additions and 1008 deletions
+209 -311
View File
@@ -3,380 +3,278 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Thành tựu và Bài viết Bệnh viện</title>
<title>Trang Tin Tức - Bài Viết Nổi Bật</title>
<style>
/* ===================================================
1. RESET CSS & FONT CƠ BẢN
1. RESET & BASIC STYLES
=================================================== */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial,
sans-serif;
}
body {
background-color: #f8fafc;
color: #1e293b;
padding: 40px 20px;
display: flex;
justify-content: center;
}
.news-container {
/* ===================================================
2. GRID LAYOUT CHÍNH (12 CỘT)
=================================================== */
.news-section {
max-width: 1200px;
margin: 0 auto;
}
/* ===================================================
2. FILTER TABS (THANH LỌC DANH MỤC)
=================================================== */
.filter-tabs {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 30px;
}
.tab-btn {
padding: 8px 18px;
border: none;
background-color: #e2e8f0;
color: #475569;
font-size: 14px;
font-weight: 500;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
}
.tab-btn:hover {
background-color: #cbd5e1;
}
.tab-btn.active {
background-color: #0284c7; /* Màu xanh chủ đạo y tế */
color: #ffffff;
}
/* ===================================================
3. CARD GRID (LƯỚI 3 CỘT chuẩn UI)
=================================================== */
.news-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
margin-bottom: 40px;
}
.news-card {
width: 100%;
background-color: #ffffff;
padding: 24px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
transition:
transform 0.25s ease,
box-shadow 0.25s ease;
cursor: pointer;
border: 1px solid #f1f5f9;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 24px;
}
.news-card:hover {
transform: translateY(-4px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}
/* THUMBNAIL & BADGE NĂM */
.card-thumb {
position: relative;
width: 100%;
aspect-ratio: 16 / 9; /* Cố định tỉ lệ hình ảnh */
overflow: hidden;
background-color: #e2e8f0;
}
.card-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
}
.year-badge {
position: absolute;
top: 10px;
right: 10px;
background-color: #0284c7;
color: #ffffff;
font-size: 12px;
font-weight: 600;
padding: 4px 10px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* NỘI DUNG CARD */
.card-body {
padding: 16px 18px 20px;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.card-title {
font-size: 14px;
/* Component thẻ Badge (TIN TỨC / SỰ KIỆN) */
.badge {
display: inline-block;
padding: 4px 8px;
background-color: #f1f5f9;
color: #475569;
font-size: 11px;
font-weight: 700;
color: #0284c7; /* Chữ xanh y tế */
line-height: 1.45;
/* Cắt bớt văn bản thành 3 dòng kèm dấu ... */
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-transform: uppercase;
border-radius: 4px;
letter-spacing: 0.5px;
}
/* ===================================================
4. PHÂN TRANG (PAGINATION)
=================================================== */
.pagination {
display: flex;
justify-content: center;
align-items: center;
list-style: none;
gap: 8px;
}
.page-link {
display: inline-flex;
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
border-radius: 50%;
border: 1px solid #e2e8f0;
background-color: #ffffff;
color: #64748b;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: all 0.2s ease;
}
.page-link:hover {
border-color: #0284c7;
color: #0284c7;
}
.page-link.active {
background-color: #0284c7;
color: #ffffff;
border-color: #0284c7;
}
.page-dots {
padding: 0 4px;
.post-date {
font-size: 12px;
color: #94a3b8;
}
/* ===================================================
5. RESPONSIVE
3. CỘT TRÁI - BÀI VIẾT NỔI BẬT (FEATURED POST)
=================================================== */
.featured-post {
grid-column: span 6; /* Chiếm 6/12 cột */
display: flex;
flex-direction: column;
gap: 16px;
}
.featured-img-box {
width: 100%;
aspect-ratio: 16 / 9;
border-radius: 8px;
overflow: hidden;
}
.featured-img-box img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.featured-post:hover .featured-img-box img {
transform: scale(1.03);
}
.meta-row {
display: flex;
align-items: center;
gap: 12px;
}
.featured-title {
font-size: 22px;
font-weight: 700;
color: #0284c7; /* Màu xanh chủ đạo */
line-height: 1.3;
cursor: pointer;
text-decoration: none;
}
.featured-title:hover {
color: #0369a1;
}
.featured-excerpt {
font-size: 14px;
color: #475569;
line-height: 1.6;
}
/* ===================================================
4. CỘT PHẢI - LƯỚI 4 BÀI NHỎ (GRID 2x2)
=================================================== */
.side-news-grid {
grid-column: span 6; /* Chiếm 6/12 cột còn lại */
display: grid;
grid-template-columns: repeat(2, 1fr); /* Tách thành 2 cột nhỏ */
gap: 20px;
}
.small-post {
display: flex;
flex-direction: column;
gap: 8px;
text-decoration: none;
color: inherit;
}
.small-img-box {
width: 100%;
aspect-ratio: 16 / 10;
border-radius: 8px;
overflow: hidden;
}
.small-img-box img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.small-post:hover .small-img-box img {
transform: scale(1.04);
}
.small-title {
font-size: 14px;
font-weight: 700;
color: #1e293b;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 3; /* Giới hạn tối đa 3 dòng */
-webkit-box-orient: vertical;
overflow: hidden;
}
.small-post:hover .small-title {
color: #0284c7;
}
/* ===================================================
5. RESPONSIVE (Cho Tablet & Mobile)
=================================================== */
@media (max-width: 992px) {
.news-grid {
grid-template-columns: repeat(2, 1fr); /* Tablet chia 2 cột */
.featured-post,
.side-news-grid {
grid-column: span 12; /* Chuyển thành 1 cột dọc lớn */
}
}
@media (max-width: 576px) {
.news-grid {
grid-template-columns: 1fr; /* Mobile hiển th 1 cột */
.side-news-grid {
grid-template-columns: 1fr; /* Lưới bài nhỏ chuyển thành 1 cột trên Mobile */
}
.filter-tabs {
justify-content: flex-start;
.featured-title {
font-size: 18px;
}
}
</style>
</head>
<body>
<div class="news-container">
<!-- 1. TAB LỌC NỘI DUNG -->
<div class="filter-tabs">
<button class="tab-btn active">Tất cả</button>
<button class="tab-btn">Điều trị</button>
<button class="tab-btn">Đào tạo - Nghiên cứu khoa học</button>
<button class="tab-btn">Quản trị Bệnh viện</button>
</div>
<section class="news-section">
<!-- CỘT TRÁI: Bài viết nổi bật lớn -->
<article class="featured-post">
<div class="featured-img-box">
<img
src="https://picsum.photos/800/450?random=1"
alt="Nhà giáo nhân dân Nguyễn Đình Hối"
/>
</div>
<div class="meta-row">
<span class="badge">Tin tức</span>
<span class="post-date">06/07/2026</span>
</div>
<a href="#" class="featured-title">Thư cảm tạ</a>
<p class="featured-excerpt">
Đại học Y Dược Thành phố Hồ Chí Minh, Bệnh viện Đại học Y Dược Thành
phố Hồ Chí Minh và gia quyến vô cùng xúc động và trân trọng gửi lời
cảm tạ sâu sắc.
</p>
</article>
<!-- 2. DANH SÁCH BÀI VIẾT dạng LƯỚI GRID -->
<div class="news-grid">
<!-- Card 1 -->
<article class="news-card">
<div class="card-thumb">
<img
src="https://picsum.photos/400/250?random=1"
alt="Bài viết 1"
/>
<span class="year-badge">2026</span>
</div>
<div class="card-body">
<h3 class="card-title">
Bệnh viện Đại học Y Dược TP. Hồ Chí Minh ghi dấu ấn tại giải
thưởng "Đại sứ truyền thông...
</h3>
</div>
</article>
<!-- Card 2 -->
<article class="news-card">
<div class="card-thumb">
<!-- CỘT PHẢI: Lưới 4 bài viết nhỏ (2x2) -->
<div class="side-news-grid">
<!-- Bài nhỏ 1 -->
<a href="#" class="small-post">
<div class="small-img-box">
<img
src="https://picsum.photos/400/250?random=2"
alt="Bài viết 2"
alt="Tuần lễ thế giới nuôi con bằng sữa mẹ"
/>
<span class="year-badge">2026</span>
</div>
<div class="card-body">
<h3 class="card-title">
Tác phẩm "Tuyển tập những bệnh án lâm sàng đặc sắc" đạt giải B
giải thưởng sách quốc gia...
</h3>
<div class="meta-row">
<span class="badge">Sự kiện</span>
</div>
</article>
<h3 class="small-title">
Tuần lễ thế giới nuôi con bằng sữa mẹ 2026
</h3>
<span class="post-date">04/08/2026</span>
</a>
<!-- Card 3 -->
<article class="news-card">
<div class="card-thumb">
<!-- Bài nhỏ 2 -->
<a href="#" class="small-post">
<div class="small-img-box">
<img
src="https://picsum.photos/400/250?random=3"
alt="Bài viết 3"
alt="Đau lưng ở nhân viên văn phòng"
/>
<span class="year-badge">2026</span>
</div>
<div class="card-body">
<h3 class="card-title">
Trái tim từ bắc vào nam hồi sinh sự sống cho bệnh nhi ngày đầu
xuân mới
</h3>
<div class="meta-row">
<span class="badge">Tin tức</span>
</div>
</article>
<h3 class="small-title">
Đau lưng ở nhân viên văn phòng: Đừng đợi đến khi cột sống “lên
tiếng”
</h3>
<span class="post-date">01/08/2026</span>
</a>
<!-- Card 4 -->
<article class="news-card">
<div class="card-thumb">
<!-- Bài nhỏ 3 -->
<a href="#" class="small-post">
<div class="small-img-box">
<img
src="https://picsum.photos/400/250?random=4"
alt="Bài viết 4"
alt="Bệnh lý miễn dịch thần kinh"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Ca ghép tim xuyên đêm tại Bệnh viện Đại học Y Dược TP. Hồ Chí
Minh: Cuộc chạy đua sinh tử...
</h3>
<div class="meta-row">
<span class="badge">Tin tức</span>
</div>
</article>
<h3 class="small-title">
Bệnh lý miễn dịch thần kinh - Phát hiện sớm để điều trị tốt
</h3>
<span class="post-date">31/07/2026</span>
</a>
<!-- Card 5 -->
<article class="news-card">
<div class="card-thumb">
<!-- Bài nhỏ 4 -->
<a href="#" class="small-post">
<div class="small-img-box">
<img
src="https://picsum.photos/400/250?random=5"
alt="Bài viết 5"
alt="Phẫu thuật nội soi"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Đại học Y Dược TP. Hồ Chí Minh công nhận 02 nhóm nghiên cứu tiềm
năng mạnh đầu tiên
</h3>
<div class="meta-row">
<span class="badge">Tin tức</span>
</div>
</article>
<!-- Card 6 -->
<article class="news-card">
<div class="card-thumb">
<img
src="https://picsum.photos/400/250?random=6"
alt="Bài viết 6"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Bệnh viện Đại học Y Dược TP. Hồ Chí Minh - Điển hình tiên tiến
Ngành Y tế tại Đại hội Thi đ...
</h3>
</div>
</article>
<!-- Card 7 -->
<article class="news-card">
<div class="card-thumb">
<img
src="https://picsum.photos/400/250?random=7"
alt="Bài viết 7"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Bệnh viện Đại học Y Dược TP. Hồ Chí Minh tổ chức lễ kỷ niệm 100 ca
TAVI thành công trao...
</h3>
</div>
</article>
<!-- Card 8 -->
<article class="news-card">
<div class="card-thumb">
<img
src="https://picsum.photos/400/250?random=8"
alt="Bài viết 8"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Bệnh viện Đại học Y Dược TP. Hồ Chí Minh đạt giải "Vệ sinh tay
xuất sắc năm 2025"
</h3>
</div>
</article>
<!-- Card 9 -->
<article class="news-card">
<div class="card-thumb">
<img
src="https://picsum.photos/400/250?random=9"
alt="Bài viết 9"
/>
<span class="year-badge">2025</span>
</div>
<div class="card-body">
<h3 class="card-title">
Tiến bộ trong y học bào thai: Can thiệp thành công cứu sống thai
nhi mắc khối u nhau thai...
</h3>
</div>
</article>
<h3 class="small-title">
Phẫu thuật nội soi cắt phì đại liên thất và thay van động mạch chủ
</h3>
<span class="post-date">30/07/2026</span>
</a>
</div>
<!-- 3. THANH PHÂN TRANG -->
<ul class="pagination">
<li><a href="#" class="page-link">&laquo;</a></li>
<li><a href="#" class="page-link">&lsaquo;</a></li>
<li><a href="#" class="page-link active">1</a></li>
<li><a href="#" class="page-link">2</a></li>
<li><a href="#" class="page-link">3</a></li>
<li><span class="page-dots">...</span></li>
<li><a href="#" class="page-link">6</a></li>
<li><a href="#" class="page-link">&rsaquo;</a></li>
<li><a href="#" class="page-link">&raquo;</a></li>
</ul>
</div>
</section>
</body>
</html>