From 507f4018d6acf5b0ed71c10fcd5a34f7e5bf92a5 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 24 Mar 2026 11:17:42 +0800 Subject: [PATCH] feat(landing): add researchers trust band --- apps/landing/src/app/[locale]/page.tsx | 7 ++- .../components/widgets/landing/TrustedBy.tsx | 54 ++++++++++--------- apps/landing/src/lib/landing-data.test.ts | 21 ++++++++ apps/landing/src/lib/landing-data.ts | 13 +++++ apps/landing/src/messages/en.json | 1 + apps/landing/src/messages/jp.json | 1 + apps/landing/src/messages/zh.json | 1 + 7 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 apps/landing/src/lib/landing-data.test.ts diff --git a/apps/landing/src/app/[locale]/page.tsx b/apps/landing/src/app/[locale]/page.tsx index 5a73785f2..df98734a0 100644 --- a/apps/landing/src/app/[locale]/page.tsx +++ b/apps/landing/src/app/[locale]/page.tsx @@ -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 ( <> - + {/* */} {/* */} diff --git a/apps/landing/src/components/widgets/landing/TrustedBy.tsx b/apps/landing/src/components/widgets/landing/TrustedBy.tsx index 3dbffd84d..22f828e66 100644 --- a/apps/landing/src/components/widgets/landing/TrustedBy.tsx +++ b/apps/landing/src/components/widgets/landing/TrustedBy.tsx @@ -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 = ({ companies, + researchers, metrics, }) => { const trustedT = useTranslations('landing.trustedBy') @@ -34,34 +36,36 @@ export const TrustedBy: Component = ({ }, ] + const renderTrustRow = (items: TrustedCompany[], eyebrow: string) => ( +
+

+ {eyebrow} +

+ +
+ {items.map((item) => ( +
+
+ {item.name} +
+ {item.name} +
+ ))} +
+
+ ) + return (
-
-

- {trustedT('eyebrow')} -

- -
- {companies.map((company) => ( -
-
- {company.name} -
- - {company.name} - -
- ))} -
+
+ {renderTrustRow(companies, trustedT('eyebrow'))} + {renderTrustRow(researchers, trustedT('researchersEyebrow'))}
diff --git a/apps/landing/src/lib/landing-data.test.ts b/apps/landing/src/lib/landing-data.test.ts new file mode 100644 index 000000000..6bb2be6e6 --- /dev/null +++ b/apps/landing/src/lib/landing-data.test.ts @@ -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', + ]) + }) +}) diff --git a/apps/landing/src/lib/landing-data.ts b/apps/landing/src/lib/landing-data.ts index 75bba2989..d368c6a16 100644 --- a/apps/landing/src/lib/landing-data.ts +++ b/apps/landing/src/lib/landing-data.ts @@ -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, diff --git a/apps/landing/src/messages/en.json b/apps/landing/src/messages/en.json index 4bec2f4ca..a2b958319 100644 --- a/apps/landing/src/messages/en.json +++ b/apps/landing/src/messages/en.json @@ -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." }, diff --git a/apps/landing/src/messages/jp.json b/apps/landing/src/messages/jp.json index eb9a303ec..a20bab613 100644 --- a/apps/landing/src/messages/jp.json +++ b/apps/landing/src/messages/jp.json @@ -48,6 +48,7 @@ }, "trustedBy": { "eyebrow": "導入が進むチーム", + "researchersEyebrow": "導入が進む研究者", "headline": "すでに Folo を使うチームがあります。", "body": "本番環境の業務用メール登録サンプルをもとに、Folo を使い始めている企業を抽出しました。" }, diff --git a/apps/landing/src/messages/zh.json b/apps/landing/src/messages/zh.json index 25ec1cb66..5fb615033 100644 --- a/apps/landing/src/messages/zh.json +++ b/apps/landing/src/messages/zh.json @@ -48,6 +48,7 @@ }, "trustedBy": { "eyebrow": "已被这些团队采用", + "researchersEyebrow": "已被这些研究者采用", "headline": "已经有团队在用 Folo。", "body": "我们基于生产环境中的工作邮箱注册样本,整理出了这些已经开始使用 Folo 的公司。" },