Skip to content

Commit 2b89266

Browse files
authored
update Singapore event page with on-page schedule (#2388)
The Singapore GraphQL Day at FOST (April 14-15, 2026) has concluded. This PR updates `/day/2026/singapore` to be a permanent record of it. - Hero CTAs collapse to a single "View the schedule" button; the CFP section is removed. - New on-page schedule reproduces the three FOST talks (Akshat Sharma, Pascal Senn, Michael Staib) with title, time (SGT), venue, topic tags derived from each abstract, full description, and speaker cards (avatars, LinkedIn, GitHub, website). - At xl+, the speaker card slots into the bottom-right of its description next to the last two paragraphs, with right and bottom borders dropped so it merges with the section edges. - Footer's "Singapore Tickets" link becomes "Singapore Schedule". - `SocialIcon` design-system component gains GitHub support. <img width="1484" height="912" alt="image" src="https://github.com/user-attachments/assets/4c75beee-0d74-464a-969f-85130ff29ac4" />
1 parent f57e038 commit 2b89266

8 files changed

Lines changed: 493 additions & 32 deletions

File tree

src/app/conf/_design-system/social-icon.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import {
44
LinkedInFilledIcon,
55
InstagramIcon,
66
GlobeIcon,
7+
GitHubIcon,
78
} from "@/icons"
89

910
export type SocialIconType =
1011
| "twitter"
1112
| "linkedin"
1213
| "facebook"
1314
| "instagram"
15+
| "github"
1416
| "website"
1517

1618
export const SocialIconType = {
@@ -22,6 +24,7 @@ export const SocialIconType = {
2224
all: [
2325
"linkedin",
2426
"twitter",
27+
"github",
2528
"instagram",
2629
"facebook",
2730
"website",
@@ -42,6 +45,8 @@ export const SocialIcon = ({ type, ...rest }: SocialIconProps) => {
4245
return <FacebookIcon {...rest} />
4346
case "instagram":
4447
return <InstagramIcon {...rest} />
48+
case "github":
49+
return <GitHubIcon {...rest} />
4550
case "website":
4651
return <GlobeIcon {...rest} />
4752
default:
@@ -59,6 +64,8 @@ export function urlForUser(type: SocialIconType, handleOrWebsite: string) {
5964
return `https://www.instagram.com/${handleOrWebsite}`
6065
case "facebook":
6166
return `https://www.facebook.com/${handleOrWebsite}`
67+
case "github":
68+
return `https://github.com/${handleOrWebsite}`
6269
case "website":
6370
return handleOrWebsite
6471
default:

src/app/day/2026/singapore/page.tsx

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,14 @@ import { Button } from "@/app/conf/_design-system/button"
44
import { Hero, HeroDateAndLocation } from "../components/hero"
55
import { AboutSection } from "../components/about-section"
66
import { WhyAttendSection } from "../components/why-attend-section"
7-
import {
8-
BecomeASpeakerSection,
9-
CfpButton,
10-
} from "../components/become-a-speaker"
117
import { EventPartnersSection } from "../components/event-partners"
12-
import { CtaCardSection } from "../components/cta-card-section"
138
import { MarqueeRows } from "@/app/conf/2026/components/marquee-rows"
149
import { PastSpeakersSection } from "../components/past-speakers"
1510
import { NavbarPlaceholder } from "../components/navbar"
1611
import { GallerySection } from "../../gallery-section"
12+
import { ScheduleSection } from "./schedule-section"
1713

18-
const TICKET_LINK =
19-
"https://portal.joinfost.io/event/future-of-software-technologies-singapore-2026/9521470b-6661-4c85-8594-b74d9d7cf2e3/graphql-day-at-fost-singapore"
14+
const SCHEDULE_ANCHOR = "#schedule"
2015

2116
const MARQUEE_ITEMS = [
2217
["SINGAPORE", "APRIL 2026", "GRAPHQL DAY", "FOST", "COMMUNITY", "APIs"],
@@ -46,10 +41,12 @@ export default function SingaporePage() {
4641
location="Singapore"
4742
/>
4843
<div className="flex flex-wrap items-center gap-x-4 gap-y-2 max-sm:*:flex-1">
49-
<Button href={TICKET_LINK} className="whitespace-nowrap md:w-fit">
50-
Get your ticket
44+
<Button
45+
href={SCHEDULE_ANCHOR}
46+
className="whitespace-nowrap md:w-fit"
47+
>
48+
View the schedule
5149
</Button>
52-
<CfpButton className="whitespace-nowrap md:w-fit" />
5350
</div>
5451
</Hero>
5552
<AboutSection />
@@ -60,28 +57,16 @@ export default function SingaporePage() {
6057
/>
6158
<div className="gql-container gql-conf-navbar-strip text-neu-900 before:bg-white/40 before:dark:bg-blk/30">
6259
<WhyAttendSection />
63-
<BecomeASpeakerSection />
6460
<PastSpeakersSection />
6561
<EventPartnersSection />
6662
<GallerySection moving />
67-
<CtaCardSection
68-
title="Get your ticket"
69-
description="Join us for a day of GraphQL talks, networking, and hands-on learning at FOST Singapore."
70-
>
71-
<Button
72-
href={TICKET_LINK}
73-
variant="primary"
74-
className="whitespace-nowrap"
75-
>
76-
Get your ticket
77-
</Button>
78-
</CtaCardSection>
79-
<MarqueeRows
80-
variant="secondary"
81-
className="my-8 xl:mb-16 xl:mt-10"
82-
items={MARQUEE_ITEMS}
83-
/>
8463
</div>
64+
<ScheduleSection />
65+
<MarqueeRows
66+
variant="secondary"
67+
className="my-8 xl:my-16"
68+
items={MARQUEE_ITEMS}
69+
/>
8570
</main>
8671
</>
8772
)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import type { StaticImageData } from "next/image"
2+
3+
import akshatSharmaAvatar from "./speakers/akshat-sharma.webp"
4+
import michaelStaibAvatar from "./speakers/michael-staib.webp"
5+
import pascalSennAvatar from "./speakers/pascal-senn.webp"
6+
7+
export interface SingaporeSpeaker {
8+
id: number
9+
name: string
10+
company: string
11+
jobtitle: string
12+
avatar: StaticImageData
13+
socialurls: { service: string; url: string }[]
14+
}
15+
16+
export interface SingaporeSession {
17+
id: number
18+
uuid: string
19+
title: string
20+
/** ISO 8601 in venue local time, Asia/Singapore */
21+
start: string
22+
/** ISO 8601 in venue local time, Asia/Singapore */
23+
end: string
24+
/** Topic tags derived from the session description. */
25+
tags: string[]
26+
/** HTML */
27+
description: string
28+
venue: string
29+
speakers: SingaporeSpeaker[]
30+
}
31+
32+
export const SINGAPORE_TIMEZONE = "Asia/Singapore"
33+
34+
/** Color per topic, picked to read clearly against the cream/dark backgrounds. */
35+
export const tagColors: Record<string, string> = {
36+
Security: "#CC6BB0",
37+
"Zero Trust": "#894545",
38+
"Service Mesh": "#36C1A0",
39+
"AI Agents": "#7e66cc",
40+
Federation: "#FC8251",
41+
"Public Sector": "#4e6e82",
42+
"Schema Evolution": "#cbc749",
43+
Observability: "#1a5b77",
44+
}
45+
46+
export const singaporeSessions: SingaporeSession[] = [
47+
{
48+
id: 3224,
49+
uuid: "80952503-07dd-4e31-acaf-b9e400f55126",
50+
title: "Securing GraphQL at Scale with Zero Trust APIs",
51+
start: "2026-04-15T15:55:00+08:00",
52+
end: "2026-04-15T16:20:00+08:00",
53+
tags: ["Security", "Zero Trust", "Service Mesh"],
54+
description:
55+
"<p>Modern microservice architectures often decentralize authentication and authorization, leading to inconsistent security policies and increased attack surfaces. GraphQL, while powerful, introduces unique risks such as over-fetching, query batching abuse, and introspection-based attacks that many teams underestimate.</p>\n<p>In this talk, I present a real-world case study of building a secure, identity-aware GraphQL gateway that enforces Zero Trust principles across distributed services. By integrating centralized identity management with Keycloak and leveraging service mesh technologies like Istio and Envoy, we created a unified layer for authentication, authorization, and traffic governance.</p>\n<p>The session will walk through practical challenges, including enforcing fine-grained access control, implementing query cost analysis, and mitigating abuse patterns in production. Attendees will gain insights into designing secure GraphQL APIs that scale without compromising performance or developer experience.</p>\n<p>This talk matters because API security is no longer optional. As organizations increasingly adopt GraphQL, understanding how to secure it in real-world systems is critical to preventing data leaks and maintaining trust.</p>\n",
56+
venue: "Stage 3",
57+
speakers: [
58+
{
59+
id: 4557,
60+
name: "Akshat Sharma",
61+
company: "Deskree",
62+
jobtitle: "Technology Advocate",
63+
avatar: akshatSharmaAvatar,
64+
socialurls: [
65+
{
66+
service: "linkedin",
67+
url: "https://www.linkedin.com/in/akshat-sharma11",
68+
},
69+
],
70+
},
71+
],
72+
},
73+
{
74+
id: 3225,
75+
uuid: "2a24223a-16d0-40fa-821b-b91c491ff9a6",
76+
title: "GraphQL as the Execution Layer for AI Agents",
77+
start: "2026-04-15T16:20:00+08:00",
78+
end: "2026-04-15T16:45:00+08:00",
79+
tags: ["AI Agents", "Federation", "Public Sector"],
80+
description:
81+
"<p>Your next million API consumers won't be developers. They'll be AI agents. And they don't read documentation, parse hypermedia links, or guess which of your 200 REST endpoints returns the data they need.</p>\n<p>This talk examines what happens when autonomous AI agents become the primary consumers of your API layer. Drawing on real data from Singapore's public government APIs, I'll show how REST responses waste 30–60% of an agent's token budget on structural overhead, and how a typed, self-describing schema changes the equation entirely.</p>\n<p>We'll walk through the three properties that make an API truly agent-native: discoverability, precision, and composability. We'll look at what it would take to unify API estates like Singapore's 3,000+ government APIs across 75+ agencies into a single, self-describing surface. A pattern Gartner expects 30% of enterprises to adopt by 2027.</p>\n<p>You'll leave with a framework for what makes an API truly agent-native, why GraphQL's type system and federation model get you there, and how to start without a rewrite.</p>\n",
82+
venue: "Stage 3",
83+
speakers: [
84+
{
85+
id: 2446,
86+
name: "Pascal Senn",
87+
company: "ChilliCream",
88+
jobtitle: "Founder",
89+
avatar: pascalSennAvatar,
90+
socialurls: [
91+
{
92+
service: "linkedin",
93+
url: "https://www.linkedin.com/in/pascal-senn-90899a15a",
94+
},
95+
{ service: "github", url: "https://github.com/PascalSenn" },
96+
{ service: "website", url: "https://chillicream.com" },
97+
],
98+
},
99+
],
100+
},
101+
{
102+
id: 3226,
103+
uuid: "02d9d427-d1ff-4f78-8d8c-243565d0f1cd",
104+
title:
105+
"Closing the Loop: How GraphQL Gives Coding Agents Eyes on What Actually Matters",
106+
start: "2026-04-15T16:45:00+08:00",
107+
end: "2026-04-15T17:10:00+08:00",
108+
tags: ["AI Agents", "Schema Evolution", "Observability"],
109+
description:
110+
"<p>Coding agents are reshaping how we build software. Implementing features, refactoring systems, and shipping changes at a pace unthinkable 6 months ago. But to be successful with agents you need the right feedback loop. One that guides your agent to success, not into the spiral of death.</p>\n<p>Ask Claude to add a review system to your product API. Without knowing what's in use, it might reshape your types, move fields, and break your deployed clients because it is missing a crucial feedback loop of what's in use in your clients.</p>\n<p>GraphQL changes this. Every client operation explicitly declares the exact fields and types it needs. That gives you something rare: field-level usage data across your entire consumer base. Not endpoint hits, but actual demand, broken down to the individual field.</p>\n<p>When coding agents can access this data, they stop guessing. Evolve your schema grounded in reality, not assumptions.</p>\n<p>This talk shows how GraphQL's inherent usage visibility and the rise of coding agents create a feedback loop that didn't exist before. And why it matters for anyone building APIs that need to evolve fast.</p>\n",
111+
venue: "Stage 3",
112+
speakers: [
113+
{
114+
id: 1881,
115+
name: "Michael Staib",
116+
company: "ChilliCream",
117+
jobtitle: "Founder",
118+
avatar: michaelStaibAvatar,
119+
socialurls: [
120+
{
121+
service: "linkedin",
122+
url: "https://www.linkedin.com/in/michael-staib-31519571/",
123+
},
124+
{ service: "github", url: "https://github.com/michaelstaib" },
125+
{ service: "website", url: "https://chillicream.com" },
126+
],
127+
},
128+
],
129+
},
130+
]

0 commit comments

Comments
 (0)