@@ -1,28 +1,10 @@
import { useState } from "react" ;
import { Search , PlusCircle , Code2 , ScanBarcode , ShieldCheck , ArrowRight } from "lucide-react" ;
import { Search , PlusCircle , ScanBarcode , ShieldCheck , 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,23 +39,32 @@ 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" >
< section
className = { ` relative overflow-hidden rounded-3xl border border-gray-100 bg-gradient-to-b from-white to-brand-50/40 px-4 text-center shadow-card sm:px-6 ${
searched
? "py-8 sm:py-10"
: "flex min-h-[calc(100vh-12rem)] flex-col items-center justify-center py-12 sm:min-h-[calc(100vh-13rem)] sm:py-16"
} ` }
>
< 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"
className = "pointer-events-none absolute -top-24 left-1/2 h-72 w-[42rem] max-w-full -translate-x-1/2 rounded-full bg-brand-200/30 blur-3xl"
/ >
< div className = "relative" >
< div className = "relative w-full " >
< 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-4xl sm:text-5xl font-extrabold tracking-tight text-gray-900" >
< h1 className = "mt-5 text-4xl font-extrabold tracking-tight text-gray-900 sm:text-5xl " >
天 < 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-gray-500 " >
< p className = "mx-auto mt-3 max-w-xl text-sm text-gray-500 sm:text-base " >
输 入 商 品 名 称 或 条 码 , 检 索 客 观 、 可 溯 源 的 商 品 资 料 。 人 人 可 查 , 人 人 可 贡 献 。
< / p >
< form onSubmit = { ( e ) = > run ( undefined , e ) } className = "mx-auto mt-7 flex max-w-2xl gap-2" >
< form
onSubmit = { ( e ) = > run ( undefined , e ) }
className = "mx-auto mt-7 flex w-full max-w-2xl flex-col gap-2 sm:flex-row"
>
< 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
@@ -84,7 +75,7 @@ export default function Home({
className = "flex-1 bg-transparent py-3.5 outline-none"
/ >
< / div >
< button type = "submit" disabled = { loading } className = "btn-primary px-7" >
< button type = "submit" disabled = { loading } className = "btn-primary px-7 py-3.5 sm:py-0 " >
{ loading ? "检索中…" : "检索" }
< / button >
< / form >
@@ -106,7 +97,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 +145,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 >
) ;