Add large image action to AI recommendations

This commit is contained in:
Jacky Ser
2026-08-11 16:28:39 +08:00
parent 7eed023539
commit e8759531b7
2 changed files with 15 additions and 9 deletions

View File

@@ -170,14 +170,15 @@ select:focus, input:focus, textarea:focus { border-color: var(--blue); box-shado
.recommendation-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; gap: 10px; } .recommendation-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; gap: 10px; }
.recommendation-card { min-width: 0; min-height: 442px; display: flex; flex-direction: column; overflow: hidden; border: 1px solid #dce3ed; border-radius: 14px; background: white; box-shadow: 0 8px 24px rgba(38,70,125,.06); } .recommendation-card { min-width: 0; min-height: 442px; display: flex; flex-direction: column; overflow: hidden; border: 1px solid #dce3ed; border-radius: 14px; background: white; box-shadow: 0 8px 24px rgba(38,70,125,.06); }
.recommendation-card.is-primary { border-color: #cfdaf0; box-shadow: 0 8px 24px rgba(38,70,125,.1); } .recommendation-card.is-primary { border-color: #cfdaf0; box-shadow: 0 8px 24px rgba(38,70,125,.1); }
.recommendation-image-wrap { position: relative; display: grid; place-items: center; overflow: hidden; background: #eff4fb; } .recommendation-image-wrap { position: relative; width: 100%; padding: 0; display: grid; place-items: center; overflow: hidden; border: 0; color: inherit; background: #eff4fb; cursor: pointer; text-align: left; }
.recommendation-image-wrap img { display: block; width: 100%; height: auto; object-fit: contain; mix-blend-mode: multiply; } .recommendation-image-wrap img { display: block; width: 100%; height: auto; object-fit: contain; mix-blend-mode: multiply; transition: transform .25s ease; }
.match-badge { position: absolute; left: 12px; top: 12px; padding: 6px 9px; border-radius: 7px; color: white; background: var(--orange); font-size: 9px; font-weight: 800; } .recommendation-image-wrap:hover img { transform: scale(1.04); }
.recommendation-image-wrap:focus-visible { outline: 3px solid rgba(24,94,232,.28); outline-offset: -3px; }
.match-badge { position: absolute; left: 12px; bottom: 12px; padding: 6px 9px; border-radius: 7px; color: white; background: var(--orange); font-size: 9px; font-weight: 800; box-shadow: 0 5px 13px rgba(80,45,13,.2); }
.recommendation-zoom-hint { position: absolute; right: 12px; bottom: 12px; padding: 5px 8px; border: 1px solid rgba(255,255,255,.7); border-radius: 6px; color: #53637b; background: rgba(255,255,255,.9); font-size: 8px; font-weight: 700; }
.recommendation-content { position: relative; flex: 1; display: flex; flex-direction: column; min-width: 0; padding: 14px 13px 12px; } .recommendation-content { position: relative; flex: 1; display: flex; flex-direction: column; min-width: 0; padding: 14px 13px 12px; }
.match-score { position: absolute; right: 16px; top: 15px; display: grid; text-align: right; color: #7c889a; font-size: 9px; }
.match-score strong { color: var(--blue); font-size: 18px; }
.product-code { margin: 0 0 4px; color: #8b96a8; font-size: 9px; } .product-code { margin: 0 0 4px; color: #8b96a8; font-size: 9px; }
.recommendation-content h3 { min-height: 38px; max-width: calc(100% - 42px); margin: 0; overflow: hidden; font-size: 14px; line-height: 1.35; } .recommendation-content h3 { min-height: 38px; max-width: 100%; margin: 0; overflow: hidden; font-size: 14px; line-height: 1.35; }
.product-subtitle { margin: 5px 0 13px; color: #7b8799; font-size: 10px; } .product-subtitle { margin: 5px 0 13px; color: #7b8799; font-size: 10px; }
.metric-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; } .metric-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.metric { padding: 8px 9px; border-radius: 8px; background: #f4f7fb; display: grid; gap: 3px; } .metric { padding: 8px 9px; border-radius: 8px; background: #f4f7fb; display: grid; gap: 3px; }

View File

@@ -838,14 +838,19 @@ export default function Home() {
<div className="recommendation-grid"> <div className="recommendation-grid">
{topMatches.map((match, index) => ( {topMatches.map((match, index) => (
<article className={`recommendation-card ${index === 0 ? "is-primary" : ""}`} key={match.product.id}> <article className={`recommendation-card ${index === 0 ? "is-primary" : ""}`} key={match.product.id}>
<div className="recommendation-image-wrap"> <button
type="button"
className="recommendation-image-wrap"
onClick={() => setSelectedCatalogProduct(match.product)}
aria-label={`查看${match.product.name}大图`}
>
<img src={match.product.image} alt={match.product.name} /> <img src={match.product.image} alt={match.product.name} />
<span className="match-badge"> <span className="match-badge">
{index === 0 ? (match.coreCompatible ? "首选推荐" : "待复核候选") : `${match.confidence}% 匹配`} {index === 0 ? (match.coreCompatible ? "首选推荐" : "待复核候选") : `${match.confidence}% 匹配`}
</span> </span>
</div> <span className="recommendation-zoom-hint"></span>
</button>
<div className="recommendation-content"> <div className="recommendation-content">
<div className="match-score"><span></span><strong>{match.confidence}%</strong></div>
<p className="product-code">{match.product.code}</p> <p className="product-code">{match.product.code}</p>
<h3>{match.product.name}</h3> <h3>{match.product.name}</h3>
<p className="product-subtitle">{match.product.category} · {match.product.size || "尺寸待复核"}</p> <p className="product-subtitle">{match.product.category} · {match.product.size || "尺寸待复核"}</p>