feat(landing): add researchers trust band

This commit is contained in:
DIYgod 2026-03-24 11:17:42 +08:00
parent 5c866585de
commit 507f4018d6
7 changed files with 72 additions and 26 deletions

View File

@ -9,6 +9,7 @@ import {
getHeroTimelineItems,
getLandingMetrics,
TRUSTED_COMPANIES,
TRUSTED_RESEARCH_INSTITUTIONS,
} from '~/lib/landing-data'
type LocaleParams = { locale?: string }
@ -27,7 +28,11 @@ export default async function Home({
return (
<>
<LandingHero items={heroItems} />
<TrustedBy companies={TRUSTED_COMPANIES} metrics={metrics} />
<TrustedBy
companies={TRUSTED_COMPANIES}
researchers={TRUSTED_RESEARCH_INSTITUTIONS}
metrics={metrics}
/>
<Features discoverSources={DISCOVER_FALLBACK} />
{/* <ViewsShowcase /> */}
{/* <Audience /> */}

View File

@ -6,6 +6,7 @@ import type { LandingMetrics, TrustedCompany } from '~/lib/landing-data'
type TrustedByProps = {
companies: TrustedCompany[]
researchers: TrustedCompany[]
metrics: LandingMetrics
}
@ -18,6 +19,7 @@ const formatCompact = (value: number) => compactFormatter.format(value)
export const TrustedBy: Component<TrustedByProps> = ({
companies,
researchers,
metrics,
}) => {
const trustedT = useTranslations('landing.trustedBy')
@ -34,34 +36,36 @@ export const TrustedBy: Component<TrustedByProps> = ({
},
]
const renderTrustRow = (items: TrustedCompany[], eyebrow: string) => (
<div className="flex flex-col items-center gap-5 text-center">
<p className="text-[11px] font-medium uppercase tracking-[0.28em] text-accent/90">
{eyebrow}
</p>
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-4">
{items.map((item) => (
<div key={item.name} className="inline-flex items-center gap-2.5">
<div className="flex size-8 items-center justify-center rounded-full bg-background-secondary p-1">
<img
src={`https://icons.folo.is/${item.host}`}
alt={item.name}
className="size-full rounded-full object-cover grayscale"
loading="lazy"
/>
</div>
<span className="text-sm font-medium text-text">{item.name}</span>
</div>
))}
</div>
</div>
)
return (
<section className="mx-auto mt-14 w-full max-w-[var(--container-max-width-2xl)] px-4 md:mt-16 lg:mt-20">
<div className="flex flex-col gap-16">
<div className="flex flex-col items-center gap-5 text-center">
<p className="text-[11px] font-medium uppercase tracking-[0.28em] text-accent/90">
{trustedT('eyebrow')}
</p>
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-4">
{companies.map((company) => (
<div
key={company.name}
className="inline-flex items-center gap-2.5"
>
<div className="flex size-8 items-center justify-center rounded-full bg-background-secondary p-1">
<img
src={`https://icons.folo.is/${company.host}`}
alt={company.name}
className="size-full rounded-full object-cover grayscale"
loading="lazy"
/>
</div>
<span className="text-sm font-medium text-text">
{company.name}
</span>
</div>
))}
</div>
<div className="flex flex-col gap-8">
{renderTrustRow(companies, trustedT('eyebrow'))}
{renderTrustRow(researchers, trustedT('researchersEyebrow'))}
</div>
<div className="flex flex-col items-center gap-4 text-center">

View File

@ -0,0 +1,21 @@
import { describe, expect, it } from 'vitest'
import { TRUSTED_RESEARCH_INSTITUTIONS } from './landing-data'
describe('TRUSTED_RESEARCH_INSTITUTIONS', () => {
it('keeps the QS-sorted top 10 institutions stable', () => {
expect(TRUSTED_RESEARCH_INSTITUTIONS).toHaveLength(10)
expect(TRUSTED_RESEARCH_INSTITUTIONS.map((item) => item.name)).toEqual([
'MIT',
'Stanford',
'Oxford',
'Harvard',
'Cambridge',
'NUS',
'UCL',
'NTU Singapore',
'Peking University',
'UPenn',
])
})
})

View File

@ -343,6 +343,19 @@ export const TRUSTED_COMPANIES: TrustedCompany[] = [
{ name: 'NVIDIA', host: 'nvidia.com', users: 4 },
]
export const TRUSTED_RESEARCH_INSTITUTIONS: TrustedCompany[] = [
{ name: 'MIT', host: 'mit.edu', users: 1 },
{ name: 'Stanford', host: 'stanford.edu', users: 2 },
{ name: 'Oxford', host: 'ox.ac.uk', users: 1 },
{ name: 'Harvard', host: 'harvard.edu', users: 4 },
{ name: 'Cambridge', host: 'cam.ac.uk', users: 1 },
{ name: 'NUS', host: 'nus.edu.sg', users: 11 },
{ name: 'UCL', host: 'ucl.ac.uk', users: 2 },
{ name: 'NTU Singapore', host: 'ntu.edu.sg', users: 6 },
{ name: 'Peking University', host: 'pku.edu.cn', users: 41 },
{ name: 'UPenn', host: 'upenn.edu', users: 5 },
]
const LANDING_METRICS_FALLBACK: LandingMetrics = {
feeds: 1267577,
entries: 300849952,

View File

@ -48,6 +48,7 @@
},
"trustedBy": {
"eyebrow": "Trusted by teams at",
"researchersEyebrow": "Trusted by researchers at",
"headline": "Teams already using Folo.",
"body": "We sampled production work-email registrations to find the companies that have already started reading with Folo."
},

View File

@ -48,6 +48,7 @@
},
"trustedBy": {
"eyebrow": "導入が進むチーム",
"researchersEyebrow": "導入が進む研究者",
"headline": "すでに Folo を使うチームがあります。",
"body": "本番環境の業務用メール登録サンプルをもとに、Folo を使い始めている企業を抽出しました。"
},

View File

@ -48,6 +48,7 @@
},
"trustedBy": {
"eyebrow": "已被这些团队采用",
"researchersEyebrow": "已被这些研究者采用",
"headline": "已经有团队在用 Folo。",
"body": "我们基于生产环境中的工作邮箱注册样本,整理出了这些已经开始使用 Folo 的公司。"
},