25-05-2026
This commit is contained in:
15
package-lock.json
generated
15
package-lock.json
generated
@@ -6356,6 +6356,21 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"zod": "^3.25.0 || ^4.0.0"
|
"zod": "^3.25.0 || ^4.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "16.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.0.tgz",
|
||||||
|
"integrity": "sha512-Tr0j94MphimCCks+1rtYPzQFK+faJuhHWCegU9S9gDlgyOk8Y3kPmO64UcjyzZAlligeBtYZ/2bEyrKq0d2wqQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,56 +2,120 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { categoryDetail } from "@/data/buildpc/categoryDetail";
|
import { categoryDetail } from "@/data/buildpc/categoryDetail";
|
||||||
import ModalContent from "../modal";
|
import ModalContent from "../modal";
|
||||||
|
import SelectedItemRow from "../modal/SelectedItemRow";
|
||||||
|
|
||||||
export default function BuildPCCategories({ categories }: any) {
|
export default function BuildPCCategories({ categories }: any) {
|
||||||
// console.log("categoryDetail: ", categoryDetail)
|
|
||||||
|
|
||||||
const [selectedCategory, setSelectedCategory] = useState(null);
|
const [selectedCategory, setSelectedCategory] = useState<any>(null);
|
||||||
const [categoryInfo, setCategoryInfo] = useState<any>(null);
|
const [categoryInfo, setCategoryInfo] = useState<any>(null);
|
||||||
|
const [buildData, setBuildData] = useState<any[]>([]);
|
||||||
|
|
||||||
|
const storageKey = "buildpc";
|
||||||
|
|
||||||
|
// Load khi mount
|
||||||
|
useEffect(() => {
|
||||||
|
const oldData = localStorage.getItem(storageKey);
|
||||||
|
setBuildData(oldData ? JSON.parse(oldData) : []);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Nghe event update
|
||||||
|
useEffect(() => {
|
||||||
|
const handleUpdate = () => {
|
||||||
|
const oldData = localStorage.getItem(storageKey);
|
||||||
|
setBuildData(oldData ? JSON.parse(oldData) : []);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("buildpcUpdated", handleUpdate);
|
||||||
|
return () => window.removeEventListener("buildpcUpdated", handleUpdate);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Set category info khi mở modal
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedCategory) {
|
if (selectedCategory) {
|
||||||
const filterCategory = categoryDetail.find((item: any) => item.id === selectedCategory);
|
const filterCategory = categoryDetail.find(
|
||||||
|
(item: any) => item.id === selectedCategory
|
||||||
|
);
|
||||||
setCategoryInfo(filterCategory);
|
setCategoryInfo(filterCategory);
|
||||||
}
|
}
|
||||||
}, [selectedCategory])
|
}, [selectedCategory]);
|
||||||
|
|
||||||
|
// Xoá sản phẩm
|
||||||
|
const handleRemove = (rowId: number) => {
|
||||||
|
const newData = buildData.filter((b: any) => b.rowId !== rowId);
|
||||||
|
localStorage.setItem(storageKey, JSON.stringify(newData));
|
||||||
|
setBuildData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Đổi số lượng
|
||||||
|
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(storageKey, JSON.stringify(newData));
|
||||||
|
setBuildData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="buildpc-holder-container" id="js-buildpc-layout">
|
<div className="buildpc-holder-container">
|
||||||
{categories.map((item: any, index: number) => (
|
{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}>
|
<div className="item-drive" key={item.id}>
|
||||||
<p className="item-title leading-5">
|
<p className="item-title leading-5">
|
||||||
<span>{index + 1}. {item.name}</span>
|
<span>{index + 1}. {item.name}</span>
|
||||||
|
|
||||||
<span
|
|
||||||
className="block text-16 font-500"
|
|
||||||
style={{ color: '#E16B10' }}
|
|
||||||
id={`js-item-offer-${item.id}`} />
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="item-drive-info">
|
<div className="item-drive-info">
|
||||||
<a href="#js-modal-popup"
|
|
||||||
|
{product ? (
|
||||||
|
<SelectedItemRow
|
||||||
|
product={product}
|
||||||
|
rowId={item.id}
|
||||||
|
onRemove={handleRemove}
|
||||||
|
onQuantityChange={handleQuantityChange}
|
||||||
|
onEdit={(rowId) => setSelectedCategory(rowId)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<a
|
||||||
|
href="#js-modal-popup"
|
||||||
data-fancybox=""
|
data-fancybox=""
|
||||||
className="js-open-selection open-selection"
|
className="open-selection"
|
||||||
id={`js-category-info-${item.id}`}
|
|
||||||
data-info={`{"id":${item.id},"name":"${item.name}"}`}
|
|
||||||
onClick={() => setSelectedCategory(item.id)}
|
onClick={() => setSelectedCategory(item.id)}
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus" /> Chọn {item.name}
|
<i className="bx bx-plus" /> Chọn {item.name}
|
||||||
</a>
|
</a>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="js-item-row"
|
|
||||||
id={`js-selected-item-${item.id}`}
|
|
||||||
data-id={item.id} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="buildpc-modal-popup-container text-black" id="js-modal-popup" style={{ display: 'none', padding: 0 }}>
|
<div
|
||||||
|
className="buildpc-modal-popup-container text-black"
|
||||||
|
id="js-modal-popup"
|
||||||
|
style={{ display: 'none', padding: 0 }}
|
||||||
|
>
|
||||||
<ModalContent item={categoryInfo} />
|
<ModalContent item={categoryInfo} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
@@ -11,9 +11,15 @@ import Promotion from "./Promotion";
|
|||||||
import Buttons from "./Buttons";
|
import Buttons from "./Buttons";
|
||||||
|
|
||||||
export default function BuildPc() {
|
export default function BuildPc() {
|
||||||
|
const [fancyboxRef] = useFancybox({});
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState(1);
|
const [activeTab, setActiveTab] = useState(1);
|
||||||
|
|
||||||
const [fancyboxRef] = useFancybox({});
|
const handleTabChange = (tabIndex: number) => {
|
||||||
|
|
||||||
|
setActiveTab(tabIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -61,7 +67,7 @@ export default function BuildPc() {
|
|||||||
key={item}
|
key={item}
|
||||||
type="button"
|
type="button"
|
||||||
className={item === activeTab ? "active" : ""}
|
className={item === activeTab ? "active" : ""}
|
||||||
onClick={() => setActiveTab(item)}
|
onClick={() => handleTabChange(item)}
|
||||||
>
|
>
|
||||||
Cấu hình {item}
|
Cấu hình {item}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export default function Paging({ item }: any) {
|
|||||||
<div className="popup-paging">
|
<div className="popup-paging">
|
||||||
{
|
{
|
||||||
item.map((item: any) => (
|
item.map((item: any) => (
|
||||||
<a key={item.name} href={item.url}
|
<a key={item.name} href="#"
|
||||||
className={`${item.is_active ? 'active' : ''} capitalize`}
|
className={`${item.is_active ? 'active' : ''} capitalize`}
|
||||||
>
|
>
|
||||||
{item.name}
|
{item.name}
|
||||||
|
|||||||
@@ -1,7 +1,48 @@
|
|||||||
|
'use client';
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { Fancybox } from "@fancyapps/ui/dist/fancybox/";
|
||||||
|
|
||||||
export default function ProductItem({ item, rowId }: any) {
|
export default function ProductItem({ item, rowId }: any) {
|
||||||
|
|
||||||
|
const handleBuy = () => {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
|
const storageKey = "buildpc";
|
||||||
|
const oldData = localStorage.getItem(storageKey);
|
||||||
|
const parsed = oldData ? JSON.parse(oldData) : [];
|
||||||
|
|
||||||
|
const productData = {
|
||||||
|
id : item.productId,
|
||||||
|
name : item.productName,
|
||||||
|
url : item.productUrl,
|
||||||
|
price : item.price,
|
||||||
|
image : item.productImage.large,
|
||||||
|
quantity : 1,
|
||||||
|
sku : item.productSKU,
|
||||||
|
warranty : item.warranty || ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildIndex = parsed.findIndex((b: any) => b.rowId === rowId);
|
||||||
|
|
||||||
|
if (buildIndex !== -1) {
|
||||||
|
parsed[buildIndex].info = [productData];
|
||||||
|
} else {
|
||||||
|
parsed.push({
|
||||||
|
rowId: rowId,
|
||||||
|
info: [productData]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(storageKey, JSON.stringify(parsed));
|
||||||
|
|
||||||
|
// báo cho component cha
|
||||||
|
window.dispatchEvent(new Event("buildpcUpdated"));
|
||||||
|
|
||||||
|
// đóng popup
|
||||||
|
Fancybox.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-item">
|
<div className="p-item">
|
||||||
<Link href={item.productUrl} className="item-img">
|
<Link href={item.productUrl} className="item-img">
|
||||||
@@ -48,9 +89,9 @@ export default function ProductItem({ item, rowId }: any) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
onClick={handleBuy}
|
||||||
className="btn-buy p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
className="btn-buy p-btn bx bx-plus bg-btn text-white rounded-full w-9 h-9 text-20"
|
||||||
data-row-id={rowId}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
93
src/components/buildpc/modal/SelectedItemRow.tsx
Normal file
93
src/components/buildpc/modal/SelectedItemRow.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
product: any;
|
||||||
|
rowId: number;
|
||||||
|
onRemove: (rowId: number) => void;
|
||||||
|
onQuantityChange: (rowId: number, quantity: number) => void;
|
||||||
|
onEdit: (rowId: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SelectedItemRow({
|
||||||
|
product,
|
||||||
|
rowId,
|
||||||
|
onRemove,
|
||||||
|
onQuantityChange,
|
||||||
|
onEdit
|
||||||
|
}: Props) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="js-item-row">
|
||||||
|
<div className="contain-item-drive">
|
||||||
|
|
||||||
|
<a href={product.url} target="_blank" className="item-img">
|
||||||
|
<img src={product.image} alt={product.name} />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div className="item-text">
|
||||||
|
|
||||||
|
<div className="item-left">
|
||||||
|
<a href={product.url} target="_blank" className="item-name">
|
||||||
|
{product.name}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span className="font-500">- Kho hàng:</span>
|
||||||
|
{product.quantity > 0 ? "Còn hàng" : "Hết hàng"}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span className="font-500">- Bảo hành:</span>
|
||||||
|
{product.warranty || "—"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="item-right">
|
||||||
|
|
||||||
|
<div className="item-quantity-group">
|
||||||
|
<b>{product.price.toLocaleString()}</b>
|
||||||
|
|
||||||
|
<div className="flex items-center" style={{ display: "flex", gap: "10px" }}>
|
||||||
|
<span>x</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={product.quantity}
|
||||||
|
className="item-quantity"
|
||||||
|
min={1}
|
||||||
|
max={50}
|
||||||
|
onChange={(e) =>
|
||||||
|
onQuantityChange(rowId, Number(e.target.value))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span>=</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<b className="item-price">
|
||||||
|
{(product.price * product.quantity).toLocaleString()}
|
||||||
|
</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="item-button-group">
|
||||||
|
<a href="#js-modal-popup" data-fancybox
|
||||||
|
type="button"
|
||||||
|
title="Thay đổi"
|
||||||
|
className="btn-action_seclect show-popup_select bx bx-edit"
|
||||||
|
onClick={() => onEdit(rowId)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="Xóa"
|
||||||
|
className="btn-action_seclect delete_select bx bx-trash remove-item"
|
||||||
|
onClick={() => onRemove(rowId)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,8 +6,6 @@ import Paing from "./Paging";
|
|||||||
export default function ModalContent({ item }: any) {
|
export default function ModalContent({ item }: any) {
|
||||||
if (!item) return null;
|
if (!item) return null;
|
||||||
|
|
||||||
console.log(item)
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
attribute_filter_list,
|
attribute_filter_list,
|
||||||
@@ -23,8 +21,14 @@ export default function ModalContent({ item }: any) {
|
|||||||
<div className="popup-select">
|
<div className="popup-select">
|
||||||
<div className="popup-header">
|
<div className="popup-header">
|
||||||
<p>Chọn linh kiện</p>
|
<p>Chọn linh kiện</p>
|
||||||
|
|
||||||
<div className="popup-search-holder">
|
<div className="popup-search-holder">
|
||||||
<input type="text" defaultValue='' id="js-buildpc-search-keyword" className="input-search" placeholder="Nhập từ khóa cần tìm" />
|
<input
|
||||||
|
type="text"
|
||||||
|
defaultValue=""
|
||||||
|
className="input-search"
|
||||||
|
placeholder="Nhập từ khóa cần tìm"
|
||||||
|
/>
|
||||||
|
|
||||||
<button className="btn-search bg-linear rounded-full" id="js-buildpc-search-btn">
|
<button className="btn-search bg-linear rounded-full" id="js-buildpc-search-btn">
|
||||||
<i className="block !w-full !h-full icons icon-search" />
|
<i className="block !w-full !h-full icons icon-search" />
|
||||||
@@ -40,7 +44,8 @@ export default function ModalContent({ item }: any) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="popup-main">
|
<div className="popup-main">
|
||||||
{product_list && product_list.length > 0 ? (
|
{product_list && product_list.length > 0 ?
|
||||||
|
(
|
||||||
<>
|
<>
|
||||||
<div className="popup-filter-group">
|
<div className="popup-filter-group">
|
||||||
<p className="group-titlle"> Lọc sản phẩm </p>
|
<p className="group-titlle"> Lọc sản phẩm </p>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useState } from 'react';
|
|||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import FAQ from "./Faq";
|
import FAQ from "./Faq";
|
||||||
import DesignerItem from "@/components/shared/DesignerItem";
|
import DesignerItem from "./DesignerItem";
|
||||||
import { usePagination } from "@/hooks/usePagination";
|
import { usePagination } from "@/hooks/usePagination";
|
||||||
import ButtonShowMore from "@/components/shared/ProductShowMore";
|
import ButtonShowMore from "@/components/shared/ProductShowMore";
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { categories } from "@/data/categories";
|
import { categories } from "@/data/categories";
|
||||||
import { JobData } from "@/data/articles/Job";
|
import { JobData } from "@/data/articles/Job";
|
||||||
import RecruitItem from "@/components/shared/RecruitItem"
|
import RecruitItem from "./RecruitItem"
|
||||||
|
|
||||||
export default function RecruitPage() {
|
export default function RecruitPage() {
|
||||||
|
|
||||||
|
|||||||
@@ -6524,215 +6524,5 @@ export const categoryDetail = [
|
|||||||
"product_list": [],
|
"product_list": [],
|
||||||
"paging_collection": [],
|
"paging_collection": [],
|
||||||
"paging_count": 0
|
"paging_count": 0
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 16,
|
|
||||||
"name": "\u1ed4 C\u1ee9ng SSD",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "\u1ed4 C\u1ee9ng HDD",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"name": "VGA",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Ngu\u1ed3n",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 8,
|
|
||||||
"name": "V\u1ecf Case",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 22,
|
|
||||||
"name": "Qu\u1ea1t T\u1ea3n Nhi\u1ec7t",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "T\u1ea3n Nhi\u1ec7t CPU",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 28,
|
|
||||||
"name": "T\u1ea3n Nhi\u1ec7t N\u01b0\u1edbc AIO",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "M\u00e0n H\u00ecnh",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 18,
|
|
||||||
"name": "B\u00e0n ph\u00edm",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 19,
|
|
||||||
"name": "Chu\u1ed9t",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 26,
|
|
||||||
"name": "Tai Nghe",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 74,
|
|
||||||
"name": "B\u00e0n M\u00e1y M\u00e1y T\u00ednh",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 90,
|
|
||||||
"name": "Gh\u1ebf Gaming",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 23,
|
|
||||||
"name": "Thi\u1ebft B\u1ecb M\u1ea1ng",
|
|
||||||
"attribute_filter_list": [],
|
|
||||||
"brand_filter_list": [],
|
|
||||||
"price_filter_list": [],
|
|
||||||
"sort_by_collection": [],
|
|
||||||
"sort_option": "order",
|
|
||||||
"search_query": "",
|
|
||||||
"search_url": "",
|
|
||||||
"product_list": [],
|
|
||||||
"paging_collection": [],
|
|
||||||
"paging_count": 0
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -16,66 +16,6 @@ export const buildPcData = {
|
|||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "RAM"
|
"name": "RAM"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 16,
|
|
||||||
"name": "\u1ed4 C\u1ee9ng SSD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "\u1ed4 C\u1ee9ng HDD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"name": "VGA"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Ngu\u1ed3n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 8,
|
|
||||||
"name": "V\u1ecf Case"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 22,
|
|
||||||
"name": "Qu\u1ea1t T\u1ea3n Nhi\u1ec7t"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "T\u1ea3n Nhi\u1ec7t CPU"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 28,
|
|
||||||
"name": "T\u1ea3n Nhi\u1ec7t N\u01b0\u1edbc AIO"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "M\u00e0n H\u00ecnh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 18,
|
|
||||||
"name": "B\u00e0n ph\u00edm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 19,
|
|
||||||
"name": "Chu\u1ed9t"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 26,
|
|
||||||
"name": "Tai Nghe"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 74,
|
|
||||||
"name": "B\u00e0n M\u00e1y M\u00e1y T\u00ednh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 90,
|
|
||||||
"name": "Gh\u1ebf Gaming"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 23,
|
|
||||||
"name": "Thi\u1ebft B\u1ecb M\u1ea1ng"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
.buildpc-page .buildpc-btn-action .item{font-size: 16px;font-weight: 500;height: 52px;border-radius: 40px;border: 1px solid #259AFF;color: #fff;text-transform: uppercase;display: flex;align-items: center;justify-content: center;gap: 8px;padding: 0 24px;background: linear-gradient(165.29deg, #259AFF 8.53%, #114CDD 93.19%);}
|
.buildpc-page .buildpc-btn-action .item{font-size: 16px;font-weight: 500;height: 52px;border-radius: 40px;border: 1px solid #259AFF;color: #fff;text-transform: uppercase;display: flex;align-items: center;justify-content: center;gap: 8px;padding: 0 24px;background: linear-gradient(165.29deg, #259AFF 8.53%, #114CDD 93.19%);}
|
||||||
.buildpc-page .buildpc-btn-action .btn-cart {background: linear-gradient(148.21deg, #FFD83E -14.02%, #FF4E2A 70.14%) !important;border-color: transparent !important;padding: 0 35px}
|
.buildpc-page .buildpc-btn-action .btn-cart {background: linear-gradient(148.21deg, #FFD83E -14.02%, #FF4E2A 70.14%) !important;border-color: transparent !important;padding: 0 35px}
|
||||||
.buildpc-page .buildpc-btn-action .item:hover, .buildpc-holder-container .item-drive .open-selection:hover{background:#0678DB;color: #fff}
|
.buildpc-page .buildpc-btn-action .item:hover, .buildpc-holder-container .item-drive .open-selection:hover{background:#0678DB;color: #fff}
|
||||||
.buildpc-holder-container{border:1px solid #e1e1e1;min-height: 300px;margin-bottom: 20px;overflow: hidden;border-radius: 24px;background: #fff}
|
.buildpc-holder-container{border:1px solid #e1e1e1;margin-bottom: 20px;overflow: hidden;border-radius: 24px;background: #fff}
|
||||||
.buildpc-holder-container p{margin: 0}
|
.buildpc-holder-container p{margin: 0}
|
||||||
.buildpc-holder-container .item-drive{border-bottom:1px solid #e1e1e1;display:flex;flex-wrap:wrap;line-height:22px;overflow: hidden;align-items: center}
|
.buildpc-holder-container .item-drive{border-bottom:1px solid #e1e1e1;display:flex;flex-wrap:wrap;line-height:22px;overflow: hidden;align-items: center}
|
||||||
.buildpc-holder-container .item-drive:last-child{border-bottom: 0}
|
.buildpc-holder-container .item-drive:last-child{border-bottom: 0}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
.buildpc-holder-container .item-drive .item-drive-info{width:calc(100% - 220px);padding:16px;border-left: 1px solid #e1e1e1}
|
.buildpc-holder-container .item-drive .item-drive-info{width:calc(100% - 220px);padding:16px;border-left: 1px solid #e1e1e1}
|
||||||
.buildpc-holder-container .item-drive .open-selection{cursor: pointer;background: #fff;height: 38px;border: 1px solid #259AFF;border-radius: 40px;color: #0678DB;font-size: 14px;font-weight: 500;display: inline-flex;align-items: center;gap: 4px;padding: 0 16px;text-transform: uppercase;}
|
.buildpc-holder-container .item-drive .open-selection{cursor: pointer;background: #fff;height: 38px;border: 1px solid #259AFF;border-radius: 40px;color: #0678DB;font-size: 14px;font-weight: 500;display: inline-flex;align-items: center;gap: 4px;padding: 0 16px;text-transform: uppercase;}
|
||||||
.buildpc-holder-container .item-drive .open-selection .bx{font-size: 18px}
|
.buildpc-holder-container .item-drive .open-selection .bx{font-size: 18px}
|
||||||
.buildpc-page .contain-item-drive{background: #fff;margin: -47px -16px -12px;position: relative;z-index: 1;display: flex;flex-wrap: wrap;align-items: flex-start;padding: 16px;}
|
.buildpc-page .contain-item-drive{background: #fff;margin: 0 -16px -12px;position: relative;z-index: 1;display: flex;flex-wrap: wrap;align-items: flex-start;padding: 16px;}
|
||||||
.buildpc-page .contain-item-drive .item-img{width:80px;margin:0 10px 0 0}
|
.buildpc-page .contain-item-drive .item-img{width:80px;margin:0 10px 0 0}
|
||||||
.buildpc-page .contain-item-drive .item-text{width:calc(100% - 90px);display:flex;flex-wrap:wrap;align-items:flex-start}
|
.buildpc-page .contain-item-drive .item-text{width:calc(100% - 90px);display:flex;flex-wrap:wrap;align-items:flex-start}
|
||||||
.buildpc-page .contain-item-drive .item-name {display: table;color: #004BA4;font-weight: 600;line-height: 18px;font-size: 14px;margin-bottom: 4px}
|
.buildpc-page .contain-item-drive .item-name {display: table;color: #004BA4;font-weight: 600;line-height: 18px;font-size: 14px;margin-bottom: 4px}
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
.buildpc-popup .popup-filter-holder::-webkit-scrollbar,.buildpc-popup .popup-product-list::-webkit-scrollbar{width:8px;height:10px}
|
.buildpc-popup .popup-filter-holder::-webkit-scrollbar,.buildpc-popup .popup-product-list::-webkit-scrollbar{width:8px;height:10px}
|
||||||
.buildpc-popup .filter-item{margin-bottom:16px}
|
.buildpc-popup .filter-item{margin-bottom:16px}
|
||||||
.buildpc-popup .filter-item .filter-name{display: block;font-weight: 600;margin: 0 0 8px;font-size: 14px;line-height: 18px;}
|
.buildpc-popup .filter-item .filter-name{display: block;font-weight: 600;margin: 0 0 8px;font-size: 14px;line-height: 18px;}
|
||||||
.buildpc-popup .filter-list-holder{display:flex;flex-wrap:wrap;justify-content:space-between;font-size: 13px;line-height: 18px}
|
.buildpc-popup .filter-list-holder{font-size: 13px;line-height: 18px;display: grid;grid-template-columns: repeat(2, 1fr);gap: 5px 10px;}
|
||||||
.buildpc-popup .filter-list-holder label{display:flex;align-items:center;gap: 4px;width:48%;margin:0 0 8px;cursor:pointer}
|
.buildpc-popup .filter-list-holder label{display:flex;align-items:center;gap: 4px;margin:0 0 8px;cursor:pointer}
|
||||||
.buildpc-popup .filter-list-holder label:hover{color:#0676DA}
|
.buildpc-popup .filter-list-holder label:hover{color:#0676DA}
|
||||||
.buildpc-popup .sort-paging-group{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;background: #f8f8f8;padding: 8px 12px 8px 16px;margin-right: -10px}
|
.buildpc-popup .sort-paging-group{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;background: #f8f8f8;padding: 8px 12px 8px 16px;margin-right: -10px}
|
||||||
.buildpc-popup .sort-paging-group select{cursor:pointer;outline:none;height: 26px;margin-left: 5px;background: #F2F2F2;border-radius: 30px;padding: 0 10px;}
|
.buildpc-popup .sort-paging-group select{cursor:pointer;outline:none;height: 26px;margin-left: 5px;background: #F2F2F2;border-radius: 30px;padding: 0 10px;}
|
||||||
|
|||||||
Reference in New Issue
Block a user