feat: implement specialty content module with expanded Page entity fields, database migrations, and data import utilities
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
<?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="20260728140500-1" author="system">
|
||||
<addColumn tableName="sis_page">
|
||||
<column name="contact_email" type="varchar(255)"/>
|
||||
<column name="contact_address" type="varchar(500)"/>
|
||||
<column name="contact_phone" type="varchar(100)"/>
|
||||
<column name="hero_image" type="varchar(1000)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?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="20260728160000-1" author="system">
|
||||
<addColumn tableName="sis_page">
|
||||
<column name="specialty_category" type="varchar(50)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="20260728160000-2" author="system">
|
||||
<!-- Khoa lâm sàng -->
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'khoa-cap-cuu'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'khoa-than-kinh-dot-quy'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'tim-mach'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'khoa-ngoai-tong-hop'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'khoa-kham-benh'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'phau-thuat-gay-me-hoi-suc'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'don-vi-can-thiep-mach-dsa'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'don-vi-cap-cuu-ngoai-vien'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_LAM_SANG"/><where>slug = 'chuyen-khoa-tai-mui-hong'</where></update>
|
||||
|
||||
<!-- Khoa cận lâm sàng -->
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_CAN_LAM_SANG"/><where>slug = 'khoa-chan-doan-hinh-anh'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_CAN_LAM_SANG"/><where>slug = 'khoa-xet-nghiem'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_CAN_LAM_SANG"/><where>slug = 'khoa-vat-ly-tri-lieu-phuc-hoi-chuc-nang'</where></update>
|
||||
|
||||
<!-- Khoa hỗ trợ lâm sàng -->
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_HO_TRO_LAM_SANG"/><where>slug = 'khoa-duoc'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_HO_TRO_LAM_SANG"/><where>slug = 'khoa-dinh-duong-tiet-che'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_HO_TRO_LAM_SANG"/><where>slug = 'don-vi-kiem-soat-nhiem-khuan'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_HO_TRO_LAM_SANG"/><where>slug = 'don-vi-kham-suc-khoe-ngoai-vien'</where></update>
|
||||
<update tableName="sis_page"><column name="specialty_category" value="KHOA_HO_TRO_LAM_SANG"/><where>slug = 'phong-quan-ly-van-hanh'</where></update>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -50,4 +50,6 @@
|
||||
<include file="config/liquibase/changelog/20260723185500_add_doctor_schedule.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260724150000_alter_setting_value.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260724151500_alter_setting_value_to_clob.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260728140500_add_contact_fields_to_page.xml" relativeToChangelogFile="false"/>
|
||||
<include file="config/liquibase/changelog/20260728160000_add_specialty_category.xml" relativeToChangelogFile="false"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -1213,12 +1213,19 @@ figure.table table tr:hover {
|
||||
}
|
||||
|
||||
.education {
|
||||
.gap-3 {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex !important;
|
||||
}
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
.rounded-full {
|
||||
justify-content: center;
|
||||
background-color: var(--color-white);
|
||||
@@ -1227,10 +1234,27 @@ figure.table table tr:hover {
|
||||
height: 32px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-navigation {
|
||||
border-radius: 24px;
|
||||
cursor: pointer;
|
||||
background-color: var(--color-white);
|
||||
color: var(--color-black);
|
||||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
color: var(--color-old-brick);
|
||||
}
|
||||
svg:hover{
|
||||
background-color: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.training-sidebar {
|
||||
.gap-3 {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
margin-bottom: 4px;
|
||||
|
||||
@@ -1245,4 +1269,21 @@ figure.table table tr:hover {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
border: solid 1px #efeff0;
|
||||
border-radius: 15px;
|
||||
padding: 1rem;
|
||||
.btn {
|
||||
padding: 0.75rem;
|
||||
border-radius: 15px;
|
||||
}
|
||||
.flex.items-center {
|
||||
justify-content: center;
|
||||
}
|
||||
a {
|
||||
text-decoration-line: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size) / 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size) / 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next svg,.swiper-button-prev svg{width:100%;height:100%;object-fit:contain;transform-origin:center}.swiper-rtl .swiper-button-next svg,.swiper-rtl .swiper-button-prev svg{transform:rotate(180deg)}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-lock{display:none}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:normal;line-height:1}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:"prev"}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:var(--swiper-navigation-sides-offset,10px);left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:"next"}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
/* PLEASE DO NOT COPY AND PASTE THIS CODE. */(function(){var w=window,C='___grecaptcha_cfg',cfg=w[C]=w[C]||{},N='grecaptcha';var gr=w[N]=w[N]||{};gr.ready=gr.ready||function(f){(cfg['fns']=cfg['fns']||[]).push(f);};w['__recaptcha_api']='https://www.google.com/recaptcha/api2/';(cfg['render']=cfg['render']||[]).push('onload');(cfg['anchor-ms']=cfg['anchor-ms']||[]).push(20000);(cfg['execute-ms']=cfg['execute-ms']||[]).push(30000);w['__google_recaptcha_client']=true;var d=document,po=d.createElement('script');po.type='text/javascript';po.async=true; po.charset='utf-8';po.src='https://www.gstatic.com/recaptcha/releases/A7KpaEASfhDcK0nXxgQEyyYv/recaptcha__en_gb.js';po.crossOrigin='anonymous';po.integrity='sha384-5OOK2erh/YOEG9kGHGnFP3+VW3JJ6xFMntvj2Hukmf0CErQumRfz6RUGAs6A/57r';var e=d.querySelector('script[nonce]'),n=e&&(e['nonce']||e.getAttribute('nonce'));if(n){po.setAttribute('nonce',n);}var s=d.getElementsByTagName('script')[0];s.parentNode.insertBefore(po, s);})();
|
||||
+1
@@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{24473:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,14933,23)),Promise.resolve().then(n.t.bind(n,86695,23)),Promise.resolve().then(n.t.bind(n,54775,23)),Promise.resolve().then(n.t.bind(n,22908,23)),Promise.resolve().then(n.t.bind(n,23624,23)),Promise.resolve().then(n.t.bind(n,59440,23)),Promise.resolve().then(n.t.bind(n,62920,23)),Promise.resolve().then(n.t.bind(n,19710,23))}},e=>{var s=s=>e(e.s=s);e.O(0,[1032,4619],()=>(s(36596),s(24473))),_N_E=e.O()}]);
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
!function(r,i){"use strict";var e,o=r.location,s=r.document,t=s.querySelector('[src*="'+i+'"]'),l=t&&t.getAttribute("data-domain"),p=r.localStorage.plausible_ignore;function c(e){console.warn("Ignoring Event: "+e)}function a(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(o.hostname)||"file:"===o.protocol)return c("localhost");if(!(r.phantom||r._phantom||r.__nightmare||r.navigator.webdriver||r.Cypress)){if("true"==p)return c("localStorage flag");var a={};a.n=e,a.u=o.href,a.d=l,a.r=s.referrer||null,a.w=r.innerWidth,t&&t.meta&&(a.m=JSON.stringify(t.meta)),t&&t.props&&(a.p=JSON.stringify(t.props));var n=new XMLHttpRequest;n.open("POST",i+"/api/event",!0),n.setRequestHeader("Content-Type","text/plain"),n.send(JSON.stringify(a)),n.onreadystatechange=function(){4==n.readyState&&t&&t.callback&&t.callback()}}}function n(){e!==o.pathname&&(e=o.pathname,a("pageview"))}try{var u,h=r.history;h.pushState&&(u=h.pushState,h.pushState=function(){u.apply(this,arguments),n()},r.addEventListener("popstate",n));var g=r.plausible&&r.plausible.q||[];r.plausible=a;for(var f=0;f<g.length;f++)a.apply(this,g[f]);"prerender"===s.visibilityState?s.addEventListener("visibilitychange",function(){e||"visible"!==s.visibilityState||n()}):n()}catch(e){console.error(e),(new Image).src=i+"/api/error?message="+encodeURIComponent(e.message)}}(window,"https://analytics.jamstackvietnam.com");
|
||||
+1
File diff suppressed because one or more lines are too long
+1710
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
@@ -186,22 +186,20 @@
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
[class*='btn-navigation-']:hover:not([disabled]):not(.swiper-button-disabled):not(.swiper-button-lock) {
|
||||
background-color: var(--color-primary-600);
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Related Courses (Chương trình khác) -->
|
||||
<section class="py-6 xl:py-12 md:py-8 bg-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="container mx-auto px-4" style="text-align: center">
|
||||
<h2 class="display-7 text-primary-600 text-center xl:mb-8 md:mb-6 mb-4">Chương trình khác</h2>
|
||||
<div class="relative md:flex md:items-center">
|
||||
<div class="relative flex items-center gap-3">
|
||||
<button
|
||||
class="btn-navigation flex-shrink-0 lg:mr-4 mr-2 !relative z-10 md:size-[42px] size-[32px] items-center justify-center rounded-full bg-white shadow-sm border border-gray-100 hover:bg-primary-600 hover:text-white transition-colors cursor-pointer group btn-navigation-chuong-trinh-khac-prev md:!flex hidden"
|
||||
class="btn-navigation flex-shrink-0 lg:mr-4 mr-2 z-10 flex items-center justify-center btn-navigation-chuong-trinh-khac-prev"
|
||||
style="width: 42px; height: 42px; min-width: 42px; flex-shrink: 0"
|
||||
>
|
||||
<svg
|
||||
class="lucide lucide-chevron-up size-4 -rotate-90"
|
||||
class="lucide lucide-chevron-up size-4"
|
||||
style="transform: rotate(-90deg)"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -215,19 +213,19 @@
|
||||
<path d="m18 15-6-6-6 6"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
class="swiper swiper-chuong-trinh-khac [&>.swiper-pagination]:!static [&>.swiper-pagination]:mt-1 lg:[&>.swiper-pagination]:!hidden w-full"
|
||||
>
|
||||
<div class="swiper swiper-chuong-trinh-khac w-full" style="overflow: hidden">
|
||||
<div class="swiper-wrapper">
|
||||
<th:block th:utext="${hookManager.applyFilters('swiper_slider_items', '', 'chuong-trinh-khac')}"></th:block>
|
||||
</div>
|
||||
<div class="swiper-pagination"></div>
|
||||
<div class="swiper-pagination hidden"></div>
|
||||
</div>
|
||||
<button
|
||||
class="btn-navigation flex-shrink-0 lg:ml-4 ml-2 !relative z-10 md:size-[42px] size-[32px] items-center justify-center rounded-full bg-white shadow-sm border border-gray-100 hover:bg-primary-600 hover:text-white transition-colors cursor-pointer group btn-navigation-chuong-trinh-khac-next md:!flex hidden"
|
||||
class="btn-navigation flex-shrink-0 lg:ml-4 ml-2 z-10 flex items-center justify-center btn-navigation-chuong-trinh-khac-next"
|
||||
style="width: 42px; height: 42px; min-width: 42px; flex-shrink: 0"
|
||||
>
|
||||
<svg
|
||||
class="lucide lucide-chevron-down size-4 -rotate-90"
|
||||
class="lucide lucide-chevron-down size-4"
|
||||
style="transform: rotate(-90deg)"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
|
||||
@@ -180,6 +180,42 @@
|
||||
title.</small>
|
||||
</div>
|
||||
|
||||
<!-- Specialty/Contact Info -->
|
||||
<div class="card bg-light mb-4">
|
||||
<div class="card-body">
|
||||
<h6 class="font-weight-bold text-primary mb-3">Thông tin liên hệ & Banner (Dành riêng cho trang Chuyên khoa)</h6>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="contactEmail" class="font-weight-bold">Email</label>
|
||||
<input type="text" class="form-control" id="contactEmail" th:field="*{contactEmail}" placeholder="vd: capcuu@umc.edu.vn">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="contactPhone" class="font-weight-bold">Điện thoại / SĐT</label>
|
||||
<input type="text" class="form-control" id="contactPhone" th:field="*{contactPhone}" placeholder="vd: 028 3952 5115">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="contactAddress" class="font-weight-bold">Địa chỉ</label>
|
||||
<input type="text" class="form-control" id="contactAddress" th:field="*{contactAddress}" placeholder="vd: Tầng trệt - Khu A">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="heroImage" class="font-weight-bold">Ảnh Banner (Hero Image URL)</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="heroImage" th:field="*{heroImage}" placeholder="URL ảnh">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary" onclick="document.getElementById('mediaManagerBtn').click()">
|
||||
<i class="fas fa-image"></i> Chọn ảnh
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Block Editor Content -->
|
||||
<div class="form-group">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
@@ -249,6 +285,7 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/@editorjs/underline@1.1.0/dist/bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@editorjs/image@2.9.0/dist/image.umd.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@editorjs/attaches@1.3.0/dist/bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@editorjs/raw@2.4.3/dist/bundle.js"></script>
|
||||
|
||||
<!--
|
||||
============================================================
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,302 @@
|
||||
<!doctype html>
|
||||
<html
|
||||
lang="en"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{themes/__${activeTheme}__/layout(forceFullWidth=true, bodyClass='specialty-list-page')}"
|
||||
>
|
||||
<head>
|
||||
<title>Chuyên khoa - Bệnh viện S.I.S Cần Thơ</title>
|
||||
<meta name="description" content="Danh sách các chuyên khoa tại Bệnh viện Đa khoa Quốc tế S.I.S Cần Thơ" />
|
||||
|
||||
<link rel="stylesheet" th:href="@{/theme-assets/bvdhyd/css/b6b2bf2d3af810a6.css}" />
|
||||
<link rel="stylesheet" th:href="@{/theme-assets/bvdhyd/css/3cd83cfe34ca397f.css}" />
|
||||
<link rel="stylesheet" th:href="@{/theme-assets/bvdhyd/css/45d4f6442d75f756.css}" />
|
||||
<link rel="stylesheet" th:href="@{/theme-assets/bvdhyd/css/c37340727ca4fe15.css}" />
|
||||
|
||||
<style>
|
||||
.specialty-card {
|
||||
background: white;
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.1),
|
||||
0 1px 2px rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.specialty-card:hover {
|
||||
background: var(--color-old-brick);
|
||||
color: white;
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 10px 25px rgba(0, 84, 166, 0.25);
|
||||
}
|
||||
.specialty-card:hover .specialty-icon {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.specialty-card:hover .specialty-icon svg {
|
||||
color: white;
|
||||
}
|
||||
.specialty-card:hover .specialty-name {
|
||||
color: white;
|
||||
}
|
||||
.specialty-icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
background: #f0f7ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.specialty-icon svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
color: var(--color-old-brick);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.specialty-name {
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.4;
|
||||
color: var(--color-old-brick);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 0.5rem 1.25rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border: 1px solid #e5e7eb;
|
||||
background: white;
|
||||
color: #374151;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.filter-btn:hover {
|
||||
border-color: var(--color-primary-600, #0054a6);
|
||||
color: var(--color-primary-600, #0054a6);
|
||||
}
|
||||
.filter-btn.active {
|
||||
background: var(--color-primary-600, #0054a6);
|
||||
color: white;
|
||||
border-color: var(--color-primary-600, #0054a6);
|
||||
}
|
||||
.filter-btn .count {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.filter-btn.active .count {
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.section-label {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-primary-600, #0054a6);
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 2px solid var(--color-primary-600, #0054a6);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.specialty-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
.specialty-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
.specialty-icon svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.specialty-name {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<section class="xl:py-12 md:py-8 py-6" style="background: #f6f6f6">
|
||||
<div class="container mx-auto px-4">
|
||||
<!-- Page Title -->
|
||||
<h1 class="display-4 text-primary-600 text-center xl:mb-8 md:mb-6 mb-4">Chuyên khoa</h1>
|
||||
|
||||
<!-- Filter Dropdown -->
|
||||
<div
|
||||
id="specialties_sel"
|
||||
class="flex justify-center xl:mb-10 md:mb-7 mb-5 relative w-full md:max-w-[320px] mx-auto xl:mb-10 md:mb-7 mb-5 title-4"
|
||||
>
|
||||
<select
|
||||
onchange="window.location.href = this.value"
|
||||
class="w-full group bg-white rounded-lg border lg:hover:border-primary-600 cursor-pointer xl:px-6 px-4 py-3 flex items-center justify-between lg:duration-150 shadow border-gray-200"
|
||||
>
|
||||
<option th:value="@{/chuyen-khoa}" th:selected="${currentCategory == 'all'}">Tất cả ([[${countAll}]])</option>
|
||||
<option th:value="@{/chuyen-khoa(category='khoa-lam-sang')}" th:selected="${currentCategory == 'khoa-lam-sang'}">
|
||||
Khoa lâm sàng ([[${countLamSang}]])
|
||||
</option>
|
||||
<option th:value="@{/chuyen-khoa(category='khoa-can-lam-sang')}" th:selected="${currentCategory == 'khoa-can-lam-sang'}">
|
||||
Khoa cận lâm sàng ([[${countCanLamSang}]])
|
||||
</option>
|
||||
<option
|
||||
th:value="@{/chuyen-khoa(category='khoa-ho-tro-lam-sang')}"
|
||||
th:selected="${currentCategory == 'khoa-ho-tro-lam-sang'}"
|
||||
>
|
||||
Khoa hỗ trợ lâm sàng ([[${countHoTro}]])
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Specialty Grid -->
|
||||
<div class="grid lg:grid-cols-4 md:grid-cols-3 grid-cols-2 xl:gap-8 md:gap-6 gap-4">
|
||||
<a th:each="spec : ${specialties}" th:href="@{/chuyen-khoa/{slug}(slug=${spec.slug})}" class="specialty-card">
|
||||
<div class="specialty-icon">
|
||||
<th:block th:switch="${spec.slug}">
|
||||
<!-- chuyen-khoa-tai-mui-hong -->
|
||||
<th:block th:case="'chuyen-khoa-tai-mui-hong'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/Taimuihong-blue.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- don-vi-kiem-soat-nhiem-khuan -->
|
||||
<th:block th:case="'don-vi-kiem-soat-nhiem-khuan'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-29.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-cap-cuu -->
|
||||
<th:block th:case="'khoa-cap-cuu'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-37.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-chan-doan-hinh-anh -->
|
||||
<th:block th:case="'khoa-chan-doan-hinh-anh'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-3.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-dinh-duong-tiet-che -->
|
||||
<th:block th:case="'khoa-dinh-duong-tiet-che'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-9.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-duoc -->
|
||||
<th:block th:case="'khoa-duoc'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-11.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-kham-benh -->
|
||||
<th:block th:case="'khoa-kham-benh'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-27.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-than-kinh-dot-quy -->
|
||||
<th:block th:case="'khoa-than-kinh-dot-quy'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/Thankinh-blue.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-vat-ly-tri-lieu-phuc-hoi-chuc-nang -->
|
||||
<th:block th:case="'khoa-vat-ly-tri-lieu-phuc-hoi-chuc-nang'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/Phuchoichucnang-blue.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- khoa-xet-nghiem -->
|
||||
<th:block th:case="'khoa-xet-nghiem'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/Xetnghiem-blue.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- phau-thuat-gay-me-hoi-suc -->
|
||||
<th:block th:case="'phau-thuat-gay-me-hoi-suc'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/library-13.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- tim-mach -->
|
||||
<th:block th:case="'tim-mach'">
|
||||
<img
|
||||
src="https://console.bvdaihoc.com.vn/uploads/chuyen-khoa/Timmachcanthiep-blue.png"
|
||||
alt="Icon"
|
||||
class="w-12 h-12 object-contain mx-auto"
|
||||
/>
|
||||
</th:block>
|
||||
<!-- Default -->
|
||||
<th:block th:case="*">
|
||||
<div class="w-12 h-12 rounded-full bg-primary-100 flex items-center justify-center text-primary-600 mx-auto">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="w-6 h-6"
|
||||
>
|
||||
<path d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 012 2v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6a2 2 0 012-2zM9 14h6M12 11v6" />
|
||||
</svg>
|
||||
</div>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</div>
|
||||
<span class="specialty-name" th:text="${spec.title}">Tên chuyên khoa</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Empty state -->
|
||||
<div th:if="${#lists.isEmpty(specialties)}" class="text-center py-12">
|
||||
<p class="text-gray-500 text-lg">Không tìm thấy chuyên khoa nào trong nhóm này.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user