update 16:18 12/05

This commit is contained in:
2025-05-12 16:18:45 +07:00
parent 26d6c8ec81
commit 0f914a48ea
9 changed files with 3008 additions and 19 deletions

View File

@@ -7,15 +7,14 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="./src/assets/css/font.css"> <link rel="stylesheet" href="./src/assets/css/font.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" />
<link rel="stylesheet" href="../src/assets/css/style.css" rel="stylesheet" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<link rel="stylesheet" href="/src/assets/css/style.css" rel="stylesheet" />
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/index.tsx"></script> <script type="module" src="./src/index.tsx"></script>
</body> </body>
</html> </html>

177
package-lock.json generated
View File

@@ -5,8 +5,11 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"@fancyapps/ui": "^5.0.36",
"preact": "^10.26.6", "preact": "^10.26.6",
"preact-iso": "^2.9.1", "preact-iso": "^2.9.1",
"react-fancybox": "^1.0.2",
"react-slick": "^0.30.3",
"swiper": "^11.2.6", "swiper": "^11.2.6",
"tailwindcss": "^4.1.5" "tailwindcss": "^4.1.5"
}, },
@@ -829,6 +832,11 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@fancyapps/ui": {
"version": "5.0.36",
"resolved": "https://registry.npmjs.org/@fancyapps/ui/-/ui-5.0.36.tgz",
"integrity": "sha512-GMygQzp1MBTFNTT6AzpbL6pXTD6bTxwjmmpI1fe8Ozmmiseu8/g82Sudl1YhcbZmS4bJgaBOF5THDFGpXQ1fDw=="
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -1711,6 +1719,11 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
"node_modules/color-convert": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1978,6 +1991,11 @@
"integrity": "sha512-qS+qH9oqVYc1ooubTiB9l904WVyM6qNYxtOEEGReoZXw3xlqeYdFr5GclNzbkAufWgwWLEPoDi3d9MoRwwIjGw==", "integrity": "sha512-qS+qH9oqVYc1ooubTiB9l904WVyM6qNYxtOEEGReoZXw3xlqeYdFr5GclNzbkAufWgwWLEPoDi3d9MoRwwIjGw==",
"dev": true "dev": true
}, },
"node_modules/enquire.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
"integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw=="
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -3367,6 +3385,14 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true "dev": true
}, },
"node_modules/json2mq": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
"integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
"dependencies": {
"string-convert": "^0.2.0"
}
},
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -3437,6 +3463,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
"node_modules/lodash.memoize": { "node_modules/lodash.memoize": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -3908,12 +3939,54 @@
} }
] ]
}, },
"node_modules/react": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^19.1.0"
}
},
"node_modules/react-fancybox": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/react-fancybox/-/react-fancybox-1.0.2.tgz",
"integrity": "sha512-YGazlghF1mu/oNq4Mn/ciZy5LLCFo2s9O4lwIoZQR5x/1a/1BTqGvXyQaUCe/JhX7xeaF6qjy+P75o/kvV6i9A=="
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true "dev": true
}, },
"node_modules/react-slick": {
"version": "0.30.3",
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.3.tgz",
"integrity": "sha512-B4x0L9GhkEWUMApeHxr/Ezp2NncpGc+5174R02j+zFiWuYboaq98vmxwlpafZfMjZic1bjdIqqmwLDcQY0QaFA==",
"dependencies": {
"classnames": "^2.2.5",
"enquire.js": "^2.1.6",
"json2mq": "^0.2.0",
"lodash.debounce": "^4.0.8",
"resize-observer-polyfill": "^1.5.0"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/reflect.getprototypeof": { "node_modules/reflect.getprototypeof": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -3956,6 +4029,11 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "2.0.0-next.5", "version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
@@ -4122,6 +4200,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"peer": true
},
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -4306,6 +4390,11 @@
"node": ">=16" "node": ">=16"
} }
}, },
"node_modules/string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="
},
"node_modules/string.prototype.matchall": { "node_modules/string.prototype.matchall": {
"version": "4.0.12", "version": "4.0.12",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
@@ -4687,9 +4776,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "6.3.3", "version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
"integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
@@ -5406,6 +5495,11 @@
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"dev": true "dev": true
}, },
"@fancyapps/ui": {
"version": "5.0.36",
"resolved": "https://registry.npmjs.org/@fancyapps/ui/-/ui-5.0.36.tgz",
"integrity": "sha512-GMygQzp1MBTFNTT6AzpbL6pXTD6bTxwjmmpI1fe8Ozmmiseu8/g82Sudl1YhcbZmS4bJgaBOF5THDFGpXQ1fDw=="
},
"@humanwhocodes/config-array": { "@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -5992,6 +6086,11 @@
"supports-color": "^7.1.0" "supports-color": "^7.1.0"
} }
}, },
"classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
"color-convert": { "color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -6182,6 +6281,11 @@
"integrity": "sha512-qS+qH9oqVYc1ooubTiB9l904WVyM6qNYxtOEEGReoZXw3xlqeYdFr5GclNzbkAufWgwWLEPoDi3d9MoRwwIjGw==", "integrity": "sha512-qS+qH9oqVYc1ooubTiB9l904WVyM6qNYxtOEEGReoZXw3xlqeYdFr5GclNzbkAufWgwWLEPoDi3d9MoRwwIjGw==",
"dev": true "dev": true
}, },
"enquire.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
"integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw=="
},
"entities": { "entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -7171,6 +7275,14 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true "dev": true
}, },
"json2mq": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
"integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
"requires": {
"string-convert": "^0.2.0"
}
},
"json5": { "json5": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -7223,6 +7335,11 @@
"p-locate": "^5.0.0" "p-locate": "^5.0.0"
} }
}, },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
"lodash.memoize": { "lodash.memoize": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -7549,12 +7666,44 @@
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true "dev": true
}, },
"react": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"peer": true
},
"react-dom": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"peer": true,
"requires": {
"scheduler": "^0.26.0"
}
},
"react-fancybox": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/react-fancybox/-/react-fancybox-1.0.2.tgz",
"integrity": "sha512-YGazlghF1mu/oNq4Mn/ciZy5LLCFo2s9O4lwIoZQR5x/1a/1BTqGvXyQaUCe/JhX7xeaF6qjy+P75o/kvV6i9A=="
},
"react-is": { "react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true "dev": true
}, },
"react-slick": {
"version": "0.30.3",
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.3.tgz",
"integrity": "sha512-B4x0L9GhkEWUMApeHxr/Ezp2NncpGc+5174R02j+zFiWuYboaq98vmxwlpafZfMjZic1bjdIqqmwLDcQY0QaFA==",
"requires": {
"classnames": "^2.2.5",
"enquire.js": "^2.1.6",
"json2mq": "^0.2.0",
"lodash.debounce": "^4.0.8",
"resize-observer-polyfill": "^1.5.0"
}
},
"reflect.getprototypeof": { "reflect.getprototypeof": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -7585,6 +7734,11 @@
"set-function-name": "^2.0.2" "set-function-name": "^2.0.2"
} }
}, },
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": { "resolve": {
"version": "2.0.0-next.5", "version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
@@ -7690,6 +7844,12 @@
"is-regex": "^1.2.1" "is-regex": "^1.2.1"
} }
}, },
"scheduler": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
"peer": true
},
"semver": { "semver": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -7823,6 +7983,11 @@
"integrity": "sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==", "integrity": "sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==",
"dev": true "dev": true
}, },
"string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="
},
"string.prototype.matchall": { "string.prototype.matchall": {
"version": "4.0.12", "version": "4.0.12",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
@@ -8069,9 +8234,9 @@
} }
}, },
"vite": { "vite": {
"version": "6.3.3", "version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
"integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",

View File

@@ -7,8 +7,11 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@fancyapps/ui": "^5.0.36",
"preact": "^10.26.6", "preact": "^10.26.6",
"preact-iso": "^2.9.1", "preact-iso": "^2.9.1",
"react-fancybox": "^1.0.2",
"react-slick": "^0.30.3",
"swiper": "^11.2.6", "swiper": "^11.2.6",
"tailwindcss": "^4.1.5" "tailwindcss": "^4.1.5"
}, },

