Skip to content

Commit 7d9ab0b

Browse files
authored
Merge pull request #787 from zackproser/speaking-page
Add initial speaker page
2 parents ab8a9b7 + 45b9826 commit 7d9ab0b

File tree

5 files changed

+333
-0
lines changed

5 files changed

+333
-0
lines changed

src/app/speaking/page.jsx

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
import Head from 'next/head'
2+
import Image from 'next/image'
3+
import Link from 'next/link'
4+
import { SimpleLayout } from '@/components/SimpleLayout'
5+
import { createMetadata } from '@/utils/createMetadata'
6+
import { ExternalLink, Calendar, Users, Building2, Youtube, Link as LinkIcon } from 'lucide-react'
7+
8+
// Import speaking images from the a16z blog post
9+
import a16z1 from '@/images/a16z-1.webp'
10+
// Import WorkOS internal training images
11+
import aiFundamentals from '@/images/ai-fundamentals.webp'
12+
import neuralNetworksLearn from '@/images/neural-networks-learn.webp'
13+
14+
export const metadata = createMetadata({
15+
title: 'Speaking Engagements - Zachary Proser',
16+
description: 'AI engineer speaker, conference presenter, and technical trainer. Public talks on AI, infrastructure as code, vector databases, and developer tools. Available for speaking engagements and corporate training.',
17+
author: 'Zachary Proser',
18+
date: '2025-6-02',
19+
slug: 'speaking',
20+
image: a16z1,
21+
keywords: [
22+
'Zachary Proser speaking',
23+
'AI engineer speaker',
24+
'conference speaker',
25+
'technical trainer',
26+
'AI talks',
27+
'infrastructure as code speaker',
28+
'vector database expert',
29+
'developer tools speaker',
30+
'corporate training',
31+
'engineering training',
32+
'AI fundamentals',
33+
'machine learning speaker',
34+
'DevOps speaker',
35+
'cloud infrastructure'
36+
],
37+
tags: [
38+
'speaking',
39+
'conferences',
40+
'AI',
41+
'machine learning',
42+
'infrastructure as code',
43+
'vector databases',
44+
'developer tools',
45+
'training',
46+
'workshops'
47+
]
48+
});
49+
50+
// Speaking engagements data
51+
const speakingEngagements = [
52+
{
53+
id: 'a16z-dec-2023',
54+
type: 'public',
55+
title: 'Navigating from Jupyter Notebooks to Production',
56+
event: 'Pinecone & Cohere Meetup at a16z',
57+
date: 'December 6, 2023',
58+
location: 'Andreesen Horowitz, San Francisco, CA',
59+
description: 'I introduced the new Pinecone AWS Reference Architecture with Pulumi and explained infrastructure as code, using a mountaineering metaphor to compare getting from prototype to production.',
60+
image: a16z1,
61+
audience: '~125 attendees',
62+
topics: ['Infrastructure as Code', 'Pinecone', 'AWS', 'Pulumi', 'Production Deployment'],
63+
links: [
64+
{
65+
type: 'blog',
66+
url: '/blog/a16z-sf-dec-2023-ai-apps-production',
67+
label: 'Read Full Blog Post'
68+
},
69+
{
70+
type: 'twitter',
71+
url: 'https://twitter.com/zackproser/status/1732228822626619637',
72+
label: 'Twitter Thread'
73+
}
74+
],
75+
featured: true
76+
},
77+
{
78+
id: 'ai-fundamentals-internal',
79+
type: 'internal',
80+
title: 'AI Fundamentals for Engineering Teams',
81+
event: 'WorkOS Internal Training',
82+
date: 'May 2025',
83+
location: 'In-person',
84+
description: 'Comprehensive introduction to AI concepts, machine learning fundamentals, and practical applications for software engineering teams. Covered LLMs, vector databases, RAG, and hands-on implementation strategies.',
85+
image: aiFundamentals,
86+
audience: 'Engineering Team (25 developers)',
87+
topics: ['Machine Learning', 'Large Language Models', 'Vector Databases', 'RAG', 'AI Engineering'],
88+
internal: true
89+
},
90+
{
91+
id: 'ai-content-creation-internal',
92+
type: 'internal',
93+
title: 'AI-Enabled Content Creation Workshop',
94+
event: 'WorkOS Internal Training',
95+
date: 'May 2025',
96+
location: 'In-person',
97+
description: 'Interactive workshop teaching content teams how to leverage AI tools for writing, editing, ideation, and content optimization. Practical hands-on session with real-world use cases and workflow optimization.',
98+
image: neuralNetworksLearn,
99+
audience: 'Marketing & Content Team (15 members)',
100+
topics: ['AI Writing Tools', 'Content Strategy', 'Workflow Optimization', 'Prompt Engineering', 'Content Marketing'],
101+
internal: true
102+
}
103+
];
104+
105+
// Component for rendering external links with icons
106+
function ExternalLinkButton({ link }) {
107+
const getIcon = () => {
108+
switch (link.type) {
109+
case 'youtube':
110+
return <Youtube className="h-4 w-4" />;
111+
case 'blog':
112+
return <LinkIcon className="h-4 w-4" />;
113+
case 'twitter':
114+
return <ExternalLink className="h-4 w-4" />;
115+
default:
116+
return <ExternalLink className="h-4 w-4" />;
117+
}
118+
};
119+
120+
const getButtonStyle = () => {
121+
switch (link.type) {
122+
case 'youtube':
123+
return 'bg-red-600 hover:bg-red-700 text-white';
124+
case 'blog':
125+
return 'bg-blue-600 hover:bg-blue-700 text-white';
126+
case 'twitter':
127+
return 'bg-sky-500 hover:bg-sky-600 text-white';
128+
default:
129+
return 'bg-gray-600 hover:bg-gray-700 text-white';
130+
}
131+
};
132+
133+
const isExternal = link.url.startsWith('http');
134+
const LinkComponent = isExternal ? 'a' : Link;
135+
136+
const linkProps = isExternal
137+
? { href: link.url, target: '_blank', rel: 'noopener noreferrer' }
138+
: { href: link.url };
139+
140+
return (
141+
<LinkComponent
142+
{...linkProps}
143+
className={`inline-flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-colors ${getButtonStyle()}`}
144+
>
145+
{getIcon()}
146+
{link.label}
147+
</LinkComponent>
148+
);
149+
}
150+
151+
// Component for a single speaking engagement card
152+
function SpeakingCard({ engagement }) {
153+
return (
154+
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg hover:shadow-xl transition-all duration-300 overflow-hidden">
155+
{/* Image */}
156+
<div className="relative h-48 bg-gradient-to-br from-blue-600 to-purple-700">
157+
<Image
158+
src={engagement.image}
159+
alt={engagement.title}
160+
fill
161+
className="object-cover"
162+
/>
163+
{/* Badge for internal vs public */}
164+
<div className="absolute top-4 left-4">
165+
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium ${
166+
engagement.type === 'internal'
167+
? 'bg-amber-100 text-amber-800 dark:bg-amber-900/20 dark:text-amber-400'
168+
: 'bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400'
169+
}`}>
170+
{engagement.type === 'internal' ? <Building2 className="h-3 w-3" /> : <Users className="h-3 w-3" />}
171+
{engagement.type === 'internal' ? 'Internal' : 'Public'}
172+
</span>
173+
</div>
174+
{/* Featured badge */}
175+
{engagement.featured && (
176+
<div className="absolute top-4 right-4">
177+
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-400">
178+
⭐ Featured
179+
</span>
180+
</div>
181+
)}
182+
</div>
183+
184+
{/* Content */}
185+
<div className="p-6">
186+
<div className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 mb-2">
187+
<Calendar className="h-4 w-4" />
188+
{engagement.date}
189+
</div>
190+
191+
<h3 className="text-xl font-bold text-gray-900 dark:text-white mb-2">
192+
{engagement.title}
193+
</h3>
194+
195+
<p className="text-blue-600 dark:text-blue-400 font-medium mb-3">
196+
{engagement.event}
197+
</p>
198+
199+
<p className="text-gray-600 dark:text-gray-300 mb-4 line-clamp-3">
200+
{engagement.description}
201+
</p>
202+
203+
{/* Details */}
204+
<div className="space-y-2 mb-4 text-sm">
205+
<div className="flex items-center gap-2 text-gray-500 dark:text-gray-400">
206+
<Users className="h-4 w-4" />
207+
<span>{engagement.audience}</span>
208+
</div>
209+
<div className="text-gray-500 dark:text-gray-400">
210+
📍 {engagement.location}
211+
</div>
212+
</div>
213+
214+
{/* Topics */}
215+
<div className="mb-4">
216+
<div className="flex flex-wrap gap-2">
217+
{engagement.topics.map((topic, index) => (
218+
<span
219+
key={index}
220+
className="inline-block px-2 py-1 bg-blue-100 dark:bg-blue-900/20 text-blue-800 dark:text-blue-400 text-xs rounded-md"
221+
>
222+
{topic}
223+
</span>
224+
))}
225+
</div>
226+
</div>
227+
228+
{/* Links */}
229+
{engagement.links && engagement.links.length > 0 && (
230+
<div className="flex flex-wrap gap-2">
231+
{engagement.links.map((link, index) => (
232+
<ExternalLinkButton key={index} link={link} />
233+
))}
234+
</div>
235+
)}
236+
</div>
237+
</div>
238+
);
239+
}
240+
241+
export default function Speaking() {
242+
const publicEngagements = speakingEngagements.filter(e => e.type === 'public');
243+
const internalEngagements = speakingEngagements.filter(e => e.type === 'internal');
244+
245+
return (
246+
<>
247+
<Head>
248+
<title>Speaking - Zachary Proser</title>
249+
<meta
250+
name="description"
251+
content="Public talks, internal training sessions, and conference presentations on AI, infrastructure, and developer tools."
252+
/>
253+
</Head>
254+
<SimpleLayout
255+
title="Speaking Engagements"
256+
intro="I speak at conferences, meetups, and corporate events about AI, infrastructure as code, vector databases, and developer tools. I also provide internal training for engineering and content teams."
257+
>
258+
{/* Stats Section */}
259+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
260+
<div className="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-6 text-center">
261+
<div className="text-3xl font-bold text-blue-600 dark:text-blue-400 mb-2">
262+
{publicEngagements.length}
263+
</div>
264+
<div className="text-blue-800 dark:text-blue-300 font-medium">Public Talks</div>
265+
</div>
266+
<div className="bg-amber-50 dark:bg-amber-900/20 rounded-lg p-6 text-center">
267+
<div className="text-3xl font-bold text-amber-600 dark:text-amber-400 mb-2">
268+
{internalEngagements.length}
269+
</div>
270+
<div className="text-amber-800 dark:text-amber-300 font-medium">Internal Training</div>
271+
</div>
272+
<div className="bg-green-50 dark:bg-green-900/20 rounded-lg p-6 text-center">
273+
<div className="text-3xl font-bold text-green-600 dark:text-green-400 mb-2">
274+
165+
275+
</div>
276+
<div className="text-green-800 dark:text-green-300 font-medium">Total Attendees</div>
277+
</div>
278+
</div>
279+
280+
{/* Public Engagements */}
281+
<section className="mb-12">
282+
<h2 className="text-2xl font-bold text-gray-900 dark:text-white mb-6 flex items-center gap-2">
283+
<Users className="h-6 w-6 text-green-600" />
284+
Public Speaking
285+
</h2>
286+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
287+
{publicEngagements.map((engagement) => (
288+
<SpeakingCard key={engagement.id} engagement={engagement} />
289+
))}
290+
</div>
291+
</section>
292+
293+
{/* Internal Training */}
294+
<section className="mb-12">
295+
<h2 className="text-2xl font-bold text-gray-900 dark:text-white mb-6 flex items-center gap-2">
296+
<Building2 className="h-6 w-6 text-amber-600" />
297+
Corporate Training & Workshops
298+
</h2>
299+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
300+
{internalEngagements.map((engagement) => (
301+
<SpeakingCard key={engagement.id} engagement={engagement} />
302+
))}
303+
</div>
304+
</section>
305+
306+
{/* CTA Section */}
307+
<section className="bg-gradient-to-r from-blue-600 to-purple-700 rounded-xl p-8 text-white text-center">
308+
<h2 className="text-2xl font-bold mb-4">Looking for a Speaker?</h2>
309+
<p className="text-blue-100 mb-6 max-w-2xl mx-auto">
310+
I&apos;m available for conference talks, meetups, corporate training, and workshops.
311+
I speak about AI engineering, infrastructure as code, vector databases, developer tools,
312+
and practical machine learning implementations.
313+
</p>
314+
<div className="flex flex-col sm:flex-row gap-4 justify-center">
315+
<Link
316+
href="/contact"
317+
className="inline-flex items-center justify-center px-6 py-3 bg-white text-blue-600 font-semibold rounded-md hover:bg-blue-50 transition-colors"
318+
>
319+
Book a Speaking Engagement
320+
</Link>
321+
<Link
322+
href="/ai-training"
323+
className="inline-flex items-center justify-center px-6 py-3 bg-blue-500 hover:bg-blue-400 text-white font-semibold rounded-md transition-colors"
324+
>
325+
View Training Services
326+
</Link>
327+
</div>
328+
</section>
329+
</SimpleLayout>
330+
</>
331+
);
332+
}

src/components/ConsultancyNav.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const navItems = [
3838
],
3939
},
4040
{ name: 'About', href: '/about' },
41+
{ name: 'Speaking', href: '/speaking' },
4142
{ name: 'Testimonials', href: '/testimonials' },
4243
{ name: 'Contact', href: '/contact' },
4344
];

src/images/ai-fundamentals.webp

187 KB
Loading
77 KB
Loading

src/neural-networks-learn.webp

77 KB
Loading

0 commit comments

Comments
 (0)