Add precision gear product cards
This commit is contained in:
146
app/page.tsx
146
app/page.tsx
@@ -7,6 +7,7 @@ import {
|
||||
type CatalogProduct,
|
||||
} from "./catalog-data";
|
||||
import { STEERING_WHEEL_ACCESSORIES } from "./catalog-accessories";
|
||||
import { PRECISION_GEAR_PRODUCTS, PRECISION_GEAR_SUBCATEGORIES } from "./precision-gear-data";
|
||||
import { getCatalogProductDimensionImage, getCatalogProductImage } from "./catalog-image-map";
|
||||
|
||||
const CATALOG_PRODUCTS = [...RAW_CATALOG_PRODUCTS, ...STEERING_WHEEL_ACCESSORIES].map((product) => ({
|
||||
@@ -52,20 +53,6 @@ const PRIMARY_CATALOG_CATEGORIES = [
|
||||
|
||||
const CATALOG_FILTER_CATEGORIES = ["全部产品", ...PRIMARY_CATALOG_CATEGORIES, "静音舵机"];
|
||||
|
||||
const PRECISION_GEAR_SUBCATEGORIES = [
|
||||
["轴", 15],
|
||||
["单伞齿", 23],
|
||||
["单直齿", 160],
|
||||
["单皇冠齿", 9],
|
||||
["双联直齿", 186],
|
||||
["其他双联齿", 18],
|
||||
["双联皇冠齿", 16],
|
||||
["蜗杆", 32],
|
||||
["异形零件", 18],
|
||||
["离合齿", 29],
|
||||
["差速器组件", 5],
|
||||
] as const;
|
||||
|
||||
const FEATURED_SPEC_ORDER = [
|
||||
"堵转扭矩",
|
||||
"额定电压",
|
||||
@@ -99,6 +86,25 @@ function getProductDimensionSummary(product: CatalogProduct) {
|
||||
return dimensions.length > 0 ? dimensions.join(" × ") : "尺寸图待补充";
|
||||
}
|
||||
|
||||
const PRECISION_GEAR_CARD_SPEC_ORDER = [
|
||||
"模数",
|
||||
"齿数",
|
||||
"材质",
|
||||
"外径(mm)",
|
||||
"长(mm)",
|
||||
"宽(mm)",
|
||||
"高(mm)",
|
||||
"孔径",
|
||||
"类别",
|
||||
];
|
||||
|
||||
function getPrecisionGearCardSpecs(product: CatalogProduct) {
|
||||
return PRECISION_GEAR_CARD_SPEC_ORDER
|
||||
.filter((label) => product.specs[label])
|
||||
.slice(0, 2)
|
||||
.map((label) => [label, product.specs[label]] as const);
|
||||
}
|
||||
|
||||
const SERVO_CATEGORIES = ["标准舵机", "异形舵机", "全金属舵机", "大扭矩舵机", "积木舵机"];
|
||||
const SILENT_SERVO_CATEGORY = "静音舵机";
|
||||
const CUSTOM_SERVO_CATEGORY = "非标准舵机定制";
|
||||
@@ -362,6 +368,9 @@ export default function Home() {
|
||||
const [catalogCategory, setCatalogCategory] = useState("全部产品");
|
||||
const [catalogScale, setCatalogScale] = useState("all");
|
||||
const [catalogLimit, setCatalogLimit] = useState(24);
|
||||
const [precisionGearQuery, setPrecisionGearQuery] = useState("");
|
||||
const [precisionGearCategory, setPrecisionGearCategory] = useState("全部子类");
|
||||
const [precisionGearLimit, setPrecisionGearLimit] = useState(24);
|
||||
const [selectedCatalogProduct, setSelectedCatalogProduct] = useState<CatalogProduct | null>(null);
|
||||
|
||||
const matches = useMemo(() => getMatches(requirements), [requirements]);
|
||||
@@ -392,6 +401,22 @@ export default function Home() {
|
||||
});
|
||||
}, [catalogCategory, catalogQuery, catalogScale]);
|
||||
const visibleCatalog = filteredCatalog.slice(0, catalogLimit);
|
||||
const filteredPrecisionGears = useMemo(() => {
|
||||
const query = precisionGearQuery.trim().toLowerCase();
|
||||
return PRECISION_GEAR_PRODUCTS.filter((product) => {
|
||||
if (precisionGearCategory !== "全部子类" && product.subCategory !== precisionGearCategory) return false;
|
||||
if (!query) return true;
|
||||
const haystack = [
|
||||
product.name,
|
||||
product.code,
|
||||
product.subCategory,
|
||||
...Object.keys(product.specs),
|
||||
...Object.values(product.specs),
|
||||
].join(" ").toLowerCase();
|
||||
return haystack.includes(query);
|
||||
});
|
||||
}, [precisionGearCategory, precisionGearQuery]);
|
||||
const visiblePrecisionGears = filteredPrecisionGears.slice(0, precisionGearLimit);
|
||||
const needsEngineer =
|
||||
!top?.coreCompatible ||
|
||||
requirements.annualVolume === "50000件以上" ||
|
||||
@@ -1087,6 +1112,93 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div className="precision-gear-catalog" aria-label="精密齿轮配件产品卡片">
|
||||
<div className="precision-gear-catalog-heading">
|
||||
<div>
|
||||
<p className="step-kicker">产品卡片目录</p>
|
||||
<h4>精密齿轮配件 · 511 款</h4>
|
||||
</div>
|
||||
<p>小型卡片展示型号、子类和关键规格,点击图片可查看产品大图与完整参数。</p>
|
||||
</div>
|
||||
<div className="precision-gear-controls">
|
||||
<input
|
||||
value={precisionGearQuery}
|
||||
onChange={(event) => {
|
||||
setPrecisionGearQuery(event.target.value);
|
||||
setPrecisionGearLimit(24);
|
||||
}}
|
||||
placeholder="搜索齿轮名称、编码、材质或规格"
|
||||
aria-label="搜索精密齿轮配件"
|
||||
/>
|
||||
<div className="precision-gear-pills" aria-label="精密齿轮子类筛选">
|
||||
<button
|
||||
type="button"
|
||||
className={precisionGearCategory === "全部子类" ? "active" : ""}
|
||||
onClick={() => {
|
||||
setPrecisionGearCategory("全部子类");
|
||||
setPrecisionGearLimit(24);
|
||||
}}
|
||||
>全部子类 · 511</button>
|
||||
{PRECISION_GEAR_SUBCATEGORIES.map(([name, count]) => (
|
||||
<button
|
||||
type="button"
|
||||
key={name}
|
||||
className={precisionGearCategory === name ? "active" : ""}
|
||||
onClick={() => {
|
||||
setPrecisionGearCategory(name);
|
||||
setPrecisionGearLimit(24);
|
||||
}}
|
||||
>{name} · {count}</button>
|
||||
))}
|
||||
</div>
|
||||
<p className="precision-gear-result">找到 <strong>{filteredPrecisionGears.length}</strong> 款配件</p>
|
||||
</div>
|
||||
|
||||
{visiblePrecisionGears.length > 0 ? (
|
||||
<div className="precision-gear-grid">
|
||||
{visiblePrecisionGears.map((product) => (
|
||||
<article className="precision-gear-card" key={product.id}>
|
||||
<button
|
||||
type="button"
|
||||
className="precision-gear-image"
|
||||
onClick={() => setSelectedCatalogProduct(product)}
|
||||
aria-label={`查看${product.name}大图`}
|
||||
>
|
||||
<img src={product.image} alt={product.name} loading="lazy" />
|
||||
<span>点击查看大图</span>
|
||||
</button>
|
||||
<div className="precision-gear-card-body">
|
||||
<p>{product.subCategory}</p>
|
||||
<h5>{product.name}</h5>
|
||||
<code>{product.code}</code>
|
||||
<dl>
|
||||
{getPrecisionGearCardSpecs(product).map(([label, value]) => (
|
||||
<div key={label}><dt>{label}</dt><dd>{value}</dd></div>
|
||||
))}
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="catalog-empty precision-gear-empty">
|
||||
<strong>没有找到匹配的精密齿轮</strong>
|
||||
<p>可以尝试减少关键词,或切换到“全部子类”。</p>
|
||||
<button type="button" onClick={() => { setPrecisionGearQuery(""); setPrecisionGearCategory("全部子类"); setPrecisionGearLimit(24); }}>
|
||||
清除筛选
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{precisionGearLimit < filteredPrecisionGears.length && (
|
||||
<div className="load-more-wrap precision-gear-load-more">
|
||||
<button type="button" onClick={() => setPrecisionGearLimit((current) => current + 24)}>
|
||||
加载更多齿轮配件 <span>已显示 {visiblePrecisionGears.length} / {filteredPrecisionGears.length}</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{selectedCatalogProduct && (
|
||||
@@ -1139,7 +1251,11 @@ export default function Home() {
|
||||
<h2 id="catalog-modal-title">{selectedCatalogProduct.name}</h2>
|
||||
<code>{selectedCatalogProduct.code}</code>
|
||||
<p className="catalog-source-note">
|
||||
{selectedCatalogProduct.page > 0 ? `官方产品目录第 ${selectedCatalogProduct.page} 页` : "商城产品资料 · 舵盘配件"}
|
||||
{selectedCatalogProduct.page > 0
|
||||
? `官方产品目录第 ${selectedCatalogProduct.page} 页`
|
||||
: selectedCatalogProduct.category === "舵盘配件"
|
||||
? "商城产品资料 · 舵盘配件"
|
||||
: "商城产品资料 · 精密齿轮配件"}
|
||||
</p>
|
||||
<div className="catalog-modal-highlight">
|
||||
<span>产品尺寸</span>
|
||||
|
||||
Reference in New Issue
Block a user