Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions ui/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Link from 'next/link'
import { notFound } from 'next/navigation'
import { hasLocale } from 'next-intl'
import { getMessages, getTranslations, setRequestLocale } from 'next-intl/server'
import { Heart, Home, Settings2, Sparkles } from 'lucide-react'
import { Heart, Settings2, Sparkles } from 'lucide-react'
import { AuthSessionProvider } from '@/components/auth-session-provider'
import { IntlProvider } from '@/components/intl-provider'
import { Toaster } from '@/components/ui/toaster'
Expand Down Expand Up @@ -43,7 +43,6 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro

const messages = await getMessages()
const navItems = [
{ href: `/${locale}`, label: locale === 'zh' ? '首页' : 'Home', icon: Home },
{ href: `/${locale}/favorites`, label: locale === 'zh' ? '收藏' : 'Favorites', icon: Heart },
{ href: `/${locale}/preferences`, label: locale === 'zh' ? '偏好' : 'Preferences', icon: Settings2 },
]
Expand All @@ -58,10 +57,7 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro
<span className="grid h-9 w-9 place-items-center rounded-xl bg-primary text-primary-foreground shadow-sm">
<Sparkles className="h-4 w-4" />
</span>
<div>
<p className="text-sm font-semibold text-foreground sm:text-base">AI Tool Picker</p>
<p className="text-xs text-muted-foreground">{locale === 'zh' ? '更快完成 AI 工具初选' : 'Shortlist the right AI tools faster'}</p>
</div>
<p className="text-sm font-semibold text-foreground sm:text-base">AI Tool Picker</p>
</Link>

<div className="flex items-center gap-1 sm:gap-2">
Expand Down
9 changes: 1 addition & 8 deletions ui/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useLocale, useTranslations } from "next-intl"
import { useRouter } from "next/navigation"
import { HomeHero } from "@/components/home/home-hero"
import { HomeQuickScenes } from "@/components/home/home-quick-scenes"
import { HomeResultsPreview } from "@/components/home/home-results-preview"
import { SearchInput } from "@/components/search-input"
import { useSearchFlow } from "@/hooks/use-search-flow"
import { useHistory } from "@/hooks/use-history"
Expand Down Expand Up @@ -39,6 +38,7 @@ export default function HomePage() {
() =>
[...(quickScenesConfig as QuickSceneConfig[])]
.sort((a, b) => a.order - b.order)
.slice(0, 4)
.map((scene) => ({ ...scene, label: t(scene.languageKey) })),
[t],
)
Expand Down Expand Up @@ -78,17 +78,10 @@ export default function HomePage() {
/>
}
scenarioTitle={t("home.quickScenesTitle")}
stats={[
{ label: t("home.stats.countLabel"), value: t("home.stats.countValue") },
{ label: t("home.stats.timeLabel"), value: t("home.stats.timeValue") },
{ label: t("home.stats.reasonLabel"), value: t("home.stats.reasonValue") },
]}
quickScenes={<HomeQuickScenes scenes={quickScenes} query={searchFlow.query} onSelect={searchFlow.setQuery} />}
/>

{searchFlow.error && <p className="rounded-xl border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">{searchFlow.error}</p>}

<HomeResultsPreview title={t("home.resultsTitle")} subtitle={t("home.resultsPreviewSubtitle")} emptyHint={t("home.emptyHint")} />
</main>
)
}
51 changes: 8 additions & 43 deletions ui/components/home/home-hero.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import type { ReactNode } from "react"
import { ShieldCheck, Sparkles, Timer } from "lucide-react"

type HeroStat = {
label: string
value: string
}

type HomeHeroProps = {
title: string
Expand All @@ -13,50 +7,21 @@ type HomeHeroProps = {
inputArea: ReactNode
quickScenes: ReactNode
scenarioTitle: string
stats: HeroStat[]
}

const iconMap = [Sparkles, Timer, ShieldCheck]

export function HomeHero({ title, subtitle, trustNote, inputArea, quickScenes, scenarioTitle, stats }: HomeHeroProps) {
export function HomeHero({ title, subtitle, trustNote, inputArea, quickScenes, scenarioTitle }: HomeHeroProps) {
return (
<section className="app-panel relative overflow-hidden px-6 py-7 sm:px-8 sm:py-9">
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_right,color-mix(in_oklab,var(--primary)_14%,transparent)_0%,transparent_46%)]" />
<div className="relative space-y-8">
<div className="space-y-4">
<p className="inline-flex items-center rounded-full border border-border/70 bg-background/80 px-3 py-1 text-xs font-medium tracking-wide text-muted-foreground">
AI Tool Decision Assistant
</p>
<div className="space-y-3">
<h1 className="max-w-4xl text-[length:var(--font-title-xl)] font-semibold leading-[var(--line-height-title)] tracking-tight text-foreground">{title}</h1>
<p className="max-w-3xl text-[length:var(--font-body-md)] text-muted-foreground">{subtitle}</p>
</div>
<div className="app-panel-subtle flex flex-wrap items-center justify-between gap-3 rounded-2xl px-4 py-3 text-sm text-muted-foreground">
<span>{trustNote}</span>
<span className="inline-flex items-center gap-1 text-xs font-medium uppercase tracking-[0.12em]">Linear / Vercel inspired workflow</span>
</div>
<section className="app-panel px-6 py-7 sm:px-8 sm:py-9">
<div className="space-y-6">
<div className="space-y-3">
<h1 className="max-w-4xl text-[length:var(--font-title-xl)] font-semibold leading-[var(--line-height-title)] tracking-tight text-foreground">{title}</h1>
<p className="max-w-3xl text-[length:var(--font-body-md)] text-muted-foreground">{subtitle}</p>
</div>

{inputArea}

<div className="grid gap-3 sm:grid-cols-3">
{stats.map((stat, index) => {
const Icon = iconMap[index] ?? Sparkles
return (
<div key={stat.label} className="app-panel-muted flex items-start gap-3 rounded-2xl p-4">
<span className="mt-0.5 rounded-lg bg-background p-2 text-primary">
<Icon className="h-4 w-4" />
</span>
<div>
<p className="text-xs text-muted-foreground">{stat.label}</p>
<p className="mt-1 text-sm font-medium text-foreground">{stat.value}</p>
</div>
</div>
)
})}
</div>

<div className="space-y-3 border-t border-border/70 pt-5">
<div className="space-y-3 border-t border-border/70 pt-4">
<p className="text-xs text-muted-foreground sm:text-sm">{trustNote}</p>
<h2 className="text-sm font-medium text-foreground sm:text-base">{scenarioTitle}</h2>
{quickScenes}
</div>
Expand Down
Loading