Skip to content

Commit dd174f6

Browse files
committed
feat(content): expand home front-matter with subtitle, intro, learn-more
1 parent eed487a commit dd174f6

3 files changed

Lines changed: 78 additions & 39 deletions

File tree

content/home.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
---
2-
hero: What we build in the open.
3-
intro: Flexion Labs gathers our open source work in one place — products we steward, tools we share, and the commitment behind them.
2+
title: Flexion Labs
3+
subtitle: Solutions for the public, in the open
4+
intro: |
5+
Flexion is committed to excellence in civic technology. We are also
6+
committed to transparency. As part of that commitment, Flexion Labs
7+
is featuring some of the tools we've developed.
8+
9+
These are yours to fork and use. Or [reach out to us](https://flexion.us/contact-us/)
10+
about an engagement. Instead of starting from zero, we can leverage existing
11+
Flexion Labs work to allow us to more quickly build what you need.
12+
learnMore:
13+
commitment: |
14+
Flexion is open by default. Unless there's a specific reason we can't,
15+
we develop in the open.
16+
about: |
17+
We help organizations stay future-ready by building high-quality, adaptive
18+
software solutions that are easy to use, modify, and modernize.
419
---

src/build/hero.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { parse as parseYaml } from 'yaml'
2+
import { marked } from 'marked'
23
import { join } from 'node:path'
34
import type { HeroContent } from '../pages/home'
45

@@ -8,9 +9,22 @@ export async function loadHero(rootDir: string): Promise<HeroContent> {
89
const file = Bun.file(join(rootDir, 'content', 'home.md'))
910
const raw = await file.text()
1011
const match = raw.match(FRONTMATTER_RE)
11-
const parsed = match ? (parseYaml(match[1]) as Record<string, unknown>) : {}
12-
return {
13-
hero: typeof parsed.hero === 'string' ? parsed.hero : 'Flexion Labs',
14-
intro: typeof parsed.intro === 'string' ? parsed.intro : '',
12+
const parsed = match ? ((parseYaml(match[1]) ?? {}) as Record<string, unknown>) : {}
13+
14+
const title = stringOr(parsed.title, 'Flexion Labs')
15+
const subtitle = stringOr(parsed.subtitle, '')
16+
const introMarkdown = stringOr(parsed.intro, '')
17+
const intro = introMarkdown
18+
? (marked.parse(introMarkdown, { async: false }) as string)
19+
: ''
20+
const lm = (parsed.learnMore ?? {}) as Record<string, unknown>
21+
const learnMore = {
22+
commitment: stringOr(lm.commitment, ''),
23+
about: stringOr(lm.about, ''),
1524
}
25+
return { title, subtitle, intro, learnMore }
26+
}
27+
28+
function stringOr(value: unknown, fallback: string): string {
29+
return typeof value === 'string' ? value : fallback
1630
}

src/pages/home.tsx

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,70 @@
1+
import { raw } from 'hono/html'
12
import { Layout } from '../design/common/layout'
2-
import { FeaturedCard } from '../design/components/featured-card'
3-
import type { Catalog } from '../catalog/types'
3+
import { LabCard } from '../design/components/lab-card'
4+
import { url } from '../build/config'
5+
import type { FeaturedLab } from '../build/featured'
46
import type { SiteConfig } from '../build/config'
57

6-
export type HeroContent = { hero: string; intro: string }
8+
export type HeroContent = {
9+
title: string
10+
subtitle: string
11+
intro: string // pre-rendered HTML
12+
learnMore: {
13+
commitment: string
14+
about: string
15+
}
16+
}
717

818
export function Home({
9-
catalog,
1019
hero,
20+
featured,
1121
config,
1222
}: {
13-
catalog: Catalog
1423
hero: HeroContent
24+
featured: FeaturedLab[]
1525
config: SiteConfig
1626
}) {
17-
const featuredOrder = ['forms', 'forms-lab', 'document-extractor', 'flexion-notify']
18-
const featured = catalog
19-
.filter((e) => e.featured && !e.hidden)
20-
.sort((a, b) => {
21-
const ai = featuredOrder.indexOf(a.name)
22-
const bi = featuredOrder.indexOf(b.name)
23-
return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi)
24-
})
25-
const visible = catalog.filter((e) => !e.hidden)
26-
const active = visible.filter((e) => e.tier === 'active').length
27-
const languages = new Set(
28-
visible.map((e) => e.language).filter((l): l is string => Boolean(l)),
29-
).size
30-
3127
return (
3228
<Layout title={null} config={config}>
3329
<section class="home-hero">
34-
<h1>{hero.hero}</h1>
35-
<p class="home-hero__intro">{hero.intro}</p>
30+
<h1>{hero.title}</h1>
31+
{hero.subtitle ? (
32+
<p class="home-hero__subtitle">{hero.subtitle}</p>
33+
) : null}
34+
{hero.intro ? (
35+
<div class="home-intro">{raw(hero.intro)}</div>
36+
) : null}
3637
</section>
3738

3839
<section class="home-featured" aria-labelledby="featured-heading">
3940
<div class="home-featured__header">
40-
<h2 id="featured-heading">Featured</h2>
41-
<p class="home-featured__intro">
42-
Products and tools we actively steward — built for government, shared with everyone.
43-
</p>
41+
<h2 id="featured-heading">Featured labs</h2>
4442
</div>
4543
<div class="home-featured__list">
46-
{featured.map((entry) => (
47-
<FeaturedCard entry={entry} basePath={config.basePath} />
44+
{featured.map((lab) => (
45+
<LabCard lab={lab} />
4846
))}
4947
</div>
5048
</section>
5149

52-
<section class="home-stats">
53-
<ul class="home-stats__grid">
54-
<li><strong>{visible.length}</strong> public projects</li>
55-
<li><strong>{active}</strong> actively maintained</li>
56-
<li><strong>{languages}</strong> languages</li>
57-
</ul>
50+
<section class="home-learn-more" aria-labelledby="learn-more-heading">
51+
<h2 id="learn-more-heading">Learn more</h2>
52+
<div class="home-learn-more__grid">
53+
<article class="home-learn-more__item">
54+
<h3>Our open source commitment</h3>
55+
<p>{hero.learnMore.commitment}</p>
56+
<p>
57+
<a href={url('/commitment/', config.basePath)}>Read our commitment &rarr;</a>
58+
</p>
59+
</article>
60+
<article class="home-learn-more__item">
61+
<h3>About Flexion</h3>
62+
<p>{hero.learnMore.about}</p>
63+
<p>
64+
<a href={url('/about/', config.basePath)}>Learn about Flexion &rarr;</a>
65+
</p>
66+
</article>
67+
</div>
5868
</section>
5969
</Layout>
6070
)

0 commit comments

Comments
 (0)