@@ -1,28 +1,8 @@
import { useState } from "react" ;
import { Search , PlusCircle , Code2 , ScanBarcode , ShieldCheck , ArrowRight } from "lucide-react" ;
import { Search , PlusCircle , ArrowRight } from "lucide-react" ;
import { api } from "../api" ;
import type { ProductSummary } from "../types" ;
const EXAMPLES = [ "可乐" , "Nutella" , "牛奶" , "5449000000996" ] ;
const FEATURES = [
{
icon : Search ,
title : "客观可查" ,
desc : "按名称或条码检索商品的成分、营养、规格等官方事实。" ,
} ,
{
icon : ShieldCheck ,
title : "可溯源" ,
desc : "每条资料标注数据来源与质量分,公开透明、人人可核。" ,
} ,
{
icon : Code2 ,
title : "开放 API" ,
desc : "免鉴权只读 REST 接口,开发者可直接接入商品档案。" ,
} ,
] ;
export default function Home ( {
onOpen ,
onContribute ,
@@ -57,47 +37,47 @@ export default function Home({
return (
< div className = "animate-fade-up" >
< section className = "relative overflow-hidden rounded-3xl border border-gray-100 bg-gradient-to-b from-white to-brand-50/40 px-6 py-14 text-center shadow-card" >
< div
aria - hidden
className = "pointer-events-none absolute -top-24 left-1/2 h-72 w-[42rem] -translate-x-1/2 rounded-full bg-brand-200/30 blur-3xl"
/ >
< div className = "relative" >
< span className = "inline-flex items-center gap-1.5 rounded-full border border-brand-200 bg-white/70 px-3 py-1 text-xs font-medium text-brand-700" >
< ShieldCheck className = "w-3.5 h-3.5" / > 公 益 · 开 放 · 可 溯 源
< / span >
< h1 className = "mt-5 text-4 xl sm: text-5 xl font-extrabold tracking-tight text-gray-900" >
天 < span className = "bg-gradient-to-r from-brand-600 to-emerald-500 bg-clip-text text-transparent" > 工 < / span >
< / h1 >
< p className = "mx-auto mt-3 max-w-xl text-g ray-5 00" >
输 入 商 品 名 称 或 条 码 , 检 索 客 观 、 可 溯 源 的 商 品 资 料 。 人 人 可 查 , 人 人 可 贡 献 。
< / p >
< section
className = { ` flex flex-col items-center px-4 text-center ${
searched
? "pt-2 pb-6"
: "min-h-[calc(100vh-12rem)] justify-center"
} ` }
>
< h1
className = { ` font-medium tracking-tight text-gray-800 ${
searched ? " text-3 xl" : " text-6 xl sm:text-7xl"
} ` }
>
天 < span className = "text-b rand-6 00" > 工 < / span >
< / h1 >
< form onSubmit = { ( e ) = > run ( undefined , e ) } className = "mx-auto mt-7 flex max-w-2xl gap-2" >
< div className = "flex flex-1 items-center gap-2 rounded-xl border border-gray-200 bg-white px-3.5 shadow-sm transition focus-within:border-brand-400 focus-within:ring-4 focus-within:ring-brand-500/10" >
< Search className = "h-5 w-5 shrink-0 text-gray-400" / >
< input
autoFocus
value = { q }
onChange = { ( e ) = > setQ ( e . target . value ) }
placeholder = "例如:可乐、Nutella、5449000000996"
className = "flex-1 bg-transparent py-3.5 outline-none"
/ >
< / div >
< button type = "submit" disabled = { loading } className = "btn-primary px-7" >
{ loading ? "检索中…" : "检索" }
< / button >
< / form >
< div className = "mt-4 flex flex-wrap items-center justify-center gap-2" >
< span className = "text-xs text-gray-400" > 试 试 : < / span >
{ EXAMPLES . map ( ( ex ) = > (
< button key = { ex } type = "button" className = "chip" onClick = { ( ) = > run ( ex ) } >
< ScanBarcode className = "w-3 h-3" / > { ex }
< / button >
) ) }
< form
onSubmit = { ( e ) = > run ( undefined , e ) }
className = "mx-auto mt-8 w-full max-w-xl"
>
< div className = "flex items-center gap-3 rounded-full border border-gray-200 bg-white px-5 py-3 shadow-sm transition hover:shadow-md focus-within:shadow-md" >
< Search className = "h-5 w-5 shrink-0 text-gray-400" / >
< input
autoFocus
value = { q }
onChange = { ( e ) = > setQ ( e . target . value ) }
placeholder = "搜索商品名称或条码"
className = "flex-1 bg-transparent outline-none"
/ >
< / div >
< / div >
{ ! searched && (
< div className = "mt-8" >
< button
type = "submit"
disabled = { loading }
className = "rounded-md border border-gray-200 bg-gray-50 px-6 py-2.5 text-sm text-gray-700 transition hover:border-gray-300 hover:shadow-sm"
>
{ loading ? "检索中…" : "检索" }
< / button >
< / div >
) }
< / form >
< / section >
{ error && (
@@ -106,7 +86,7 @@ export default function Home({
< / div >
) }
{ searched ? (
{ searched && (
< div className = "mt-8" >
< div className = "mb-3 text-sm text-gray-500" >
共 < span className = "font-semibold text-gray-700" > { total } < / span > 条 结 果
@@ -154,18 +134,6 @@ export default function Home({
< / ul >
) }
< / div >
) : (
< div className = "mt-8 grid gap-4 sm:grid-cols-3" >
{ FEATURES . map ( ( { icon : Icon , title , desc } ) = > (
< div key = { title } className = "card p-5 transition hover:shadow-card-hover" >
< span className = "grid h-10 w-10 place-items-center rounded-xl bg-brand-50 text-brand-600" >
< Icon className = "h-5 w-5" / >
< / span >
< h3 className = "mt-3 font-semibold text-gray-800" > { title } < / h3 >
< p className = "mt-1 text-sm leading-relaxed text-gray-500" > { desc } < / p >
< / div >
) ) }
< / div >
) }
< / div >
) ;