diff --git a/src/lib/config.ts b/src/lib/config.ts
index 778b63fd..651bb395 100644
--- a/src/lib/config.ts
+++ b/src/lib/config.ts
@@ -6,3 +6,4 @@ export const description =
export const url = dev ? 'http://localhost:37572' : 'https://pauseai.info'
export const botName = 'RogueGPT'
export const verificationParameter = 'verificationKey'
+export const defaultTitle = 'Volunteer'
diff --git a/src/lib/types.ts b/src/lib/types.ts
index cf8b0034..a697615e 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -34,6 +34,19 @@ export type AirtableSignatory = {
duplicate?: boolean
}
+export type Person = {
+ id: string
+ name: string
+ /** URL to image file */
+ image?: string
+ bio: string
+ title?: string
+ /** Doesn't want to be visible on the /people page */
+ privacy?: boolean
+ checked?: boolean
+ duplicate?: boolean
+}
+
export type Team = {
id: string
name: string
diff --git a/src/routes/api/people/+server.ts b/src/routes/api/people/+server.ts
new file mode 100644
index 00000000..09b10893
--- /dev/null
+++ b/src/routes/api/people/+server.ts
@@ -0,0 +1,87 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import type { Person } from '$lib/types'
+import { defaultTitle } from '$lib/config'
+import { json } from '@sveltejs/kit'
+import { fetchAllPages } from '$lib/airtable'
+
+/**
+ * Fallback people data to use in development if Airtable fetch fails
+ */
+const fallbackPeople: Person[] = [
+ {
+ id: 'fallback-stub1',
+ name: '[FALLBACK DATA] Example Person',
+ bio: 'I hold places when Airtable API is unavailable.',
+ title: 'Placeholder',
+ image: 'https://api.dicebear.com/7.x/bottts/svg?seed=fallback1',
+ privacy: false,
+ checked: true
+ },
+ {
+ id: 'fallback-stub2',
+ name: '[FALLBACK DATA] Holdor',
+ bio: 'Thrown at games',
+ title: 'of Plays',
+ image: 'https://api.dicebear.com/7.x/bottts/svg?seed=fallback2',
+ privacy: false,
+ checked: true
+ }
+]
+
+function recordToPerson(record: any): Person {
+ return {
+ id: record.id || 'noId',
+ name: record.fields['Full name'],
+ bio: record.fields.Bio2,
+ title: record.fields.Title || defaultTitle,
+ image: record.fields.Photo && record.fields.Photo[0].thumbnails.large.url,
+ privacy: record.fields.Privacy,
+ checked: record.fields.About,
+ duplicate: record.fields.duplicate
+ }
+}
+
+const filter = (p: Person) => {
+ return (
+ p.image &&
+ !p.privacy &&
+ p.checked &&
+ p.title?.trim() !== '' &&
+ p.title !== defaultTitle &&
+ !p.duplicate
+ )
+}
+
+export async function GET({ fetch, setHeaders }) {
+ const url = `https://api.airtable.com/v0/appWPTGqZmUcs3NWu/tblL1icZBhTV1gQ9o`
+ setHeaders({
+ 'cache-control': 'public, max-age=3600' // 1 hour in seconds
+ })
+
+ try {
+ // Create fallback records in the expected Airtable format
+ const fallbackRecords = fallbackPeople.map((person) => ({
+ id: person.id,
+ fields: {
+ Name: person.name,
+ bio: person.bio,
+ title: person.title,
+ image: [{ thumbnails: { large: { url: person.image } } }],
+ privacy: person.privacy,
+ checked: person.checked
+ }
+ }))
+
+ const records = await fetchAllPages(fetch, url, fallbackRecords)
+ const out: Person[] = records
+ .map(recordToPerson)
+ .filter(filter)
+ // Shuffle the array, although not truly random
+ .sort(() => 0.5 - Math.random())
+ return json(out)
+ } catch (e) {
+ console.error('Error fetching people:', e)
+ // Return fallback data instead of error
+ return json(fallbackPeople.filter(filter))
+ }
+}
diff --git a/src/routes/api/posts/+server.ts b/src/routes/api/posts/+server.ts
index 64daf638..f4e75e8c 100644
--- a/src/routes/api/posts/+server.ts
+++ b/src/routes/api/posts/+server.ts
@@ -5,6 +5,7 @@ import { communitiesMeta } from '../../communities/communities'
import { meta as pdoomMeta } from '../../pdoom/meta'
import { meta as quotesMeta } from '../../quotes/meta'
import { meta as emailBuilderMeta } from '../../email-builder/meta'
+import { meta as peopleMeta } from '../../people/meta'
import { meta as teamsMeta } from '../../teams/meta'
import { meta as statementMeta } from '../../statement/meta'
import { meta as dearSirDemisMeta } from '../../dear-sir-demis-2025/meta'
@@ -16,6 +17,7 @@ const hardCodedPages: Post[] = [
pdoomMeta,
quotesMeta,
emailBuilderMeta,
+ peopleMeta,
teamsMeta,
statementMeta,
dearSirDemisMeta
diff --git a/src/routes/people/+page.svelte b/src/routes/people/+page.svelte
new file mode 100644
index 00000000..9b1d177d
--- /dev/null
+++ b/src/routes/people/+page.svelte
@@ -0,0 +1,30 @@
+
+
+
No team members found
+ {/if} +