up
483
data/article.json
Normal file
@@ -0,0 +1,483 @@
|
||||
[
|
||||
{
|
||||
"id": 401,
|
||||
"title": "3 kiểu cầm chuột cơ bản: Palm, Claw và Fingertip",
|
||||
"extend": false,
|
||||
"summary": "Cách cầm chuột có ảnh hưởng rất lớn đến hiệu quả công việc của người sử dụng. 3 kiểu cầm chuột cơ bản: Palm, Claw và Fingertip là các kiểu cầm chuột phổ biến nhất hiện nay.",
|
||||
"createDate": "03-12-2020, 10:34 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "08-12-2020, 3:44 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 59,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 1,
|
||||
"url": "/3-kieu-cam-chuot-co-ban-palm-claw-va-fingertip",
|
||||
"image": {
|
||||
"thum": "/media/news/120_401_cac_kieu_cam_chuot_2.jpg",
|
||||
"original": "/media/news/401_cac_kieu_cam_chuot_2.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 276,
|
||||
"title": "7 phần mềm giả lập Android tốt nhất 2020",
|
||||
"extend": false,
|
||||
"summary": "Hiện nay, sự phát triển của các tựa game mobile đang càng ngày càng thịnh hành, nhu cầu chơi game của anh em không còn gói gọn trên chiếc điện thoại của mình nữa. ",
|
||||
"createDate": "26-08-2020, 10:26 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "08-12-2020, 3:28 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 930,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 2,
|
||||
"url": "/phan-mem-gia-lap-android",
|
||||
"image": {
|
||||
"thum": "/media/news/120_276_8_best_features_of_bluestacks_4_2.jpg",
|
||||
"original": "/media/news/276_8_best_features_of_bluestacks_4_2.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 393,
|
||||
"title": "6 Trình Duyệt Web Tốt Nhất 2021 Bạn Nên Tham Khảo",
|
||||
"extend": false,
|
||||
"summary": "Bạn có muốn lựa chọn một trình duyệt phù hợp cho máy tính? Hoàng Hà PC sẽ gợi ý cho bạn top 6 trình duyệt web tốt nhất 2020 nhé!",
|
||||
"createDate": "30-11-2020, 2:41 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "08-12-2020, 11:49 am",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 82,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 3,
|
||||
"url": "/trinh-duyet-web",
|
||||
"image": {
|
||||
"thum": "/media/news/120_393_top_trinh_duyet_web_4.jpg",
|
||||
"original": "/media/news/393_top_trinh_duyet_web_4.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 400,
|
||||
"title": "Thông số benchmark chip AMD Ryzen 9 5950X",
|
||||
"extend": false,
|
||||
"summary": "Nguồn tin cho thấy thông số benchmark AMD Ryzen 9 5950X. Điều này tạo tiền đề cho người dùng có thể ước lược sức mạnh của CPU này trước khi mua sản phẩm.",
|
||||
"createDate": "03-12-2020, 10:20 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "24-02-2023, 10:58 am",
|
||||
"lastUpdateBy": 10,
|
||||
"visit": 78,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "ngoctm@hurasoft.com",
|
||||
"counter": 4,
|
||||
"url": "/thong-so-benchmark-chip-amd-ryzen-9-5950x",
|
||||
"image": {
|
||||
"thum": "/media/news/120_400_benchmark_chip_amd_ryzen_9_5950x_2.jpg",
|
||||
"original": "/media/news/400_benchmark_chip_amd_ryzen_9_5950x_2.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 271,
|
||||
"title": "Hướng dẫn chọn CPU cho PC làm đồ họa chuyên nghiệp",
|
||||
"extend": false,
|
||||
"summary": "Có một câu chuyện nghe tưởng dễ nhưng rất nhiều anh em đắn đo khi chọn mua một cấu hình máy tính đó là nên chọn CPU phù hợp với công việc của mình đặc biệt là làm đồ họa chuyên nghiệp.Vậy chúng ta nên chọn CPU Ryzen hay là Intel?",
|
||||
"createDate": "25-07-2020, 2:43 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "01-12-2020, 3:35 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 1841,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 5,
|
||||
"url": "/huong-dan-chon-cpu-cho-pc-lam-do-hoa-chuyen-nghiep",
|
||||
"image": {
|
||||
"thum": "/media/news/120_271_truy___n_th__ng_i9_10900k_03.jpg",
|
||||
"original": "/media/news/271_truy___n_th__ng_i9_10900k_03.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 420,
|
||||
"title": "Thị trường mới nổi thúc đẩy doanh số iPhone",
|
||||
"extend": false,
|
||||
"summary": "rong báo cáo tài chính ba tháng đầu năm (quý II/2023 theo năm tài khóa của Apple) tuần trước, CEO Tim Cook cho biết doanh số iPhone lập kỷ lục tại nhiều nước. Hầu hết những cái tên ông đề cập đều từ thị trường mới nổi, như Mexico, Indonesia, Philippines, Malaysia, Arab Saudi, Thổ Nhĩ Kỳ, UAE, Brazil và Ấn Độ.",
|
||||
"createDate": "09-05-2023, 12:03 pm",
|
||||
"createBy": 11,
|
||||
"lastUpdate": "17-12-2024, 9:27 am",
|
||||
"lastUpdateBy": 32,
|
||||
"visit": 0,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "https://vnexpress.net/thi-truong-moi-noi-cuu-apple-4602429.html",
|
||||
"author": "Hồng",
|
||||
"counter": 6,
|
||||
"url": "/thi-truong-moi-noi-thuc-day-doanh-so-iphone",
|
||||
"image": {
|
||||
"thum": "/media/news/120_420_lenovo_thinkpad_x250_cu___gia___re___0820.jpeg",
|
||||
"original": "/media/news/420_lenovo_thinkpad_x250_cu___gia___re___0820.jpeg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 407,
|
||||
"title": "Hướng Dẫn Cài Đặt Cấu Hình LMHT: Tốc Chiến Chơi Mượt Trên Máy Tính",
|
||||
"extend": false,
|
||||
"summary": "Sau bao ngày mong đợi, LMHT: Tốc Chiến phiên bản Mobile phát hành bởi VNG đã có thể chính thức tải về trên cả Android lẫn IOS. \r\n",
|
||||
"createDate": "09-12-2020, 8:37 am",
|
||||
"createBy": 8,
|
||||
"lastUpdate": "17-04-2024, 4:00 pm",
|
||||
"lastUpdateBy": 24,
|
||||
"visit": 73,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Uyên Hura",
|
||||
"counter": 7,
|
||||
"url": "/huong-dan-cai-dat-cau-hinh-lmht-toc-chien-choi-muot-tren-may-tinh",
|
||||
"image": {
|
||||
"thum": "/media/news/120_407_toc_chien_mobile.JPG",
|
||||
"original": "/media/news/407_toc_chien_mobile.JPG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 327,
|
||||
"title": "Các Bước Vệ Sinh Máy Tính Tại Hoàng Hà PC",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "15-10-2020, 1:58 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "01-12-2020, 3:24 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 493,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 8,
|
||||
"url": "/ve-sinh-may-tinh",
|
||||
"image": {
|
||||
"thum": "/media/news/120_327_vesinhmaytinh.jpg",
|
||||
"original": "/media/news/327_vesinhmaytinh.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 326,
|
||||
"title": "Cấu Hình Máy Tính Chơi Game Genshin Impact giá rẻ",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "12-10-2020, 2:24 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "11-12-2020, 2:26 pm",
|
||||
"lastUpdateBy": 10,
|
||||
"visit": 1709,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "cau-hinh-may-tinh-choi-pubg-genshin-impact",
|
||||
"author": "Hoàng Hà PC",
|
||||
"counter": 9,
|
||||
"url": "/cau-hinh-may-tinh-choi-game-genshin-impact-gia-re",
|
||||
"image": {
|
||||
"thum": "/media/news/120_326_genshin_impact.jpg",
|
||||
"original": "/media/news/326_genshin_impact.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 318,
|
||||
"title": "10 Cấu Hình Máy Tính Sản Xuất Âm Nhạc 2020",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "02-10-2020, 10:42 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "01-12-2020, 10:17 am",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 359,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "cau-hinh-may-tinh-audio",
|
||||
"author": "Admin",
|
||||
"counter": 10,
|
||||
"url": "/cau-hinh-may-tinh-san-xuat-am-nhac",
|
||||
"image": {
|
||||
"thum": "/media/news/120_318_musician_sound_soundman_music_783988.jpg",
|
||||
"original": "/media/news/318_musician_sound_soundman_music_783988.jpg"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": 18,
|
||||
"title": "Cấu Hình Máy Tính Chạy Giả Lập Nox Player",
|
||||
"extend": false,
|
||||
"summary": "Để mở được nhiều giả lập NoxPlayer thì yêu cầu máy tính phải có CPU nhiều nhân, hỗ trợ ảo hóa, và RAM hệ thống phải nhiều, Card đồ họa phải có từ 4GB VRAM trở lên.",
|
||||
"createDate": "27-10-2018, 2:38 pm",
|
||||
"createBy": 1,
|
||||
"lastUpdate": "15-12-2020, 3:28 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 158494,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 1,
|
||||
"url": "/cau-hinh-may-tinh-chay-gia-lap-nox-player",
|
||||
"image": {
|
||||
"thum": "/media/news/120_18_xigmatek__vera_kinh_cuong_luc.jpg",
|
||||
"original": "/media/news/18_xigmatek__vera_kinh_cuong_luc.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"title": "17 Cấu Hình Máy Tính Dựng Phim, Render Edit Video Theo Ngân Sách 2020",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "30-10-2018, 10:07 am",
|
||||
"createBy": 1,
|
||||
"lastUpdate": "24-04-2023, 1:26 pm",
|
||||
"lastUpdateBy": 16,
|
||||
"visit": 208812,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Nguyễn An",
|
||||
"counter": 2,
|
||||
"url": "/cau-hinh-may-tinh-dung-phim",
|
||||
"image": {
|
||||
"thum": "/media/news/120_19_cau_hinh_may_tinh_dung_phim.jpg",
|
||||
"original": "/media/news/19_cau_hinh_may_tinh_dung_phim.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 62,
|
||||
"title": "7 Cấu Hình Máy Tính Cho Streamer Livestream Chuyên Nghiệp 2020",
|
||||
"extend": false,
|
||||
"summary": "Hiện nay Stream game hay Livestream trên mạng xã hội, youtube đang ngày càng phổ biến, vì vậy lựa chọn những cấu hình dành cho stream game càng ngày càng phổ biến đối với các game thủ đặc biết là những người muốn kiếm tiền từ những công việc trên. Vì vậy Hoàng Hà PC muốn hướng dẫn anh em chọn lựa sao cho phù hợp nhất cấu hình máy tính cho Livestream.\r\n\r\n",
|
||||
"createDate": "14-06-2019, 3:05 pm",
|
||||
"createBy": 8,
|
||||
"lastUpdate": "07-12-2020, 8:38 am",
|
||||
"lastUpdateBy": 10,
|
||||
"visit": 75688,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Hoàng Hà PC",
|
||||
"counter": 3,
|
||||
"url": "/may-tinh-stream",
|
||||
"image": {
|
||||
"thum": "/media/news/120_62_pc_streamer.jpg",
|
||||
"original": "/media/news/62_pc_streamer.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 107,
|
||||
"title": "10 Cấu Hình Máy Tính Chơi Game Hot Nhất 2021",
|
||||
"extend": false,
|
||||
"summary": "Hoàng Hà PC xin chia sẻ top những cấu hình game dễ dàng cân đối ngân sách cũng như thoải mái thưởng thức trong thế giới game.",
|
||||
"createDate": "21-11-2019, 11:48 am",
|
||||
"createBy": 8,
|
||||
"lastUpdate": "15-12-2020, 3:34 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 189996,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 4,
|
||||
"url": "/cau-hinh-may-tinh-choi-game",
|
||||
"image": {
|
||||
"thum": "/media/news/120_107_9100f_1060__1_.jpg",
|
||||
"original": "/media/news/107_9100f_1060__1_.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 205,
|
||||
"title": "Cấu Hình Máy Tính Chạy Phần Mềm Lumion Chuyên Dụng",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "16-03-2020, 4:56 pm",
|
||||
"createBy": 8,
|
||||
"lastUpdate": "02-12-2020, 2:12 pm",
|
||||
"lastUpdateBy": 10,
|
||||
"visit": 16223,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Hoàng Hà PC",
|
||||
"counter": 5,
|
||||
"url": "/cau-hinh-may-tinh-chay-phan-mem-lumion-chuyen-dung",
|
||||
"image": {
|
||||
"thum": "/media/news/120_205_case_i9_h500p.JPG",
|
||||
"original": "/media/news/205_case_i9_h500p.JPG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 279,
|
||||
"title": "10 Cấu Hình Máy Tính Chuyên Render Farm",
|
||||
"extend": false,
|
||||
"summary": "Cấu hình máy tính Render Farm ở các mức ngân sách đầu tư, các công nghệ mới nhất luôn được cập nhật liên tục tới quý khách hàng.",
|
||||
"createDate": "07-09-2020, 4:09 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "16-12-2020, 11:35 am",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 468,
|
||||
"is_featured": 0,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 6,
|
||||
"url": "/cau-hinh-may-tinh-render-farm",
|
||||
"image": {
|
||||
"thum": "/media/news/120_279____nh_deepcool.jpg",
|
||||
"original": "/media/news/279____nh_deepcool.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 327,
|
||||
"title": "Các Bước Vệ Sinh Máy Tính Tại Hoàng Hà PC",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "15-10-2020, 1:58 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "01-12-2020, 3:24 pm",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 493,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 7,
|
||||
"url": "/ve-sinh-may-tinh",
|
||||
"image": {
|
||||
"thum": "/media/news/120_327_vesinhmaytinh.jpg",
|
||||
"original": "/media/news/327_vesinhmaytinh.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 326,
|
||||
"title": "Cấu Hình Máy Tính Chơi Game Genshin Impact giá rẻ",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "12-10-2020, 2:24 pm",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "11-12-2020, 2:26 pm",
|
||||
"lastUpdateBy": 10,
|
||||
"visit": 1709,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "cau-hinh-may-tinh-choi-pubg-genshin-impact",
|
||||
"author": "Hoàng Hà PC",
|
||||
"counter": 8,
|
||||
"url": "/cau-hinh-may-tinh-choi-game-genshin-impact-gia-re",
|
||||
"image": {
|
||||
"thum": "/media/news/120_326_genshin_impact.jpg",
|
||||
"original": "/media/news/326_genshin_impact.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 318,
|
||||
"title": "10 Cấu Hình Máy Tính Sản Xuất Âm Nhạc 2020",
|
||||
"extend": false,
|
||||
"summary": "",
|
||||
"createDate": "02-10-2020, 10:42 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "01-12-2020, 10:17 am",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 359,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "cau-hinh-may-tinh-audio",
|
||||
"author": "Admin",
|
||||
"counter": 9,
|
||||
"url": "/cau-hinh-may-tinh-san-xuat-am-nhac",
|
||||
"image": {
|
||||
"thum": "/media/news/120_318_musician_sound_soundman_music_783988.jpg",
|
||||
"original": "/media/news/318_musician_sound_soundman_music_783988.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 305,
|
||||
"title": "Yêu Cầu Ram Cho Chỉnh Sửa Photoshop?",
|
||||
"extend": false,
|
||||
"summary": "Vì vậy Hoàng Hà PC thực hiện bài viết này để giúp cho bạn có cái nhìn rõ ràng hơn về RAM trong việc chỉnh sửa Photoshop, từ đó các bạn sẽ dễ dàng hơn cho việc chọn lựa.",
|
||||
"createDate": "25-09-2020, 10:56 am",
|
||||
"createBy": 10,
|
||||
"lastUpdate": "14-12-2020, 11:59 am",
|
||||
"lastUpdateBy": 8,
|
||||
"visit": 644,
|
||||
"is_featured": 1,
|
||||
"article_time": "",
|
||||
"review_rate": 0,
|
||||
"review_count": 0,
|
||||
"video_code": "",
|
||||
"external_url": "",
|
||||
"author": "Admin",
|
||||
"counter": 10,
|
||||
"url": "/can-bao-nhieu-ram-cho-chinh-sua-anh",
|
||||
"image": {
|
||||
"thum": "/media/news/120_305_chinh_sua_anh_ram.jpg",
|
||||
"original": "/media/news/305_chinh_sua_anh_ram.jpg"
|
||||
}
|
||||
}
|
||||
]
|
||||
638
data/banner.json
Normal file
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"homepage": {
|
||||
"banner_homepage_webmau4": [
|
||||
{
|
||||
"id": 234,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/02_02-7adfa02946cc4bccfbf2fec2ed354839.jpg\" width='2048' height='922' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/02_02-7adfa02946cc4bccfbf2fec2ed354839.jpg",
|
||||
"desUrl": "/ad.php?id=234",
|
||||
"title": "",
|
||||
"width": 2048,
|
||||
"height": 922,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 220,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/bannerhome.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/bannerhome.png",
|
||||
"desUrl": "/ad.php?id=220",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 233,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/02_02-95a170ae73d9fd20e2812baa677d1c1e.png\" width='1186' height='551' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/02_02-95a170ae73d9fd20e2812baa677d1c1e.png",
|
||||
"desUrl": "/ad.php?id=233",
|
||||
"title": "",
|
||||
"width": 1186,
|
||||
"height": 551,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"brand_home": [
|
||||
{
|
||||
"id": 223,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/dell.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/dell.png",
|
||||
"desUrl": "/ad.php?id=223",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 222,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/asus.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/asus.png",
|
||||
"desUrl": "/ad.php?id=222",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 224,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/lenovo.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/lenovo.png",
|
||||
"desUrl": "/ad.php?id=224",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 225,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/lenovo.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/lenovo.png",
|
||||
"desUrl": "/ad.php?id=225",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 226,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/opppo.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/opppo.png",
|
||||
"desUrl": "/ad.php?id=226",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 227,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/samsung.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/samsung.png",
|
||||
"desUrl": "/ad.php?id=227",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 228,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/static/assets/webmau4/images/sony.png\" alt=\"\" />",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/static/assets/webmau4/images/sony.png",
|
||||
"desUrl": "/ad.php?id=228",
|
||||
"title": "",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_danh_muc_san_pham_noi_bat_trang_chu": [
|
||||
{
|
||||
"id": 199,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/26_Febc873840dfc4284638e9fa20bd6bb057b.png\" width='1200' height='60' alt=\"Tết rộn ràng\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/26_Febc873840dfc4284638e9fa20bd6bb057b.png",
|
||||
"desUrl": "/ad.php?id=199",
|
||||
"title": "Tết rộn ràng",
|
||||
"width": 1200,
|
||||
"height": 60,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"slide_home_page_mobile_2020": [
|
||||
{
|
||||
"id": 201,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/19_Marafc1ec25a581a9c98c60ec0d8a258aca.jpg\" width='935' height='528' alt=\"slider home mobile\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/19_Marafc1ec25a581a9c98c60ec0d8a258aca.jpg",
|
||||
"desUrl": "/ad.php?id=201",
|
||||
"title": "slider home mobile",
|
||||
"width": 935,
|
||||
"height": 528,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 178,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/07_Janf712465f2dee122615983809f95a6598.png\" width='640' height='436' alt=\"Flash Sale - Hoàng Hà PC\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/07_Janf712465f2dee122615983809f95a6598.png",
|
||||
"desUrl": "/ad.php?id=178",
|
||||
"title": "Flash Sale - Hoàng Hà PC",
|
||||
"width": 640,
|
||||
"height": 436,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_bottom": [
|
||||
{
|
||||
"id": 203,
|
||||
"display": "",
|
||||
"fileUrl": "",
|
||||
"desUrl": "/ad.php?id=203",
|
||||
"title": "chuan",
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"slider_xstore": [
|
||||
{
|
||||
"id": 204,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/13_Augc8fd1aca7ef5ac5da89697f3ed1e7631.png\" width='630' height='385' alt=\"banner silder 1\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/13_Augc8fd1aca7ef5ac5da89697f3ed1e7631.png",
|
||||
"desUrl": "/ad.php?id=204",
|
||||
"title": "banner silder 1",
|
||||
"width": 630,
|
||||
"height": 385,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 205,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/18_09-ae53bb7429af1001041ece256831f3a1.png\" width='680' height='380' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/18_09-ae53bb7429af1001041ece256831f3a1.png",
|
||||
"desUrl": "/ad.php?id=205",
|
||||
"title": "",
|
||||
"width": 680,
|
||||
"height": 380,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_homepage_webmau3": [
|
||||
{
|
||||
"id": 213,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/14_10-9aa4e705b3e5a9e33789638547a367ea.png\" width='1920' height='616' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/14_10-9aa4e705b3e5a9e33789638547a367ea.png",
|
||||
"desUrl": "/ad.php?id=213",
|
||||
"title": "",
|
||||
"width": 1920,
|
||||
"height": 616,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 212,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/14_10-9aa4e705b3e5a9e33789638547a367ea.png\" width='1920' height='616' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/14_10-9aa4e705b3e5a9e33789638547a367ea.png",
|
||||
"desUrl": "/ad.php?id=212",
|
||||
"title": "",
|
||||
"width": 1920,
|
||||
"height": 616,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_under_slider_webmau3": [
|
||||
{
|
||||
"id": 214,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/14_10-e66706e1afed4a6877828501fa299621.png\" width='805' height='310' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/14_10-e66706e1afed4a6877828501fa299621.png",
|
||||
"desUrl": "/ad.php?id=214",
|
||||
"title": "",
|
||||
"width": 805,
|
||||
"height": 310,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 215,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/14_10-c024c13179be75ab71998ae7f5b361f9.png\" width='805' height='310' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/14_10-c024c13179be75ab71998ae7f5b361f9.png",
|
||||
"desUrl": "/ad.php?id=215",
|
||||
"title": "",
|
||||
"width": 805,
|
||||
"height": 310,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_under_slider_mobile_webmau3": [
|
||||
{
|
||||
"id": 216,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/03_11-640a1b5d2a7d38e6a1260109bdabbea8.png\" width='406' height='160' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/03_11-640a1b5d2a7d38e6a1260109bdabbea8.png",
|
||||
"desUrl": "/ad.php?id=216",
|
||||
"title": "",
|
||||
"width": 406,
|
||||
"height": 160,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 217,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/03_11-640a1b5d2a7d38e6a1260109bdabbea8.png\" width='406' height='160' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/03_11-640a1b5d2a7d38e6a1260109bdabbea8.png",
|
||||
"desUrl": "/ad.php?id=217",
|
||||
"title": "",
|
||||
"width": 406,
|
||||
"height": 160,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_slider_mobile_webmau3": [
|
||||
{
|
||||
"id": 218,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/03_11-b5af30f1e089d0e6191ed5d9eaa00788.png\" width='414' height='133' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/03_11-b5af30f1e089d0e6191ed5d9eaa00788.png",
|
||||
"desUrl": "/ad.php?id=218",
|
||||
"title": "",
|
||||
"width": 414,
|
||||
"height": 133,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 219,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/03_11-b5af30f1e089d0e6191ed5d9eaa00788.png\" width='414' height='133' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/03_11-b5af30f1e089d0e6191ed5d9eaa00788.png",
|
||||
"desUrl": "/ad.php?id=219",
|
||||
"title": "",
|
||||
"width": 414,
|
||||
"height": 133,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_sp_hot": [
|
||||
{
|
||||
"id": 198,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/26_Febc873840dfc4284638e9fa20bd6bb057b.png\" width='1200' height='60' alt=\"sản phẩm hot\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/26_Febc873840dfc4284638e9fa20bd6bb057b.png",
|
||||
"desUrl": "/ad.php?id=198",
|
||||
"title": "sản phẩm hot",
|
||||
"width": 1200,
|
||||
"height": 60,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 235,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/23_05-cc21423649a9a6135d942b9e5f8f0dad.jpg\" width='1320' height='450' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/23_05-cc21423649a9a6135d942b9e5f8f0dad.jpg",
|
||||
"desUrl": "/ad.php?id=235",
|
||||
"title": "",
|
||||
"width": 1320,
|
||||
"height": 450,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_webmau4_mb": [
|
||||
{
|
||||
"id": 229,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/07_12-43aed9fac2b0c00f7b38b09bc64143b0.png\" width='66' height='38' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/07_12-43aed9fac2b0c00f7b38b09bc64143b0.png",
|
||||
"desUrl": "/ad.php?id=229",
|
||||
"title": "",
|
||||
"width": 66,
|
||||
"height": 38,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 230,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/07_12-f6d971f169081174b23368752e5c8d62.png\" width='67' height='38' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/07_12-f6d971f169081174b23368752e5c8d62.png",
|
||||
"desUrl": "/ad.php?id=230",
|
||||
"title": "",
|
||||
"width": 67,
|
||||
"height": 38,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 231,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/07_12-346678d3f4c5f84fee37622f8ea33fa3.png\" width='66' height='38' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/07_12-346678d3f4c5f84fee37622f8ea33fa3.png",
|
||||
"desUrl": "/ad.php?id=231",
|
||||
"title": "",
|
||||
"width": 66,
|
||||
"height": 38,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 232,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/07_12-720875b403edbcc76ca06d57d2eda9e5.png\" width='66' height='38' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/07_12-720875b403edbcc76ca06d57d2eda9e5.png",
|
||||
"desUrl": "/ad.php?id=232",
|
||||
"title": "",
|
||||
"width": 66,
|
||||
"height": 38,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_homepage_2020": [
|
||||
{
|
||||
"id": 125,
|
||||
"display": "<a href=\"/ad.php?id=125\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Dec91020aa63fdc40d993105e95b5978c8e.png\" width='396' height='250' alt=\"System For machine Learing - AI Tensorflow\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Dec91020aa63fdc40d993105e95b5978c8e.png",
|
||||
"desUrl": "/ad.php?id=125",
|
||||
"title": "System For machine Learing - AI Tensorflow",
|
||||
"width": 396,
|
||||
"height": 250,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 120,
|
||||
"display": "<a href=\"/ad.php?id=120\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Dec622325326661f8ad6035623e10d3ce25.png\" width='396' height='250' alt=\"Workstation Chuyên Dụng Render\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Dec622325326661f8ad6035623e10d3ce25.png",
|
||||
"desUrl": "/ad.php?id=120",
|
||||
"title": "Workstation Chuyên Dụng Render",
|
||||
"width": 396,
|
||||
"height": 250,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 121,
|
||||
"display": "<a href=\"/ad.php?id=121\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Dec11d7b04aad430d1ecf3b096fccb5e251.png\" width='396' height='250' alt=\"Server Chuyên Dụng - Máy Ảo Giả Lập\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Dec11d7b04aad430d1ecf3b096fccb5e251.png",
|
||||
"desUrl": "/ad.php?id=121",
|
||||
"title": "Server Chuyên Dụng - Máy Ảo Giả Lập",
|
||||
"width": 396,
|
||||
"height": 250,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 122,
|
||||
"display": "<a href=\"/ad.php?id=122\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Decca0bd36159b9bd59d8f3147a227b6555.png\" width='396' height='250' alt=\"PC Gaming - Live Stream\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Decca0bd36159b9bd59d8f3147a227b6555.png",
|
||||
"desUrl": "/ad.php?id=122",
|
||||
"title": "PC Gaming - Live Stream",
|
||||
"width": 396,
|
||||
"height": 250,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_slider_trang_chu_demo": [
|
||||
{
|
||||
"id": 206,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/13_10-396562c7c09bd2b55fb0f7ba1d1fdf7e.jpg\" width='1600' height='525' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/13_10-396562c7c09bd2b55fb0f7ba1d1fdf7e.jpg",
|
||||
"desUrl": "/ad.php?id=206",
|
||||
"title": "",
|
||||
"width": 1600,
|
||||
"height": 525,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 209,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/13_10-396562c7c09bd2b55fb0f7ba1d1fdf7e.jpg\" width='1600' height='525' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/13_10-396562c7c09bd2b55fb0f7ba1d1fdf7e.jpg",
|
||||
"desUrl": "/ad.php?id=209",
|
||||
"title": "",
|
||||
"width": 1600,
|
||||
"height": 525,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_slider_trang_chu_mb_demo": [
|
||||
{
|
||||
"id": 211,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/11_10-960ff53f90331e036cf5a590bd4980ed.png\" width='394' height='129' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/11_10-960ff53f90331e036cf5a590bd4980ed.png",
|
||||
"desUrl": "/ad.php?id=211",
|
||||
"title": "",
|
||||
"width": 394,
|
||||
"height": 129,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 210,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_10-9aa4e705b3e5a9e33789638547a367ea.png\" width='394' height='129' alt=\"\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_10-9aa4e705b3e5a9e33789638547a367ea.png",
|
||||
"desUrl": "/ad.php?id=210",
|
||||
"title": "",
|
||||
"width": 394,
|
||||
"height": 129,
|
||||
"fileType": 1,
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_right_home_2020": [
|
||||
{
|
||||
"id": 146,
|
||||
"display": "<a href=\"/ad.php?id=146\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/12_Dec0526e3c415d0376815cb13d8a72759e3.png\" width='327' height='222' alt=\"Free Ship Toàn Quốc - Hoàng Hà PC\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/12_Dec0526e3c415d0376815cb13d8a72759e3.png",
|
||||
"desUrl": "/ad.php?id=146",
|
||||
"title": "Free Ship Toàn Quốc - Hoàng Hà PC",
|
||||
"width": 327,
|
||||
"height": 222,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 147,
|
||||
"display": "<a href=\"/ad.php?id=147\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/12_Dec0f3234304fd9ab1343138f4b37f83631.png\" width='327' height='222' alt=\"Xây Dựng Cấu Hình - Hoàng Hà PC\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/12_Dec0f3234304fd9ab1343138f4b37f83631.png",
|
||||
"desUrl": "/ad.php?id=147",
|
||||
"title": "Xây Dựng Cấu Hình - Hoàng Hà PC",
|
||||
"width": 327,
|
||||
"height": 222,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 148,
|
||||
"display": "<a href=\"/ad.php?id=148\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/12_Deca861455749b049ec413a8a01bb9a98f0.png\" width='327' height='222' alt=\"Bảo Hành Tận Nhà Khi Mua PC tại Hoàng Hà PC\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/12_Deca861455749b049ec413a8a01bb9a98f0.png",
|
||||
"desUrl": "/ad.php?id=148",
|
||||
"title": "Bảo Hành Tận Nhà Khi Mua PC tại Hoàng Hà PC",
|
||||
"width": 327,
|
||||
"height": 222,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 149,
|
||||
"display": "<a href=\"/ad.php?id=149\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/12_Decf1edec55c0c16c3f86ba59e682b5e303.png\" width='327' height='222' alt=\"Miễn Phí Vệ Sinh PC\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/12_Decf1edec55c0c16c3f86ba59e682b5e303.png",
|
||||
"desUrl": "/ad.php?id=149",
|
||||
"title": "Miễn Phí Vệ Sinh PC",
|
||||
"width": 327,
|
||||
"height": 222,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_bot_slider_2020": [
|
||||
{
|
||||
"id": 152,
|
||||
"display": "<a href=\"/ad.php?id=152\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Decf2d16a0e839a84a7a8bb6ceeb6c61dbd.png\" width='640' height='400' alt=\"Flash Sale | Giảm Giá Cực Sốc !\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Decf2d16a0e839a84a7a8bb6ceeb6c61dbd.png",
|
||||
"desUrl": "/ad.php?id=152",
|
||||
"title": "Flash Sale | Giảm Giá Cực Sốc !",
|
||||
"width": 640,
|
||||
"height": 400,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 151,
|
||||
"display": "<a href=\"/ad.php?id=151\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Dec7d9b1aaf8185be88e8ae4a3f73376b5c.png\" width='640' height='400' alt=\"Gian Hàng Thanh Lý\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Dec7d9b1aaf8185be88e8ae4a3f73376b5c.png",
|
||||
"desUrl": "/ad.php?id=151",
|
||||
"title": "Gian Hàng Thanh Lý",
|
||||
"width": 640,
|
||||
"height": 400,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 150,
|
||||
"display": "<a href=\"/ad.php?id=150\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Deca23272dc601644cf6ff9c77e79de6c09.png\" width='640' height='400' alt=\"PC workstation core i9\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Deca23272dc601644cf6ff9c77e79de6c09.png",
|
||||
"desUrl": "/ad.php?id=150",
|
||||
"title": "PC workstation core i9",
|
||||
"width": 640,
|
||||
"height": 400,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 153,
|
||||
"display": "<a href=\"/ad.php?id=153\" target='_blank' rel='nofollow'>\n <img border=0 src=\"https://demopc8.hurasoft.com/media/banner/10_Decfb99c41cc35a8d3ba27d62c1e42c002a.png\" width='640' height='400' alt=\"Workstation - Hiệu năng cao\"/></a>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/10_Decfb99c41cc35a8d3ba27d62c1e42c002a.png",
|
||||
"desUrl": "/ad.php?id=153",
|
||||
"title": "Workstation - Hiệu năng cao",
|
||||
"width": 640,
|
||||
"height": 400,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_slider_anphat": [
|
||||
{
|
||||
"id": 183,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/16_Mar80db83526b73f51003424e4693ee34fc.jpg\" width='935' height='528' alt=\"Horizon Forbidden West - game độc quyền cho PS5\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/16_Mar80db83526b73f51003424e4693ee34fc.jpg",
|
||||
"desUrl": "/ad.php?id=183",
|
||||
"title": "Horizon Forbidden West - game độc quyền cho PS5",
|
||||
"width": 935,
|
||||
"height": 528,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 184,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/16_Marb8aa7a874ee8dc3d0870bd568cc0a86c.jpg\" width='935' height='528' alt=\"Hitman 3: Sự trở lại sáng chói, cực kỳ ấn tượng\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/16_Marb8aa7a874ee8dc3d0870bd568cc0a86c.jpg",
|
||||
"desUrl": "/ad.php?id=184",
|
||||
"title": "Hitman 3: Sự trở lại sáng chói, cực kỳ ấn tượng",
|
||||
"width": 935,
|
||||
"height": 528,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 185,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/16_Mar11be7cc954bafbcf03da6709f0b1217e.jpg\" width='9' height='528' alt=\"Đối mặt với với những chiến binh vĩ đại nhất thế giới\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/16_Mar11be7cc954bafbcf03da6709f0b1217e.jpg",
|
||||
"desUrl": "/ad.php?id=185",
|
||||
"title": "Đối mặt với với những chiến binh vĩ đại nhất thế giới",
|
||||
"width": 9,
|
||||
"height": 528,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_bottom_sale": [
|
||||
{
|
||||
"id": 193,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/25_Febc1d6d1517fe530ba64ebff821fd9ba02.png\" width='416' height='223' alt=\"sản phẩm sale 20%\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/25_Febc1d6d1517fe530ba64ebff821fd9ba02.png",
|
||||
"desUrl": "/ad.php?id=193",
|
||||
"title": "sản phẩm sale 20%",
|
||||
"width": 416,
|
||||
"height": 223,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 194,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/25_Feb3f6b607b46221889be00a350d566f74e.png\" width='415' height='223' alt=\"sản phẩm sale 30%\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/25_Feb3f6b607b46221889be00a350d566f74e.png",
|
||||
"desUrl": "/ad.php?id=194",
|
||||
"title": "sản phẩm sale 30%",
|
||||
"width": 415,
|
||||
"height": 223,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 195,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/25_Febe7b51aa82a8ab0e757891b126e98bf60.png\" width='41' height='223' alt=\"sản phẩm sale 50%\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/25_Febe7b51aa82a8ab0e757891b126e98bf60.png",
|
||||
"desUrl": "/ad.php?id=195",
|
||||
"title": "sản phẩm sale 50%",
|
||||
"width": 41,
|
||||
"height": 223,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
],
|
||||
"banner_right_anphat": [
|
||||
{
|
||||
"id": 196,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/25_Febd8190acd69535625f34f028394fd7f3e.png\" width='385' height='252' alt=\"Banner top\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/25_Febd8190acd69535625f34f028394fd7f3e.png",
|
||||
"desUrl": "/ad.php?id=196",
|
||||
"title": "Banner top",
|
||||
"width": 385,
|
||||
"height": 252,
|
||||
"fileType": "",
|
||||
"summary": ""
|
||||
},
|
||||
{
|
||||
"id": 197,
|
||||
"display": "<img border=0 src=\"https://demopc8.hurasoft.com/media/banner/25_Febf653150e7b05b74250ddfdf790f54221.png\" width='385' height='252' alt=\"Banner-bottom\"/>",
|
||||
"fileUrl": "https://demopc8.hurasoft.com/media/banner/25_Febf653150e7b05b74250ddfdf790f54221.png",
|
||||
"desUrl": "/ad.php?id=197",
|
||||
"title": "Banner-bottom",
|
||||
"width": 385,
|
||||
"height": 252,
|
||||
"fileType": "banner",
|
||||
"summary": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
2207
data/component.json
Normal file
8787
data/db.json
Normal file
13636
data/page_category.json
Normal file
8304
data/product.json
Normal file
1
global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module "*.css";
|
||||
@@ -1,7 +1,18 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
images: {
|
||||
remotePatterns: [new URL('https://demopc8.hurasoft.com/static/assets/htpstore/images/**')],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{ protocol: "https", hostname: "demopc8.hurasoft.com", pathname: "/static/**" },
|
||||
{ protocol: "https", hostname: "demopc8.hurasoft.com", pathname: "/media/**" },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
1087
package-lock.json
generated
23
package.json
@@ -6,22 +6,33 @@
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
"lint": "eslint",
|
||||
"start-api": "json-server --watch data/db.json --port 5000"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^7.1.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.1.0",
|
||||
"@fortawesome/react-fontawesome": "^3.1.0",
|
||||
"@headlessui/react": "^2.2.9",
|
||||
"bootstrap": "^5.3.8",
|
||||
"clsx": "^2.1.1",
|
||||
"next": "15.5.4",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"next": "15.5.4"
|
||||
"swiper": "^12.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@tailwindcss/postcss": "^4.1.14",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"tailwindcss": "^4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.5.4",
|
||||
"@eslint/eslintrc": "^3"
|
||||
"json-server": "^1.0.0-beta.3",
|
||||
"postcss": "^8.5.6",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
|
||||
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
BIN
public/image/bg-discount.png
Normal file
|
After Width: | Height: | Size: 919 B |
BIN
public/image/bg-product.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
public/image/comment-logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/image/header-bg-2.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
public/image/icon-arrow.png
Normal file
|
After Width: | Height: | Size: 218 B |
BIN
public/image/sprite.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
public/image/star-icon.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
public/image/star_rating.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
105
src/api/apiService.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { ArticleDataType } from "@/types/article";
|
||||
import { ProductDataType } from "@/types/products";
|
||||
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:5000";
|
||||
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
||||
type QueryValue = string | number | boolean | null | undefined;
|
||||
type QueryParams = Record<string, QueryValue | QueryValue[]>;
|
||||
|
||||
interface RequestOptions<TBody = unknown> {
|
||||
method?: HttpMethod;
|
||||
params?: QueryParams;
|
||||
body?: TBody;
|
||||
signal?: AbortSignal;
|
||||
cache?: RequestCache;
|
||||
next?: NextFetchRequestConfig;
|
||||
}
|
||||
|
||||
export interface ListParams extends QueryParams {
|
||||
limit?: number; // THÊM limit
|
||||
page?: number;
|
||||
offset?: number;
|
||||
q?: string; // tuỳ chọn (search)
|
||||
sort?: string;
|
||||
categoryId?: number | string;
|
||||
}
|
||||
|
||||
function buildURL(path: string, params?: QueryParams) {
|
||||
const url = new URL(path, BASE_URL);
|
||||
if (params) {
|
||||
for (const [k, v] of Object.entries(params)) {
|
||||
if (Array.isArray(v)) {
|
||||
v.forEach((vv) => {
|
||||
if (vv !== undefined && vv !== null) url.searchParams.append(k, String(vv));
|
||||
});
|
||||
} else if (v !== undefined && v !== null) {
|
||||
url.searchParams.set(k, String(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
async function apiRequest<TResp = unknown, TBody = unknown>(
|
||||
endpoint: string,
|
||||
options: RequestOptions<TBody> = {}
|
||||
): Promise<TResp> {
|
||||
const {
|
||||
method = "GET",
|
||||
params,
|
||||
body,
|
||||
signal,
|
||||
cache = "no-store",
|
||||
next,
|
||||
} = options;
|
||||
|
||||
const url = buildURL(endpoint, params);
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: body && method !== "GET" ? JSON.stringify(body) : undefined,
|
||||
signal,
|
||||
cache,
|
||||
next,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const msg = await res.text().catch(() => res.statusText);
|
||||
throw new Error(`API ${method} ${endpoint} failed: ${res.status} ${msg}`);
|
||||
}
|
||||
return res.json() as Promise<TResp>;
|
||||
}
|
||||
|
||||
// API cho bài viết
|
||||
export const fetchListArticles = (params?: ListParams) =>
|
||||
apiRequest<{ list: ArticleDataType[]; total?: number }>("/article", {
|
||||
params,
|
||||
});
|
||||
|
||||
// GET /articleDetails?path=:slug
|
||||
export const fetchArticleDetail = (slug: string) =>
|
||||
apiRequest<ArticleDataType>("/articleDetails", {
|
||||
params: { path: slug },
|
||||
});
|
||||
|
||||
// API cho công việc
|
||||
export const fetchListProduct = (params?: ListParams) =>
|
||||
apiRequest<{ list: ProductDataType[]; total?: number }>("/product", {
|
||||
params,
|
||||
});
|
||||
export const fetchProductDetail = (slug: string) =>
|
||||
apiRequest<ProductDataType>("/productDetails", {
|
||||
params: { path: slug },
|
||||
});
|
||||
|
||||
|
||||
export const fetchProductsByCategoryId = (
|
||||
categoryId: number | string,
|
||||
params?: Omit<ListParams, "categoryId">
|
||||
) =>
|
||||
fetchListProduct({
|
||||
...params,
|
||||
categoryId,
|
||||
});
|
||||
85
src/app/[category]/page.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import page_category from "../../../data/page_category.json";
|
||||
|
||||
const PageCategory = () => {
|
||||
return (
|
||||
<div className="product-page container">
|
||||
<div className="global-breadcrumb">
|
||||
<ol className="ul clearfix">
|
||||
<li>
|
||||
<Link href="/" className="nopad-l">
|
||||
<span>Trang chủ</span>
|
||||
</Link>
|
||||
</li>
|
||||
{page_category.current_category.path.path.map((path, index) => (
|
||||
<li key={index}>
|
||||
<Link href={path.url} className="nopad-l">
|
||||
<span>{path.name}</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{Array.isArray(page_category.current_category.children) &&
|
||||
page_category.current_category.children.length > 0 ? (
|
||||
<div className="child-collection-group bg-white">
|
||||
{page_category.current_category.children.map((cate) => (
|
||||
<Link key={cate.id} href={cate.url}>
|
||||
{cate.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
<div className="product-col-group d-flex flex-wrap">
|
||||
<div className="col-left filter-group">
|
||||
<div className="bg-white"></div>
|
||||
</div>
|
||||
|
||||
<div className="col-right">
|
||||
<div className="title-group d-flex flex-wrap align-items-center justify-content-between">
|
||||
<div className="font-600">
|
||||
<h2 className="title">{page_category.current_category.name}</h2>
|
||||
<span> (Tổng {page_category.product_count} sản phẩm)</span>
|
||||
</div>
|
||||
|
||||
<div className="sort-by-group d-flex align-items-center">
|
||||
<select>
|
||||
<option value="{{ page.current_category.request_path }}">
|
||||
Sắp xếp theo
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<Link
|
||||
href="javascript:void(0)"
|
||||
className="{% if global.user_settings.product_display_type == 'grid' %}active{% endif %} fa fa-th-large"
|
||||
></Link>
|
||||
<Link
|
||||
href="javascript:void(0)"
|
||||
className="{% if global.user_settings.product_display_type == 'list' %}active{% endif %} fa fa-th-list"
|
||||
></Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-container {% if global.user_settings.product_display_type == 'list' %} p-container-list {% endif %}"></div>
|
||||
|
||||
<div className="paging">
|
||||
<a href="{{ _item.url }}" className="active"></a>
|
||||
</div>
|
||||
|
||||
<div className="tag-group">
|
||||
<a href="">
|
||||
<i className="fa fa-tag"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageCategory;
|
||||
|
Before Width: | Height: | Size: 25 KiB |
@@ -1,26 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
101
src/app/homepage/ArticleHome.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { Navigation, Scrollbar } from "swiper/modules";
|
||||
import { ArticleDataType } from "@/types/article";
|
||||
import { fetchListArticles } from "@/api/apiService";
|
||||
import ItemArticle from "@/components/article/itemArticle";
|
||||
|
||||
type ArticleListResp = { list: ArticleDataType[]; total?: number };
|
||||
|
||||
export default function ArticleHome() {
|
||||
const [articletList, setProductList] = useState<ArticleListResp | null>(null);
|
||||
const [loadingUi, setLoadingUI] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const getProductList = async () => {
|
||||
try {
|
||||
const data = await fetchListArticles({ _limit: 10, _page: 1 });
|
||||
setProductList(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch jobs:", error);
|
||||
} finally {
|
||||
setLoadingUI(false);
|
||||
}
|
||||
};
|
||||
getProductList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="bg-white" id="js-home-art-container">
|
||||
<div
|
||||
className="container global-footer-art d-flex flex-wrap"
|
||||
style={{ padding: "24px 6px 33px 6px" }}
|
||||
>
|
||||
<div className="item-left">
|
||||
<h2 className="title">TIN NỔI BẬT TRONG NGÀY</h2>
|
||||
|
||||
<div className="d-flex flex-wrap" style={{ minHeight: "360px" }}>
|
||||
{articletList &&
|
||||
Array.isArray(articletList) &&
|
||||
articletList.length > 0 ? (
|
||||
<div className="big-item footer-art-big" id="js-featured-big">
|
||||
{articletList.slice(0, 1).map((article) => (
|
||||
<div key={article.id}>
|
||||
<ItemArticle article={article} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="big-item footer-art-big text-center text-2xl py-[50px] font-bold italic">
|
||||
Danh sách tin tức đang cập nhật
|
||||
</div>
|
||||
)}
|
||||
|
||||
{articletList &&
|
||||
Array.isArray(articletList) &&
|
||||
articletList.length > 0 ? (
|
||||
<div className="small-items">
|
||||
{articletList.slice(1, 5).map((article) => (
|
||||
<ItemArticle key={article.id} article={article} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="big-item footer-art-big text-center text-2xl py-[50px] font-bold italic">
|
||||
Danh sách tin tức đang cập nhật
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item-right">
|
||||
<h2 className="title">TIN KHUYẾN MÃI</h2>
|
||||
{articletList &&
|
||||
Array.isArray(articletList) &&
|
||||
articletList.length > 0 ? (
|
||||
<div className="footer-art-big">
|
||||
<Swiper
|
||||
modules={[Navigation, Scrollbar]}
|
||||
navigation
|
||||
loop
|
||||
autoplay
|
||||
spaceBetween={10}
|
||||
slidesPerView={1}
|
||||
>
|
||||
{articletList.map((article) => (
|
||||
<SwiperSlide key={article.id}>
|
||||
<ItemArticle article={article} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
) : (
|
||||
<div className="big-item footer-art-big text-center text-2xl py-[50px] font-bold italic">
|
||||
Danh sách tin tức đang cập nhật
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
80
src/app/homepage/BoxGroupProductCategory.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { Navigation, Scrollbar } from "swiper/modules";
|
||||
import component from "../../../data/component.json";
|
||||
import { fetchListProduct } from "@/api/apiService";
|
||||
import ProductItemSlider from "@/components/product/ProductItemSlider";
|
||||
import { ProductDataType } from "@/types/products";
|
||||
|
||||
type ProductListResp = { list: ProductDataType[]; total?: number };
|
||||
|
||||
export default function BoxGroupProductCategory() {
|
||||
const [productList, setProductList] = useState<ProductListResp | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const getProductList = async () => {
|
||||
try {
|
||||
const data = await fetchListProduct({ _limit: 10, _page: 1 });
|
||||
setProductList(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch jobs:", error);
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
getProductList();
|
||||
}, []);
|
||||
|
||||
const featuredCategories =
|
||||
component.product.all_category?.filter((c) => c.is_featured == "1") ?? [];
|
||||
|
||||
return (
|
||||
<div className="box-group-category">
|
||||
{featuredCategories.map((component) => (
|
||||
<div className="home-product-group" key={component.id}>
|
||||
<div className="title-group text-uppercase d-flex align-items-center justify-content-between">
|
||||
<div className="d-flex align-items-center gap-[10px]">
|
||||
<h2 className="title">{component.title}</h2>
|
||||
{component.children.slice(0, 3).map((children) => (
|
||||
<Link href={children.url} key={children.id}>
|
||||
<h3>{children.title}</h3>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="blue d-flex align-items-center gap-[5px]">
|
||||
<Link href={component.url} className="">
|
||||
XEM THÊM
|
||||
</Link>
|
||||
<i className="fa-solid fa-right-long"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div className="home-product-holder">
|
||||
{productList &&
|
||||
Array.isArray(productList) &&
|
||||
productList.length > 0 ? (
|
||||
<Swiper
|
||||
modules={[Navigation, Scrollbar]}
|
||||
navigation
|
||||
loop
|
||||
spaceBetween={10}
|
||||
slidesPerView={5}
|
||||
>
|
||||
{productList.map((product) => (
|
||||
<SwiperSlide key={product.id}>
|
||||
<ProductItemSlider product={product} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
) : (
|
||||
<div className="text-center text-2xl py-[50px] font-bold italic">
|
||||
Danh sách sản phẩm đang cập nhật
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
112
src/app/homepage/ListProductBestSale.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { Navigation, Scrollbar } from "swiper/modules";
|
||||
import { fetchListProduct } from "@/api/apiService";
|
||||
import ProductItemSlider from "@/components/product/ProductItemSlider";
|
||||
import { ProductDataType } from "@/types/products";
|
||||
|
||||
type ProductListResp = { list: ProductDataType[]; total?: number };
|
||||
|
||||
export default function ListProductBestSale() {
|
||||
const [productList, setProductList] = useState<ProductListResp | null>(null);
|
||||
const [loadingUi, setLoadingUI] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const getProductList = async () => {
|
||||
try {
|
||||
const data = await fetchListProduct({ _limit: 10, _page: 1 });
|
||||
setProductList(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch jobs:", error);
|
||||
} finally {
|
||||
setLoadingUI(false);
|
||||
}
|
||||
};
|
||||
getProductList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="home-product-bestsale-container lazy"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/static/assets/htpstore/images/home-product-bg.png")',
|
||||
}}
|
||||
id="js-bestsale-container"
|
||||
>
|
||||
<div className="text-center text-uppercase titlt-group">
|
||||
<h2 className="title">TOP SẢN PHẨM BÁN CHẠY</h2>
|
||||
|
||||
<div className="pro-cat-list">
|
||||
<a href="">
|
||||
<h3>pc gaming</h3>
|
||||
</a>
|
||||
<a href="">
|
||||
<h3>laptop gaming</h3>
|
||||
</a>
|
||||
<a href="">
|
||||
<h3>máy in canon</h3>
|
||||
</a>
|
||||
<a href="">
|
||||
<h3>màn hình máy tính</h3>
|
||||
</a>
|
||||
<a href="">
|
||||
<h3>màn hình gaming</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loadingUi ? (
|
||||
<div
|
||||
id="js-bestsale-holder"
|
||||
style={{ minHeight: "390px", position: "relative" }}
|
||||
>
|
||||
{[...Array(4)].map((_, index) => (
|
||||
<div className="item-job" key={index}>
|
||||
<div className="job-left flex items-center">
|
||||
<div className="name line-clamp-1 bg-gray-200 h-[21px] w-[300px] mr-[15px] animate-pulse"></div>
|
||||
<div className="time bg-gray-200 h-[20px] w-[120px] block animate-pulse"></div>
|
||||
</div>
|
||||
<div className="job-right flex items-center">
|
||||
<div className="localhost bg-gray-200 h-[21px] w-[60px] mr-[20px] block animate-pulse"></div>
|
||||
<div className="more bg-gray-200 h-[21px] block w-[120px] animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
id="js-bestsale-holder"
|
||||
style={{ minHeight: "390px", position: "relative" }}
|
||||
>
|
||||
{productList &&
|
||||
Array.isArray(productList) &&
|
||||
productList.length > 0 ? (
|
||||
<Swiper
|
||||
modules={[Navigation, Scrollbar]}
|
||||
navigation
|
||||
loop
|
||||
spaceBetween={10}
|
||||
slidesPerView={5}
|
||||
>
|
||||
{productList.map((product) => (
|
||||
<SwiperSlide key={product.id}>
|
||||
<ProductItemSlider product={product} />
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
) : (
|
||||
<div className="text-center text-2xl py-[50px] font-bold italic">
|
||||
Danh sách sản phẩm đang cập nhật
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<a href="/san-pham-ban-chay" className="view-more">
|
||||
XEM THÊM <i className="fa fa-long-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
47
src/app/homepage/slider.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import { Autoplay, Pagination } from "swiper/modules";
|
||||
|
||||
const slides = [
|
||||
{
|
||||
href: "/",
|
||||
src: "https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png",
|
||||
alt: "Banner 1",
|
||||
},
|
||||
{
|
||||
href: "/",
|
||||
src: "https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png",
|
||||
alt: "Banner 2",
|
||||
},
|
||||
];
|
||||
|
||||
export default function HomeSlider() {
|
||||
return (
|
||||
<div id="js-home-slider" className="slider-group">
|
||||
<Swiper
|
||||
modules={[Autoplay, Pagination]}
|
||||
autoplay={{ delay: 3000, disableOnInteraction: false }}
|
||||
pagination={{ clickable: true }}
|
||||
loop
|
||||
slidesPerView={1}
|
||||
className="custom-dots"
|
||||
>
|
||||
{slides.map((s, i) => (
|
||||
<SwiperSlide key={i} className="item">
|
||||
<a href={s.href} aria-label={s.alt}>
|
||||
{/* Dùng <img> để không phụ thuộc cấu hình next/image */}
|
||||
<img
|
||||
src={s.src} // Đặt file ảnh vào /public/
|
||||
width={692}
|
||||
height={492}
|
||||
alt={s.alt}
|
||||
loading="lazy"
|
||||
style={{ display: "block", width: "100%", height: "auto" }}
|
||||
/>
|
||||
</a>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import "@fortawesome/fontawesome-free/css/all.min.css";
|
||||
import { Mulish } from "next/font/google";
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import "@/styles/style.css";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
const mulish = Mulish({
|
||||
subsets: ["latin", "vietnamese"],
|
||||
display: "swap",
|
||||
variable: "--font-mulish",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -23,11 +23,14 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
<html
|
||||
suppressHydrationWarning
|
||||
className={`${mulish.variable} font-sans antialiased`}
|
||||
>
|
||||
<body>
|
||||
<Header />
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
175
src/app/page.tsx
@@ -1,103 +1,90 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import HomeSlider from "./homepage/slider";
|
||||
import ListProductBestSale from "./homepage/ListProductBestSale";
|
||||
import BoxGroupProductCategory from "./homepage/BoxGroupProductCategory";
|
||||
import ArticleHome from "./homepage/ArticleHome";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
|
||||
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js logo"
|
||||
width={180}
|
||||
height={38}
|
||||
priority
|
||||
/>
|
||||
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
|
||||
<li className="mb-2 tracking-[-.01em]">
|
||||
Get started by editing{" "}
|
||||
<code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
|
||||
src/app/page.tsx
|
||||
</code>
|
||||
.
|
||||
</li>
|
||||
<li className="tracking-[-.01em]">
|
||||
Save and see your changes instantly.
|
||||
</li>
|
||||
</ol>
|
||||
<div className="homepage">
|
||||
<div className="container">
|
||||
<div className="home-banner-group hover-img">
|
||||
<HomeSlider />
|
||||
|
||||
<div className="flex gap-4 items-center flex-col sm:flex-row">
|
||||
<a
|
||||
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="dark:invert"
|
||||
src="/vercel.svg"
|
||||
alt="Vercel logomark"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
Deploy now
|
||||
</a>
|
||||
<a
|
||||
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Read our docs
|
||||
</a>
|
||||
<div className="banner-right-group">
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png"
|
||||
width="692"
|
||||
height="492"
|
||||
alt="Banner"
|
||||
className="lazy"
|
||||
/>
|
||||
</Link>
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png"
|
||||
width="692"
|
||||
height="492"
|
||||
alt="Banner"
|
||||
className="lazy"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/file.svg"
|
||||
alt="File icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Learn
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/window.svg"
|
||||
alt="Window icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Examples
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
||||
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
aria-hidden
|
||||
src="/globe.svg"
|
||||
alt="Globe icon"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Go to nextjs.org →
|
||||
</a>
|
||||
</footer>
|
||||
<div className="home-banner-under hover-img">
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png"
|
||||
width="692"
|
||||
height="492"
|
||||
alt="Banner"
|
||||
className="lazy"
|
||||
/>
|
||||
</Link>
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png"
|
||||
width="692"
|
||||
height="492"
|
||||
alt="Banner"
|
||||
className="lazy"
|
||||
/>
|
||||
</Link>
|
||||
<Link href="/">
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/demopc8-banner-slider-homepage-test-1.png"
|
||||
width="692"
|
||||
height="492"
|
||||
alt="Banner"
|
||||
className="lazy"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<ListProductBestSale />
|
||||
|
||||
<BoxGroupProductCategory />
|
||||
|
||||
{/* <div className="home-product-group">
|
||||
<div className="title-group text-uppercase clearfix">
|
||||
<h2 className="title">{{ _item.title }}</h2>
|
||||
|
||||
<div>
|
||||
{% for _item_child in _item.children | limit: 4 %}{% if _item_child.is_featured == 1 %}
|
||||
<a href="{{ _item_child.url }}"><h3>{{ _item_child.title }}</h3></a>
|
||||
{% endif %}{% endfor %}
|
||||
|
||||
<a href="{{ _item.url }}" className="blue">XEM THÊM <i className="fa fa-long-arrow-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="home-product-holder" id="js-product-{{ _item.id }}"><!-- ajax --> </div>
|
||||
</div> */}
|
||||
|
||||
<ArticleHome />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
300
src/components/Footer.tsx
Normal file
@@ -0,0 +1,300 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
export default function GlobalFooter() {
|
||||
// Newsletter state
|
||||
const [email, setEmail] = useState("");
|
||||
const [sending, setSending] = useState(false);
|
||||
const [sent, setSent] = useState<null | "ok" | "err">(null);
|
||||
|
||||
// So sánh sản phẩm (demo): danh sách id đang chọn
|
||||
const [compareOpen, setCompareOpen] = useState(false);
|
||||
const compareItems = useMemo<string[]>(() => [], []); // TODO: truyền từ props hoặc context
|
||||
|
||||
const subscribeNewsletter = useCallback(async () => {
|
||||
if (!email.trim()) return;
|
||||
try {
|
||||
setSending(true);
|
||||
// TODO: gọi API thực tế của bạn ở đây
|
||||
// await fetch("/api/newsletter", { method: "POST", body: JSON.stringify({ email }) });
|
||||
await new Promise((r) => setTimeout(r, 600));
|
||||
setSent("ok");
|
||||
setEmail("");
|
||||
} catch {
|
||||
setSent("err");
|
||||
} finally {
|
||||
setSending(false);
|
||||
}
|
||||
}, [email]);
|
||||
|
||||
const compareClose = useCallback(() => setCompareOpen(false), []);
|
||||
const compareLink = useCallback(() => {
|
||||
// TODO: điều hướng đến trang so sánh thực tế, ví dụ: /so-sanh?ids=1,2,3
|
||||
// router.push(`/so-sanh?ids=${compareItems.join(",")}`);
|
||||
alert("Đi đến trang so sánh (demo).");
|
||||
}, [compareItems]);
|
||||
|
||||
const goTop = useCallback(() => {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}, []);
|
||||
|
||||
// Ví dụ: tự mở khối so sánh khi có item
|
||||
useEffect(() => {
|
||||
if (compareItems.length > 0) setCompareOpen(true);
|
||||
}, [compareItems]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="global-footer-container bg-white">
|
||||
{/* Newsletter */}
|
||||
<div className="footer-newsletter-group text-white">
|
||||
<p className="text-20 font-800 text-center">
|
||||
ĐĂNG KÝ NHẬN EMAIL THÔNG BÁO KHUYẾN MẠI HOẶC ĐỂ ĐƯỢC TƯ VẤN MIỄN PHÍ
|
||||
</p>
|
||||
|
||||
<div className="newsletter-form position-relative">
|
||||
<input
|
||||
type="email"
|
||||
id="js-email-newsletter"
|
||||
className="newsletter-input"
|
||||
placeholder="Nhập email của bạn"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
onKeyDown={(e) => e.key === "Enter" && subscribeNewsletter()}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={subscribeNewsletter}
|
||||
disabled={sending}
|
||||
>
|
||||
{sending ? "ĐANG GỬI..." : "GỬI"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{sent === "ok" && (
|
||||
<p className="text-center mt-2" role="status">
|
||||
Đăng ký thành công!
|
||||
</p>
|
||||
)}
|
||||
{sent === "err" && (
|
||||
<p className="text-center mt-2 text-danger" role="alert">
|
||||
Có lỗi xảy ra, vui lòng thử lại.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Social / policies */}
|
||||
<div className="footer-social-group container text-15 font-300">
|
||||
<div className="row">
|
||||
<div className="col-3 d-flex flex-wrap align-items-center">
|
||||
<i className="icons icon-truck" aria-hidden />
|
||||
<p className="text">
|
||||
<b>CHÍNH SÁCH GIAO HÀNG</b>
|
||||
<span>Nhận hàng và thanh toán tại nhà</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="col-3 d-flex flex-wrap align-items-center">
|
||||
<i className="icons icon-trade" aria-hidden />
|
||||
<p className="text">
|
||||
<b>ĐỔI TRẢ DỄ DÀNG</b>
|
||||
<span>Dùng thử trong vòng 3 ngày</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="col-3 d-flex flex-wrap align-items-center">
|
||||
<i className="icons icon-payment" aria-hidden />
|
||||
<p className="text">
|
||||
<b>THANH TOÁN TIỆN LỢI</b>
|
||||
<span>Trả tiền mặt, CK, trả góp 0%</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="col-3 d-flex flex-wrap align-items-center">
|
||||
<i className="icons icon-comment" aria-hidden />
|
||||
<p className="text">
|
||||
<b>HỖ TRỢ NHIỆT TÌNH</b>
|
||||
<span>Tư vấn, giải đáp mọi thắc mắc</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Info columns */}
|
||||
<div className="footer-info-group">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-3">
|
||||
<p className="title">GIỚI THIỆU HTPSTORE</p>
|
||||
<div className="info-list">
|
||||
<Link href="/gioi-thieu">Giới thiệu công ty</Link>
|
||||
<Link href="/lien-he">Thông tin liên hệ</Link>
|
||||
<Link href="/tuyen-dung">Thông tin tuyển dụng</Link>
|
||||
<Link href="/tin-tuc">Tin tức</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-3">
|
||||
<p className="title">HỖ TRỢ KHÁCH HÀNG</p>
|
||||
<div className="info-list">
|
||||
<Link href="/huong-dan-mua-hang-truc-tuyen">
|
||||
Hướng dẫn mua hàng trực tuyến
|
||||
</Link>
|
||||
<Link href="/huong-dan-thanh-toan">Hướng dẫn thanh toán</Link>
|
||||
<Link href="/huong-dan-mua-hang-tra-gop">
|
||||
Hướng dẫn mua hàng trả góp
|
||||
</Link>
|
||||
<Link href="/in-hoa-don-dien-tu">In hóa đơn điện tử</Link>
|
||||
<Link href="/gui-yeu-cau-bao-hanh">Gửi yêu cầu bảo hành</Link>
|
||||
<Link href="/gop-y-khieu-nai">Góp ý, Khiếu Nại</Link>
|
||||
|
||||
<Link href="/?show_version=mobile" className="view-mobile">
|
||||
Xem giao diện bản mobile
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-3">
|
||||
<p className="title">CHÍNH SÁCH CHUNG</p>
|
||||
<div className="info-list">
|
||||
<Link href="/chinh-sach-quy-dinh-chung">
|
||||
Chính sách, quy định chung
|
||||
</Link>
|
||||
<Link href="/chinh-sach-van-chuyen">
|
||||
Chính sách vận chuyển
|
||||
</Link>
|
||||
<Link href="/chinh-sach-bao-hanh">Chính sách bảo hành</Link>
|
||||
<Link href="/chinh-sach-doi-tra-va-hoan-tien">
|
||||
Chính sách đổi trả và hoàn tiền
|
||||
</Link>
|
||||
<Link href="/chinh-sach-hang-chinh-hang">
|
||||
Chính sách hàng chính hãng
|
||||
</Link>
|
||||
<Link href="/bao-mat-thong-tin-khach-hang">
|
||||
Bảo mật thông tin khách hàng
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-3">
|
||||
<p className="title">THÔNG TIN KHUYẾN MẠI</p>
|
||||
<div className="info-list">
|
||||
<Link href="/khuyen-mai">Thông tin khuyến mại</Link>
|
||||
<Link href="/san-pham-xa-hang">Sản phẩm khuyến mại</Link>
|
||||
<Link href="/san-pham-ban-chay">Sản phẩm bán chạy</Link>
|
||||
<Link href="/san-pham-moi">Sản phẩm mới</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Copyright */}
|
||||
<div className="container" style={{ padding: "30px 10px" }}>
|
||||
<p style={{ color: "#0033CC", fontWeight: 300, margin: 0 }}>
|
||||
© 2021 HTPSTORE. All rights reserved
|
||||
<br />
|
||||
Công Ty TNHH Thương Mại Và Phát Triển Công Nghệ Hưng Thịnh Phát
|
||||
<br />
|
||||
Địa chỉ: Tòa Hope Residences H5-TM3, Số 1 Nguyễn Lam, Phường Phúc
|
||||
Đồng, Quận Long Biên, Thành phố Hà Nội.
|
||||
<br />
|
||||
Giấy phép đăng ký kinh doanh: 0109802587 do Sở Kế Hoạch và Đầu Tư
|
||||
Tp.Hà Nội cấp
|
||||
<br />
|
||||
Email:{" "}
|
||||
<a href="mailto:linhbk@htpstore.com.vn">linhbk@htpstore.com.vn</a>.
|
||||
Điện thoại: 0243.206.8456 - Hotline: 0965.530.489
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Thông báo thành công (ẩn/hiện bằng state nếu cần) */}
|
||||
<div className="success-form" style={{ display: "none" }}>
|
||||
<div className="content-container">
|
||||
<div className="success-checkmark">
|
||||
<div className="check-icon">
|
||||
<span className="icon-line line-tip"></span>
|
||||
<span className="icon-line line-long"></span>
|
||||
<div className="icon-circle"></div>
|
||||
<div className="icon-fix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center content-text text-24">
|
||||
Thêm sản phẩm vào giỏ hàng thành công!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* So sánh sản phẩm */}
|
||||
{compareOpen && (
|
||||
<div className="global-compare-group">
|
||||
<div className="title text-22 text-white d-flex align-items-center justify-content-between font-600">
|
||||
<p className="m-0">SO SÁNH SẢN PHẨM</p>
|
||||
<button
|
||||
type="button"
|
||||
className="close-compare text-white fa fa-times"
|
||||
onClick={compareClose}
|
||||
aria-label="Đóng so sánh"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="text-center red mt-2 text-18 font-500"
|
||||
id="js-alert"
|
||||
></div>
|
||||
|
||||
<div className="pro-compare-holder">
|
||||
<div className="compare-pro-holder clearfix" id="js-compare-holder">
|
||||
{/* TODO: render danh sách sản phẩm so sánh ở đây */}
|
||||
</div>
|
||||
<button type="button" className="btn-compare" onClick={compareLink}>
|
||||
SO SÁNH
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tooltip container (tuỳ logic, bạn có thể render portal) */}
|
||||
<div id="tooltip" />
|
||||
|
||||
{/* Fixed right buttons */}
|
||||
<div className="global-fixed-right">
|
||||
<a
|
||||
href="#"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="fa fa-facebook"
|
||||
aria-label="Facebook"
|
||||
/>
|
||||
<a
|
||||
href="#"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="fa fa-youtube-play"
|
||||
aria-label="YouTube"
|
||||
/>
|
||||
<Link
|
||||
href="/lien-he"
|
||||
target="_blank"
|
||||
className="fa fa-envelope"
|
||||
aria-label="Liên hệ"
|
||||
/>
|
||||
<Link
|
||||
href="/gioi-thieu"
|
||||
target="_blank"
|
||||
className="fa fa-comment"
|
||||
aria-label="Giới thiệu"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="fa fa-angle-up"
|
||||
id="js-goTop"
|
||||
aria-label="Lên đầu trang"
|
||||
onClick={goTop}
|
||||
style={{ background: "transparent", border: 0, cursor: "pointer" }}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
945
src/components/Header.tsx
Normal file
@@ -0,0 +1,945 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
export type Category = {
|
||||
id?: string | number;
|
||||
url: string;
|
||||
title: string;
|
||||
thumbnail?: string; // tương đương _item.thumnail
|
||||
children?: Category[]; // cấp 2 -> cấp 3 -> cấp 4
|
||||
};
|
||||
|
||||
export default function GlobalHeader() {
|
||||
const pathname = usePathname();
|
||||
const isHome = pathname === "/" || pathname === "";
|
||||
return (
|
||||
<>
|
||||
<div className="global-header-container">
|
||||
<div className="header-top-group">
|
||||
<div className="container d-flex align-items-center justify-content-between text-13 position-relative">
|
||||
<div className="item-left">
|
||||
<a
|
||||
href={`tel:0243.206.8456`}
|
||||
className="bg-linear d-inline-block"
|
||||
>
|
||||
<i className="fa fa-phone fa-rotate-270" /> CSKHL{" "}
|
||||
<b>0243.206.8456</b>
|
||||
</a>
|
||||
|
||||
<div className="header-support d-inline-block">
|
||||
<p className="bg-linear m-0">
|
||||
<i className="fa fa-headphones" /> Hỗ trợ khách hàng
|
||||
</p>
|
||||
{/* include 'other/header_hotline' → thay bằng block custom nếu cần */}
|
||||
<div className="header-hotline-dropdown">
|
||||
{/* bạn có thể render danh sách hotline tại đây */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item-right">
|
||||
<Link href="/san-pham-da-xem">
|
||||
<i className="fa fa-check" /> Sản phẩm đã xem
|
||||
</Link>
|
||||
<Link href="/tin-tuc">
|
||||
<i className="fa-solid fa-newspaper" /> Tin tức nổi bật
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="global-header-main-container">
|
||||
<div className="container header-main-group position-relative">
|
||||
<div className="header-middle-group d-flex flex-wrap align-items-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="logo text-center block"
|
||||
aria-label="Trang chủ"
|
||||
>
|
||||
{/* Bạn có thể dùng <img> thường nếu không muốn cấu hình next/image */}
|
||||
<Image
|
||||
src="https://demopc8.hurasoft.com/static/assets/htpstore/images/logo_logo.png"
|
||||
alt="Logo"
|
||||
width={190}
|
||||
height={79}
|
||||
className="inline-block h-auto w-auto"
|
||||
priority
|
||||
/>
|
||||
</Link>
|
||||
|
||||
{/* Search */}
|
||||
<div className="header-search-group position-relative">
|
||||
<form
|
||||
method="get"
|
||||
action="/tim"
|
||||
name="search"
|
||||
className="bg-white d-block position-relative overflow-hidden"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="js-seach-input"
|
||||
name="q"
|
||||
placeholder="Nhập tên sản phẩm, từ khóa cần tìm."
|
||||
autoComplete="off"
|
||||
className="text-search"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-search fa fa-search"
|
||||
aria-label="Tìm kiếm"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<div
|
||||
className="autocomplete-suggestions"
|
||||
id="js-seach-result"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Right info */}
|
||||
<div className="header-right-group d-flex align-items-center justify-content-between text-15 font-300 text-white">
|
||||
<div className="item">
|
||||
<i className="icons icon-phone" />
|
||||
<p className="text">
|
||||
<span>Hotline</span>
|
||||
<b className="text-18 d-block font-800">0965.530.489</b>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<i className="icons icon-user" />
|
||||
<p className="text">
|
||||
<Link href="/dang-ky">Đăng ký</Link>
|
||||
<Link href="/dang-nhap">Đăng nhập</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Link href="/cart" className="item item-cart">
|
||||
<i className="icons icon-cart" />
|
||||
<span className="cart-count js-cart-count">0</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="header-bottom-group d-flex flex-wrap align-items-center">
|
||||
{/* Category Menu */}
|
||||
<div className="header-menu-group ">
|
||||
<p className="title text-18 font-700 text-white m-0 text-center">
|
||||
<i className="fa fa-bars" /> DANH MỤC SẢN PHẨM
|
||||
</p>
|
||||
<div
|
||||
className={`menu-holder ${!isHome ? "menu-other-page" : ""}`}
|
||||
>
|
||||
<div className="item">
|
||||
<a href="/man-hinh-may-tinh" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_9_1688117425.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_9_1688117425.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Màn Hình Máy Tính</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/man-hinh-theo-kich-thuoc" className="cat-2">
|
||||
Màn Hình Theo Kích Thước
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-may-tinh-17-inch-21-inch">
|
||||
17 inch - 21.5 inch
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-may-tinh-22-inch-24-inch">
|
||||
22 inch - 24 inch
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-may-tinh-25-inch-27-inch">
|
||||
25 inch - 27 inch
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-may-tinh-28-inch-32-inch">
|
||||
28 inch - 32 inch
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-may-tinh-32-inch-49-inch">
|
||||
32 inch - 49 inch
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/man-hinh-theo-hang" className="cat-2">
|
||||
Màn Hình Theo Hãng
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-benq">Màn Hình BenQ</a>
|
||||
|
||||
<div className="cat-4-holder">
|
||||
<a href="/ben-q-hang">Ben Q Hãng</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-lg">Màn Hình LG</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-viewsonic">Màn Hình Viewsonic</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-samsung">Màn Hình Samsung</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-hkc">Màn Hình HKC</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-dell">Màn Hình Dell</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-hp">Màn Hình HP</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-asus">Màn Hình Asus</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-aoc">Màn Hình AOC</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/man-hinh-theo-nhu-cau" className="cat-2">
|
||||
Màn Hình Theo Nhu Cầu
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-choi-game">Màn Hình Chơi Game</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-do-hoa-thiet-ke">
|
||||
Màn Hình Đồ Họa,Thiết Kế
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/man-hinh-van-phong">Màn Hình Văn Phòng</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/pc-workstation" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_1_1663215484.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_1_1663215484.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">PC, Workstation</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a
|
||||
href="/hoang-ha-workstation-intel-core-i7-i9"
|
||||
className="cat-2"
|
||||
>
|
||||
HH WORKSTATION - INTEL CORE
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a
|
||||
href="/hoang-ha-workstation-intel-xeon"
|
||||
className="cat-2"
|
||||
>
|
||||
HH WORKSTATION - INTEL XEON
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a
|
||||
href="/hoang-ha-workstation-amd-ryzen"
|
||||
className="cat-2"
|
||||
>
|
||||
HH WORKSTATION - AMD RYZEN
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a
|
||||
href="/hhpc-workstation-render-edit-video"
|
||||
className="cat-2"
|
||||
>
|
||||
WORKSTATION RENDER - VIDEO
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/server-may-ao-gia-lap" className="cat-2">
|
||||
SERVER - MÁY ẢO - GIẢ LẬP
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/pc-dong-bo" className="cat-2">
|
||||
MÁY TÍNH ĐỒNG BỘ
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/may-tinh-van-phong" className="cat-2">
|
||||
MÁY TÍNH VĂN PHÒNG
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/pc-gaming" className="cat-2">
|
||||
PC GAMING
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a
|
||||
href="/machine-learning-ai-tensorflow"
|
||||
className="cat-2"
|
||||
>
|
||||
MACHINE LEARNING / AI
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/gaming-gear" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_25_1663215532.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_25_1663215532.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Gaming Gear</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/ban-phim" className="cat-2">
|
||||
Bàn Phím
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/chuot-may-tinh" className="cat-2">
|
||||
Chuột Máy Tính
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/ban-di-chuot-gaming" className="cat-2">
|
||||
Bàn Di Chuột
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/tai-nghe" className="cat-2">
|
||||
Tai Nghe
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/ban-may-tinh" className="cat-2">
|
||||
Bàn Gaming
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/loa-vi-tinh" className="cat-2">
|
||||
Loa Vi Tính
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/ghe-game" className="cat-2">
|
||||
Ghế Gaming
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/phu-kien" className="cat-2">
|
||||
Phụ Kiện
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/thiet-bi-studio-stream" className="cat-2">
|
||||
Thiết Bị Studio, Stream
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/cpu-bo-vi-xu-ly" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_2_1663215326.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_2_1663215326.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">CPU - Bộ Vi Xử Lý</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/cpu-intel" className="cat-2">
|
||||
CPU Intel
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-intel-core-i3">Intel Core i3</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-intel-core-i5">Intel Core i5</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-intel-core-i7">Intel Core i7</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-intel-core-i9">Intel Core i9</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-intel-xeon">Intel Xeon</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/cpu-amd" className="cat-2">
|
||||
CPU AMD
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-amd-ryzen-3">AMD Ryzen 3</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-amd-ryzen-5">AMD Ryzen 5</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-amd-ryzen-7">AMD Ryzen 7</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/cpu-amd-ryzen-9">AMD Ryzen 9</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/amd-ryzen-threadripper">
|
||||
AMD Ryzen Threadripper
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/vga-card-man-hinh" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_6_1663215223.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_6_1663215223.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">VGA - Card Màn Hình</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/vga-nvidia" className="cat-2">
|
||||
VGA NVIDIA
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/gtx-1050-1050ti-series">
|
||||
NVIDIA GTX 1050/1050Ti
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/gtx-1060">NVIDIA GTX 1060</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/gtx-1660-1660ti-series">
|
||||
NVIDIA GTX 1660/1660Ti
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-gtx-1650">NVIDIA GTX 1650 / Super</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/rtx-2060">NVIDIA RTX 2060 / Super</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/rtx-2070">NVIDIA RTX 2070 / Super</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/rtx-2080">NVIDIA RTX 2080 / Super</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/rtx-2080ti">NVIDIA RTX 2080Ti</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-quadro">NVIDIA Quadro</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-rtx-3060-ti">NVIDIA RTX 3060 Ti</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-rtx-3070">NVIDIA RTX 3070</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-rtx-3080">NVIDIA RTX 3080</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/nvidia-rtx-3090">NVIDIA RTX 3090</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/vga-amd-radeon" className="cat-2">
|
||||
VGA AMD Radeon
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/main-bo-mach-chu" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_3_1663215458.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_3_1663215458.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Mainboard - Bo Mạch Chủ</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/mainboard-intel" className="cat-2">
|
||||
Mainboard Intel
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-b365">
|
||||
Mainboard Intel B365
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-b460">
|
||||
Mainboard Intel B460
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-z390">
|
||||
Mainboard Intel Z390
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-z490">
|
||||
Mainboard Intel Z490
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-c246">
|
||||
Mainboard Intel C246
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-x299">
|
||||
Mainboard Intel X299
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-intel-khac">
|
||||
Mainboard Intel Khác
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/mainboard-amd" className="cat-2">
|
||||
Mainboard AMD
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-b450">Mainboard AMD B450</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-x370">Mainboard AMD X370</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-x470">Mainboard AMD X470</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-x570">Mainboard AMD X570</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-x399">Mainboard AMD X399</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/mainboard-amd-trx40">Mainboard AMD TRX40</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/ram-bo-nho-trong" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_4_1663215185.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_4_1663215185.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">RAM - Bộ Nhớ Trong</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/ram-theo-hang" className="cat-2">
|
||||
Ram Theo Hãng
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/ram-corsair">RAM CORSAIR</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/ram-gskill">RAM GSKILL</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/ram-ecc">RAM SERVER ECC - REGISTERED</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/ram-team">RAM TEAM</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/ram-adata">RAM ADATA</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/hdd-ssd-nas" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_5_1663215160.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_5_1663215160.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">HDD - SSD - NAS</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/o-cung-hdd" className="cat-2">
|
||||
Ổ Cứng HDD
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/o-cung-the-ran-ssd" className="cat-2">
|
||||
Ổ Cứng Thể Rắn SSD
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/o-cung-di-dong-usb" className="cat-2">
|
||||
Ổ Cứng Di Động - USB
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/o-luu-tru-nas" className="cat-2">
|
||||
Ổ Lưu Trữ NAS
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/psu-nguon-may-tinh" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_7_1663214223.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_7_1663214223.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">PSU - Nguồn máy tính</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/case-vo-may-tinh" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_8_1663215125.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_8_1663215125.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Case - Vỏ Máy Tính</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/thiet-bi-mang" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_23_1663214442.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_23_1663214442.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Thiết Bị Mạng</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/thiet-bi-phat-wifi" className="cat-2">
|
||||
Thiết Bị Phát Wifi
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/asus">Bộ Phát Wifi Asus</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/bo-phat-wifi-linksys">
|
||||
Bộ Phát Wifi Linksys
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/thiet-bi-mang-tp-link">
|
||||
Bộ Phát Wifi TP-LINK
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/usb-card-mang" className="cat-2">
|
||||
USB - Card Mạng
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/usb-wifi">USB- Wifi</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/card-wifi">Card Wifi</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/card-lan">Card Lan</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/switch-bo-chia-mang" className="cat-2">
|
||||
Switch - Bộ Chia Mạng
|
||||
</a>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/toc-do-10-100-mbps">Tốc độ 10/100 Mbps</a>
|
||||
</div>
|
||||
|
||||
<div className="cat-3-holder">
|
||||
<a href="/toc-do-10-100-1000mbps">
|
||||
Tốc độ 10/100/1000Mbps
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/tan-nhiet-cooling" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_icon_24_1663214938.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_icon_24_1663214938.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Tản Nhiệt Cooling</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/tan-nhiet-cpu" className="cat-2">
|
||||
Tản Nhiệt Khí
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/quat-tan-nhiet" className="cat-2">
|
||||
Quạt Tản Nhiệt
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/tan-nhiet-nuoc-aio" className="cat-2">
|
||||
Tản Nhiệt Nước AIO
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="item">
|
||||
<a href="/phan-mem-ban-quyen" className="cat-1">
|
||||
<span
|
||||
className="cat-thumb lazy"
|
||||
data-bg="url('https://demopc8.hurasoft.com/media/category/cat_858ddc83e5347068f6ecf9b26713e49f.png')"
|
||||
data-was-processed="true"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'url("https://demopc8.hurasoft.com/media/category/cat_858ddc83e5347068f6ecf9b26713e49f.png")',
|
||||
}}
|
||||
></span>
|
||||
<span className="cat-title">Phần Mềm Bản Quyền</span>
|
||||
</a>
|
||||
|
||||
<div className="sub-menu">
|
||||
<div className="sub-item">
|
||||
<a href="/phan-mem-microsoft-windows" className="cat-2">
|
||||
Phần mềm Microsoft Windows
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/phan-mem-microsoft-office" className="cat-2">
|
||||
Phần mềm Microsoft Office
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="sub-item">
|
||||
<a href="/phan-mem-diet-virus" className="cat-2">
|
||||
Phần mềm diệt virus
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right USP list */}
|
||||
<div className="header-bottom-right d-flex flex-wrap align-items-center font-300 text-16">
|
||||
<Link href="" className="item" target="_blank">
|
||||
<i className="icons icon-warranty" />
|
||||
<span className="text">Bảo hành tận nơi</span>
|
||||
</Link>
|
||||
<Link href="" className="item" target="_blank">
|
||||
<i className="icons icon-ship" />
|
||||
<span className="text">Giao hàng toàn quốc</span>
|
||||
</Link>
|
||||
<Link href="" className="item" target="_blank">
|
||||
<i className="icons icon-payment" />
|
||||
<span className="text">Thanh toán tại nhà</span>
|
||||
</Link>
|
||||
<Link href="" className="item" target="_blank">
|
||||
<i className="icons icon-trade" />
|
||||
<span className="text">Đổi trả trong 3 ngày</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
62
src/components/article/itemArticle.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
type ArticleImage = { original: string; width?: number; height?: number };
|
||||
export type Article = {
|
||||
url: string;
|
||||
title: string;
|
||||
image?: ArticleImage | null;
|
||||
article_time?: string | null;
|
||||
createDate?: string | null;
|
||||
review_count?: number | null;
|
||||
visit?: number | null;
|
||||
};
|
||||
|
||||
type Props = { article: Article };
|
||||
|
||||
function formatArtDate(dateStr?: string | null) {
|
||||
if (!dateStr) return "";
|
||||
const d = new Date(dateStr);
|
||||
if (isNaN(d.getTime())) return "";
|
||||
const dd = `${d.getDate()}`.padStart(2, "0");
|
||||
const mm = `${d.getMonth() + 1}`.padStart(2, "0");
|
||||
const yyyy = d.getFullYear();
|
||||
return `${dd}/${mm}/${yyyy}`;
|
||||
}
|
||||
|
||||
export default function ItemArticle({ article }: Props) {
|
||||
const href = article.url || "#";
|
||||
const imgSrc =
|
||||
"https://demopc8.hurasoft.com" + article.image?.original ||
|
||||
"/static/assets/images/not-image.png";
|
||||
const displayDate =
|
||||
formatArtDate(article.article_time) || formatArtDate(article.createDate);
|
||||
const comments = article.review_count ?? 0;
|
||||
const views = article.visit ?? 0;
|
||||
|
||||
return (
|
||||
<div className="footer-art-item art-item flex gap-3">
|
||||
<Link href={href} className="img">
|
||||
<Image
|
||||
src={imgSrc}
|
||||
alt={article.title || ""}
|
||||
fill
|
||||
className="object-cover"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<div className="text min-w-0">
|
||||
<Link href={href} className="line-clamp-2 font-medium hover:underline">
|
||||
{article.title}
|
||||
</Link>
|
||||
|
||||
<time className="mt-1 block text-sm text-gray-500">
|
||||
<i className="fa fa-calendar" /> {displayDate}
|
||||
<i className="fa fa-comment ml-3" /> {comments}
|
||||
<i className="fa fa-eye ml-3" /> {views}
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
3
src/components/article/itemSliderArticle.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
0
src/components/product/BoxFilter.tsx
Normal file
95
src/components/product/ProductItem.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import { ProductDataType } from "@/types/products";
|
||||
|
||||
const ProductItem = ({ product }: { product: ProductDataType }) => (
|
||||
<div className="p-item">
|
||||
<a href="/nguon-may-tinh-jetek-rm750w" className="p-img">
|
||||
<Image
|
||||
src="/media/product/250_2042_jetek_rm_750w_1.jpg"
|
||||
alt="Nguồn Máy Tính JETEK RM 750W - 80 PLUS GOLD"
|
||||
/>
|
||||
</a>
|
||||
<div className="p-text">
|
||||
<p className="p-sku">Mã: 0</p>
|
||||
|
||||
<a href="/nguon-may-tinh-jetek-rm750w" className="p-name">
|
||||
Nguồn Máy Tính JETEK RM 750W - 80 PLUS GOLD
|
||||
</a>
|
||||
|
||||
<div className="p-price-group">
|
||||
<div>
|
||||
<del></del>
|
||||
<span className="p-price">1.990.000 đ</span>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="p-btn-cart"
|
||||
onclick="addProductToCart(2042, 0)"
|
||||
></a>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
className="p-btn-compare js-p-compare"
|
||||
onclick="compare_addProduct(2042,'/media/product/250_2042_jetek_rm_750w_1.jpg', this)"
|
||||
data-id="{2042"
|
||||
>
|
||||
So sánh
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="p-tooltip">
|
||||
<p className="tooltip-title">
|
||||
Nguồn Máy Tính JETEK RM 750W - 80 PLUS GOLD
|
||||
</p>
|
||||
|
||||
<div className="tooltip-content">
|
||||
<div className="tooltip-summary">
|
||||
<span className="item">
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style="color: #dd1616;margin-right: 5px;"
|
||||
></i>
|
||||
Nguồn JETEK RM 750W
|
||||
</span>
|
||||
<span className="item">
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style="color: #dd1616;margin-right: 5px;"
|
||||
></i>
|
||||
Chuẩn hiệu suất: 80 Plus Gold
|
||||
</span>
|
||||
<span className="item">
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style="color: #dd1616;margin-right: 5px;"
|
||||
></i>
|
||||
Công suất: 750W - Hiệu suất 90%
|
||||
</span>
|
||||
<span className="item">
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style="color: #dd1616;margin-right: 5px;"
|
||||
></i>
|
||||
Công nghệ DC to DC
|
||||
</span>
|
||||
<span className="item">
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style="color: #dd1616;margin-right: 5px;"
|
||||
></i>
|
||||
Quạt: 1 x 120 mm (Smart Fan)
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="position-relative text-center">
|
||||
<span className="p-price">1.990.000 đ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ProductItem;
|
||||
131
src/components/product/ProductItemSlider.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import type { ProductDataType } from "@/types/products";
|
||||
|
||||
type Props = {
|
||||
product: ProductDataType;
|
||||
onAddToCart?: (productId: number) => void;
|
||||
onCompare?: (p: ProductDataType) => void;
|
||||
};
|
||||
|
||||
function formatVND(n?: number | null) {
|
||||
if (!n || n <= 0) return "";
|
||||
return n.toLocaleString("vi-VN") + " đ";
|
||||
}
|
||||
|
||||
function pickPrice(p: ProductDataType) {
|
||||
// Ưu tiên promotion_price nếu có, rồi đến sale_rules.price, rồi price
|
||||
const normal =
|
||||
(p.sale_rules?.normal_price as number | undefined) ??
|
||||
p.marketPrice ??
|
||||
p.price ??
|
||||
0;
|
||||
const current =
|
||||
(p.promotion_price as number | null) ??
|
||||
(p.sale_rules?.price as number | undefined) ??
|
||||
p.price ??
|
||||
0;
|
||||
const hasDiscount = normal > 0 && current > 0 && current < normal;
|
||||
return { current, normal, hasDiscount };
|
||||
}
|
||||
|
||||
function getBullets(p: ProductDataType, max = 5): string[] {
|
||||
const raw = (p.productSummary || "").replace(/\r/g, "\n");
|
||||
let parts =
|
||||
raw
|
||||
.split(/\n|•|-|–|—/g)
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean) || [];
|
||||
if (parts.length === 0) {
|
||||
parts = [
|
||||
p.brand?.name ? `Thương hiệu: ${p.brand.name}` : "",
|
||||
p.warranty ? `Bảo hành: ${p.warranty}` : "",
|
||||
].filter(Boolean);
|
||||
}
|
||||
return parts.slice(0, max);
|
||||
}
|
||||
|
||||
const ProductItemSlider = ({ product, onAddToCart, onCompare }: Props) => {
|
||||
const { current, normal, hasDiscount } = pickPrice(product);
|
||||
const img =
|
||||
"https://demopc8.hurasoft.com" + product.productImage?.large ||
|
||||
"https://demopc8.hurasoft.com" + product.productImage?.small ||
|
||||
"https://demopc8.hurasoft.com/static/assets/giaodien_2025/images/not-image.png";
|
||||
const href = product.productUrl || "#";
|
||||
const name = product.productName || "Sản phẩm";
|
||||
const sku = product.productSKU || "—";
|
||||
const productId = product.productId ?? Number(product.id);
|
||||
|
||||
return (
|
||||
<div className="p-item">
|
||||
<Link href={href} className="p-img" aria-label={name}>
|
||||
<Image
|
||||
src={img}
|
||||
alt={name}
|
||||
width={250}
|
||||
height={250}
|
||||
className="block w-full h-auto object-contain"
|
||||
sizes="(max-width: 768px) 60vw, 250px"
|
||||
priority={false}
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<div className="p-text">
|
||||
<p className="p-sku">Mã: {sku}</p>
|
||||
|
||||
<Link href={href} className="p-name">
|
||||
{name}
|
||||
</Link>
|
||||
|
||||
<div className="p-price-group">
|
||||
<div>
|
||||
{hasDiscount ? <del>{formatVND(normal)}</del> : <del />}
|
||||
<span className="p-price">{formatVND(current)}</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn-cart"
|
||||
onClick={() => onAddToCart?.(productId)}
|
||||
aria-label="Thêm vào giỏ"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="p-btn-compare js-p-compare"
|
||||
onClick={() => onCompare?.(product)}
|
||||
data-id={productId}
|
||||
>
|
||||
So sánh
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tooltip */}
|
||||
<div className="p-tooltip">
|
||||
<p className="tooltip-title">{name}</p>
|
||||
<div className="tooltip-content">
|
||||
<div className="tooltip-summary">
|
||||
{getBullets(product).map((t, i) => (
|
||||
<span className="item" key={i}>
|
||||
<i
|
||||
className="fa fa-certificate"
|
||||
style={{ color: "#dd1616", marginRight: 5 }}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{t}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="position-relative text-center">
|
||||
<span className="p-price">{formatVND(current)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductItemSlider;
|
||||
3263
src/styles/style.css
Normal file
33
src/types/article.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// types/article.ts
|
||||
export type FeaturedFlag = 0 | 1;
|
||||
|
||||
export interface ArticleImage {
|
||||
thum: string;
|
||||
original: string;
|
||||
}
|
||||
|
||||
export interface Article {
|
||||
id: number;
|
||||
title: string;
|
||||
extend: boolean;
|
||||
summary: string;
|
||||
createDate: string; // ví dụ: "03-12-2020, 10:34 am"
|
||||
createBy: number;
|
||||
lastUpdate: string; // ví dụ: "08-12-2020, 3:44 pm"
|
||||
lastUpdateBy: number;
|
||||
visit: number;
|
||||
is_featured: FeaturedFlag;
|
||||
article_time: string;
|
||||
review_rate: number;
|
||||
review_count: number;
|
||||
video_code: string;
|
||||
external_url: string;
|
||||
author: string;
|
||||
counter: number;
|
||||
url: string;
|
||||
image: ArticleImage;
|
||||
}
|
||||
|
||||
export interface ArticleDataType {
|
||||
article: Article[];
|
||||
}
|
||||
104
src/types/products.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
export type Currency = "vnd" | string;
|
||||
|
||||
export interface ImageSizes {
|
||||
small: string;
|
||||
large: string;
|
||||
original: string;
|
||||
}
|
||||
|
||||
export interface ImageItem {
|
||||
image: ImageSizes;
|
||||
alt: string;
|
||||
}
|
||||
|
||||
export interface Brand {
|
||||
id: number;
|
||||
brand_index: string;
|
||||
name: string;
|
||||
image: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ReviewInfo {
|
||||
rate: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface CommentInfo {
|
||||
rate: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface SaleRules {
|
||||
price: number;
|
||||
normal_price: number;
|
||||
min_purchase: number;
|
||||
max_purchase: number;
|
||||
remain_quantity: number;
|
||||
from_time: number | string;
|
||||
to_time: number | string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface Category {
|
||||
id: number;
|
||||
catPath: string;
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ProductTypeFlags {
|
||||
isNew: 0 | 1;
|
||||
isHot: 0 | 1;
|
||||
isBestSale: 0 | 1;
|
||||
isSaleOff: 0 | 1;
|
||||
"online-only": 0 | 1;
|
||||
}
|
||||
|
||||
export interface ProductDataType {
|
||||
id: number;
|
||||
productId: number;
|
||||
priceUnit: string;
|
||||
marketPrice: number;
|
||||
price: number;
|
||||
price_off: number | string; // ví dụ có nơi là %, có nơi là "" -> để union
|
||||
currency: Currency;
|
||||
sale_rules: SaleRules;
|
||||
lastUpdate: string; // "YYYY-MM-DD HH:mm:ss"
|
||||
warranty: string;
|
||||
productName: string;
|
||||
productSummary: string;
|
||||
package_accessory?: string;
|
||||
productImage: ImageSizes;
|
||||
imageCollection: { image: ImageSizes; alt: string }[];
|
||||
productUrl: string;
|
||||
brand: Brand;
|
||||
visit: number;
|
||||
rating: number;
|
||||
reviewCount: number;
|
||||
review: ReviewInfo;
|
||||
comment: CommentInfo;
|
||||
quantity: number;
|
||||
productSKU: string;
|
||||
productModel: string;
|
||||
hasVAT: 0 | 1;
|
||||
condition: string;
|
||||
config_count: number;
|
||||
configurable: number;
|
||||
component_count: number;
|
||||
specialOffer?: Record<string, unknown>;
|
||||
specialOfferGroup?: unknown[];
|
||||
productType: ProductTypeFlags;
|
||||
bulk_price: unknown | null;
|
||||
thum_poster: string;
|
||||
thum_poster_type: string;
|
||||
addon: unknown[];
|
||||
variants: unknown[];
|
||||
variant_option: unknown[];
|
||||
extend: unknown | null;
|
||||
weight: number;
|
||||
promotion_price: number | null;
|
||||
deal_list: unknown[];
|
||||
pricing_traces: Array<{ price: number; type: string; type_id?: number }>;
|
||||
categories: Category[];
|
||||
}
|
||||
27
tailwind.config.js
Normal file
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
purge: [],
|
||||
darkMode: false, // or 'media' or 'class'
|
||||
theme: {
|
||||
container: { center: true, padding: "16px" },
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
primary: "#E53935",
|
||||
dark: "#B71C1C",
|
||||
gray: "#F5F5F5",
|
||||
},
|
||||
},
|
||||
boxShadow: {
|
||||
header: "0 0 2px 0 #e7e7e7",
|
||||
},
|
||||
},
|
||||
},
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
variants: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||