From 6fe098bc5ba222ebfa19b9262b353c4867ff6014 Mon Sep 17 00:00:00 2001 From: "WIN11\\laptop01" Date: Thu, 25 Jun 2026 16:38:03 +0700 Subject: [PATCH] =?UTF-8?q?ho=C3=A0n=20th=C3=A0nh=20block=20editor=20c?= =?UTF-8?q?=E1=BB=A7a=20Pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Design/adminPage_ideas.md | 69 ++++ sisvietnamvn_main/README.md | 54 +++ .../sisvietnamvn/web/config/MvcConfig.java | 29 ++ .../web/config/SecurityConfiguration.java | 3 +- .../web/config/WebConfigurer.java | 7 +- .../web/controller/PageController.java | 79 +++++ .../ManageDashboardController.java} | 9 +- .../manage/ManagePageController.java | 135 ++++++++ .../controller/manage/MediaController.java | 79 +++++ .../controller/manage/SnippetController.java | 56 ++++ .../com/sisvietnamvn/web/domain/Page.java | 136 ++++++++ .../sisvietnamvn/web/domain/PageStatus.java | 10 + .../sisvietnamvn/web/hook/HookManager.java | 111 +++++++ .../web/hook/SamplePluginHooks.java | 63 ++++ .../web/repository/PageRepository.java | 40 +++ .../sisvietnamvn/web/service/PageService.java | 152 +++++++++ .../main/resources/config/application-dev.yml | 1 + .../20260625100000_add_page_entity.xml | 33 ++ .../resources/config/liquibase/master.xml | 1 + .../src/main/resources/static/css/custom.css | 36 ++ .../main/resources/static/js/lazysizes.min.js | 3 + .../static/js/manage/editor-config.js | 180 ++++++++++ .../manage/editor-plugins/_sample-plugin.js | 69 ++++ .../js/manage/editor-plugins/html-snippet.js | 138 ++++++++ .../resources/templates/fragments/header.html | 4 +- .../templates/fragments/manage-layout.html | 30 ++ .../templates/manage/pages/form.html | 307 ++++++++++++++++++ .../templates/manage/pages/list.html | 95 ++++++ .../src/main/resources/templates/page.html | 110 +++++++ .../templates/snippets/test_banner.html | 5 + .../39379c54-ad8f-414c-b7f9-6b747290f4ab.webp | Bin 0 -> 45458 bytes .../48e097c8-7cad-47aa-a8de-aaab0c7d3428.webp | Bin 0 -> 45458 bytes 32 files changed, 2036 insertions(+), 8 deletions(-) create mode 100644 Design/adminPage_ideas.md create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/MvcConfig.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/PageController.java rename sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/{ManageController.java => manage/ManageDashboardController.java} (61%) create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManagePageController.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/MediaController.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/SnippetController.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/Page.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/PageStatus.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/HookManager.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/SamplePluginHooks.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/repository/PageRepository.java create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/PageService.java create mode 100644 sisvietnamvn_main/src/main/resources/config/liquibase/changelog/20260625100000_add_page_entity.xml create mode 100644 sisvietnamvn_main/src/main/resources/static/js/lazysizes.min.js create mode 100644 sisvietnamvn_main/src/main/resources/static/js/manage/editor-config.js create mode 100644 sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/_sample-plugin.js create mode 100644 sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/html-snippet.js create mode 100644 sisvietnamvn_main/src/main/resources/templates/manage/pages/form.html create mode 100644 sisvietnamvn_main/src/main/resources/templates/manage/pages/list.html create mode 100644 sisvietnamvn_main/src/main/resources/templates/page.html create mode 100644 sisvietnamvn_main/src/main/resources/templates/snippets/test_banner.html create mode 100644 sisvietnamvn_main/uploads/39379c54-ad8f-414c-b7f9-6b747290f4ab.webp create mode 100644 sisvietnamvn_main/uploads/48e097c8-7cad-47aa-a8de-aaab0c7d3428.webp diff --git a/Design/adminPage_ideas.md b/Design/adminPage_ideas.md new file mode 100644 index 00000000..5a311b4b --- /dev/null +++ b/Design/adminPage_ideas.md @@ -0,0 +1,69 @@ +Dưới đây là danh sách đầy đủ toàn bộ các chức năng của trang quản trị WordPress (WordPress Admin Dashboard), được chia làm hai phần chính: Giao diện người dùng (UI/UX) và Các hàm PHP/APIs dành cho Lập trình viên để phát triển/tùy biến trang admin. + +PHẦN 1: CÁC CHỨC NĂNG TRÊN GIAO DIỆN ADMIN (UI MENUS) +Đây là các chức năng mặc định xuất hiện ở thanh Menu bên trái (Sidebar) của trang quản trị: + +Menu chính Menu con Chức năng chi tiết +1. Dashboard (Bảng điều khiển) Home Xem tổng quan trạng thái website (Site Health, số lượng bài viết/trang, bình luận gần đây, hoạt động viết nháp nhanh). +Updates Cập nhật phiên bản WordPress Core, Themes, Plugins và các gói dịch vụ ngôn ngữ. +2. Posts (Bài viết) All Posts Quản lý toàn bộ bài viết tin tức, blog, lọc theo ngày/chuyên mục. +Add New Soạn thảo bài viết mới bằng Block Editor (Gutenberg) hoặc Classic Editor. +Categories Tạo và quản lý các Chuyên mục (thư mục phân loại bài viết). +Tags Tạo và quản lý các Thẻ (nhãn từ khóa tìm kiếm nhanh). +3. Media (Thư viện) Library Quản lý toàn bộ hình ảnh, tài liệu (PDF, Docx), video, âm thanh đã tải lên. +Add New Tải tệp tin mới lên máy chủ. +4. Pages (Trang) All Pages Quản lý các trang tĩnh (ví dụ: Trang chủ, Trang liên hệ, Giới thiệu bệnh viện, Giờ làm việc...). +Add New Tạo trang tĩnh mới. +5. Comments (Bình luận) (Không có) Quản lý bình luận của người đọc (Phê duyệt, Trả lời, Đánh dấu Spam, Xóa tạm/Xóa vĩnh viễn). +6. Appearance (Giao diện) Themes Cài đặt, kích hoạt hoặc xóa các giao diện hiển thị của website. +Customize Chỉnh sửa giao diện trực quan theo thời gian thực (Header, Footer, Colors, Font, v.v.). +Widgets Quản lý các khối nội dung ở Sidebar hoặc Footer. +Menus Thiết kế menu điều hướng chính ở đầu trang và chân trang. +Theme File Editor Chỉnh sửa trực tiếp file code của giao diện (chỉ dùng cho lập trình viên). +7. Plugins (Gói mở rộng) Installed Plugins Quản lý, kích hoạt, vô hiệu hóa hoặc xóa các Plugin đang có trên hệ thống. +Add New Tìm kiếm và cài đặt Plugin mới từ thư viện WordPress.org hoặc upload file .zip. +Plugin File Editor Chỉnh sửa mã nguồn của các Plugin trực tiếp từ admin. +8. Users (Thành viên) All Users Quản lý danh sách toàn bộ tài khoản đăng ký trên hệ thống. +Add New Tạo tài khoản người dùng mới và chỉ định vai trò (Role). +Profile Chỉnh sửa thông tin cá nhân của tài khoản đang đăng nhập (đổi pass, ngôn ngữ hiển thị). +9. Tools (Công cụ) Available Tools Các công cụ hỗ trợ chuyển đổi dữ liệu. +Import / Export Nhập/Xuất toàn bộ bài viết, trang, media sang file .xml để sao lưu hoặc chuyển host. +Site Health Kiểm tra sức khỏe hệ thống (phiên bản PHP, MySQL, các lỗi bảo mật). +Export / Erase Personal Data Xuất hoặc xóa dữ liệu cá nhân của người dùng để tuân thủ luật bảo mật (GDPR). +10. Settings (Cài đặt) General Thiết lập tên website, câu khẩu hiệu, địa chỉ email admin, múi giờ, định dạng ngày tháng. +Writing Cấu hình mặc định khi soạn thảo văn bản và gửi bài viết qua email. +Reading Thiết lập trang chủ hiển thị, số lượng bài viết tối đa trên một trang blog, chặn công cụ tìm kiếm. +Discussion Cấu hình bình luận (yêu cầu phê duyệt, chặn từ ngữ nhạy cảm). +Media Cài đặt kích thước mặc định cho ảnh khi upload (Thumbnail, Medium, Large). +Permalinks Định dạng cấu trúc đường dẫn tĩnh (URL) tối ưu cho SEO (ví dụ: /post-name/). +Privacy Thiết lập trang chính sách bảo mật cho website. +PHẦN 2: CÁC HÀM PHP & HOOKS ĐỂ PHÁT TRIỂN TRANG ADMIN (DEVELOPER API) +Nếu bạn đang lập trình tùy biến trang admin (hoặc xây dựng CMS tương tự), WordPress cung cấp bộ API để tạo và kiểm soát trang admin sau: + +1. Các hàm tạo Menu & Submenu trong Admin +add_menu_page(): Thêm một Menu chính mới (cấp cao nhất) ở thanh sidebar bên trái. +add_submenu_page(): Thêm một Menu con (Submenu) vào dưới một Menu chính bất kỳ. +Các hàm phái sinh viết nhanh (Helper functions): +add_options_page(): Thêm trang con vào menu Settings (Cài đặt). +add_theme_page(): Thêm trang con vào menu Appearance (Giao diện). +add_plugins_page(): Thêm trang con vào menu Plugins. +add_users_page(): Thêm trang con vào menu Users (Thành viên). +add_dashboard_page(): Thêm trang con vào menu Dashboard (Bảng điều khiển). +add_management_page(): Thêm trang con vào menu Tools (Công cụ). +2. Các Action Hooks quan trọng trong Admin +admin_menu: Chạy khi cấu trúc menu admin đang được khởi tạo. Đây là nơi bắt buộc để gọi các hàm add_menu_page() và add_submenu_page(). +admin_init: Chạy khi trang admin được tải và khởi tạo. Thường dùng để đăng ký cấu hình (Settings API), kiểm tra quyền hoặc xử lý form gửi lên. +admin_enqueue_scripts: Hook chuẩn duy nhất để tải thêm file CSS và JavaScript tùy chỉnh vào trang quản trị (tránh làm ảnh hưởng đến các plugin khác). +admin_post_{action} & admin_post_nopriv_{action}: Xử lý các yêu cầu gửi Form (POST/GET) từ trang quản trị một cách an toàn. +3. Các hàm kiểm tra Phân quyền & Trạng thái +is_admin(): Kiểm tra xem trang hiện tại người dùng đang truy cập có thuộc phân hệ quản trị (backend /wp-admin/) hay không. +current_user_can( $capability ): Kiểm tra người dùng hiện tại có đủ quyền thực hiện hành động hay không (ví dụ: current_user_can('manage_options') để kiểm tra quyền Admin). +get_current_screen(): Lấy thông tin chi tiết về trang admin hiện tại đang hiển thị (ID, Base, Post Type). +4. Settings API (Quản lý và lưu trữ thiết lập) +register_setting(): Đăng ký một tùy chọn (option) mới trong cơ sở dữ liệu để lưu trữ cấu hình. +add_settings_section(): Tạo ra một vùng chứa (section) trên trang để gom nhóm các trường cài đặt. +add_settings_field(): Thêm một trường nhập liệu (Input, Checkbox, Select) vào vùng chứa đã tạo. +settings_fields() & do_settings_sections(): Các hàm render giao diện form cấu hình tự động và tạo mã bảo mật Token (Nonce). +TIP + +Ứng dụng cho dự án Spring Boot hiện tại: Nếu bạn đang chuyển đổi hoặc xây dựng mới phân hệ Quản trị (Admin Panel) cho dự án website bệnh viện S.I.S Cần Thơ, bạn có thể ánh xạ các chức năng của WordPress như trên thành các Controller trong Spring Boot (ví dụ: @Controller @RequestMapping("/admin")), chia các chức năng quản lý thành các REST API và phân quyền truy cập thông qua Spring Security (tương đương với current_user_can trong WordPress). \ No newline at end of file diff --git a/sisvietnamvn_main/README.md b/sisvietnamvn_main/README.md index fe19d118..e7b97b31 100644 --- a/sisvietnamvn_main/README.md +++ b/sisvietnamvn_main/README.md @@ -312,3 +312,57 @@ spring: username: sisvietnam password: sisvietnam ``` + +## Admin Pages & Block Editor Management + +We have implemented a WordPress-like static pages management feature at `/manage/pages`. This includes an interactive block-based editor powered by **Editor.js**. + +### 1. How to Run and Access +1. Start your Oracle database or ensure it is accessible. +2. Run the application in development mode: + ```powershell + ./gradlew bootRun + ``` +3. Open your browser and navigate to: [http://localhost:8080/manage/pages](http://localhost:8080/manage/pages) + +### 2. Form Fields & Features +When creating or editing a page (`/manage/pages/new` or `/manage/pages/{id}/edit`): +- **Title**: Name of the page (e.g. `About Us`, `Giới thiệu`). +- **Slug**: The URL path. If left blank, it is automatically generated from the Title, supporting clean Vietnamese character conversions (e.g. `Bệnh viện S.I.S Cần Thơ` -> `benh-vien-s-i-s-can-tho`). +- **Status**: Status of the page (`DRAFT`, `PUBLISHED`, `ARCHIVED`). +- **Display Order**: Controls sorting of page links (lower numbers appear first). +- **Meta Description**: A short summary used for SEO metadata in ``. +- **Page Content (Block Editor)**: Interactive wysiwyg editor utilizing Editor.js. + +### 3. Using the Block Editor +- **Add a Block**: Press `Enter` to create a new paragraph, or click the `+` icon (or press `Tab` on an empty line) to pick a block type: + - **Heading**: Formatted HTML headers (H2, H3, H4). + - **List**: Bulleted or numbered lists (supports nested lists via `Tab`). + - **Quote**: Stylized blockquotes with a caption field. + - **Table**: Simple tables with columns and rows. + - **Code**: Formatted code block. + - **Warning**: Notice or alert box with title & message. + - **Delimiter**: Horizontal dividers. +- **Inline Styling**: Highlight any text in a paragraph to apply **Bold**, *Italic*, Links, Underlines, `Inline Code`, or Highlighter. +- **Reorder & Actions**: Hover over any block and use the handle menu (`⋮⋮`) to drag-and-drop, move up/down, convert to another block type, or delete. + +### 4. How the Plugin System Works (Extensibility) +If you want to create new custom block types (e.g., custom slider, doctor list, video embed) in the future: +1. Create your plugin script file inside `src/main/resources/static/js/manage/editor-plugins/` (e.g. `video-embed-plugin.js`). +2. Implement your custom block class or wrap an existing Editor.js tool. +3. Register your tool globally by adding it to `window.SISEditorPlugins`: + ```javascript + window.SISEditorPlugins = window.SISEditorPlugins || {}; + window.SISEditorPlugins['videoEmbed'] = { + class: VideoEmbedToolClass, + inlineToolbar: true, + config: { + placeholder: 'Enter video URL...' + } + }; + ``` +4. In `src/main/resources/templates/manage/pages/form.html`, load the script in the `
` tag **before** the main configuration script: + ```html + + ``` +5. The initialization logic in [editor-config.js](file:///c:/Users/laptop01/Documents/sisvietnamvn_01/sisvietnamvn_main/src/main/resources/static/js/manage/editor-config.js) will automatically scan `window.SISEditorPlugins` and register them. diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/MvcConfig.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/MvcConfig.java new file mode 100644 index 00000000..2ebea21d --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/MvcConfig.java @@ -0,0 +1,29 @@ +package com.sisvietnamvn.web.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.nio.file.Path; +import java.nio.file.Paths; + +@Configuration +public class MvcConfig implements WebMvcConfigurer { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + exposeDirectory("uploads", registry); + } + + private void exposeDirectory(String dirName, ResourceHandlerRegistry registry) { + Path uploadDir = Paths.get(dirName); + String uploadPath = uploadDir.toFile().getAbsolutePath(); + + if (dirName.startsWith("../")) { + dirName = dirName.replace("../", ""); + } + + registry.addResourceHandler("/" + dirName + "/**") + .addResourceLocations("file:/" + uploadPath + "/"); + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/SecurityConfiguration.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/SecurityConfiguration.java index de5239cf..e98db2cf 100644 --- a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/SecurityConfiguration.java +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/SecurityConfiguration.java @@ -46,8 +46,9 @@ public class SecurityConfiguration { authz .requestMatchers(HttpMethod.GET, "/", "/about", "/flex-finish", "/tin-tuc", "/tin-tuc/**", "/lien-he", "/manage/**", "/css/**", "/images/**", "/js/**", "/UMass*/**", "/Undergraduate*/**", - "/favicon.ico", "/favicons/**", "/flex-finish/**", "/contact-us/**") + "/favicon.ico", "/favicons/**", "/flex-finish/**", "/contact-us/**", "/uploads/**", "/api/manage/snippets/**", "/page/**") .permitAll() + .requestMatchers(HttpMethod.POST, "/manage/**", "/api/manage/media/upload").permitAll() .requestMatchers(HttpMethod.GET, "/swagger-ui/**", "/v3/api-docs/**").permitAll() .requestMatchers(HttpMethod.POST, "/api/authenticate").permitAll() .requestMatchers(HttpMethod.GET, "/api/authenticate").permitAll() diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/WebConfigurer.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/WebConfigurer.java index b512f9e5..881e6d43 100644 --- a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/WebConfigurer.java +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/config/WebConfigurer.java @@ -13,6 +13,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; +import com.sisvietnamvn.web.hook.HookManager; import tech.jhipster.config.JHipsterConstants; import tech.jhipster.config.JHipsterProperties; import tech.jhipster.config.h2.H2ConfigurationHelper; @@ -26,12 +27,13 @@ public class WebConfigurer implements ServletContextInitializer { private static final Logger LOG = LoggerFactory.getLogger(WebConfigurer.class); private final Environment env; - private final JHipsterProperties jHipsterProperties; + private final HookManager hookManager; - public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) { + public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties, HookManager hookManager) { this.env = env; this.jHipsterProperties = jHipsterProperties; + this.hookManager = hookManager; } @Override @@ -44,6 +46,7 @@ public class WebConfigurer implements ServletContextInitializer { initH2Console(servletContext); } LOG.info("Web application fully configured"); + hookManager.doAction("init"); } @Bean diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/PageController.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/PageController.java new file mode 100644 index 00000000..c85faaa5 --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/PageController.java @@ -0,0 +1,79 @@ +package com.sisvietnamvn.web.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sisvietnamvn.web.domain.Page; +import com.sisvietnamvn.web.security.AuthoritiesConstants; +import com.sisvietnamvn.web.security.SecurityUtils; +import com.sisvietnamvn.web.service.PageService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Controller for rendering public-facing pages dynamically. + */ +@Controller +public class PageController { + + private static final Logger LOG = LoggerFactory.getLogger(PageController.class); + + private final PageService pageService; + private final ObjectMapper objectMapper; + + public PageController(PageService pageService, ObjectMapper objectMapper) { + this.pageService = pageService; + this.objectMapper = objectMapper; + } + + /** + * GET /page/{slug} : Render a page dynamically by slug. + */ + @GetMapping("/page/{slug}") + public String getPage(@PathVariable("slug") String slug, Model model) { + LOG.debug("REST request to get public Page : {}", slug); + + Optional pageOpt = pageService.findBySlug(slug); + + if (pageOpt.isEmpty()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Page not found"); + } + + Page page = pageOpt.get(); + + // Security Check: If Draft, only Admins can view + if ("DRAFT".equals(page.getStatus()) && !SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.ADMIN)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Page not found"); + } + + // Parse Editor.js content JSON to extract blocks + List> blocks = Collections.emptyList(); + if (page.getContent() != null && !page.getContent().trim().isEmpty()) { + try { + // Editor.js JSON has a "blocks" array at the root level + Map editorData = objectMapper.readValue(page.getContent(), new TypeReference<>() {}); + if (editorData.containsKey("blocks")) { + blocks = (List>) editorData.get("blocks"); + } + } catch (JsonProcessingException e) { + LOG.error("Failed to parse Editor.js JSON for page slug: {}", slug, e); + } + } + + model.addAttribute("page", page); + model.addAttribute("blocks", blocks); + + return "page"; + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/ManageController.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManageDashboardController.java similarity index 61% rename from sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/ManageController.java rename to sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManageDashboardController.java index a1217490..a9bceb63 100644 --- a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/ManageController.java +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManageDashboardController.java @@ -1,16 +1,19 @@ -package com.sisvietnamvn.web.controller; +package com.sisvietnamvn.web.controller.manage; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +/** + * Controller for the admin dashboard index page. + * Serves the main "/manage" landing page. + */ @Controller @RequestMapping("/manage") -public class ManageController { +public class ManageDashboardController { @GetMapping({"", "/"}) public String index() { return "manage/index"; } - } diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManagePageController.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManagePageController.java new file mode 100644 index 00000000..b4325f6a --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/ManagePageController.java @@ -0,0 +1,135 @@ +package com.sisvietnamvn.web.controller.manage; + +import com.sisvietnamvn.web.domain.Page; +import com.sisvietnamvn.web.domain.PageStatus; +import com.sisvietnamvn.web.hook.HookManager; +import com.sisvietnamvn.web.service.PageService; +import jakarta.validation.Valid; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +/** + * Controller for managing CMS Pages in the admin panel. + * Provides CRUD operations for static pages. + */ +@Controller +@RequestMapping("/manage/pages") +public class ManagePageController { + + private static final Logger LOG = LoggerFactory.getLogger(ManagePageController.class); + + private final PageService pageService; + private final HookManager hookManager; + + public ManagePageController(PageService pageService, HookManager hookManager) { + this.pageService = pageService; + this.hookManager = hookManager; + } + + /** + * Triggered before any handler method in this controller. + */ + @ModelAttribute + public void adminInit() { + hookManager.doAction("admin_init"); + } + + /** + * GET /manage/pages — List all pages. + */ + @GetMapping + public String listPages(Model model) { + LOG.debug("Request to list all pages"); + model.addAttribute("pages", pageService.findAll()); + return "manage/pages/list"; + } + + /** + * GET /manage/pages/new — Show the "Add New Page" form. + */ + @GetMapping("/new") + public String showCreateForm(Model model) { + LOG.debug("Request to show create page form"); + Page page = new Page(); + page.setStatus(PageStatus.DRAFT); + page.setDisplayOrder(0); + model.addAttribute("page", page); + model.addAttribute("statuses", PageStatus.values()); + model.addAttribute("isNew", true); + return "manage/pages/form"; + } + + /** + * POST /manage/pages — Save a new page. + */ + @PostMapping + public String createPage(@Valid @ModelAttribute("page") Page page, + BindingResult bindingResult, + Model model, + RedirectAttributes redirectAttributes) { + LOG.debug("Request to create Page : {}", page); + if (bindingResult.hasErrors()) { + model.addAttribute("statuses", PageStatus.values()); + model.addAttribute("isNew", true); + return "manage/pages/form"; + } + pageService.save(page); + redirectAttributes.addFlashAttribute("successMessage", "Page created successfully!"); + return "redirect:/manage/pages"; + } + + /** + * GET /manage/pages/{id}/edit — Show the "Edit Page" form. + */ + @GetMapping("/{id}/edit") + public String showEditForm(@PathVariable Long id, Model model, RedirectAttributes redirectAttributes) { + LOG.debug("Request to show edit form for Page : {}", id); + Optional pageOptional = pageService.findById(id); + if (pageOptional.isEmpty()) { + redirectAttributes.addFlashAttribute("errorMessage", "Page not found."); + return "redirect:/manage/pages"; + } + model.addAttribute("page", pageOptional.get()); + model.addAttribute("statuses", PageStatus.values()); + model.addAttribute("isNew", false); + return "manage/pages/form"; + } + + /** + * POST /manage/pages/{id} — Update an existing page. + */ + @PostMapping("/{id}") + public String updatePage(@PathVariable Long id, + @Valid @ModelAttribute("page") Page page, + BindingResult bindingResult, + Model model, + RedirectAttributes redirectAttributes) { + LOG.debug("Request to update Page : {}", id); + if (bindingResult.hasErrors()) { + model.addAttribute("statuses", PageStatus.values()); + model.addAttribute("isNew", false); + return "manage/pages/form"; + } + page.setId(id); + pageService.save(page); + redirectAttributes.addFlashAttribute("successMessage", "Page updated successfully!"); + return "redirect:/manage/pages"; + } + + /** + * POST /manage/pages/{id}/delete — Delete a page. + */ + @PostMapping("/{id}/delete") + public String deletePage(@PathVariable Long id, RedirectAttributes redirectAttributes) { + LOG.debug("Request to delete Page : {}", id); + pageService.delete(id); + redirectAttributes.addFlashAttribute("successMessage", "Page deleted successfully!"); + return "redirect:/manage/pages"; + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/MediaController.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/MediaController.java new file mode 100644 index 00000000..77452f0d --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/MediaController.java @@ -0,0 +1,79 @@ +package com.sisvietnamvn.web.controller.manage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@RestController +@RequestMapping("/api/manage/media") +public class MediaController { + + private final Logger log = LoggerFactory.getLogger(MediaController.class); + + // Save files in an 'uploads' directory at the project root + private final String UPLOAD_DIR = "uploads/"; + + @PostMapping("/upload") + public ResponseEntity> uploadFile(@RequestParam("file") MultipartFile file) { + log.debug("REST request to upload file: {}", file.getOriginalFilename()); + + Map response = new HashMap<>(); + + if (file == null || file.isEmpty()) { + response.put("success", 0); + return ResponseEntity.badRequest().body(response); + } + + try { + // Ensure the upload directory exists + Path uploadPath = Paths.get(UPLOAD_DIR); + if (!Files.exists(uploadPath)) { + Files.createDirectories(uploadPath); + } + + // Generate a unique file name to avoid conflicts + String originalFilename = StringUtils.cleanPath(file.getOriginalFilename()); + String extension = ""; + int dotIndex = originalFilename.lastIndexOf('.'); + if (dotIndex > 0) { + extension = originalFilename.substring(dotIndex); + } + String newFilename = UUID.randomUUID().toString() + extension; + + // Save the file + Path filePath = uploadPath.resolve(newFilename); + Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); + + // Construct the Editor.js expected response + Map fileData = new HashMap<>(); + fileData.put("url", "/uploads/" + newFilename); + fileData.put("name", originalFilename); + fileData.put("size", file.getSize()); + if (extension.startsWith(".")) { + fileData.put("extension", extension.substring(1)); + } + + response.put("success", 1); + response.put("file", fileData); + + return ResponseEntity.ok(response); + + } catch (IOException e) { + log.error("Failed to store uploaded file", e); + response.put("success", 0); + return ResponseEntity.internalServerError().body(response); + } + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/SnippetController.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/SnippetController.java new file mode 100644 index 00000000..645c2481 --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/controller/manage/SnippetController.java @@ -0,0 +1,56 @@ +package com.sisvietnamvn.web.controller.manage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * REST controller for fetching predefined HTML snippets to be previewed in Editor.js. + */ +@RestController +@RequestMapping("/api/manage/snippets") +public class SnippetController { + + private static final Logger LOG = LoggerFactory.getLogger(SnippetController.class); + private final ResourceLoader resourceLoader; + + public SnippetController(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + /** + * GET /api/manage/snippets/{id} : get the raw HTML of a snippet + */ + @GetMapping(value = "/{id}", produces = MediaType.TEXT_HTML_VALUE) + public ResponseEntity getSnippet(@PathVariable("id") String id) { + LOG.debug("REST request to get Snippet : {}", id); + + // Prevent path traversal attacks + if (id == null || id.contains("..") || id.contains("/")) { + return ResponseEntity.badRequest().body("Invalid Snippet ID"); + } + + String path = "classpath:templates/snippets/" + id + ".html"; + Resource resource = resourceLoader.getResource(path); + + if (!resource.exists() || !resource.isReadable()) { + LOG.warn("Snippet not found at path: {}", path); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("
Snippet ID " + id + " not found.
"); + } + + try { + String content = new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8); + return ResponseEntity.ok().body(content); + } catch (IOException e) { + LOG.error("Error reading snippet file: {}", path, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error reading snippet file"); + } + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/Page.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/Page.java new file mode 100644 index 00000000..3754258a --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/Page.java @@ -0,0 +1,136 @@ +package com.sisvietnamvn.web.domain; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.Serial; +import java.util.Objects; + +/** + * A CMS Page entity representing a static page (e.g. About Us, Contact, Working Hours). + * Maps to the "sis_page" database table. + */ +@Entity +@Table(name = "sis_page") +public class Page extends AbstractAuditingEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") + private Long id; + + @NotNull + @Size(max = 255) + @Column(name = "title", length = 255, nullable = false) + private String title; + + @NotNull + @Size(max = 255) + @Column(name = "slug", length = 255, nullable = false, unique = true) + private String slug; + + @Lob + @Column(name = "content") + private String content; + + @Size(max = 500) + @Column(name = "meta_description", length = 500) + private String metaDescription; + + @NotNull + @Enumerated(EnumType.STRING) + @Column(name = "status", length = 20, nullable = false) + private PageStatus status = PageStatus.DRAFT; + + @Column(name = "display_order") + private Integer displayOrder = 0; + + // --- Getters and Setters --- + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSlug() { + return slug; + } + + public void setSlug(String slug) { + this.slug = slug; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getMetaDescription() { + return metaDescription; + } + + public void setMetaDescription(String metaDescription) { + this.metaDescription = metaDescription; + } + + public PageStatus getStatus() { + return status; + } + + public void setStatus(PageStatus status) { + this.status = status; + } + + public Integer getDisplayOrder() { + return displayOrder; + } + + public void setDisplayOrder(Integer displayOrder) { + this.displayOrder = displayOrder; + } + + // --- equals, hashCode, toString --- + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Page page)) return false; + return id != null && id.equals(page.id); + } + + @Override + public int hashCode() { + // Use a constant value to ensure consistency across entity state transitions. + // See: https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); + } + + @Override + public String toString() { + return "Page{" + + "id=" + getId() + + ", title='" + getTitle() + "'" + + ", slug='" + getSlug() + "'" + + ", status='" + getStatus() + "'" + + ", displayOrder=" + getDisplayOrder() + + "}"; + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/PageStatus.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/PageStatus.java new file mode 100644 index 00000000..1b9dfa25 --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/domain/PageStatus.java @@ -0,0 +1,10 @@ +package com.sisvietnamvn.web.domain; + +/** + * Enumeration representing the publication status of a CMS page. + */ +public enum PageStatus { + DRAFT, + PUBLISHED, + ARCHIVED +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/HookManager.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/HookManager.java new file mode 100644 index 00000000..47ed7d18 --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/HookManager.java @@ -0,0 +1,111 @@ +package com.sisvietnamvn.web.hook; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A central manager for WordPress-style Actions and Filters. + */ +@Service +public class HookManager { + + private static final Logger LOG = LoggerFactory.getLogger(HookManager.class); + + private final Map> actions = new HashMap<>(); + private final Map> filters = new HashMap<>(); + + // --- Actions --- + + public void addAction(String hookName, ActionCallback callback, int priority) { + actions.computeIfAbsent(hookName, k -> new ArrayList<>()) + .add(new ActionRegistration(callback, priority)); + actions.get(hookName).sort(Comparator.comparingInt(a -> a.priority)); + LOG.debug("Added action to hook '{}' with priority {}", hookName, priority); + } + + public void addAction(String hookName, ActionCallback callback) { + addAction(hookName, callback, 10); + } + + public void doAction(String hookName, Object... args) { + if (actions.containsKey(hookName)) { + LOG.debug("Executing action hook '{}'", hookName); + for (ActionRegistration reg : actions.get(hookName)) { + try { + reg.callback.execute(args); + } catch (Exception e) { + LOG.error("Error executing action hook '{}'", hookName, e); + } + } + } + } + + // --- Filters --- + + public void addFilter(String hookName, FilterCallback callback, int priority) { + filters.computeIfAbsent(hookName, k -> new ArrayList<>()) + .add(new FilterRegistration(callback, priority)); + filters.get(hookName).sort(Comparator.comparingInt(a -> a.priority)); + LOG.debug("Added filter to hook '{}' with priority {}", hookName, priority); + } + + public void addFilter(String hookName, FilterCallback callback) { + addFilter(hookName, callback, 10); + } + + @SuppressWarnings("unchecked") + public T applyFilters(String hookName, T value, Object... args) { + if (filters.containsKey(hookName)) { + LOG.debug("Applying filter hook '{}'", hookName); + for (FilterRegistration reg : filters.get(hookName)) { + try { + value = (T) ((FilterCallback) reg.callback).filter(value, args); + } catch (Exception e) { + LOG.error("Error applying filter hook '{}'", hookName, e); + } + } + } + return value; + } + + // --- Interfaces --- + + @FunctionalInterface + public interface ActionCallback { + void execute(Object... args); + } + + @FunctionalInterface + public interface FilterCallback { + T filter(T value, Object... args); + } + + // --- Internal Registration Records --- + + private static class ActionRegistration { + final ActionCallback callback; + final int priority; + + ActionRegistration(ActionCallback callback, int priority) { + this.callback = callback; + this.priority = priority; + } + } + + private static class FilterRegistration { + final FilterCallback callback; + final int priority; + + FilterRegistration(FilterCallback callback, int priority) { + this.callback = callback; + this.priority = priority; + } + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/SamplePluginHooks.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/SamplePluginHooks.java new file mode 100644 index 00000000..f6bcc94f --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/SamplePluginHooks.java @@ -0,0 +1,63 @@ +package com.sisvietnamvn.web.hook; + +import com.sisvietnamvn.web.domain.Page; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * A sample plugin to demonstrate the WordPress-style Hook system in action. + */ +@Component +public class SamplePluginHooks { + + private static final Logger LOG = LoggerFactory.getLogger(SamplePluginHooks.class); + + private final HookManager hookManager; + + public SamplePluginHooks(HookManager hookManager) { + this.hookManager = hookManager; + } + + @PostConstruct + public void registerHooks() { + LOG.info("Registering SamplePlugin hooks..."); + + // Example Action: Log when a page is saved + hookManager.addAction("save_post", args -> { + if (args.length > 0 && args[0] instanceof Page page) { + LOG.info("ACTION TRIGGERED (save_post): Page '{}' (ID: {}) was just saved!", page.getTitle(), page.getId()); + } + }); + + // Example Action: Log on admin init + hookManager.addAction("admin_init", args -> { + LOG.debug("ACTION TRIGGERED (admin_init): Admin panel accessed."); + }); + + // Example Filter: Automatically modify page slug if it contains 'test' + hookManager.addFilter("page_slug", (value, args) -> { + if (value instanceof String slug) { + if (slug.contains("test")) { + String newSlug = slug + "-modified-by-plugin"; + LOG.info("FILTER TRIGGERED (page_slug): Changed slug from '{}' to '{}'", slug, newSlug); + return newSlug; + } + } + return value; + }, 10); + + // Example Filter: Pre-save filter to modify page content + hookManager.addFilter("pre_save_post", (value, args) -> { + if (value instanceof Page page) { + if (page.getContent() != null && !page.getContent().contains("Auto-signature")) { + LOG.info("FILTER TRIGGERED (pre_save_post): Appending signature to page '{}'", page.getTitle()); + // In a real scenario, this would modify the JSON content of Editor.js, + // but for demonstration we just log it. + } + } + return value; + }, 20); + } +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/repository/PageRepository.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/repository/PageRepository.java new file mode 100644 index 00000000..7bc2314a --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/repository/PageRepository.java @@ -0,0 +1,40 @@ +package com.sisvietnamvn.web.repository; + +import com.sisvietnamvn.web.domain.Page; +import com.sisvietnamvn.web.domain.PageStatus; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +/** + * Spring Data JPA repository for the {@link Page} entity. + */ +@Repository +public interface PageRepository extends JpaRepository { + + /** + * Find all pages ordered by display_order ascending (for admin list view). + */ + List findAllByOrderByDisplayOrderAsc(); + + /** + * Find a page by its URL-friendly slug (for public page rendering). + */ + Optional findBySlug(String slug); + + /** + * Find all pages with a given publication status. + */ + List findByStatusOrderByDisplayOrderAsc(PageStatus status); + + /** + * Check if a slug already exists (for uniqueness validation). + */ + boolean existsBySlug(String slug); + + /** + * Check if a slug already exists for a different page (for edit validation). + */ + boolean existsBySlugAndIdNot(String slug, Long id); +} diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/PageService.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/PageService.java new file mode 100644 index 00000000..6055012e --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/PageService.java @@ -0,0 +1,152 @@ +package com.sisvietnamvn.web.service; + +import com.sisvietnamvn.web.domain.Page; +import com.sisvietnamvn.web.domain.PageStatus; +import com.sisvietnamvn.web.hook.HookManager; +import com.sisvietnamvn.web.repository.PageRepository; +import java.text.Normalizer; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Service class for managing CMS pages. + */ +@Service +@Transactional +public class PageService { + + private static final Logger LOG = LoggerFactory.getLogger(PageService.class); + + private static final Pattern NON_LATIN = Pattern.compile("[^\\w-]"); + private static final Pattern WHITESPACE = Pattern.compile("[\\s]"); + + private final PageRepository pageRepository; + private final HookManager hookManager; + + public PageService(PageRepository pageRepository, HookManager hookManager) { + this.pageRepository = pageRepository; + this.hookManager = hookManager; + } + + /** + * Get all pages sorted by display order. + */ + @Transactional(readOnly = true) + public List findAll() { + LOG.debug("Request to get all Pages"); + return pageRepository.findAllByOrderByDisplayOrderAsc(); + } + + /** + * Get a single page by ID. + */ + @Transactional(readOnly = true) + public Optional findById(Long id) { + LOG.debug("Request to get Page : {}", id); + return pageRepository.findById(id); + } + + /** + * Get a single page by its URL slug. + */ + @Transactional(readOnly = true) + public Optional findBySlug(String slug) { + LOG.debug("Request to get Page by slug : {}", slug); + return pageRepository.findBySlug(slug); + } + + /** + * Find all pages with a specific status. + */ + @Transactional(readOnly = true) + public List findByStatus(PageStatus status) { + LOG.debug("Request to get Pages by status : {}", status); + return pageRepository.findByStatusOrderByDisplayOrderAsc(status); + } + + /** + * Save a page (create or update). + * Auto-generates a URL slug from the title if the slug is empty. + */ + public Page save(Page page) { + LOG.debug("Request to save Page : {}", page); + + // Hook: pre_save_post filter + page = hookManager.applyFilters("pre_save_post", page); + + if (page.getSlug() == null || page.getSlug().isBlank()) { + page.setSlug(generateSlug(page.getTitle())); + } + // Ensure slug uniqueness by appending a suffix if needed + String baseSlug = page.getSlug(); + String candidateSlug = baseSlug; + int counter = 1; + while (isSlugTaken(candidateSlug, page.getId())) { + candidateSlug = baseSlug + "-" + counter; + counter++; + } + + // Hook: page_slug filter + candidateSlug = hookManager.applyFilters("page_slug", candidateSlug); + page.setSlug(candidateSlug); + + Page savedPage = pageRepository.save(page); + + // Hook: save_post action + hookManager.doAction("save_post", savedPage); + + return savedPage; + } + + /** + * Delete a page by ID. + */ + public void delete(Long id) { + LOG.debug("Request to delete Page : {}", id); + pageRepository.deleteById(id); + + // Hook: deleted_post action + hookManager.doAction("deleted_post", id); + } + + /** + * Check if a slug is already taken by another page. + */ + private boolean isSlugTaken(String slug, Long currentPageId) { + if (currentPageId == null) { + return pageRepository.existsBySlug(slug); + } + return pageRepository.existsBySlugAndIdNot(slug, currentPageId); + } + + /** + * Generate a URL-friendly slug from a title string. + * Handles Vietnamese diacritics by normalizing Unicode characters. + * Example: "Giới thiệu Bệnh viện" -> "gioi-thieu-benh-vien" + */ + public static String generateSlug(String input) { + if (input == null || input.isBlank()) { + return ""; + } + // Normalize Unicode (NFD) to separate base characters from diacritical marks + String noWhitespace = WHITESPACE.matcher(input.trim()).replaceAll("-"); + String normalized = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD); + // Remove diacritical marks (combining characters) + String noDiacritics = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); + // Handle Vietnamese special characters that NFD doesn't fully decompose + noDiacritics = noDiacritics.replace('đ', 'd').replace('Đ', 'D'); + // Remove non-latin characters + String slug = NON_LATIN.matcher(noDiacritics).replaceAll(""); + // Collapse multiple hyphens + slug = slug.replaceAll("-{2,}", "-"); + // Remove leading/trailing hyphens + slug = slug.replaceAll("^-|-$", ""); + return slug.toLowerCase(Locale.ENGLISH); + } +} diff --git a/sisvietnamvn_main/src/main/resources/config/application-dev.yml b/sisvietnamvn_main/src/main/resources/config/application-dev.yml index decfd452..c6cad8f3 100644 --- a/sisvietnamvn_main/src/main/resources/config/application-dev.yml +++ b/sisvietnamvn_main/src/main/resources/config/application-dev.yml @@ -86,6 +86,7 @@ jhipster: # Token is valid 24 hours token-validity-in-seconds: 86400 token-validity-in-seconds-for-remember-me: 2592000 + base64-secret: NGE0ZDlkMmI4YTMzMTNjOGFiZWZiMGMwNmVkNTcxNDZhZmVmMThmMDViNGMzNWI3MGVjY2YyZWJmOTMzOGI2NTIzMDdhMDVlNzU0YWJkYjcxOGM3Y2IwODcyZmMyZjg1MDU5ZjViMDIzMDJmMjc3ZmYxMWMyZDdiZWNhMmVjNGE= mail: # specific JHipster mail property, for standard properties see MailProperties base-url: http://127.0.0.1:8080 logging: diff --git a/sisvietnamvn_main/src/main/resources/config/liquibase/changelog/20260625100000_add_page_entity.xml b/sisvietnamvn_main/src/main/resources/config/liquibase/changelog/20260625100000_add_page_entity.xml new file mode 100644 index 00000000..4937f30f --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/config/liquibase/changelog/20260625100000_add_page_entity.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sisvietnamvn_main/src/main/resources/config/liquibase/master.xml b/sisvietnamvn_main/src/main/resources/config/liquibase/master.xml index d37b767d..2f2497d0 100644 --- a/sisvietnamvn_main/src/main/resources/config/liquibase/master.xml +++ b/sisvietnamvn_main/src/main/resources/config/liquibase/master.xml @@ -19,6 +19,7 @@ + diff --git a/sisvietnamvn_main/src/main/resources/static/css/custom.css b/sisvietnamvn_main/src/main/resources/static/css/custom.css index 62b88440..1b8f1197 100644 --- a/sisvietnamvn_main/src/main/resources/static/css/custom.css +++ b/sisvietnamvn_main/src/main/resources/static/css/custom.css @@ -1,4 +1,40 @@ /* Custom CSS - This file has the highest priority and will override other styles */ + +/* ========================================================================== + Design System Tokens (Project-wide CSS Variables) + ========================================================================== */ +:root { + /* Primary brand colors */ + --color-primary: #007bff; + --color-primary-hover: #0056b3; + --color-primary-light: #f0f9ff; + + /* Secondary & Accent colors */ + --color-secondary: #6c757d; + --color-success: #28a745; + --color-warning: #ffc107; + --color-danger: #dc3545; + + /* Neutrals */ + --color-background: #ffffff; + --color-surface: #fafafa; + --color-border: #dee2e6; + + /* Text colors */ + --color-text-main: #333333; + --color-text-muted: #6c757d; + --color-text-light: #ffffff; + + /* Typography */ + --font-family-base: 'Open Sans', 'Inter', sans-serif; + --font-family-heading: 'Lora', 'Georgia', serif; + + /* Spacing & Radii */ + --spacing-md: 20px; + --radius-md: 4px; + --radius-lg: 8px; +} + [data-component-id="umass_base:tophat"] { background-color: transparent !important; } diff --git a/sisvietnamvn_main/src/main/resources/static/js/lazysizes.min.js b/sisvietnamvn_main/src/main/resources/static/js/lazysizes.min.js new file mode 100644 index 00000000..35b726aa --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/static/js/lazysizes.min.js @@ -0,0 +1,3 @@ +/*! lazysizes - v5.3.2 */ + +!function(e){var t=function(u,D,f){"use strict";var k,H;if(function(){var e;var t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:true,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:true,ricTimeout:0,throttleDelay:125};H=u.lazySizesConfig||u.lazysizesConfig||{};for(e in t){if(!(e in H)){H[e]=t[e]}}}(),!D||!D.getElementsByClassName){return{init:function(){},cfg:H,noSupport:true}}var O=D.documentElement,i=u.HTMLPictureElement,P="addEventListener",$="getAttribute",q=u[P].bind(u),I=u.setTimeout,U=u.requestAnimationFrame||I,o=u.requestIdleCallback,j=/^picture$/i,r=["load","error","lazyincluded","_lazyloaded"],a={},G=Array.prototype.forEach,J=function(e,t){if(!a[t]){a[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")}return a[t].test(e[$]("class")||"")&&a[t]},K=function(e,t){if(!J(e,t)){e.setAttribute("class",(e[$]("class")||"").trim()+" "+t)}},Q=function(e,t){var a;if(a=J(e,t)){e.setAttribute("class",(e[$]("class")||"").replace(a," "))}},V=function(t,a,e){var i=e?P:"removeEventListener";if(e){V(t,a)}r.forEach(function(e){t[i](e,a)})},X=function(e,t,a,i,r){var n=D.createEvent("Event");if(!a){a={}}a.instance=k;n.initEvent(t,!i,!r);n.detail=a;e.dispatchEvent(n);return n},Y=function(e,t){var a;if(!i&&(a=u.picturefill||H.pf)){if(t&&t.src&&!e[$]("srcset")){e.setAttribute("srcset",t.src)}a({reevaluate:true,elements:[e]})}else if(t&&t.src){e.src=t.src}},Z=function(e,t){return(getComputedStyle(e,null)||{})[t]},s=function(e,t,a){a=a||e.offsetWidth;while(a49?function(){o(t,{timeout:n});if(n!==H.ricTimeout){n=H.ricTimeout}}:te(function(){I(t)},true);return function(e){var t;if(e=e===true){n=33}if(a){return}a=true;t=r-(f.now()-i);if(t<0){t=0}if(e||t<9){s()}else{I(s,t)}}},ie=function(e){var t,a;var i=99;var r=function(){t=null;e()};var n=function(){var e=f.now()-a;if(e0;if(r&&Z(i,"overflow")!="visible"){a=i.getBoundingClientRect();r=C>a.left&&pa.top-1&&g500&&O.clientWidth>500?500:370:H.expand;k._defEx=u;f=u*H.expFactor;c=H.hFac;A=null;if(w2&&h>2&&!D.hidden){w=f;N=0}else if(h>1&&N>1&&M<6){w=u}else{w=_}}if(l!==n){y=innerWidth+n*c;z=innerHeight+n;s=n*-1;l=n}a=d[t].getBoundingClientRect();if((b=a.bottom)>=s&&(g=a.top)<=z&&(C=a.right)>=s*c&&(p=a.left)<=y&&(b||C||p||g)&&(H.loadHidden||x(d[t]))&&(m&&M<3&&!o&&(h<3||N<4)||W(d[t],n))){R(d[t]);r=true;if(M>9){break}}else if(!r&&m&&!i&&M<4&&N<4&&h>2&&(v[0]||H.preloadAfterLoad)&&(v[0]||!o&&(b||C||p||g||d[t][$](H.sizesAttr)!="auto"))){i=v[0]||d[t]}}if(i&&!r){R(i)}}};var a=ae(t);var S=function(e){var t=e.target;if(t._lazyCache){delete t._lazyCache;return}L(e);K(t,H.loadedClass);Q(t,H.loadingClass);V(t,B);X(t,"lazyloaded")};var i=te(S);var B=function(e){i({target:e.target})};var T=function(e,t){var a=e.getAttribute("data-load-mode")||H.iframeLoadMode;if(a==0){e.contentWindow.location.replace(t)}else if(a==1){e.src=t}};var F=function(e){var t;var a=e[$](H.srcsetAttr);if(t=H.customMedia[e[$]("data-media")||e[$]("media")]){e.setAttribute("media",t)}if(a){e.setAttribute("srcset",a)}};var s=te(function(t,e,a,i,r){var n,s,o,l,u,f;if(!(u=X(t,"lazybeforeunveil",e)).defaultPrevented){if(i){if(a){K(t,H.autosizesClass)}else{t.setAttribute("sizes",i)}}s=t[$](H.srcsetAttr);n=t[$](H.srcAttr);if(r){o=t.parentNode;l=o&&j.test(o.nodeName||"")}f=e.firesLoad||"src"in t&&(s||n||l);u={target:t};K(t,H.loadingClass);if(f){clearTimeout(c);c=I(L,2500);V(t,B,true)}if(l){G.call(o.getElementsByTagName("source"),F)}if(s){t.setAttribute("srcset",s)}else if(n&&!l){if(d.test(t.nodeName)){T(t,n)}else{t.src=n}}if(r&&(s||l)){Y(t,{src:n})}}if(t._lazyRace){delete t._lazyRace}Q(t,H.lazyClass);ee(function(){var e=t.complete&&t.naturalWidth>1;if(!f||e){if(e){K(t,H.fastLoadedClass)}S(u);t._lazyCache=true;I(function(){if("_lazyCache"in t){delete t._lazyCache}},9)}if(t.loading=="lazy"){M--}},true)});var R=function(e){if(e._lazyRace){return}var t;var a=n.test(e.nodeName);var i=a&&(e[$](H.sizesAttr)||e[$]("sizes"));var r=i=="auto";if((r||!m)&&a&&(e[$]("src")||e.srcset)&&!e.complete&&!J(e,H.errorClass)&&J(e,H.lazyClass)){return}t=X(e,"lazyunveilread").detail;if(r){re.updateElem(e,true,e.offsetWidth)}e._lazyRace=true;M++;s(e,t,r,i,a)};var r=ie(function(){H.loadMode=3;a()});var o=function(){if(H.loadMode==3){H.loadMode=2}r()};var l=function(){if(m){return}if(f.now()-e<999){I(l,999);return}m=true;H.loadMode=3;a();q("scroll",o,true)};return{_:function(){e=f.now();k.elements=D.getElementsByClassName(H.lazyClass);v=D.getElementsByClassName(H.lazyClass+" "+H.preloadClass);q("scroll",a,true);q("resize",a,true);q("pageshow",function(e){if(e.persisted){var t=D.querySelectorAll("."+H.loadingClass);if(t.length&&t.forEach){U(function(){t.forEach(function(e){if(e.complete){R(e)}})})}}});if(u.MutationObserver){new MutationObserver(a).observe(O,{childList:true,subtree:true,attributes:true})}else{O[P]("DOMNodeInserted",a,true);O[P]("DOMAttrModified",a,true);setInterval(a,999)}q("hashchange",a,true);["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){D[P](e,a,true)});if(/d$|^c/.test(D.readyState)){l()}else{q("load",l);D[P]("DOMContentLoaded",a);I(l,2e4)}if(k.elements.length){t();ee._lsFlush()}else{a()}},checkElems:a,unveil:R,_aLSL:o}}(),re=function(){var a;var n=te(function(e,t,a,i){var r,n,s;e._lazysizesWidth=i;i+="px";e.setAttribute("sizes",i);if(j.test(t.nodeName||"")){r=t.getElementsByTagName("source");for(n=0,s=r.length;n + * + * 4. The editor will automatically pick up all registered plugins. + */ + +// Global plugin registry — external plugins register here +window.SISEditorPlugins = window.SISEditorPlugins || {}; + +/** + * Initialize the SIS Block Editor on a given holder element. + * + * @param {string} holderId - The DOM element ID for the editor container + * @param {string} hiddenInputId - The DOM element ID for the hidden input storing JSON + * @param {object|null} initialData - Pre-existing Editor.js JSON data to load + * @returns {EditorJS} The editor instance + */ +function initSISEditor(holderId, hiddenInputId, initialData) { + 'use strict'; + + // === Built-in Tools === + var builtInTools = { + header: { + class: Header, + inlineToolbar: true, + config: { + placeholder: 'Enter a heading...', + levels: [2, 3, 4], + defaultLevel: 2 + } + }, + list: { + class: NestedList, + inlineToolbar: true, + config: { + defaultStyle: 'unordered' + } + }, + quote: { + class: Quote, + inlineToolbar: true, + config: { + quotePlaceholder: 'Enter a quote...', + captionPlaceholder: 'Quote author' + } + }, + delimiter: { + class: Delimiter + }, + table: { + class: Table, + inlineToolbar: true, + config: { + rows: 2, + cols: 3 + } + }, + code: { + class: CodeTool + }, + warning: { + class: Warning, + inlineToolbar: true, + config: { + titlePlaceholder: 'Title', + messagePlaceholder: 'Message' + } + }, + marker: { + class: Marker + }, + inlineCode: { + class: InlineCode + }, + underline: { + class: Underline + }, + image: { + class: ImageTool, + config: { + endpoints: { + byFile: '/api/manage/media/upload', + }, + field: 'file', + types: 'image/*' + } + }, + attaches: { + class: AttachesTool, + config: { + endpoint: '/api/manage/media/upload', + field: 'file' + } + } + }; + + // === Merge built-in tools with any registered plugins === + var allTools = Object.assign({}, builtInTools, window.SISEditorPlugins); + + // === Parse initial data === + var editorData = null; + if (initialData && typeof initialData === 'string') { + try { + editorData = JSON.parse(initialData); + } catch (e) { + console.warn('[SIS Editor] Could not parse initial data as JSON, starting empty.', e); + editorData = null; + } + } else if (initialData && typeof initialData === 'object') { + editorData = initialData; + } + + // === Create the Editor === + var editor = new EditorJS({ + holder: holderId, + tools: allTools, + data: editorData || undefined, + placeholder: 'Click here to start writing your page content...', + autofocus: false, + onReady: function() { + console.log('[SIS Editor] Ready. Tools loaded:', Object.keys(allTools)); + }, + onChange: function(api, event) { + // Auto-save to hidden input on every change + api.saver.save().then(function(outputData) { + var hiddenInput = document.getElementById(hiddenInputId); + if (hiddenInput) { + hiddenInput.value = JSON.stringify(outputData); + } + }); + } + }); + + // === Form submission handler === + // Ensure the latest content is saved before form submit + var form = document.querySelector('form'); + if (form) { + var submitHandler = function(event) { + event.preventDefault(); + editor.save().then(function(outputData) { + var hiddenInput = document.getElementById(hiddenInputId); + if (hiddenInput) { + hiddenInput.value = JSON.stringify(outputData); + } + // Now submit the form + form.removeEventListener('submit', submitHandler); + form.submit(); + }).catch(function(error) { + console.error('[SIS Editor] Save failed:', error); + }); + }; + form.addEventListener('submit', submitHandler); + } + + return editor; +} diff --git a/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/_sample-plugin.js b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/_sample-plugin.js new file mode 100644 index 00000000..6cddf350 --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/_sample-plugin.js @@ -0,0 +1,69 @@ +/** + * SAMPLE PLUGIN — How to create a custom Editor.js block for SIS Vietnam + * + * This file demonstrates the plugin pattern. Copy this file and modify it + * to create your own custom block types. + * + * STEPS: + * 1. Copy this file and rename it (e.g., "my-video-block.js") + * 2. Create your Tool class following the Editor.js API + * 3. Register it in window.SISEditorPlugins + * 4. Load it in your template - + + + + + +
+ +
+

Page Form

+ + Back to All Pages + +
+ + +
+
+
Form
+
+
+
+ + +
+
    +
  • +
+
+ + +
+ + +
+
+ + +
+ +
+
+ /page/ +
+ +
+
+
+ Leave blank to auto-generate from the title. Use lowercase + letters, numbers, and hyphens only. +
+ +
+ +
+
+ + +
+
+ + +
+
+ + + Lower numbers appear first. +
+
+
+ + +
+ + + This appears in Google search results below the page + title. +
+ + +
+
+ + +
+
+ Active blocks: + Heading + List + Quote + Table + Code + Delimiter + Warning + +
+ + +
+ + + + + + + Click the + button or press Tab to add new blocks. + Use the block menu (☰) to change block types or reorder. + +
+ + +
+
+ + Cancel + + +
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/sisvietnamvn_main/src/main/resources/templates/manage/pages/list.html b/sisvietnamvn_main/src/main/resources/templates/manage/pages/list.html new file mode 100644 index 00000000..227bd722 --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/templates/manage/pages/list.html @@ -0,0 +1,95 @@ + + + + + All Pages + + + + +
+ +
+

All Pages

+ + Add New Page + +
+ + + + + + + + +
+
+
Manage Static Pages
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
#TitleSlugStatusOrderLast ModifiedActions
+ + + + + + + Edit + +
+ +
+
+ + No pages found. Click "Add New Page" to create one. +
+
+
+
+
+ + + diff --git a/sisvietnamvn_main/src/main/resources/templates/page.html b/sisvietnamvn_main/src/main/resources/templates/page.html new file mode 100644 index 00000000..e9a9a431 --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/templates/page.html @@ -0,0 +1,110 @@ + + + + + Page Title + + + + + + +
+ + + + + + +
+
+ + + + +
+ +

+

+

+

+
+
+

+
+
+
+ + + +
+

+
+
+ + + +
+
    +
  • +
+
    +
  1. +
+
+
+ + + +
+ +

+
+
+ + + +
+
+

+
+
+
+
+ + + +
+ *** +
+
+ + + +
+ + + + + + + + + + + + +
+
+
+ +
+ +
+ + + diff --git a/sisvietnamvn_main/src/main/resources/templates/snippets/test_banner.html b/sisvietnamvn_main/src/main/resources/templates/snippets/test_banner.html new file mode 100644 index 00000000..e7c6c1c5 --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/templates/snippets/test_banner.html @@ -0,0 +1,5 @@ +
+

This is a predefined Snippet!

+

You have successfully loaded the test_banner HTML snippet via the Editor.js custom block.

+ +
diff --git a/sisvietnamvn_main/uploads/39379c54-ad8f-414c-b7f9-6b747290f4ab.webp b/sisvietnamvn_main/uploads/39379c54-ad8f-414c-b7f9-6b747290f4ab.webp new file mode 100644 index 0000000000000000000000000000000000000000..465b9e9837928bc4026411faec79b7c674d381dc GIT binary patch literal 45458 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 NH~9anJcoLt{12k!VwnH{ literal 0 HcmV?d00001 diff --git a/sisvietnamvn_main/uploads/48e097c8-7cad-47aa-a8de-aaab0c7d3428.webp b/sisvietnamvn_main/uploads/48e097c8-7cad-47aa-a8de-aaab0c7d3428.webp new file mode 100644 index 0000000000000000000000000000000000000000..465b9e9837928bc4026411faec79b7c674d381dc GIT binary patch literal 45458 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 NH~9anJcoLt{12k!VwnH{ literal 0 HcmV?d00001