View File

@@ -510,6 +510,13 @@ html {
color: #000; color: #000;
} }
#js-slider-big .swiper-button-next {
right: 0;
}
#js-slider-big .swiper-button-prev {
left: 0;
}
.tabs-list .tabs-item.active { .tabs-list .tabs-item.active {
background: var(--color-global); background: var(--color-global);
color: #fff; color: #fff;
@@ -1225,6 +1232,15 @@ html {
filter: brightness(0) invert(1); filter: brightness(0) invert(1);
} }
@media screen and (min-width: 1200px) and (max-width: 1550px) {
.box-product-detail #js-slider-big img {
display: block;
height: 470px;
margin: 0 auto;
-o-object-fit: contain;
object-fit: contain;
}
}
@media (max-width: 1600px) { @media (max-width: 1600px) {
#js-box-list-review .list-review { #js-box-list-review .list-review {
max-height: 450px; max-height: 450px;

File diff suppressed because one or more lines are too long

View File

@@ -541,6 +541,15 @@ html {
color: #000; color: #000;
} }
#js-slider-big {
.swiper-button-next {
right: 0;
}
.swiper-button-prev {
left: 0;
}
}
.tabs-list { .tabs-list {
.tabs-item.active { .tabs-item.active {
background: var(--color-global); background: var(--color-global);
@@ -1284,6 +1293,15 @@ html {
} }
} }
@media screen and (min-width: 1200px) and (max-width: 1550px) {
.box-product-detail #js-slider-big img {
display: block;
height: 470px;
margin: 0 auto;
object-fit: contain;
}
}
@media (max-width: 1600px) { @media (max-width: 1600px) {
#js-box-list-review { #js-box-list-review {
.list-review { .list-review {

View File

@@ -2,7 +2,7 @@ import { render } from "preact";
import { LocationProvider, Router, Route } from "preact-iso"; import { LocationProvider, Router, Route } from "preact-iso";
import { Home } from "./pages/Home/index.jsx"; import { Home } from "./pages/Home/index.jsx";
import ProductDetail from "./pages/product/ProductPage.jsx"; import { ProductDetail } from "./pages/product/ProductPage.jsx";
import { NotFound } from "./pages/_404.jsx"; import { NotFound } from "./pages/_404.jsx";
export function App() { export function App() {
@@ -11,7 +11,7 @@ export function App() {
<main> <main>
<Router> <Router>
<Route path="/" component={Home} /> <Route path="/" component={Home} />
<Route path="/detail" component={ProductDetail} /> <Route path="/product-detail" component={ProductDetail} />
<Route default component={NotFound} /> <Route default component={NotFound} />
</Router> </Router>
</main> </main>

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,17 @@
import { h } from "preact"; import { useState, useEffect, useRef } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import { FreeMode, Navigation, Thumbs } from "swiper/modules";
export function ProductDetail() { export function ProductDetail() {
// const [activeImage, setActiveImage] = useState(
// "/src/assets/images/big-product-detail.png"
// );
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const prevButtonRef = useRef(null);
const nextButtonRef = useRef(null);
return ( return (
<div className="box-product-detail bg-[#F4F4F4]"> <div className="box-product-detail bg-[#F4F4F4]">
<div className="container"> <div className="container">
@@ -17,7 +28,7 @@ export function ProductDetail() {
className="flex items-center pr-[12px]" className="flex items-center pr-[12px]"
> >
<a <a
href="/" href="/template/homepage/homepage.html"
itemprop="item" itemprop="item"
className="nopad-l flex items-center text-[#637381]" className="nopad-l flex items-center text-[#637381]"
> >
@@ -62,6 +73,474 @@ export function ProductDetail() {
</li> </li>
</ol> </ol>
</div> </div>
<div className="p-[15px] grid grid-cols-2 gap-[15px] rounded-[8px] bg-white">
<div className="left">
<div className="relative">
<Swiper
spaceBetween={10}
navigation={true}
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
className="swiper border border-[#B1B1B1 rounded-[12px]"
id="js-slider-big"
>
<SwiperSlide>
<img src="/src/assets/images/big-product-detail.png" alt="" />
</SwiperSlide>
<SwiperSlide>
<img src="/src/assets/images/big-product-detail.jpg" alt="" />
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/big-product-detail-2.jpg"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/big-product-detail-3.jpg"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/big-product-detail-4.jpg"
alt=""
/>
</SwiperSlide>
</Swiper>
</div>
<div className="relative mt-[12px]">
<Swiper
onSwiper={setThumbsSwiper}
spaceBetween={15}
slidesPerView={5}
navigation={{
prevEl: prevButtonRef.current, // Link to the 'prev' button
nextEl: nextButtonRef.current, // Link to the 'next' button
}}
freeMode={true}
watchSlidesProgress={true}
modules={[FreeMode, Navigation, Thumbs]}
className="swiper"
id="js-slider-small"
>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
<SwiperSlide>
<img
src="/src/assets/images/small-product-detail.png"
alt=""
/>
</SwiperSlide>
</Swiper>
<div className="btn-small swiper-navigation">
<button
ref={prevButtonRef}
className="swiper-button-prev"
style={{
position: "absolute",
left: "-15px",
zIndex: 10,
}}
></button>
<button
ref={nextButtonRef}
className="swiper-button-next"
style={{
position: "absolute",
right: "-20px",
zIndex: 10,
}}
></button>
</div>
</div>
</div>
<div className="right">
<h1 className="text-[24px] text-black mb-[5px]">
Laptop Gaming Asus TUF FX505GE-BQ037T Core i7-8750H/Win10(15.6"
FHD) - Hàng Chính Hãng
</h1>
<div className="flex items-center text-base">
<div className="info-review flex items-center mr-[15px]">
<i className="icon-star star-small" />
<span className="ml-[5px] mt-[2px]">5/5</span>
</div>
<div className="info-view flex items-center mr-[15px]">
<i className="icon_2025 view" />
<span className="text-[#1877F2] ml-[5px]">120</span>
</div>
<div className="info-date flex items-center mr-[15px]">
<i className="icon_2025 time-big" />
<span className="text-[#1877F2] ml-[5px]">12/03/2025</span>
</div>
<a href="" className="info-share flex items-center">
<i className="icon_2025 share" />
<span className="ml-[5px] mt-[2px]">Chia sẻ</span>
</a>
</div>
<div className="flex items-center mt-[5px] text-base">
<div className="source-review flex items-centermr-[10px]">
<span>Reviews trên:</span>
<a href="" className="ml-[5px] text-[#1877F2]">
Internet
</a>
<p className="ml-[5px]">1233 đánh giá</p>
</div>
<div className="pl-[10px] ml-[10px] flex items-center border-l-[1.5px] border-[#000]">
<a href="" className="mr-[5px] text-[#462F91]">
BestPC
</a>
<p>12003 đánh giá</p>
</div>
</div>
<div className="box-price flex items-center my-[10px]">
<span className="mr-[10px]">Giá:</span>
<b className="text-[#D80A00] text-[28px]">
9.000.000đ - 12.000.000đ
</b>
</div>
<div className="total-shop flex items-center">
<div className="box-shop">
<i className="icon_2025 shop" />
</div>
<p className="ml-[7px]">Có 12 cửa hàng bán</p>
</div>
<div className="box-summary mt-[15px]">
<ul>
<li>
CPU: Intel Core i7-8750H ( 2.2 GHz - 4.1 GHz / 9MB / 6 nhân,
12 luồng )
</li>
<li>Màn hình: 15.6" ( 1920 x 1080 ) , không cảm ứng</li>
<li>RAM: 1 x 8GB DDR4 2666MHz</li>
<li>
Đồ họa: Intel UHD Graphics 630 / NVIDIA GeForce GTX 1050Ti 4GB
GDDR5
</li>
<li>Lưu trữ: 128GB SSD M.2 NVMe / 1TB HDD 5400RPM</li>
<li>Hệ điều hành: Windows 10 Home SL 64-bit</li>
<li>Pin: 4 cell 64 Wh Pin liền</li>
<li>khối lượng: 2.5 kg</li>
<li>Cổng giao tiếp: 1x USB 2.0,</li>
</ul>
</div>
<a
href=""
className="group mt-4 flex items-center justify-center w-ful py-[10px] border border-[#D3D3D3] rounded-[4px] text-center hover:bg-[var(--color-global)] hover:text-white"
>
<img
src="/src/assets/images/icon-file-save.png"
className="w-[18px] h-[24px] block group-hover:brightness-[0] group-hover:invert-[1]"
alt="save"
/>
<b className="ml-[10px] text-base">Lưu sản phẩm lại xem sau</b>
</a>
</div>
</div>
{/* end thông tin sản phẩm */}
<div class="p-[15px] bg-white mt-5 rounded-[8px]">
<div class="flex items-center justify-between pb-[15px] border-b-[1px] border-[#B1B1B1]">
<h3 class="text-xl ">Nhà cung cấp trên BestPC - Tại Nội</h3>
<div class="flex items-center">
<div class="flex items-center relative border border-[#b1b1b1] mr-[10px] w-[410px] h-[45px] px-[10px] rounded-[4px]">
<i class="icon_2025 map-2"></i>
<input
type="text"
placeholder="Nhập địa chỉ của bạn để tìm NCC gần nhất"
class="outline-none ml-[5px] h-full w-full"
/>
</div>
<div class="select-sort relative border border-[#b1b1b1] w-[100px] h-[45px] rounded-[4px] overflow-hidden">
<select
name=""
id=""
class=" appearance-none w-full relative pl-[10px] bg-transparent h-full z-[2]"
>
<option value="">Sắp xếp</option>
<option value="">Mới</option>
</select>
<i class="icon_2025 angle-right ml-[5px] absolute right-[7px] top-[12px] z-[1] rotate-[90deg]"></i>
</div>
</div>
</div>
<div class="mt-[10px] py-[15px] grid grid-cols-5 text-xl border-b-[1px] border-[#D9D9D9]">
<div>
<b>Nhà cung cấp</b>
</div>
<div>
<b>Chính sách vận chuyển</b>
</div>
<div>
<b>Giá</b>
</div>
<div>
<b>Sản phẩm</b>
</div>
</div>
<div class="list ">
<div class="item grid grid-cols-5 py-[10px] border-b-[1px] border-[#D9D9D9]">
<div class="flex items-start supplier">
<div class="logo mr-[10px]">
<div class="w-[70px] h-[70px] p-[10px] block border border-[#F3F3F3] rounded-[4px]">
<img
src="/src/assets/images/logo-hacom.png"
class="block w-full h-full object-contain m-[0_auto]"
width="100%"
height="100%"
alt="hacom"
/>
</div>
<div class="flex items-center justify-center mt-2">
<i class="icon_2025 map-4"></i>
<span class="ml-[5px]">3km</span>
</div>
</div>
<div>
<div class="flex items-center">
<i class="icon-star star4"></i>
<span class="ml-[5px] mt-[3px]">4.7</span>
</div>
<a href="" class="text-[#1877F2] font-bold">
Hanoicomputer
</a>
<a href="" class="text-[#E85933] underline block">
Xem 7 cửa hàng
</a>
</div>
</div>
<div class="ship">
<p>Miễn phí giao hàng</p>
<p>
Nhận giap hàng lắp đặt từ 8h00-21:30 các ngày trong tuần kể
cả ngày thứ 7, CN
</p>
</div>
<div class="price">
<div class="flex items-center text-base">
<span>Giá:</span>
<b class="ml-[5px] text-[#D80A00]">
9.000.000đ - 20.000.000đ
</b>
</div>
<b class="mt-2">Đã VAT</b>
</div>
<div class="">
<p class="name-pro pb-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
<p class="name-pro py-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
</div>
<div>
<a
href=""
class="block w-[130px] h-[40px] leading-[40px] m-[auto_0_auto_auto] text-base text-center text-white bg-orange-500 rounded hover:bg-orange-600"
>
Liên hệ ngay
</a>
</div>
</div>
<div class="item grid grid-cols-5 py-[10px] border-b-[1px] border-[#D9D9D9]">
<div class="flex items-start supplier">
<div class="logo mr-[10px]">
<div class="w-[70px] h-[70px] p-[10px] block border border-[#F3F3F3] rounded-[4px]">
<img
src="/src/assets/images/logo-hacom.png"
class="block w-full h-full object-contain m-[0_auto]"
width="100%"
height="100%"
alt="hacom"
/>
</div>
<div class="flex items-center justify-center mt-2">
<i class="icon_2025 map-4"></i>
<span class="ml-[5px]">3km</span>
</div>
</div>
<div>
<div class="flex items-center">
<i class="icon-star star4"></i>
<span class="ml-[5px] mt-[3px]">4.7</span>
</div>
<a href="" class="text-[#1877F2] font-bold">
Hanoicomputer
</a>
<a href="" class="text-[#E85933] underline block">
Xem 7 cửa hàng
</a>
</div>
</div>
<div class="ship">
<p>Miễn phí giao hàng</p>
<p>
Nhận giap hàng lắp đặt từ 8h00-21:30 các ngày trong tuần kể
cả ngày thứ 7, CN
</p>
</div>
<div class="price">
<div class="flex items-center text-base">
<span>Giá:</span>
<b class="ml-[5px] text-[#D80A00]">
9.000.000đ - 20.000.000đ
</b>
</div>
<b class="mt-2">Đã VAT</b>
</div>
<div class="">
<p class="name-pro pb-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
<p class="name-pro py-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
</div>
<div>
<a
href=""
class="block w-[130px] h-[40px] leading-[40px] m-[auto_0_auto_auto] text-base text-center text-white bg-orange-500 rounded hover:bg-orange-600"
>
Liên hệ ngay
</a>
</div>
</div>
<div class="item grid grid-cols-5 py-[10px] border-b-[1px] border-[#D9D9D9]">
<div class="flex items-start supplier">
<div class="logo mr-[10px]">
<div class="w-[70px] h-[70px] p-[10px] block border border-[#F3F3F3] rounded-[4px]">
<img
src="/src/assets/images/logo-hacom.png"
class="block w-full h-full object-contain m-[0_auto]"
width="100%"
height="100%"
alt="hacom"
/>
</div>
<div class="flex items-center justify-center mt-2">
<i class="icon_2025 map-4"></i>
<span class="ml-[5px]">3km</span>
</div>
</div>
<div>
<div class="flex items-center">
<i class="icon-star star4"></i>
<span class="ml-[5px] mt-[3px]">4.7</span>
</div>
<a href="" class="text-[#1877F2] font-bold">
Hanoicomputer
</a>
<a href="" class="text-[#E85933] underline block">
Xem 7 cửa hàng
</a>
</div>
</div>
<div class="ship">
<p>Miễn phí giao hàng</p>
<p>
Nhận giap hàng lắp đặt từ 8h00-21:30 các ngày trong tuần kể
cả ngày thứ 7, CN
</p>
</div>
<div class="price">
<div class="flex items-center text-base">
<span>Giá:</span>
<b class="ml-[5px] text-[#D80A00]">
9.000.000đ - 20.000.000đ
</b>
</div>
<b class="mt-2">Đã VAT</b>
</div>
<div class="">
<p class="name-pro pb-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
<p class="name-pro py-[10px] border-b-[1px] border-[#D9D9D9]">
8GB - 9.000.000đ new White
</p>
</div>
<div>
<a
href=""
class="block w-[130px] h-[40px] leading-[40px] m-[auto_0_auto_auto] text-base text-center text-white bg-orange-500 rounded hover:bg-orange-600"
>
Liên hệ ngay
</a>
</div>
</div>
</div>
{/* end list */}
<a
href=""
class="pt-3 block text-center text-[#FF7A00] text-xl hover:text-orange-600"
>
Xem thêm >>
</a>
</div>
{/* end nhà cung cấp */}
</div> </div>
</div> </div>
); );