feat(frontend): connect Next.js server components to Go backend REST API with resilient fallback

- Implement typed REST API client in refer_landing_page/lib/api.ts
- Support API_BASE_URL environment variable with graceful fallback to static content
- Connect Home page (projects, areas, stats), Members page (active, alumni), Publications (highlights, list, patents), Lectures, and Standardization pages to backend endpoints
- Pass all 12 SSG build, TypeScript, ESLint, and E2E quality gates
This commit is contained in:
2026-08-24 18:40:46 +09:00
parent fb6881070c
commit 9cb6258d3d
10 changed files with 415 additions and 40 deletions
+25 -18
View File
@@ -2,8 +2,10 @@ import React from "react";
import Link from "next/link";
import HeroComposition from "./_components/HeroComposition";
import { ProjectPageView } from "./_components/ProjectPageView";
import { publications, patents } from "../content/publications";
import { standardsBodies } from "../content/standards";
import { publications as staticPubs, patents as staticPatents } from "../content/publications";
import { standardsBodies as staticStandards } from "../content/standards";
import { researchProjects as staticProjects } from "../content/projects";
import { getStatsSummary, getResearchAreaNames, getResearchProjects } from "../lib/api";
// CUSTOMIZATION HOOK: 14 Core Research Areas
const RESEARCH_AREAS: string[] = [
@@ -31,16 +33,21 @@ const INTERNATIONAL_SDOS = [
"ISO/IEC JTC1/SC6: Reliable Multicasting",
];
export default function HomePage() {
const intlPubsCount = publications.filter(
(p) => p.category === "intl-journal-conf"
).length;
const patentCount = patents.length;
const stdDocsCount = standardsBodies.reduce(
(sum, b) =>
sum + b.projects.reduce((pSum, p) => pSum + p.documents.length, 0),
0
);
export default async function HomePage() {
const stats = (await getStatsSummary()) ?? {
intlPubsCount: staticPubs.filter(
(p) => p.category === "intl-journal-conf"
).length,
patentCount: staticPatents.length,
stdDocsCount: staticStandards.reduce(
(sum, b) =>
sum + b.projects.reduce((pSum, p) => pSum + p.documents.length, 0),
0
),
};
const researchAreas = (await getResearchAreaNames()) ?? RESEARCH_AREAS;
const researchProjects = (await getResearchProjects()) ?? staticProjects;
return (
<div className="container-content space-y-16 md:space-y-24 pt-10 md:pt-16 pb-16 md:pb-24">
@@ -66,7 +73,7 @@ export default function HomePage() {
<div className="pt-6 border-t border-line grid grid-cols-3 gap-4">
<div>
<div className="font-serif text-3xl text-cobalt-dark font-normal">
{intlPubsCount}
{stats.intlPubsCount}
</div>
<div className="font-mono text-xs text-ink-mute uppercase tracking-wider mt-1 leading-tight">
International Journals &amp; Conference
@@ -74,7 +81,7 @@ export default function HomePage() {
</div>
<div>
<div className="font-serif text-3xl text-cobalt-dark font-normal">
{stdDocsCount}
{stats.stdDocsCount}
</div>
<div className="font-mono text-xs text-ink-mute uppercase tracking-wider mt-1 leading-tight">
Standardization Contributions
@@ -82,7 +89,7 @@ export default function HomePage() {
</div>
<div>
<div className="font-serif text-3xl text-cobalt-dark font-normal">
{patentCount}
{stats.patentCount}
</div>
<div className="font-mono text-xs text-ink-mute uppercase tracking-wider mt-1 leading-tight">
Patent<br />
@@ -101,7 +108,7 @@ export default function HomePage() {
</section>
{/* Research Project PageView Component */}
<ProjectPageView />
<ProjectPageView projects={researchProjects} />
{/* 14 Research Areas Grid */}
<section className="space-y-8 pt-16 md:pt-20 border-t border-line">
@@ -118,12 +125,12 @@ export default function HomePage() {
</h2>
</div>
<p className="text-xs text-ink-mute font-mono">
{RESEARCH_AREAS.length} fundamental networking protocols and AI system domains
{researchAreas.length} fundamental networking protocols and AI system domains
</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{RESEARCH_AREAS.map((area, idx) => {
{researchAreas.map((area, idx) => {
const no = String(idx + 1).padStart(2, "0");
const isOdd = (idx + 1) % 2 !== 0;