Compare commits
19 Commits
5fc49b68d3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 641ac01582 | |||
| a7e23cb983 | |||
| 4d3949abaa | |||
| b567aef3d8 | |||
| a8df344207 | |||
| 2516e78720 | |||
| 756cf6410c | |||
| 2bc93383a0 | |||
| 9851c311b3 | |||
| 87bddca6c3 | |||
| cb4a4dc482 | |||
| 3c18f922b3 | |||
| 52748cb988 | |||
| a499e06b31 | |||
| 332cb5da14 | |||
| 6318621cc0 | |||
| 12509e3a7b | |||
| eb44cc2575 | |||
| bf78d0583d |
170
package-lock.json
generated
@@ -9,9 +9,12 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@fancyapps/ui": "5.0",
|
||||
"html-react-parser": "^5.2.14",
|
||||
"next": "16.1.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"sonner": "^2.0.7",
|
||||
"swiper": "^12.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -1452,7 +1455,7 @@
|
||||
"version": "19.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz",
|
||||
"integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -2487,7 +2490,7 @@
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
@@ -2624,6 +2627,68 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"entities": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@@ -2663,6 +2728,17 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
|
||||
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.24.1",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
|
||||
@@ -3680,6 +3756,53 @@
|
||||
"hermes-estree": "0.25.1"
|
||||
}
|
||||
},
|
||||
"node_modules/html-dom-parser": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-5.1.4.tgz",
|
||||
"integrity": "sha512-UGjp7y8jSrDU2RdN2J9FDOo3X+WBu+LkS/I3TjjFW020ocZWjPvave+RKk1zeuY2sUWy5fh6zHgXHthzDGlFNQ==",
|
||||
"dependencies": {
|
||||
"domhandler": "5.0.3",
|
||||
"htmlparser2": "10.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html-react-parser": {
|
||||
"version": "5.2.14",
|
||||
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.14.tgz",
|
||||
"integrity": "sha512-yiSZHuJq6LwQc450IhpLApug8bKTpHv5oVsClpVS1jEDepifXYcJu0Sw0r7pqEl89q/ZpO0nth6LEDWtz5n6qg==",
|
||||
"dependencies": {
|
||||
"domhandler": "5.0.3",
|
||||
"html-dom-parser": "5.1.4",
|
||||
"react-property": "2.0.2",
|
||||
"style-to-js": "1.1.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "0.14 || 15 || 16 || 17 || 18 || 19",
|
||||
"react": "0.14 || 15 || 16 || 17 || 18 || 19"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
|
||||
"integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.2.2",
|
||||
"entities": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -3714,6 +3837,11 @@
|
||||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/inline-style-parser": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz",
|
||||
"integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
||||
@@ -4980,6 +5108,14 @@
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/photoswipe": {
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.4.4.tgz",
|
||||
"integrity": "sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==",
|
||||
"engines": {
|
||||
"node": ">= 0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@@ -5114,6 +5250,11 @@
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/react-property": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.2.tgz",
|
||||
"integrity": "sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug=="
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@@ -5488,6 +5629,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/sonner": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",
|
||||
"integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==",
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
|
||||
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@@ -5643,6 +5793,22 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/style-to-js": {
|
||||
"version": "1.1.21",
|
||||
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz",
|
||||
"integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==",
|
||||
"dependencies": {
|
||||
"style-to-object": "1.0.14"
|
||||
}
|
||||
},
|
||||
"node_modules/style-to-object": {
|
||||
"version": "1.0.14",
|
||||
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz",
|
||||
"integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==",
|
||||
"dependencies": {
|
||||
"inline-style-parser": "0.2.7"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-jsx": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fancyapps/ui": "5.0",
|
||||
"html-react-parser": "^5.2.14",
|
||||
"next": "16.1.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"sonner": "^2.0.7",
|
||||
"swiper": "^12.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
BIN
public/images/footer-showroom-cg.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
public/images/footer-showroom-dd.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
public/images/hoang-ha-pc-cau-giay-6.jpg
Normal file
|
After Width: | Height: | Size: 370 KiB |
BIN
public/images/hoang-ha-pc-cau-giay-7.jpg
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
public/images/hoang-ha-pc-cau-giay-8.jpg
Normal file
|
After Width: | Height: | Size: 344 KiB |
BIN
public/images/hoang-ha-pc-cau-giay-9.jpg
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
public/images/hoang-ha-pc-dong-da-1.jpg
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
public/images/hoang-ha-pc-dong-da-2 (1).jpg
Normal file
|
After Width: | Height: | Size: 313 KiB |
BIN
public/images/hoang-ha-pc-dong-da-2.jpg
Normal file
|
After Width: | Height: | Size: 313 KiB |
BIN
public/images/hoang-ha-pc-dong-da-3.jpg
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
public/images/hoang-ha-pc-dong-da-4.jpg
Normal file
|
After Width: | Height: | Size: 391 KiB |
BIN
public/images/hoang-ha-pc-hcm-1.jpg
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
public/images/hoang-ha-pc-hcm-2.jpg
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/images/hoang-ha-pc-hcm-3.jpg
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
public/images/hoang-ha-pc-hcm-4.jpg
Normal file
|
After Width: | Height: | Size: 278 KiB |
BIN
public/images/hoang-ha-pc-hcm-5.jpg
Normal file
|
After Width: | Height: | Size: 407 KiB |
BIN
public/images/hoang_ha_pc_vinh_1.jpg
Normal file
|
After Width: | Height: | Size: 540 KiB |
BIN
public/images/hoang_ha_pc_vinh_10.jpg
Normal file
|
After Width: | Height: | Size: 232 KiB |
BIN
public/images/hoang_ha_pc_vinh_2.jpg
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
public/images/hoang_ha_pc_vinh_3.jpg
Normal file
|
After Width: | Height: | Size: 530 KiB |
BIN
public/images/hoang_ha_pc_vinh_4.jpg
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
public/images/phong-bao-hanh-2-min.jpg
Normal file
|
After Width: | Height: | Size: 146 KiB |
BIN
public/images/phong-bao-hanh-3-min.jpg
Normal file
|
After Width: | Height: | Size: 119 KiB |
BIN
public/images/phong-bao-hanh-4-min.jpg
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
public/images/phong-bao-hanh-5-min.jpg
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
public/images/phong-bao-hanh-6-min.jpg
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
public/images/phong-bao-hanh-min.jpg
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
public/images/showroom-central.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/images/static-about-us-pic-1.png
Normal file
|
After Width: | Height: | Size: 563 KiB |
BIN
public/images/static-about-us-pic-2.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/images/static-about-us-pic-3.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
public/images/static-about-us-pic-4.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/images/static-about-us-pic-5.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/images/static-about-us-section-hero.png
Normal file
|
After Width: | Height: | Size: 1016 KiB |
BIN
public/images/static-buy-online-banner.png
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
public/images/static-buy-online-bg-1.png
Normal file
|
After Width: | Height: | Size: 251 KiB |
BIN
public/images/static-contact-info-pic-1.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/images/static-recruit-bg-1.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
public/images/static-showroom-bg.jpg
Normal file
|
After Width: | Height: | Size: 1023 KiB |
BIN
public/images/static-showroom-pc-1.png
Normal file
|
After Width: | Height: | Size: 966 KiB |
BIN
public/images/static-showroom-top.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
public/images/static-sprite.png
Normal file
|
After Width: | Height: | Size: 203 KiB |
@@ -1,4 +1,4 @@
|
||||
body{color:#333333;font-size:14px;line-height: 18px;font-family:'SF Pro Display',sans-serif;position:relative;word-break:break-word;counter-reset:section;font-weight:400;word-break: break-word;overflow-x:hidden}
|
||||
body{color:#333333;font-size:14px;line-height: 18px;font-family:'SF Pro Display',sans-serif;position:relative;word-break:break-word;counter-reset:section;font-weight:400;word-break: break-word;}
|
||||
.fancybox__container .for-video.is-selected {border: 2px solid red;}
|
||||
|
||||
/* css loading */
|
||||
|
||||
15
src/app/(main)/buildpc/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import BuildPc from "@/components/buildpc"
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Xây Dựng Cấu Hình PC, Build PC Chuẩn Nhất✔️Giá Rẻ",
|
||||
description: "Xây dựng cấu hình máy tính PC chuyên nghiệp ✳️ máy tính đồ họa, máy tính làm việc giá rẻ ✳️ Build PC.",
|
||||
};
|
||||
|
||||
import "@/styles/buildpc.css";
|
||||
|
||||
export default function Home() {
|
||||
return(
|
||||
<BuildPc />
|
||||
)
|
||||
}
|
||||
13
src/app/(main)/cart/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
import CartHome from "@/components/cart/home";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Giỏ hàng của bạn",
|
||||
description: "",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<CartHome />
|
||||
)
|
||||
}
|
||||
15
src/app/(main)/dang-ky/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
import RegisterPage from "@/components/customer/Register"
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Đăng nhập tài khoản",
|
||||
description: "",
|
||||
};
|
||||
|
||||
import "@/styles/customer.css";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<RegisterPage />
|
||||
)
|
||||
}
|
||||
15
src/app/(main)/dang-nhap/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
import LoginPage from "@/components/customer/Login";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Đăng nhập tài khoản",
|
||||
description: "",
|
||||
};
|
||||
|
||||
import "@/styles/customer.css";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<LoginPage />
|
||||
)
|
||||
}
|
||||
13
src/app/(main)/deal/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import DealPage from "@/components/deal"
|
||||
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Flash Sale Mỗi Ngày Cực Sốc - Hoàng Hà PC ",
|
||||
description: "Flash Sale Mỗi Ngày Cực Sốc - Hoàng Hà PC",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return(
|
||||
<DealPage />
|
||||
)
|
||||
}
|
||||
37
src/app/(main)/designer-tool/[slug]/page.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { findBySlug } from "@/lib/slug/slugMap";
|
||||
import { metadataBySlug } from "@/app/[slug]/metadataBySlug";
|
||||
import { SLUG_CONFIG } from "@/app/[slug]/slugConfig";
|
||||
import { renderBySlug } from "@/app/[slug]/renderBySlug";
|
||||
import LayoutTypeSetter from "@/components/layout/LayoutTypeSetter"
|
||||
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const result = await findBySlug(slug);
|
||||
|
||||
return metadataBySlug(result);
|
||||
}
|
||||
|
||||
|
||||
export default async function SlugPage({ params }: { params: { slug: string } }) {
|
||||
|
||||
const { slug } = await params;
|
||||
const result = await findBySlug(slug);
|
||||
if (!result) notFound();
|
||||
|
||||
const config = SLUG_CONFIG[result.type];
|
||||
if (!config) notFound();
|
||||
|
||||
return (
|
||||
<LayoutTypeSetter layout="main">
|
||||
{renderBySlug(result)}
|
||||
</LayoutTypeSetter>
|
||||
);
|
||||
|
||||
}
|
||||
14
src/app/(main)/designer-tool/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
import DesignerTool from "@/components/designer-tool";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "PC Đồ Họa Tool | Chọn cấu hình theo phần mềm ",
|
||||
description: "Công cụ chọn PC đồ họa theo phần mềm: Photoshop, Illustrator, Lumion, AutoCAD… Đề xuất cấu hình chuẩn cho thiết kế 2D, 3D, CAD và render.",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
|
||||
return (
|
||||
<DesignerTool />
|
||||
)
|
||||
}
|
||||
9
src/app/(main)/layout.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export default function MainLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
12
src/app/(main)/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
import Home from "@/components/home";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Homepage- Local Pc",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<Home />
|
||||
)
|
||||
}
|
||||
13
src/app/(main)/quen-mat-khau/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
import ForgotPassword from "@/components/customer/ForgotPassword";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Quên mật khẩu",
|
||||
description: "",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<ForgotPassword />
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
|
||||
import SendResult from "@/components/cart/send";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Gửi đơn hàng",
|
||||
description: "",
|
||||
};
|
||||
|
||||
export default function SendCartPage() {
|
||||
return (
|
||||
14
src/app/(main)/taikhoan/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
import Layout from "@/components/account";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Tài khoản của tôi",
|
||||
description: "Thông tin tài khoản người dùng",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Layout />
|
||||
)
|
||||
}
|
||||
37
src/app/(main)/tim/[slug]/page.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { findBySlug } from "@/lib/slug/slugMap";
|
||||
import { metadataBySlug } from "@/app/[slug]/metadataBySlug";
|
||||
import { SLUG_CONFIG } from "@/app/[slug]/slugConfig";
|
||||
import { renderBySlug } from "@/app/[slug]/renderBySlug";
|
||||
import LayoutTypeSetter from "@/components/layout/LayoutTypeSetter"
|
||||
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const result = await findBySlug(slug);
|
||||
|
||||
return metadataBySlug(result);
|
||||
}
|
||||
|
||||
|
||||
export default async function SlugPage({ params }: { params: { slug: string } }) {
|
||||
|
||||
const { slug } = await params;
|
||||
const result = await findBySlug(slug);
|
||||
if (!result) notFound();
|
||||
|
||||
const config = SLUG_CONFIG[result.type];
|
||||
if (!config) notFound();
|
||||
|
||||
return (
|
||||
<LayoutTypeSetter layout="main">
|
||||
{renderBySlug(result)}
|
||||
</LayoutTypeSetter>
|
||||
);
|
||||
|
||||
}
|
||||
13
src/app/(main)/tim/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import ProductSearch from "@/components/search"
|
||||
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Danh sách tìm kiếm ",
|
||||
description: "Danh sách kết quả thỏa mãn",
|
||||
};
|
||||
|
||||
export default function Search() {
|
||||
return(
|
||||
<ProductSearch />
|
||||
)
|
||||
}
|
||||
13
src/app/(main)/tin-tuc/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
import ArticleHome from "@/components/article/home";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Tin tức ",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<ArticleHome />
|
||||
)
|
||||
}
|
||||
11
src/app/(static)/gioi-thieu/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import Info from "@/components/about/Info"
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Giới Thiệu Về Hoàng Hà PC",
|
||||
description: "Hoàng Hà PC được thành lập vào năm 2008. Đến nay, Hoàng Hà PC đã trở thành công ty hàng đầu trong lĩnh vực kinh doanh máy tính tại Việt Nam.",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return <Info />;
|
||||
}
|
||||
11
src/app/(static)/he-thong-cua-hang/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import HeThongCuaHang from "@/components/static/store";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Hệ Thống Cửa Hàng - Hoàng Hà PC",
|
||||
description: "Hệ Thống Cửa Hàng máy tính với 4 Showroom lớn Hoàng Hà PC Chuyên cung cấp máy tính cao cấp, máy tính đồ họa và linh kiện máy tính uy tín.",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return <HeThongCuaHang />;
|
||||
}
|
||||
16
src/app/(static)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import LayoutTypeSetter from "@/components/layout/LayoutTypeSetter";
|
||||
|
||||
import '@/styles/static_page.css';
|
||||
import '@/styles/tuyen_dung.css';
|
||||
|
||||
export default function StaticLayout({ children }: { children: ReactNode }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<LayoutTypeSetter layout="static">
|
||||
{children}
|
||||
</LayoutTypeSetter>
|
||||
</>
|
||||
);
|
||||
}
|
||||
11
src/app/(static)/lien-he/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import Contact from "@/components/about/Contact"
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Thông tin liên hệ",
|
||||
description: "Thông tin liên hệ bao gồm điện thoại, địa chỉ cửa hàng",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return <Contact />;
|
||||
}
|
||||
11
src/app/(static)/tuyen-dung/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import RecruitPage from "../../../components/recruit";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Tuyển dụng nhân sự - Cơ hội việc làm tại Hoàng Hà PC",
|
||||
description: "Tìm kiếm việc làm tại Hoàng Hà PC",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return <RecruitPage />;
|
||||
}
|
||||
20
src/app/[slug]/SlugLayoutSetter.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useLayout } from "../../components/layout/LayoutContext";
|
||||
|
||||
export default function SlugLayoutSetter({
|
||||
layout,
|
||||
children,
|
||||
}: {
|
||||
layout: "main" | "static";
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { setLayout } = useLayout();
|
||||
|
||||
useEffect(() => {
|
||||
setLayout(layout);
|
||||
}, [layout, setLayout]);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
99
src/app/[slug]/metadataBySlug.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export function metadataBySlug(result: any): Metadata {
|
||||
|
||||
switch (result.type) {
|
||||
case "product_category":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: stripHtml(result.data.summary),
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
result.data.big_image
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
case "product_detail":
|
||||
return {
|
||||
title: result.data.productName,
|
||||
description: stripHtml(result.data.productSummary),
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
result.data.productImage.large.replace('/250_', '/')
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
case "article_home":
|
||||
return {
|
||||
title: "Tin tức",
|
||||
description: "Tin tức mới nhất",
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
images: [
|
||||
result.data.productImage.large.replace('/250_', '/')
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "article_category":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: stripHtml(result.data.summary),
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
images: [
|
||||
result.data.thumbnail
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "article_detail":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: result.data.meta_description,
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
}
|
||||
};
|
||||
|
||||
case "job_detail":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: result.data.meta_description,
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
}
|
||||
};
|
||||
|
||||
case "designer_detail":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: result.data.meta_description,
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
}
|
||||
};
|
||||
|
||||
default:
|
||||
|
||||
return {
|
||||
title: result.meta_title || "Local PC",
|
||||
description: result.data.meta_description || "",
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
'/images/logo.png'
|
||||
],
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function stripHtml(html: string) {
|
||||
return html.replace(/<[^>]*>/g, '');
|
||||
}
|
||||
@@ -1,47 +1,34 @@
|
||||
// src/app/[slug]/page.tsx
|
||||
import { notFound } from "next/navigation";
|
||||
import { renderBySlug } from "./renderBySlug";
|
||||
import { metadataBySlug } from "./metadataBySlug";
|
||||
import { findBySlug } from "@/lib/slug/slugMap";
|
||||
import { notFound } from "next/navigation";
|
||||
import type { Metadata } from "next";
|
||||
import LayoutTypeSetter from "@/components/layout/LayoutTypeSetter"
|
||||
import { SLUG_CONFIG } from "./slugConfig";
|
||||
|
||||
import ProductCategory from "@/components/product/category";
|
||||
import ProductDetail from "@/components/product/detail";
|
||||
import ArticleCategory from "@/components/article/category";
|
||||
import ArticleDetail from "@/components/article/detail";
|
||||
import ArticleHome from "@/components/article/home";
|
||||
|
||||
export default async function SlugPage({
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
if (!slug) {
|
||||
notFound();
|
||||
}
|
||||
const result = await findBySlug(slug);
|
||||
|
||||
const result = findBySlug(slug);
|
||||
|
||||
if (!result) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
switch (result.type) {
|
||||
case "product_category":
|
||||
return <ProductCategory slug={result.data} />;
|
||||
|
||||
case "product_detail":
|
||||
return <ProductDetail slug={result.data} />;
|
||||
|
||||
case "article_home":
|
||||
return <ArticleHome slug={slug} />;
|
||||
|
||||
case "article_category":
|
||||
return <ArticleCategory slug={result.data} />;
|
||||
|
||||
case "article_detail":
|
||||
return <ArticleDetail slug={result.data.slug} />;
|
||||
|
||||
default:
|
||||
const _exhaustive: never = result;
|
||||
notFound();
|
||||
}
|
||||
return metadataBySlug(result);
|
||||
}
|
||||
|
||||
export default async function SlugPage({ params }: { params: { slug: string } }) {
|
||||
const { slug } = await params;
|
||||
const result = await findBySlug(slug);
|
||||
if (!result) notFound();
|
||||
|
||||
const config = SLUG_CONFIG[result.type];
|
||||
if (!config) notFound();
|
||||
|
||||
return (
|
||||
<LayoutTypeSetter layout={config.layout}>
|
||||
{renderBySlug(result)}
|
||||
</LayoutTypeSetter>
|
||||
);
|
||||
}
|
||||
11
src/app/[slug]/renderBySlug.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
// app/[slug]/renderBySlug.tsx
|
||||
import { SLUG_CONFIG } from "./slugConfig";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
export function renderBySlug(result: any) {
|
||||
const config = SLUG_CONFIG[result.type];
|
||||
|
||||
if (!config) notFound();
|
||||
|
||||
return config.render(result.data);
|
||||
}
|
||||
47
src/app/[slug]/slugConfig.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
// app/[slug]/slugConfig.ts
|
||||
import ProductCategory from "@/components/product/category";
|
||||
import ProductDetail from "@/components/product/detail";
|
||||
import ArticleCategory from "@/components/article/category";
|
||||
import ArticleDetail from "@/components/article/detail";
|
||||
import ArticleHome from "@/components/article/home";
|
||||
import JobDetail from "@/components/recruit/Detail";
|
||||
import DesignerDetail from "@/components/designer-tool/Detail";
|
||||
|
||||
export type SlugLayout = "main" | "static";
|
||||
|
||||
export const SLUG_CONFIG:
|
||||
Record<string,{
|
||||
layout: SlugLayout;
|
||||
render: (data: any) => JSX.Element;
|
||||
}> =
|
||||
{
|
||||
product_category: {
|
||||
layout: "main",
|
||||
render: (data) => <ProductCategory slug={data} />,
|
||||
},
|
||||
product_detail: {
|
||||
layout: "main",
|
||||
render: (data) => <ProductDetail slug={data} />,
|
||||
},
|
||||
article_home: {
|
||||
layout: "main",
|
||||
render: () => <ArticleHome />,
|
||||
},
|
||||
article_category: {
|
||||
layout: "main",
|
||||
render: (data) => <ArticleCategory slug={data} />,
|
||||
},
|
||||
article_detail: {
|
||||
layout: "main",
|
||||
render: (data) => <ArticleDetail slug={data} />,
|
||||
},
|
||||
designer_detail: {
|
||||
layout: "main",
|
||||
render: (data) => <DesignerDetail slug={data} />,
|
||||
},
|
||||
job_detail: {
|
||||
layout: "static",
|
||||
render: (data) => <JobDetail slug={data} />,
|
||||
},
|
||||
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
import CartHome from "@/components/cart/home";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<CartHome />
|
||||
)
|
||||
}
|
||||
@@ -1,32 +1,21 @@
|
||||
import type { Metadata } from "next";
|
||||
import type { ReactNode } from 'react';
|
||||
import Header from "@/components/other/header";
|
||||
import Footer from "@/components/other/footer";
|
||||
import { Toaster } from "sonner";
|
||||
import TooltipProvider from "@/components/providers/TooltipProvider";
|
||||
import '../styles/globals.css';
|
||||
import HeaderFooterSwitch from "@/components/other/HeaderFooterSwitch";
|
||||
import { LayoutProvider } from "@/components/layout/LayoutContext";
|
||||
import "@/styles/globals.css";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Local Pc",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="vi">
|
||||
<body>
|
||||
<Header />
|
||||
<body>
|
||||
<LayoutProvider>
|
||||
<HeaderFooterSwitch>
|
||||
<TooltipProvider>{children}</TooltipProvider>
|
||||
</HeaderFooterSwitch>
|
||||
|
||||
<TooltipProvider>
|
||||
{children}
|
||||
</TooltipProvider>
|
||||
|
||||
|
||||
<Footer />
|
||||
</body>
|
||||
<Toaster position="top-right" closeButton richColors />
|
||||
</LayoutProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
import Link from "next/link"
|
||||
import Link from "next/link";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "404 - Không tìm thấy trang | Hoàng Hà PC",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
import Home from "@/components/home";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<Home />
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
import ArticleHome from "@/components/article/home";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<ArticleHome slug="" />
|
||||
)
|
||||
}
|
||||
144
src/components/about/Contact.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
export default function Contact() {
|
||||
return (
|
||||
<>
|
||||
<h1 style={{ position: 'absolute', top: '-999px' }}>Liên hệ</h1>
|
||||
|
||||
<div className="contact-info-page main-content">
|
||||
<div className="contact-info text-20">
|
||||
<div className="container">
|
||||
<div className="contact-info-header py-6">
|
||||
<div className="contact-info-header-text">
|
||||
<h2 className="text-20 mb-3">
|
||||
Công ty tin rằng khách hàng chính là nhân tố quan trọng cho phát triển của <b className="font-weight-600 color-blue-1">Hoàng Hà PC</b>. Vì vậy, mọi hoạt động kinh doanh của công ty luôn hướng tới mục tiêu tôn trọng và bảo đảm quyền lợi cho khách hàng, chinh phục khách hàng bằng chất lượng sản phẩm và dịch vụ tốt nhất.
|
||||
</h2>
|
||||
<p>
|
||||
Để được phục vụ cũng như giải đáp mọi thắc mắc, Quý khách vui lòng liên hệ với chúng tôi theo các thông tin sau:
|
||||
</p>
|
||||
</div>
|
||||
<div className="contact-info-header-image">
|
||||
<img src="/images/static-contact-info-pic-1.png" alt="contact-info" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="contact-info-content d-flex flex-wrap">
|
||||
<div className="contact-info-box d-flex flex-column align-items-center">
|
||||
<i className="static-icons static-icon-location-3" />
|
||||
<h3 className="text-20 font-weight-bold">Showroom bán hàng</h3>
|
||||
<h4 className="text-24 font-weight-bold mb-4 mt-2">PHƯỜNG CẦU GIẤY, HÀ NỘI</h4>
|
||||
<p className="text-16 pb-3x text-center">41 Khúc Thừa Dụ, Phường Cầu Giấy, Hà Nội</p>
|
||||
|
||||
<div className="w-full pb-4x">
|
||||
<a href="https://goo.gl/maps/56ARHjWKoVhpWBCF6" className="btn btn-blue-2 w-full" target="_blank">Nhận chỉ đường</a>
|
||||
</div>
|
||||
|
||||
<ul className="contact-list d-flex flex-column">
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-phone" />
|
||||
<a className="text-14" href="tel:0969.123.666">Điện thoại: 0969.123.666</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-mail" />
|
||||
<a className="text-14" href="mailto:hoanghapcws@gmail.com">Email: hoanghapcws@gmail.com</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-clock" />
|
||||
<p className="text-14 m-0">Thời gian làm việc: 8h00 - 18h30</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* QUẬN ĐỐNG ĐA, HÀ NỘI */}
|
||||
<div className="contact-info-box d-flex flex-column align-items-center">
|
||||
<i className="static-icons static-icon-location-3" />
|
||||
<h3 className="text-20 font-weight-bold">Showroom bán hàng</h3>
|
||||
<h4 className="text-24 font-weight-bold mb-4 mt-2">PHƯỜNG ĐỐNG ĐA, HÀ NỘI</h4>
|
||||
<p className="text-16 pb-3x text-center">94E-94F Đường Láng , Phường Đống Đa, Hà Nội</p>
|
||||
|
||||
<div className="w-full pb-4x">
|
||||
<a href="https://g.page/hoanghapc?share" className="btn btn-blue-2 w-full" target="_blank">Nhận chỉ đường</a>
|
||||
</div>
|
||||
|
||||
<ul className="contact-list d-flex flex-column">
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-phone" />
|
||||
<a className="text-14" href="tel: 0396.122.999">Điện thoại: 0396.122.999</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-mail" />
|
||||
<a className="text-14" href="mailto:hoanghapcws@gmail.com">Email: hoanghapcws@gmail.com</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-clock" />
|
||||
<p className="text-14 m-0">Thời gian làm việc: 8h00 - 18h30</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* VINH, NGHỆ AN */}
|
||||
<div className="contact-info-box d-flex flex-column align-items-center">
|
||||
<i className="static-icons static-icon-location-3" />
|
||||
<h3 className="text-20 font-weight-bold">Showroom bán hàng</h3>
|
||||
<h4 className="text-24 font-weight-bold mb-4 mt-2">VINH, NGHỆ AN</h4>
|
||||
<p className="text-16 pb-3x text-center">72 Lê Lợi, Thành Vinh, Nghệ An</p>
|
||||
|
||||
<div className="w-full pb-4x">
|
||||
<a href="https://goo.gl/maps/1HQrD6mdf4VMYccs6" className="btn btn-blue-2 w-full" target="_blank">Nhận chỉ đường</a>
|
||||
</div>
|
||||
|
||||
<ul className="contact-list d-flex flex-column">
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-phone" />
|
||||
<a className="text-14" href="tel:0988.163.666">Điện thoại: 0988.163.666</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-mail" />
|
||||
<a className="text-14" href="mailto:hoanghapcws@gmail.com">Email: hoanghapcws@gmail.com</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-clock" />
|
||||
<p className="text-14 m-0">Thời gian làm việc: 8h00 - 18h30</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* HỒ CHÍ MINH */}
|
||||
<div className="contact-info-box d-flex flex-column align-items-center">
|
||||
<i className="static-icons static-icon-location-3" />
|
||||
<h3 className="text-20 font-weight-bold">Showroom bán hàng</h3>
|
||||
<h4 className="text-24 font-weight-bold mb-4 mt-2">HỒ CHÍ MINH</h4>
|
||||
<p className="text-16 pb-3x text-center">K8bis Bửu Long, Phường Hòa Hưng, Hồ Chí Minh</p>
|
||||
|
||||
<div className="w-full pb-4x">
|
||||
<a href="https://g.page/hoanghapchcm?share" className="btn btn-blue-2 w-full" target="_blank">Nhận chỉ đường</a>
|
||||
</div>
|
||||
|
||||
<ul className="contact-list d-flex flex-column">
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-phone" />
|
||||
<a className="text-14" href="tel:0968.123.666">Điện thoại: 0968.123.666</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-mail" />
|
||||
<a className="text-14" href="mailto:hoanghapcws@gmail.com">Email: hoanghapcws@gmail.com</a>
|
||||
</li>
|
||||
|
||||
<li className="d-flex align-items-center">
|
||||
<i className="static-icons static-icon-clock" />
|
||||
<p className="text-14 m-0">Thời gian làm việc: 8h00 - 18h30</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
285
src/components/about/Info.tsx
Normal file
@@ -0,0 +1,285 @@
|
||||
export default function Info() {
|
||||
return (
|
||||
<>
|
||||
<h1 style={{ position: 'absolute', top: '-99999px' }}>Giới Thiệu Hoàng Hà PC</h1>
|
||||
<div className="about-us-page">
|
||||
<div className="about-us text-16">
|
||||
<div className="about-us-header">
|
||||
<div className="about-us-header-bg section-hero" />
|
||||
<div className="container">
|
||||
<div className="text-box d-flex align-items-center flex-column font-weight-bold">
|
||||
<i className="static-icons static-icon-logo" />
|
||||
<h3 className="text-28 text-white mt-3">
|
||||
GIỚI THIỆU VỀ HOÀNG HÀ PC
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="deco-header deco-header-1" />
|
||||
<div className="deco-header deco-header-2" />
|
||||
</div>
|
||||
<div className="about-us-content">
|
||||
<div className="wrap">
|
||||
<div className="container">
|
||||
<h4 className="text-center text-16">
|
||||
<span className="font-weight-bold color-primary">Hoàng Hà PC</span>
|
||||
được thành lập vào năm 2008 với tên gọi là Trung Tâm Tin Học
|
||||
Hoàng Hà nhằm đáp ứng nhu cầu của thị trường lúc bấy giờ như
|
||||
lắp đặt hệ thống máy tính văn phòng, máy tính gaming, lắp đặt
|
||||
thi công quán net và các sản phẩm máy tính cao cấp dành cho
|
||||
thiết kế đồ họa.
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="summary py-6">
|
||||
<div className="container">
|
||||
<div className="grid grid--content-1">
|
||||
<div className="summary-text">
|
||||
<h3 className="text-28 color-primary font-weight-600 pb-3">
|
||||
SƠ LƯỢC
|
||||
</h3>
|
||||
<p className="my-3">
|
||||
Suốt nhiều năm hoạt động từ khi mới thành lập cho tới nay,
|
||||
<span className="color-primary font-weight-bold">Hoàng Hà PC</span>
|
||||
đã luôn phát triển và tạo dựng được niềm tin với khách
|
||||
hàng từ chất lượng dịch vụ đến mức giá hợp lý. Trong
|
||||
khoảng thời gian hoạt động, Trung Tâm Tin Học Hoàng Hà
|
||||
quyết định đổi tên thành
|
||||
<span className="color-primary font-weight-bold">Công ty TNHH Dịch Vụ Và Công Nghệ Hoàng
|
||||
Hà</span>
|
||||
vào năm 2016 với mục tiêu trở thành đơn vị cung cấp máy
|
||||
tính chuyên dụng cao cấp tiên phong tại Việt Nam, đi đầu
|
||||
về xu hướng công nghệ mới và tư vấn giải pháp tối ưu phần
|
||||
cứng máy tính cho các nhu cầu của người sử dụng.
|
||||
</p>
|
||||
<p className="mb-3">
|
||||
Đến nay,
|
||||
<span className="color-primary font-weight-bold">Hoàng Hà PC</span>
|
||||
tự hào là đơn vị cung cấp các sản phẩm chính hãng nổi
|
||||
tiếng như:
|
||||
<span className="color-primary font-weight-bold">Supermicro, Intel, AMD, Nvidia, Zotac,
|
||||
Gigabyte, Asus,
|
||||
Asrock, MSI, Seasonic, Gskill, Corsair…</span>
|
||||
đáp ứng yêu cầu của khách hàng trong lĩnh vực Server,
|
||||
Workstation và giữ nguyên tiêu chí từ khi Hoàng Hà PC mới
|
||||
thành lập chính là “vì khách hàng”.
|
||||
</p>
|
||||
<p className="mb-3">
|
||||
Nhờ nỗ lực phát triển không ngừng, Hoàng Hà PC đã đón nhận
|
||||
những thành viên mới, tạo nên một tập thể đoàn kết vững
|
||||
mạnh với đội ngũ nhân viên 100 thành viên, có nhiều năm
|
||||
kinh nghiệm làm việc thực tế, am hiểu sâu về hệ thống phần
|
||||
cứng và phần mềm và đặc biệt luôn tận tâm với khách hàng..
|
||||
</p>
|
||||
<p>
|
||||
<span className="color-primary font-weight-bold">Hoàng Hà PC</span>
|
||||
đã vươn lên trở thành công ty hàng đầu trong lĩnh vực lắp
|
||||
đặt máy tính cao cấp, luôn đưa ra các chính sách về hỗ trợ
|
||||
khách hàng từ bảo hành, hỗ trợ tư vấn giải pháp và tối ưu
|
||||
giá trị ngân sách một cách hiệu quả nhất một cách nhanh
|
||||
chóng và chu đáo nhất.
|
||||
</p>
|
||||
</div>
|
||||
<div className="summary-image">
|
||||
<img src="/images/static-about-us-pic-1.png" alt="About image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="core-values py-6">
|
||||
<div className="container">
|
||||
<div className="core-values-header heading-primary text-center pb-3">
|
||||
<h3 className="text-28 color-primary mb-3 font-weight-bold">
|
||||
GIÁ TRỊ CỐT LÕI HOÀNG HÀ PC
|
||||
</h3>
|
||||
<p>
|
||||
Văn hóa của Hoàng Hà PC được hình thành từ tiêu chí “<span className="font-weight-bold color-primary">vì khách hàng</span>”, đây là yếu tố quan trọng mang
|
||||
lại không chỉ sự phát
|
||||
triển của
|
||||
<span className="font-weight-bold color-primary">Hoàng Hà PC</span>
|
||||
mà còn cả giá trị tinh thần vô cùng to lớn cho nhân viên của
|
||||
<span className="font-weight-bold color-primary">Hoàng Hà PC</span>. Vì vậy giá trị cốt lõi của
|
||||
Hoàng Hà PC chính là:
|
||||
<span className="font-weight-bold color-primary"><span className="gradient-color gradient-color-1">Nỗ
|
||||
lực</span>
|
||||
-
|
||||
<span className="gradient-color gradient-color-2">Cải tiến</span>
|
||||
-
|
||||
<span className="gradient-color gradient-color-3">Sáng tạo</span>
|
||||
-
|
||||
<span className="gradient-color gradient-color-4">Trách nhiệm</span>:</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="core-values-content">
|
||||
<ul className="grid grid--4-cols grid--gap-2">
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-try-hard mx-auto" />
|
||||
<p className="text-20 font-weight-bold text-center my-2 gradient-color gradient-color-1">
|
||||
Nỗ lực
|
||||
</p>
|
||||
<span>Hoàng Hà PC luôn cống hiến hết sức mình cho mục tiêu đề
|
||||
ra. Đưa ra giải pháp tốt nhất cho khách hàng.</span>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-upgrade mx-auto" />
|
||||
<p className="text-20 font-weight-600 text-center my-2 gradient-color gradient-color-2">
|
||||
Cải tiến
|
||||
</p>
|
||||
<span>Hoàng Hà PC không ngừng cải tiến để mang đến chính sách
|
||||
phù hợp với KH nhất, vươn lên dẫn đầu trong lĩnh vực lắp
|
||||
đặt máy tính</span>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-creation mx-auto" />
|
||||
<p className="text-20 font-weight-600 text-center my-2 gradient-color gradient-color-3">
|
||||
Sáng tạo
|
||||
</p>
|
||||
<span>Hoàng Hà PC luôn đề cao sự sáng tạo kết hợp giữa giá
|
||||
trị hiện có và ý tưởng mới tạo nên sự khác biệt so với
|
||||
các công ty khác.</span>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-shield-2 mx-auto" />
|
||||
<p className="text-20 font-weight-600 text-center my-2 gradient-color gradient-color-4">
|
||||
Trách nhiệm
|
||||
</p>
|
||||
<span>Hoàng Hà PC luôn duy trì tinh thần trách nhiệm cao để
|
||||
đạt được các kết quả nhất quán với định hướng:”Vì Khách
|
||||
Hàng”.</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="organization py-6">
|
||||
<div className="container">
|
||||
<h3 className="text-28 color-primary font-weight-600 pb-3x">
|
||||
SƠ ĐỒ TỔ CHỨC HOÀNG HÀ PC
|
||||
</h3>
|
||||
<div className="organization-content">
|
||||
<div className="grid grid--2-cols grid--gap-2">
|
||||
<img src="/images/static-about-us-pic-2.png" alt="organization" />
|
||||
<img src="/images/static-about-us-pic-5.png" alt="organization" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="business py-6">
|
||||
<div className="container">
|
||||
<div className="grid grid--2-cols grid--gap-2">
|
||||
<div className="business-text">
|
||||
<h3 className="text-28 color-primary font-weight-600 mb-1">
|
||||
CÁC LĨNH VỰC KINH DOANH
|
||||
</h3>
|
||||
<p className="pb-3x">
|
||||
Đặc biệt trong lĩnh vực Tin học, Hoàng Hà PC chú trọng các
|
||||
hoạt động như:
|
||||
</p>
|
||||
<ul>
|
||||
<li className="d-flex align-items-center pr-4 mb-3">
|
||||
<div className="wraper-icon">
|
||||
<i className="static-icons static-icon-polygon-6" />
|
||||
<span className="text-20 font-weight-bold gradient-color gradient-color-4">1</span>
|
||||
</div>
|
||||
<p className="font-weight-600 ml-2">
|
||||
Cung cấp giải pháp: Máy chủ, máy tính đồ họa, máy tính
|
||||
workstation, máy tính văn phòng và các linh kiện máy
|
||||
tính.
|
||||
</p>
|
||||
</li>
|
||||
<li className="d-flex align-items-center pr-4 mb-3">
|
||||
<div className="wraper-icon">
|
||||
<i className="static-icons static-icon-polygon-6" />
|
||||
<span className="text-20 font-weight-bold gradient-color gradient-color-4">2</span>
|
||||
</div>
|
||||
<p className="font-weight-600 ml-2">
|
||||
Thiết kế giải pháp tổng thể (thiết kế hệ thống, xây
|
||||
dựng mạng LAN, WAN,..)
|
||||
</p>
|
||||
</li>
|
||||
<li className="d-flex align-items-center pr-4 mb-3">
|
||||
<div className="wraper-icon">
|
||||
<i className="static-icons static-icon-polygon-6" />
|
||||
<span className="text-20 font-weight-bold gradient-color gradient-color-4">3</span>
|
||||
</div>
|
||||
<p className="font-weight-600 ml-2">
|
||||
Tư vấn và đào tạo cho khách hàng.
|
||||
</p>
|
||||
</li>
|
||||
<li className="d-flex align-items-center pr-4 mb-3">
|
||||
<div className="wraper-icon">
|
||||
<i className="static-icons static-icon-polygon-6" />
|
||||
<span className="text-20 font-weight-bold gradient-color gradient-color-4">4</span>
|
||||
</div>
|
||||
<p className="font-weight-600 ml-2">
|
||||
Các dịch vụ bảo hành, bảo trì.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="business-image">
|
||||
<img src="/images/static-about-us-pic-3.png" alt="business-image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="achievement py-6">
|
||||
<div className="container">
|
||||
<h3 className="heading-primary text-28 color-primary font-weight-600 pb-3 text-center">
|
||||
Những Thành Tựu Hoàng Hà PC Đã Đạt Được
|
||||
</h3>
|
||||
<ul className="ul grid grid--4-cols grid--gap-2 text-center">
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-top-10 mx-auto" />
|
||||
<p className="text-20 font-weight-600 mt-2">
|
||||
Top 10 nhà cung cấp máy tính tốt nhất việt nam
|
||||
</p>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-rocket mx-auto" />
|
||||
<p className="text-20 font-weight-600 mt-2">
|
||||
Tốc độ tăng trưởng đạt 200%
|
||||
</p>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-tetris mx-auto" />
|
||||
<p className="text-20 font-weight-600 mt-2">
|
||||
Đối tác chiến lược của Intel, AMD, Asus, Gigabyte, MSI
|
||||
</p>
|
||||
</li>
|
||||
<li className="p-3">
|
||||
<i className="static-icons static-icon-10-years mx-auto" />
|
||||
<p className="text-20 font-weight-600 mt-2">
|
||||
10 Năm kinh nghiệm trong lĩnh vực máy tính đồ họa, PC
|
||||
workstation
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="customer py-6 text-white font-weight-bold" style={{ backgroundColor: '#1988ec' }}>
|
||||
<div className="container">
|
||||
<h3 className="heading-primary text-28 pb-3 text-center">
|
||||
Khách Hàng Của Hoàng Hà PC
|
||||
</h3>
|
||||
<div className="grid grid--2-cols grid--gap-2">
|
||||
<div className="customer-image">
|
||||
<img src="/images/static-about-us-pic-4.png" alt="customer-image" />
|
||||
</div>
|
||||
<ul className="ul customer-list text-20">
|
||||
<li><span/> Doanh nghiệp nhà nước </li>
|
||||
<li><span/> Tập đoàn lớn </li>
|
||||
<li><span/> Doanh nghiệp tư nhân vừa và nhỏ </li>
|
||||
<li><span/> Tổ chức phi chính phủ </li>
|
||||
<li><span/> Doanh nghiệp vốn đầu tư nước ngoài </li>
|
||||
<li><span/> Trường học, bệnh viện </li>
|
||||
<li><span/> Team Youtube, MMO </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
115
src/components/account/ChangeInfo.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
export default function ChangeInfo({ customer }: any) {
|
||||
return (
|
||||
<div className="change-info">
|
||||
<h3 className="title">Thông tin tài khoản</h3>
|
||||
<form method="post" encType="multipart/form-data" name="account_form" className="col-right-tbl" id="js-customer-info">
|
||||
<table cellPadding={5} border={0} style={{
|
||||
borderCollapse: 'collapse',
|
||||
width: '100%',
|
||||
borderColor: '#CCCCCC'
|
||||
}}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Họ tên</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="fullname"
|
||||
size={40}
|
||||
defaultValue={customer?.name}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Giới tính</td>
|
||||
<td>
|
||||
<label className="inline-flex items-center gap-1 mr-3 cursor-pointer">
|
||||
<input type="radio" name="sex" defaultValue="male" defaultChecked />
|
||||
<span> Nam </span>
|
||||
</label>
|
||||
<label className="inline-flex items-center gap-1 cursor-pointer">
|
||||
<input type="radio" name="sex" defaultValue="female" />
|
||||
<span> Nữ </span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Địa chỉ email</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="email"
|
||||
size={40}
|
||||
value={customer?.email}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="old_email"
|
||||
id="old_email"
|
||||
defaultValue="ducdt@hurasoft.com"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Địa chỉ nhà</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="address"
|
||||
id="address"
|
||||
defaultValue={customer?.address || ""}
|
||||
size={50}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tỉnh / TP</td>
|
||||
<td>
|
||||
<select
|
||||
className="form-control"
|
||||
name="province"
|
||||
defaultValue="Hà Nội"
|
||||
>
|
||||
<option value="Hà Nội">Hà Nội</option><option value="TP HCM">TP HCM</option><option value="Hải Phòng">Hải Phòng</option><option value="Đà Nẵng">Đà Nẵng</option><option value="An Giang">An Giang</option><option value="Bà Rịa-Vũng Tàu">Bà Rịa-Vũng Tàu</option><option value="Bình Dương">Bình Dương</option><option value="Bình Phước">Bình Phước</option><option value="Bình Thuận">Bình Thuận</option><option value="Bình Định">Bình Định</option><option value="Bạc Liêu">Bạc Liêu</option><option value="Bắc Giang">Bắc Giang</option><option value="Bắc Kạn">Bắc Kạn</option><option value="Bắc Ninh">Bắc Ninh</option><option value="Bến Tre">Bến Tre</option><option value="Cao Bằng">Cao Bằng</option><option value="Cà Mau">Cà Mau</option><option value="Cần Thơ">Cần Thơ</option><option value="Gia Lai">Gia Lai</option><option value="Hà Giang">Hà Giang</option><option value="Hà Nam">Hà Nam</option><option value="Hà Tĩnh">Hà Tĩnh</option><option value="Hòa Bình">Hòa Bình</option><option value="Hải Dương">Hải Dương</option><option value="Hậu Giang">Hậu Giang</option><option value="Hưng Yên">Hưng Yên</option><option value="Khánh Hòa">Khánh Hòa</option><option value="Kiên Giang">Kiên Giang</option><option value="Kon Tum">Kon Tum</option><option value="Lai Châu">Lai Châu</option><option value="Lào Cai">Lào Cai</option><option value="Lâm Đồng">Lâm Đồng</option><option value="Lạng Sơn">Lạng Sơn</option><option value="Long An">Long An</option><option value="Nam Định">Nam Định</option><option value="Nghệ An">Nghệ An</option><option value="Ninh Bình">Ninh Bình</option><option value="Ninh Thuận">Ninh Thuận</option><option value="Phú Thọ">Phú Thọ</option><option value="Phú Yên">Phú Yên</option><option value="Quảng Bình">Quảng Bình</option><option value="Quảng Nam">Quảng Nam</option><option value="Quảng Ngãi">Quảng Ngãi</option><option value="Quảng Ninh">Quảng Ninh</option><option value="Quảng Trị">Quảng Trị</option><option value="Sóc Trăng">Sóc Trăng</option><option value="Sơn La">Sơn La</option><option value="Tây Ninh">Tây Ninh</option><option value="Thanh Hóa">Thanh Hóa</option><option value="Thái Bình">Thái Bình</option><option value="Thái Nguyên">Thái Nguyên</option><option value="Thừa Thiên-Huế">Thừa Thiên-Huế</option><option value="Tiền Giang">Tiền Giang</option><option value="Trà Vinh">Trà Vinh</option><option value="Tuyên Quang">Tuyên Quang</option><option value="Vĩnh Long">Vĩnh Long</option><option value="Vĩnh Phúc">Vĩnh Phúc</option><option value="Yên Bái">Yên Bái</option><option value="Đắk Lắk">Đắk Lắk</option><option value="Đồng Nai">Đồng Nai</option><option value="Đồng Tháp">Đồng Tháp</option><option value="Điện Biên">Điện Biên</option><option value="Đăk Nông">Đăk Nông</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Điện thoại di động</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
name="mobile"
|
||||
defaultValue={customer?.mobile || ""}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td />
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-danger uppercase">
|
||||
Thay đổi
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="update" defaultValue="yes" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
40
src/components/account/ChangePassword.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
export default function ChangePassword() {
|
||||
return (
|
||||
<>
|
||||
<h3 className="title">Thay đổi mật khẩu</h3>
|
||||
|
||||
<form method="post" encType="multipart/form-data" name="account_form" className="col-right-tbl">
|
||||
<table cellPadding={5} border={0} style={{ borderCollapse: 'collapse' }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="150px">Mật khẩu hiện tại</td>
|
||||
<td>
|
||||
<input type="password" name="currentpassword" id="currentpassword" className="form-control" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mật khẩu mới</td>
|
||||
<td>
|
||||
<input type="password" name="newpassword" id="newpassword" className="form-control" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Nhập lại mật khẩu</td>
|
||||
<td>
|
||||
<input type="password" name="renewpassword" id="renewpassword" className="form-control" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td />
|
||||
<td>
|
||||
<input type="submit" defaultValue="Thay đổi" className="btn btn-danger" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="update" defaultValue="yes" />
|
||||
</form>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
23
src/components/account/Comment.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
export default function Comment({ customer } : any) {
|
||||
return (
|
||||
<>
|
||||
<h3 className="title">Bình luận sản phẩm</h3>
|
||||
|
||||
<div className="account-review-page">
|
||||
<div className="item">
|
||||
<div className="item-text">
|
||||
<a href="/link/product.php?id=6434" className="item-name"> HuraSoft - Sản phẩm test (Không xóa) </a>
|
||||
<time className="item-time"> 21/10/2025 </time>
|
||||
<p className="item-rate">
|
||||
<i className="star star-4" />
|
||||
<span style={{ color: '#f51f42' }}>Chưa duyệt</span>
|
||||
<span style={{ color: '#1BB51B' }}>Đã duyệt</span>
|
||||
</p>
|
||||
<div className="item-content">account test comment</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="account-paging"></div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
40
src/components/account/Order.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
export default function Order() {
|
||||
return (
|
||||
<>
|
||||
<h3 className="title">Danh sách đơn hàng</h3>
|
||||
<div style={{ overflow: 'auto' }} className="account-order">
|
||||
<table width="100%" border={1} style={{ borderCollapse: 'collapse' }} cellPadding={4} cellSpacing={0}>
|
||||
<tbody>
|
||||
<tr className="text-center" style={{ fontWeight: 'bold', background: '#0066c1', color: '#fff' }}>
|
||||
<td>STT</td>
|
||||
<td>Số đơn hàng</td>
|
||||
<td>Giá trị</td>
|
||||
<td>Thời gian</td>
|
||||
<td>Thông tin</td>
|
||||
</tr>
|
||||
|
||||
<tr className="text-center">
|
||||
<td>1</td>
|
||||
|
||||
<td>
|
||||
#12236
|
||||
<a href="?view=order-detail&id=12236" className="table blue font-500 m-auto">Xem chi tiết</a>
|
||||
</td>
|
||||
|
||||
<td className="red font-600">
|
||||
1.990.000
|
||||
</td>
|
||||
|
||||
<td>22-10-2025</td>
|
||||
|
||||
<td>
|
||||
<span>Đang xử lý</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div >
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
0
src/components/account/OrderDetail.tsx
Normal file
23
src/components/account/Review.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
export default function Review() {
|
||||
return (
|
||||
<>
|
||||
<h3 className="title">Đánh giá sản phẩm</h3>
|
||||
<div className="account-review-page">
|
||||
<div className="item">
|
||||
<div className="item-text">
|
||||
<a href="/link/product.php?id=6434" className="item-name"> HuraSoft - Sản phẩm test (Không xóa) </a>
|
||||
<time className="item-time"> 21/10/2025 </time>
|
||||
<p className="item-rate">
|
||||
<i className="star star-4" />
|
||||
<span style={{ color: '#f51f42' }}>Chưa duyệt</span>
|
||||
<span style={{ color: '#1BB51B' }}>Đã duyệt</span>
|
||||
</p>
|
||||
<div className="item-content">account test comment</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="account-paging"></div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
96
src/components/account/index.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
'use client';
|
||||
import Link from "next/link";
|
||||
import { CustomerInfo } from "@/data/customers"
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import ChangeInfo from "./ChangeInfo";
|
||||
import Order from "./Order";
|
||||
import ChangePass from "./ChangePassword";
|
||||
import Review from "./Review";
|
||||
import Comment from "./Comment";
|
||||
|
||||
|
||||
export default function AccountPage() {
|
||||
const searchParams = useSearchParams();
|
||||
const view = searchParams.get('view');
|
||||
const customer = CustomerInfo[0];
|
||||
|
||||
const viewComponent: any = {
|
||||
"change-info": ChangeInfo,
|
||||
"order": Order,
|
||||
"product-review": Review,
|
||||
"product-comment": Comment,
|
||||
"change-pass": ChangePass,
|
||||
};
|
||||
const ActiveComponent = viewComponent[view || "change-info"];
|
||||
|
||||
console.log(customer)
|
||||
|
||||
return (
|
||||
<div className="account-page">
|
||||
<div className="container">
|
||||
<div className="account-col-left">
|
||||
<div className="box-info">
|
||||
<p>
|
||||
Tài khoản của,
|
||||
<b> {customer.name} </b>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="box-direction font-500 text-16">
|
||||
<Link href="/taikhoan?view=change-info"
|
||||
className={view === 'change-info' ? 'current' : ''}
|
||||
>
|
||||
<i className="bx bx-user text-20" />
|
||||
<span>Thông tin tài khoản</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/taikhoan?view=order"
|
||||
className={view === 'order' ? 'current' : ''}
|
||||
>
|
||||
<i className="bx bx-list-ul-square text-20" />
|
||||
<span>Danh sách đơn hàng</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/taikhoan?view=product-review"
|
||||
className={view === 'product-review' ? 'current' : ''}
|
||||
>
|
||||
<i className="bxr bx-star text-20" />
|
||||
<span>Đánh giá của tôi</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/taikhoan?view=product-comment"
|
||||
className={view === 'product-comment' ? 'current' : ''}
|
||||
>
|
||||
<i className="bxr bx-message-dots text-20" />
|
||||
<span>Bình luận của tôi</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/taikhoan?view=change-pass"
|
||||
className={view === 'change-pass' ? 'current' : ''}
|
||||
>
|
||||
<i className="bx bx-lock text-20" />
|
||||
<span>Thay đổi mật khẩu</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/san-pham-da-xem">
|
||||
<i className="bx bx-eye text-20" />
|
||||
<span>Sản phẩm đã xem</span>
|
||||
</Link>
|
||||
|
||||
<Link href="/logout.php">
|
||||
<i className="bx bx-arrow-out-right-square-half text-20" />
|
||||
<span>Đăng xuất</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="account-col-right">
|
||||
{ActiveComponent &&
|
||||
<ActiveComponent customer={customer}
|
||||
/>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
47
src/components/article/Category/article/index.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import Link from "next/link";
|
||||
import { categories } from "@/data/categories";
|
||||
import { articleList } from "@/data/articles/index";
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function ArticleList({ slug }: any) {
|
||||
|
||||
const { article } = categories.article.all_category;
|
||||
const categoryList = slug.children?.length > 0 ? slug.children : article
|
||||
|
||||
const articleData = articleList.find((item: any) => item.id === slug.id)?.list || [];
|
||||
const { displayData, hasMore, loadMore } = useShowMore(articleData, 12);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="article-categories-group bg-[#F5F8FF] flex justify-between relative overflow-auto whitespace-nowrap uppercase font-500 leading-[18px] text-[#828282] gap-5 lg:gap-1 no-scroll border-b border-[#C5CBD8]">
|
||||
{categoryList.map((item: any) => (
|
||||
<Link className={`${item.id === slug.id ? 'active' : ''}`}
|
||||
href={item.url}
|
||||
key={item.id}
|
||||
> {item.title} </Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{displayData.length == 0
|
||||
? (<p className="text-center font-600 uppercase mt-10 text-20"> Tin tức đang cập nhật ... ! </p>)
|
||||
: (
|
||||
<>
|
||||
<div className="article-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
{displayData.map((item: any) =>
|
||||
<ArticleItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasMore &&
|
||||
<ShowMoreButton onClick={loadMore} />
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,312 +1,30 @@
|
||||
export default function ArticleCategory({ slug }: { slug: string }) {
|
||||
return(
|
||||
<>
|
||||
<h1 className="absolute top-[-999px] z-[-1]"> Danh mục tin </h1>
|
||||
<div className="article-page container !mt-8 mt-6">
|
||||
{/* <style>body{background: #F5F8FF}</style> */}
|
||||
<div className="article-categories-group bg-[#F5F8FF] flex justify-between relative overflow-auto whitespace-nowrap uppercase font-500 leading-[18px] text-[#828282] gap-5 lg:gap-1 no-scroll border-b border-[#C5CBD8]">
|
||||
<a href="" className="active">
|
||||
{" "}
|
||||
MÁY KHỎE - ĐẸP{" "}
|
||||
</a>
|
||||
<a href=""> TIN CÔNG NGHỆ </a>
|
||||
<a href=""> REVIEW SẢN PHẨM </a>
|
||||
<a href=""> BENCHMARKS </a>
|
||||
<a href=""> THỦ THUẬT </a>
|
||||
<a href=""> KHUYẾN MÃI </a>
|
||||
<a href=""> WIKI </a>
|
||||
<a href=""> tin game </a>
|
||||
'use client';
|
||||
import { useEffect } from 'react';
|
||||
import ArticleList from "./article"
|
||||
import VideoList from "./video";
|
||||
|
||||
export default function ArticleCategory({ slug }: any) {
|
||||
useEffect(() => {
|
||||
document.body.style.background = '#F5F8FF';
|
||||
}, []);
|
||||
|
||||
const { type } = slug;
|
||||
|
||||
return (
|
||||
<> <h1 className="absolute top-[-999px] z-[-1]"> {slug.title} </h1>
|
||||
|
||||
<div className="article-page container !mt-8 mt-6">
|
||||
{
|
||||
type === 'article'
|
||||
&& <ArticleList slug={slug} />
|
||||
}
|
||||
|
||||
{
|
||||
type === 'video'
|
||||
&& <VideoList slug={slug} />
|
||||
}
|
||||
|
||||
</div>
|
||||
{/* Tin tức */}
|
||||
<div className="article-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
{" "}
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?{" "}
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum
|
||||
fugit facere illo quos. Ad error suscipit, quidem optio aut
|
||||
laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time> 23/4/2024 </time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span> Mai Văn Học </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum
|
||||
fugit facere illo quos. Ad error suscipit, quidem optio aut
|
||||
laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum
|
||||
fugit facere illo quos. Ad error suscipit, quidem optio aut
|
||||
laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum
|
||||
fugit facere illo quos. Ad error suscipit, quidem optio aut
|
||||
laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum
|
||||
fugit facere illo quos. Ad error suscipit, quidem optio aut
|
||||
laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Video */}
|
||||
<div className="article-holder article-video-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />
|
||||
</span>
|
||||
<span className="item-title">
|
||||
{" "}
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070{" "}
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{/* Paging */}
|
||||
<div className="my-10 flex flex-wrap items-center justify-center gap-4 leading-10 text-center text-16 font-500">
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent bg-[#004BA4] text-white border-transparent"
|
||||
>
|
||||
{" "}
|
||||
1{" "}
|
||||
</a>
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
2{" "}
|
||||
</a>{" "}
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
3{" "}
|
||||
</a>{" "}
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
4{" "}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
)
|
||||
|
||||
58
src/components/article/Category/video/index.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
'use client';
|
||||
import { Fancybox } from "@fancyapps/ui";
|
||||
import { useEffect } from "react";
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import { VideoData } from "@/data/articles/Video";
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
|
||||
export default function VideoList() {
|
||||
|
||||
useEffect(() => {
|
||||
Fancybox.bind('[data-fancybox]', {});
|
||||
return () => Fancybox.destroy();
|
||||
}, []);
|
||||
|
||||
const { displayData, hasMore, loadMore } = useShowMore(VideoData.list, 12);
|
||||
|
||||
return (
|
||||
<>
|
||||
{displayData.length == 0
|
||||
? (<p className="text-center font-600 uppercase mt-10 text-20"> Tin tức đang cập nhật ... ! </p>)
|
||||
: (
|
||||
<>
|
||||
<div className="article-holder article-video-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
{
|
||||
displayData.map((item: any) =>
|
||||
<a
|
||||
key={item.id}
|
||||
href={item.video_code}
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
rel="nofollow"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src={item.image.original}
|
||||
alt={item.title}
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />
|
||||
</span>
|
||||
|
||||
<span className="item-title">
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
{ hasMore &&
|
||||
<ShowMoreButton onClick={loadMore} />
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
58
src/components/article/Home/ArticleCategories.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import Link from "next/link";
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function ArticleCategories({ item, data }: any) {
|
||||
|
||||
const firstItem = data[0];
|
||||
const itemList = data.slice(1, 5);
|
||||
|
||||
return (
|
||||
<div className="article-category-container" id={`js-category-${item.id}`} key={item.id}>
|
||||
<div className="container">
|
||||
<div className="group-title flex flex-wrap items-center justify-between gap-4 mb-4 lg:mb-6">
|
||||
<div className="flex items-center gap-2 lg:gap-3">
|
||||
<h2 className="m-0 font-600 text-[#004BA4] text-20 leading-6 lg:leading-10 lg:text-[32px]">
|
||||
{item.title}
|
||||
</h2>
|
||||
|
||||
<Link href={item.url}
|
||||
className="bx bx-chevron-right border-[1.5px] border-[#0677DB4D] rounded-full w-5 lg:w-8 h-5 lg:h-8 flex items-center justify-center text-[#0678DB] text-18 lg:text-[24px] hover:bg-[#0678DB] hover:text-white"
|
||||
></Link>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-auto flex gap-2 leading-[30px] text-[#0678DB] font-600 text-16 overflow-auto whitespace-nowrap no-scroll">
|
||||
{item.children.map((child: any) =>
|
||||
<Link className="bg-[#EAF1FF] px-2 rounded-[30px] hover:bg-[#0678DB] hover:text-white"
|
||||
href={child.url}
|
||||
key={child.id}
|
||||
>
|
||||
{child.title}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!data || data.length === 0 ?
|
||||
(
|
||||
<p className="text-center font-600 uppercase mt-10 text-20"> Tin tức đang cập nhật ... ! </p>
|
||||
) : (
|
||||
<div className="article-category-holder grid lg:grid-cols-2 gap-5 lg:gap-8">
|
||||
<div className="first-item">
|
||||
<ArticleItem item={firstItem} />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 lg:gap-6">
|
||||
{itemList.map((item: any) =>
|
||||
<ArticleItem
|
||||
item={item}
|
||||
key={item.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
125
src/components/article/Home/Tiktok.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
import Link from "next/link";
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Pagination, Autoplay } from 'swiper/modules';
|
||||
|
||||
export default function Tiktok() {
|
||||
|
||||
return (
|
||||
<div className="article-tiktok-container py-8 lg:py-16">
|
||||
<div className="group-title flex items-center justify-between flex-wrap gap-4 mb-6">
|
||||
<h2 className="flex items-center m-0 leading-8 font-600 text-20 text-[#004BA4] gap-[10px] lg:gap-4 lg:text-[32px] lg:leading-10">
|
||||
<i className="lazy bg-no-repeat bg-center bg-[length:100%_100%] w-8 h-8 lg:w-12 lg:h-12"
|
||||
style={{ backgroundImage: 'url(images/logo-tiktok.png)' }}
|
||||
/>
|
||||
<span> Tiktok Channel </span>
|
||||
</h2>
|
||||
|
||||
<div className="flex flex-wrap items-center justify-center text-center bg-[#DCE8FF] rounded-[16px_0_] leading-5 lg:leading-6 lg:text-[16px] gap-3 lg:w-[823px] w-full p-3 lg:p-4">
|
||||
<i className="icons icon-finger !w-6 !h-6 animation-wiggle" />
|
||||
<div className="lg:flex flex-wrap">
|
||||
<p className="m-0 mr-1">
|
||||
Theo dõi kênh tiktok của Hoàng hà PC:
|
||||
</p>
|
||||
|
||||
<Link
|
||||
href="https://www.tiktok.com/@hoangha.pc"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="text-[#0678DB] font-600 table lg:text-[16px]"
|
||||
>
|
||||
ORIGINAL SOUND - HOÀNG HÀ PC
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="swiper overflow-hidden" id="js-tiktok-slide">
|
||||
<Swiper
|
||||
spaceBetween={16}
|
||||
slidesPerView={1.7}
|
||||
loop={true}
|
||||
autoplay={{
|
||||
delay: 3000,
|
||||
disableOnInteraction: false,
|
||||
}}
|
||||
modules={[Pagination, Autoplay]}
|
||||
speed={1000}
|
||||
breakpoints= {{
|
||||
414: {
|
||||
slidesPerView: 2
|
||||
},
|
||||
576: {
|
||||
slidesPerView: 3
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4
|
||||
},
|
||||
1024: {
|
||||
slidesPerView: 6
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7260350983039945985" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-sieu-vip-pro.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16">Đơn hàng cho công ty VIP PRO</span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7259685093806034177" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn hàng đặc biệt cho khách vip </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7259272220093041926" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-pc-200-trieu.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn PC hơn 200 củ </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7256640817752820997" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-pc-300-trieu.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn hàng hơn 300 củ có gì? </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7249589730000522501" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/pc-dau-than.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> PC Full trắng vừa đẹp vừa khỏe </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7245136755375049989" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/pc-80-trieu-co-gi.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> PC 80 củ có gì? </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
63
src/components/article/Home/TopArticleList.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
'use client';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Pagination, Autoplay } from 'swiper/modules';
|
||||
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function TopArticleList({ item }: any) {
|
||||
|
||||
const leftItems = item.slice(0, 7);
|
||||
const rightItems = item.slice(7, 10);
|
||||
|
||||
return (
|
||||
<div className="top-article-container container flex flex-wrap gap-6 !mb-2 lg:!mb-6">
|
||||
<div className="col-left w-full lg:w-[718px] swiper overflow-hidden relative">
|
||||
<Swiper
|
||||
spaceBetween={10}
|
||||
slidesPerView={1}
|
||||
loop={true}
|
||||
autoplay={{
|
||||
delay: 3000,
|
||||
disableOnInteraction: false,
|
||||
}}
|
||||
modules={[Pagination, Autoplay]}
|
||||
pagination={{ clickable: true }}
|
||||
>
|
||||
{leftItems.map((item: any) => (
|
||||
<SwiperSlide key={item.id}>
|
||||
<Link href={item.url}
|
||||
{...(item.external_url ? {
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
} : {})}
|
||||
>
|
||||
<Image
|
||||
src={item.image.original}
|
||||
alt={item.title}
|
||||
width={100}
|
||||
height={100}
|
||||
unoptimized
|
||||
className="block w-full rounded-[16px]"
|
||||
/>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
|
||||
<div className="col-right w-full lg:w-[calc(100%-742px)]">
|
||||
<p className="font-600 text-20 leading-6 lg:text-[24px] lg:leading-8 mb-3">
|
||||
Tin nổi bật
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
{
|
||||
rightItems.map((item: any) => <ArticleItem key={item.id} item={item} />)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
86
src/components/article/Home/Video.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import Link from "next/link";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { VideoData } from "@/data/articles/Video";
|
||||
|
||||
export default function Video( {item} : any ) {
|
||||
const { total, list } = VideoData;
|
||||
const [active, setActive] = useState<number | null>(null);
|
||||
const [url, setUrl] = useState<string>("");
|
||||
|
||||
// set video mặc định
|
||||
useEffect(() => {
|
||||
if (list?.length > 0) {
|
||||
setActive(list[0].id);
|
||||
setUrl(list[0].video_code);
|
||||
}
|
||||
}, [list]);
|
||||
|
||||
const videoId = useMemo(() => {
|
||||
if (!url) return null;
|
||||
|
||||
// https://www.youtube.com/watch?v=xxxx
|
||||
if (url.includes('v=')) {
|
||||
return url.split('v=')[1].split('&')[0];
|
||||
}
|
||||
|
||||
// https://youtu.be/xxxx
|
||||
if (url.includes('youtu.be/')) {
|
||||
return url.split('youtu.be/')[1].split('?')[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [url]);
|
||||
|
||||
return (list.length > 0 &&
|
||||
<div className="article-video-container lg:flex flex-wrap gap-4 mt-16">
|
||||
<div className="lg:w-[732px] video-holder">
|
||||
{videoId && (
|
||||
<iframe
|
||||
src={`https://www.youtube.com/embed/${videoId}`}
|
||||
allowFullScreen
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="lg:w-[calc(100%-748px)] rounded-[16px] overflow-hidden bg-[#EAF1FF]">
|
||||
<p className="group-title m-0 text-white flex items-center gap-2 lg:gap-3 font-600 p-[8px_12px] leading-[18px] lg:text-[20px] lg:leading-6 lg:p-[12px_16px] bg-[linear-gradient(180.3deg,#259AFF_-18.56%,#114CDD_100.92%)]">
|
||||
<i className="w-[18px] h-[18px] lg:w-6 lg:h-6 lazy bg-no-repeat bg-center bg-[length:100%_100%]"
|
||||
style={{ backgroundImage: 'url(/images/icon-playlist.png)' }}
|
||||
/>
|
||||
<Link href={item[0].url}> Trending video </Link>
|
||||
</p>
|
||||
|
||||
<div className="h-[385px] p-4 pr-1 relative">
|
||||
<div className="h-full overflow-auto flex flex-col gap-4">
|
||||
{list.map((item: any) =>
|
||||
<button type="button"
|
||||
key={item.id}
|
||||
onClick={() => {
|
||||
setActive(item.id);
|
||||
setUrl(item.video_code)
|
||||
}}
|
||||
className={`video-item text-left
|
||||
${active === item.id ? 'color-main' : ''}
|
||||
`}
|
||||
>
|
||||
<span className="video-img">
|
||||
<img
|
||||
src={item.image.original}
|
||||
alt={item.title}
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<p className="video-title m-0">
|
||||
<span>{item.title}</span>
|
||||
</p>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="gradient-overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,218 +1,110 @@
|
||||
export default function ArticleDetail({ slug }: { slug: string }) {
|
||||
return(
|
||||
'use client';
|
||||
import Link from "next/link";
|
||||
import parse from "html-react-parser";
|
||||
import { useEffect } from 'react';
|
||||
import { formatArticleTime } from "@/lib/utils";
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function ArticleDetail({ slug }: any) {
|
||||
useEffect(() => {
|
||||
document.body.style.background = '#ffffff';
|
||||
}, []);
|
||||
|
||||
const time = slug.article_time || slug.lastUpdate;
|
||||
|
||||
return (
|
||||
<>
|
||||
<link
|
||||
href="https://cdn.boxicons.com/fonts/brands/boxicons-brands.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<div className="container !mt-8 mt-6">
|
||||
{/* <style> body{background: #fff;} </style> */}
|
||||
<div className="article-detail-page max-w-[824px] m-auto my-8">
|
||||
<a
|
||||
href=""
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="table border border-[#76BBFF80] rounded-[30px] bg-[#EAF1FF] px-5 leading-8 mb-3"
|
||||
>
|
||||
<span className="text-[#004BA4]"> Hoàng Hà PC trên </span>
|
||||
<span className="text-[#4285F4]">G</span>
|
||||
<span className="text-[#EA4335]">o</span>
|
||||
<span className="text-[#FBBC05]">o</span>
|
||||
<span className="text-[#4285F4]">g</span>
|
||||
<span className="text-[#34A853]">l</span>
|
||||
<span className="text-[#EA4335]">e</span>
|
||||
<span className="text-[#5F6368]"> News </span>
|
||||
</a>
|
||||
<h1 className="font-600 text-[#004BA4] text-20 leading-6 lg:leading-10 lg:text-[32px] mb-3">
|
||||
{" "}
|
||||
{"{"}
|
||||
{"{"} page.article_detail.title {"}"}
|
||||
{"}"}{" "}
|
||||
</h1>
|
||||
<div className="lg:text-[16px] lg:leading-[22px] flex items-center gap-1 mb-6 lg:mb-8">
|
||||
<i className="icons icon-time mr-1" />
|
||||
<span> Thứ sáu 25/07/2025 </span>
|
||||
<span>|</span>
|
||||
<a href=""> Mai Văn Học </a>
|
||||
</div>
|
||||
<div className="article-content lg:leading-6 lg:text-[18px]">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aspernatur
|
||||
quaerat vero itaque voluptatum? Repellendus laudantium est doloribus
|
||||
saepe accusantium, illo numquam ullam deserunt expedita repudiandae
|
||||
ipsam libero, temporibus soluta eius.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center flex-wrap lg:gap-[30px] gap-5 mb-8">
|
||||
<p className="m-0">SHARE</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<a
|
||||
href=""
|
||||
rel="nofollow"
|
||||
className="bx bx-share w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
rel="nofollow"
|
||||
className="bxl bx-facebook w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
rel="nofollow"
|
||||
className="bxl bx-youtube w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
rel="nofollow"
|
||||
className="bxl bx-instagram-alt w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
rel="nofollow"
|
||||
className="bxl bx-tiktok w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10 lg:mt-12">
|
||||
<p className="font-600 text-[32px] leading-10 mb-6 lg:text-[40px] lg:leading-12 lg:mb-8">
|
||||
{" "}
|
||||
Bài viết liên quan{" "}
|
||||
</p>
|
||||
{/* Limit: 4 */}
|
||||
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4 lg:gap-6">
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
||||
aut laudantium at!
|
||||
<link href="https://cdn.boxicons.com/fonts/brands/boxicons-brands.min.css" rel="stylesheet" />
|
||||
|
||||
<div className="container !mt-8 mt-6">
|
||||
<div className="article-detail-page max-w-[824px] m-auto my-8">
|
||||
<Link
|
||||
href=""
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="table border border-[#76BBFF80] rounded-[30px] bg-[#EAF1FF] px-5 leading-8 mb-3"
|
||||
>
|
||||
<span className="text-[#004BA4]"> Hoàng Hà PC trên </span>
|
||||
<span className="text-[#4285F4]">G</span>
|
||||
<span className="text-[#EA4335]">o</span>
|
||||
<span className="text-[#FBBC05]">o</span>
|
||||
<span className="text-[#4285F4]">g</span>
|
||||
<span className="text-[#34A853]">l</span>
|
||||
<span className="text-[#EA4335]">e</span>
|
||||
<span className="text-[#5F6368]"> News </span>
|
||||
</Link>
|
||||
|
||||
<h1 className="font-600 text-[#004BA4] text-20 leading-6 lg:leading-10 lg:text-[32px] mb-3">
|
||||
{slug.title}
|
||||
</h1>
|
||||
|
||||
<div className="lg:text-[16px] lg:leading-[22px] flex items-center gap-1 mb-6 lg:mb-8">
|
||||
<i className="icons icon-time mr-1" />
|
||||
<span> {formatArticleTime(time)} </span>
|
||||
<span>|</span>
|
||||
<a href="/author/mai-van-hoc"> {slug.author} </a>
|
||||
</div>
|
||||
|
||||
<div className="article-content lg:leading-5 lg:text-[16px] text-justify">
|
||||
{parse(slug.content)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-wrap lg:gap-[30px] gap-5 mb-8">
|
||||
<p className="m-0">SHARE</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bx bx-share w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-facebook w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-youtube w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-instagram-alt w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-tiktok w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
></Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{slug.related.article &&
|
||||
<div className="mt-10 lg:mt-12">
|
||||
<p className="font-600 text-[32px] leading-10 mb-6 lg:text-[40px] lg:leading-12 lg:mb-8">
|
||||
Bài viết liên quan
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4 lg:gap-6">
|
||||
{
|
||||
slug.related.article.slice(0, 4).map((item: any) =>
|
||||
<ArticleItem
|
||||
item={item}
|
||||
key={item.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
||||
aut laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
||||
aut laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
/>
|
||||
</a>
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum
|
||||
quidem asperiores provident dicta veniam deleniti eaque
|
||||
repudiandae cum esse, ducimus officiis quibusdam pariatur neque
|
||||
voluptates voluptas. Quisquam qui minus dolorum?
|
||||
</h3>
|
||||
</a>
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit,
|
||||
obcaecati ducimus veritatis aliquid sunt accusamus unde nisi
|
||||
nostrum fugit facere illo quos. Ad error suscipit, quidem optio
|
||||
aut laudantium at!
|
||||
</div>
|
||||
<div className="art-time">
|
||||
<i className="bx bx-calendar-alt text-16 text-[#A0A5AC]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
21
src/components/buildpc/Buttons.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
export default function Buttons() {
|
||||
return (
|
||||
<div className="buildpc-btn-action">
|
||||
<button className="item" data-action="create-image">
|
||||
Tải ảnh cấu hình <i className="bxr bx-chevron-down" />
|
||||
</button>
|
||||
|
||||
<button className="item" data-action="download-excel">
|
||||
Tải file excel cấu hình <i className="bxr bx-chevron-down" />
|
||||
</button>
|
||||
|
||||
<button className="item" data-action="view">
|
||||
<i className="bx bx-window " /> Xem & In
|
||||
</button>
|
||||
|
||||
<button className="item btn-cart" data-action="add-cart">
|
||||
<i className="icon-cart" /> Thêm vào giỏ hàng
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
59
src/components/buildpc/Content.tsx
Normal file
52
src/components/buildpc/Popups.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
export default function Popups({ onRebuild }: any) {
|
||||
|
||||
return (<>
|
||||
{/* Rebuild */}
|
||||
<div className="buildpc-popup-container buildpc-popup-rebuild text-black" id="popup-rebuild_config">
|
||||
<div className="popup-content-group">
|
||||
<i className="fa fa-exclamation-circle" />
|
||||
<b>LÀM MỚI</b>
|
||||
<p>Cảnh báo: Toàn bộ linh kiện của bộ PC hiện tại sẽ bị xóa đi</p>
|
||||
|
||||
<div className="popup-btn-group">
|
||||
<button className="btn-cancel" data-fancybox-close> Hủy </button>
|
||||
|
||||
<button
|
||||
className="btn-red"
|
||||
style={{ background: '#FA354A', color: '#fff' }}
|
||||
onClick={() => {
|
||||
onRebuild();
|
||||
}}>
|
||||
Xác nhận
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* error */}
|
||||
<div className="buildpc-popup-container buildpc-popup-rebuild" id="fancybox-opps">
|
||||
<div className="popup-content-group">
|
||||
<i className="fa fa-exclamation-circle" />
|
||||
<b>OPPS...</b>
|
||||
<p>Bạn chưa chọn sản phẩm nào</p>
|
||||
<div className="popup-btn-group">
|
||||
<button className="btn-red js-close-popup" style={{ background: '#FA354A', color: '#fff' }} onClick={() => { /* Fancybox.close(); */ }}> OK </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Popup variant */}
|
||||
<div className="popup-select-variant-container" id="js-popup-select-variant-container">
|
||||
<div className="popup-select-content">
|
||||
<div className="popup-title">
|
||||
<p className="m-0 font-600 text-20">CHỌN CẤU HÌNH</p>
|
||||
<a href="javascript:void(0)"
|
||||
onClick={() => { /* $('.popup-select-variant-container').hide(); $('#js-product-selected-info-holder, #js-variant-containe').html('');*/ }} className="bx bx-x font-600" />
|
||||
</div>
|
||||
<div id="js-product-selected-info-holder">{/* load variant item */} </div>
|
||||
<div className="popup-select-holder" id="js-variant-container">{/* load variant list */} </div>
|
||||
<button type="button" className="popup-select-btn">CHỌN CẤU HÌNH NÀY</button>
|
||||
</div>
|
||||
</div>
|
||||
</>)
|
||||
}
|
||||
17
src/components/buildpc/Promotion.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
export default function Promotion({ total }: any) {
|
||||
return (
|
||||
<div className="buildpc-info-group">
|
||||
<p>
|
||||
Chi phí dự tính:
|
||||
<span
|
||||
className="font-600"
|
||||
style={{ color: '#FF4E2A' }}
|
||||
>
|
||||
{total.toLocaleString()} đ
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div className="buildpc-promotion-content" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
142
src/components/buildpc/categories/index.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
'use client';
|
||||
import { useEffect, useState } from "react";
|
||||
import { Fancybox } from "@fancyapps/ui/dist/fancybox/";
|
||||
import { categoryDetail } from "@/data/buildpc/categoryDetail";
|
||||
import ModalContent from "../modal";
|
||||
import SelectedItemRow from "../modal/SelectedItemRow";
|
||||
|
||||
export default function BuildPCCategories({
|
||||
categories,
|
||||
activeTab,
|
||||
buildData,
|
||||
setBuildData
|
||||
}: any) {
|
||||
|
||||
const [selectedCategory, setSelectedCategory] = useState<any>(null);
|
||||
const [categoryInfo, setCategoryInfo] = useState<any>(null);
|
||||
|
||||
const getStorageKey = () => `buildpc_tab_${activeTab}`;
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCategory) {
|
||||
const filterCategory = categoryDetail.find(
|
||||
(item: any) => item.id === selectedCategory
|
||||
);
|
||||
setCategoryInfo(filterCategory);
|
||||
}
|
||||
}, [selectedCategory]);
|
||||
|
||||
const handleSaveProduct = (rowId: number, product: any) => {
|
||||
|
||||
const newData = [
|
||||
...buildData.filter((b: any) => b.rowId !== rowId), // loại bỏ row cũ
|
||||
{
|
||||
rowId,
|
||||
info: [product]
|
||||
}
|
||||
];
|
||||
|
||||
localStorage.setItem(getStorageKey(), JSON.stringify(newData));
|
||||
setBuildData(newData);
|
||||
|
||||
window.dispatchEvent(new Event("buildpcUpdated"));
|
||||
};
|
||||
|
||||
// ==============================
|
||||
// REMOVE
|
||||
// ==============================
|
||||
const handleRemove = (rowId: number) => {
|
||||
const newData = buildData.filter((b: any) => b.rowId !== rowId);
|
||||
localStorage.setItem(getStorageKey(), JSON.stringify(newData));
|
||||
setBuildData(newData);
|
||||
};
|
||||
|
||||
// ==============================
|
||||
// QUANTITY
|
||||
// ==============================
|
||||
const handleQuantityChange = (rowId: number, quantity: number) => {
|
||||
|
||||
const newData = buildData.map((b: any) => {
|
||||
if (b.rowId === rowId) {
|
||||
return {
|
||||
...b,
|
||||
info: [
|
||||
{
|
||||
...b.info[0],
|
||||
quantity
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
return b;
|
||||
});
|
||||
|
||||
localStorage.setItem(getStorageKey(), JSON.stringify(newData));
|
||||
setBuildData(newData);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="buildpc-holder-container">
|
||||
{categories.map((item: any, index: number) => {
|
||||
|
||||
const selectedBuild = buildData.find((b: any) => b.rowId === item.id);
|
||||
|
||||
const product = selectedBuild?.info?.[0];
|
||||
|
||||
return (
|
||||
<div className="item-drive" key={item.id}>
|
||||
<p className="item-title leading-5">
|
||||
<span>{index + 1}. {item.name}</span>
|
||||
</p>
|
||||
|
||||
<div className="item-drive-info">
|
||||
{ product
|
||||
? (
|
||||
<SelectedItemRow
|
||||
product={product}
|
||||
rowId={item.id}
|
||||
onRemove={handleRemove}
|
||||
onQuantityChange={handleQuantityChange}
|
||||
onEdit={(rowId: number) => setSelectedCategory(rowId)}
|
||||
/>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="open-selection"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
setSelectedCategory(item.id);
|
||||
|
||||
Fancybox.show([
|
||||
{
|
||||
src: "#js-modal-popup",
|
||||
type: "inline",
|
||||
},
|
||||
]);
|
||||
}}
|
||||
>
|
||||
<i className="bx bx-plus" /> Chọn {item.name}
|
||||
</button>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="buildpc-modal-popup-container text-black"
|
||||
id="js-modal-popup"
|
||||
style={{ display: 'none', padding: 0 }}
|
||||
>
|
||||
<ModalContent
|
||||
item={categoryInfo}
|
||||
onSave={handleSaveProduct}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
147
src/components/buildpc/index.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
'use client';
|
||||
import Link from "next/link";
|
||||
import useFancybox from '@/hooks/useFancyBox';
|
||||
import { Fancybox } from "@fancyapps/ui/dist/fancybox/";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { buildPcData } from "@/data/buildpc";
|
||||
|
||||
import Content from "./Content";
|
||||
import BuildPCCategories from "./categories";
|
||||
import BuildPcPopups from "./Popups";
|
||||
import Promotion from "./Promotion";
|
||||
import Buttons from "./Buttons";
|
||||
|
||||
|
||||
export default function BuildPc() {
|
||||
|
||||
const [fancyboxRef] = useFancybox({});
|
||||
|
||||
const [activeTab, setActiveTab] = useState(1);
|
||||
const [buildData, setBuildData] = useState<any[]>([]);
|
||||
|
||||
const getStorageKey = (tab: number) => `buildpc_tab_${tab}`;
|
||||
|
||||
// Load data khi đổi tab
|
||||
useEffect(() => {
|
||||
const oldData = localStorage.getItem(getStorageKey(activeTab));
|
||||
setBuildData(oldData ? JSON.parse(oldData) : []);
|
||||
}, [activeTab]);
|
||||
|
||||
|
||||
const handleTabChange = (tabIndex: number) => {
|
||||
setActiveTab(tabIndex);
|
||||
};
|
||||
|
||||
const handleRebuild = () => {
|
||||
const storageKey = getStorageKey(activeTab);
|
||||
|
||||
localStorage.removeItem(storageKey);
|
||||
|
||||
setBuildData([]);
|
||||
|
||||
Fancybox.close();
|
||||
};
|
||||
|
||||
const totalPrice = useMemo(() => {
|
||||
return buildData.reduce((total, item) => {
|
||||
const product = item?.info?.[0];
|
||||
if (!product) return total;
|
||||
|
||||
const price = Number(product.price) || 0;
|
||||
const quantity = Number(product.quantity) || 1;
|
||||
|
||||
return total + (price * quantity);
|
||||
}, 0);
|
||||
}, [buildData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={fancyboxRef}>
|
||||
<div className="global-breadcrumb">
|
||||
<div className="container">
|
||||
<ol itemScope itemType="http://schema.org/BreadcrumbList" className="ul clearfix">
|
||||
<li itemProp="itemListElement" itemScope itemType="http://schema.org/ListItem">
|
||||
<Link href="/" itemProp="item" className="nopad-l">
|
||||
<span itemProp="name">Trang chủ</span>
|
||||
</Link>
|
||||
<meta itemProp="position" content="1" />
|
||||
</li>
|
||||
<li itemProp="itemListElement" itemScope itemType="http://schema.org/ListItem">
|
||||
<Link href="https://hoanghapc.vn/buildpc" itemProp="item" className="nopad-l">
|
||||
<span itemProp="name"> Xây dựng máy tính - tạo máy tính </span>
|
||||
</Link>
|
||||
<meta itemProp="position" content="2" />
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="buildpc-page">
|
||||
<div className="container">
|
||||
<h1 className="mb-6 font-600 text-[#004BA4] text-20 leading-6 lg:leading-10 lg:text-[32px]">
|
||||
Xây Dựng Cấu Hình Máy Tính
|
||||
</h1>
|
||||
|
||||
<div className="overflow-hidden relative mb-6">
|
||||
<Link href="">
|
||||
<img src="https://hoanghapccdn.com/media/banner/23_02-a0bcc210735ecfa67eccf8a434ab61b1.jpg"
|
||||
alt="Banner"
|
||||
width={100}
|
||||
height={100}
|
||||
className="block w-full h-full lazy"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="btn-buildpc-group mb-6">
|
||||
{
|
||||
[1, 2, 3, 4, 5].map((item) => (
|
||||
<button
|
||||
key={item}
|
||||
type="button"
|
||||
className={item === activeTab ? "active" : ""}
|
||||
onClick={() => handleTabChange(item)}
|
||||
>
|
||||
Cấu hình {item}
|
||||
</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="buildpc-detail-group gap-4">
|
||||
<Promotion total={totalPrice} />
|
||||
|
||||
<Link
|
||||
href="#popup-rebuild_config"
|
||||
data-fancybox=""
|
||||
className="flex items-center gap-3 bg-btn text-white rounded-[30px] leading-10 text-16 font-500 px-6"
|
||||
>
|
||||
LÀM MỚI <i className="bx bx-rotate-ccw" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<BuildPCCategories
|
||||
categories={ buildPcData.category_config }
|
||||
activeTab={ activeTab }
|
||||
buildData={ buildData }
|
||||
setBuildData={ setBuildData }
|
||||
/>
|
||||
|
||||
<div className="flex flex-wrap items-center justify-between text-18 font-500 leading-6">
|
||||
<Promotion total={totalPrice} />
|
||||
|
||||
<Buttons />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Content />
|
||||
|
||||
<BuildPcPopups
|
||||
onRebuild={handleRebuild}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
73
src/components/buildpc/modal/Filter.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
export default function Filter({
|
||||
attributeFilter,
|
||||
brandFilter,
|
||||
priceFilter
|
||||
}: any) {
|
||||
|
||||
return (
|
||||
<div className="popup-filter-holder">
|
||||
|
||||
{ brandFilter && brandFilter.length > 0 &&
|
||||
<div className="filter-item brand-filter">
|
||||
<p className="filter-name capitalize"> Hãng sản xuất </p>
|
||||
|
||||
<div className="filter-list-holder">
|
||||
{
|
||||
brandFilter.map((item: any) => (
|
||||
<label key={item.id}>
|
||||
<input type="checkbox"
|
||||
defaultChecked={item.is_selected === 1}
|
||||
/>
|
||||
<span className="value-filter">{item.name} ({item.count})</span>
|
||||
</label>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
{ priceFilter && priceFilter.length > 0 &&
|
||||
<div className="filter-item">
|
||||
<p className="filter-name capitalize"> Khoảng giá </p>
|
||||
|
||||
<div className="filter-list-holder">
|
||||
{
|
||||
priceFilter.map((item: any, index: number) => (
|
||||
<label key={`price-${index}`}>
|
||||
<input type="checkbox"
|
||||
defaultChecked={item.is_selected === 1}
|
||||
/>
|
||||
<span className="value-filter">{item.name} ({item.count})</span>
|
||||
</label>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
{ attributeFilter && attributeFilter.length > 0 &&
|
||||
attributeFilter.map((item: any, index: number) => (
|
||||
<div key={index} className="filter-item" >
|
||||
<p className="filter-name capitalize"> {item.name} </p>
|
||||
|
||||
<div className="filter-list-holder">
|
||||
{
|
||||
item.value_list.map((value: any) => (
|
||||
<label key={value.id}>
|
||||
<input type="checkbox"
|
||||
defaultChecked={item.is_selected === 1}
|
||||
/>
|
||||
|
||||
<span className="value-filter capitalize">
|
||||
{value.name} ({value.count})
|
||||
</span>
|
||||
</label>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||