feat(public): 首页移除品牌/产地筛选,合格档案数移至页脚 #10

Merged
lixu merged 1 commits from devin/1782010793-home-tweaks into main 2026-06-21 11:01:03 +08:00
2 changed files with 21 additions and 39 deletions
+19 -1
View File
@@ -1,9 +1,10 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import { Boxes, Search, PlusCircle, Code2 } from "lucide-react";
import Home from "./components/Home";
import ProductView from "./components/ProductView";
import Contribute from "./components/Contribute";
import ApiDocs from "./components/ApiDocs";
import { api } from "./api";
type View =
| { name: "home" }
@@ -13,6 +14,14 @@ type View =
export default function App() {
const [view, setView] = useState<View>({ name: "home" });
const [qualified, setQualified] = useState<number | null>(null);
useEffect(() => {
api
.stats()
.then((s) => setQualified(s.qualified))
.catch(() => setQualified(null));
}, []);
return (
<div className="min-h-full flex flex-col">
@@ -73,6 +82,15 @@ export default function App() {
<footer className="border-t bg-white">
<div className="max-w-5xl mx-auto px-4 py-4 text-xs text-gray-400 leading-relaxed">
{qualified != null && (
<div className="mb-2 text-gray-500">
<span className="mx-1 font-semibold text-emerald-600">
{qualified.toLocaleString()}
</span>
</div>
)}
/
稿
<button onClick={() => setView({ name: "api" })} className="ml-1 text-emerald-600 hover:underline">
+2 -38
View File
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useState } from "react";
import { Search, PlusCircle, Code2 } from "lucide-react";
import { api } from "../api";
import type { ProductSummary } from "../types";
@@ -13,31 +13,18 @@ export default function Home({
onApi: () => void;
}) {
const [q, setQ] = useState("");
const [brand, setBrand] = useState("");
const [country, setCountry] = useState("");
const [items, setItems] = useState<ProductSummary[]>([]);
const [total, setTotal] = useState(0);
const [searched, setSearched] = useState(false);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [qualified, setQualified] = useState<number | null>(null);
useEffect(() => {
api
.stats()
.then((s) => setQualified(s.qualified))
.catch(() => setQualified(null));
}, []);
async function run(e?: React.FormEvent) {
e?.preventDefault();
setLoading(true);
setError("");
try {
const res = await api.search(q.trim(), 1, 30, {
brand: brand.trim() || undefined,
country: country.trim() || undefined,
});
const res = await api.search(q.trim(), 1, 30);
setItems(res.items);
setTotal(res.total);
setSearched(true);
@@ -55,15 +42,6 @@ export default function Home({
<p className="mt-2 text-gray-500">
</p>
{qualified != null && (
<p className="mt-3 text-sm text-gray-500">
<span className="mx-1 font-semibold text-emerald-600">
{qualified.toLocaleString()}
</span>
</p>
)}
<form onSubmit={run} className="mt-6 max-w-2xl mx-auto flex gap-2">
<div className="flex-1 flex items-center gap-2 bg-white border rounded-lg px-3 shadow-sm focus-within:ring-2 focus-within:ring-emerald-400">
<Search className="w-5 h-5 text-gray-400" />
@@ -83,20 +61,6 @@ export default function Home({
{loading ? "检索中…" : "检索"}
</button>
</form>
<div className="mt-3 max-w-2xl mx-auto flex flex-wrap items-center justify-center gap-2 text-sm">
<input
value={brand}
onChange={(e) => setBrand(e.target.value)}
placeholder="按品牌筛选(如 Ferrero"
className="flex-1 min-w-[14rem] bg-white border rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-emerald-300"
/>
<input
value={country}
onChange={(e) => setCountry(e.target.value)}
placeholder="按产地筛选(如 China"
className="flex-1 min-w-[14rem] bg-white border rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-emerald-300"
/>
</div>
<button
onClick={onApi}
className="mt-4 inline-flex items-center gap-1.5 text-sm text-emerald-700 hover:underline"