Skip to content

Commit 3125128

Browse files
committed
Add font family configuration option in admin panel and apply it site-wide
* Introduce a new font family selection feature in the AdminConfigPage for customizing typography. * Update the GitHub data generation script to include the selected font family. * Modify App component to apply the chosen font family dynamically. * Ensure CSS styles reflect the selected font family across the application.
1 parent eeb0d6f commit 3125128

7 files changed

Lines changed: 95 additions & 1 deletion

File tree

gitforge.config.example.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"eyebrow": "Open-source, developer-first profile",
1414
"minorInfo": "Brief tagline or quick intro that appears in the hero section."
1515
},
16+
"fontFamily": "system",
1617
"showVideosSection": true,
1718
"showBlogsSection": true,
1819
"showProjectsSection": true,

gitforge.config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"url": "https://www.linkedin.com/in/aaminu/"
2020
}
2121
],
22+
"fontFamily": "comic-sans",
2223
"showVideosSection": true,
2324
"showBlogsSection": true,
2425
"showProjectsSection": true,

scripts/generate-github-data.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ async function main() {
510510
count: listedRepoCount,
511511
sort: listedRepoSort,
512512
},
513+
fontFamily: fileConfig.fontFamily || 'system',
513514
// Section visibility flags for the client (default true when omitted in config)
514515
showVideosSection: fileConfig.showVideosSection !== false,
515516
showBlogsSection: fileConfig.showBlogsSection !== false,

src/App.tsx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useState } from 'react'
22
import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom'
33
import siteContent from './siteContent.json'
4+
import { githubConfig } from './generated/githubData'
45

56
type Theme = 'dark' | 'light'
67

@@ -37,6 +38,52 @@ function App() {
3738
window.localStorage.setItem('gitforge-theme', theme)
3839
}, [theme])
3940

41+
// Apply font family from generated GitHub config
42+
useEffect(() => {
43+
const font = (githubConfig as {
44+
fontFamily?: 'system' | 'ubuntu' | 'comic-sans' | 'inter' | 'roboto'
45+
}).fontFamily || 'system'
46+
let value =
47+
"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
48+
if (font === 'ubuntu') {
49+
value = "'Ubuntu', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
50+
// Inject Google Fonts stylesheet for Ubuntu if not already present
51+
if (!document.getElementById('gf-font-ubuntu')) {
52+
const link = document.createElement('link')
53+
link.id = 'gf-font-ubuntu'
54+
link.rel = 'stylesheet'
55+
link.href =
56+
'https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500;700&display=swap'
57+
document.head.appendChild(link)
58+
}
59+
} else if (font === 'inter') {
60+
value =
61+
"'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
62+
if (!document.getElementById('gf-font-inter')) {
63+
const link = document.createElement('link')
64+
link.id = 'gf-font-inter'
65+
link.rel = 'stylesheet'
66+
link.href =
67+
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'
68+
document.head.appendChild(link)
69+
}
70+
} else if (font === 'roboto') {
71+
value =
72+
"'Roboto', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
73+
if (!document.getElementById('gf-font-roboto')) {
74+
const link = document.createElement('link')
75+
link.id = 'gf-font-roboto'
76+
link.rel = 'stylesheet'
77+
link.href =
78+
'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap'
79+
document.head.appendChild(link)
80+
}
81+
} else if (font === 'comic-sans') {
82+
value = "'Comic Sans MS', 'Comic Sans', cursive"
83+
}
84+
document.documentElement.style.setProperty('--gf-font-family', value)
85+
}, [])
86+
4087
// GitHub Pages 404 redirect: ?/path -> /path
4188
useEffect(() => {
4289
const q = location.search
@@ -75,7 +122,7 @@ function App() {
75122
}, [hero.title])
76123

77124
const rootClasses =
78-
'min-h-screen font-sans bg-slate-50 text-slate-900 dark:bg-[#050509] dark:text-slate-50'
125+
'min-h-screen bg-slate-50 text-slate-900 dark:bg-[#050509] dark:text-slate-50'
79126
const headerClasses =
80127
theme === 'dark'
81128
? 'sticky top-0 z-20 border-b border-white/5 bg-[#050509]/90 backdrop-blur'

src/admin/pages/AdminConfigPage.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function AdminConfigPage() {
1919
} = useAdminAuthContext()
2020

2121
const {
22+
updateConfigField,
2223
handleFeaturedReposChange,
2324
updateHero,
2425
updateCustomLink,
@@ -52,6 +53,39 @@ export function AdminConfigPage() {
5253
onMinorInfoChange={(v) => updateHero('minorInfo', v)}
5354
/>
5455

56+
<section className="space-y-3 rounded-xl border border-slate-800 bg-slate-900/40 p-4">
57+
<h3 className="text-sm font-semibold text-slate-200">Typography</h3>
58+
<p className="text-xs text-slate-400">
59+
Choose the primary font used across the portfolio.
60+
</p>
61+
<div className="mt-2">
62+
<label className="block text-[11px] font-medium uppercase tracking-[0.18em] text-slate-500">
63+
Font family
64+
</label>
65+
<select
66+
className="mt-1 w-full rounded-md border border-slate-700 bg-slate-950 px-3 py-2 text-sm text-slate-100 focus:border-emerald-500 focus:outline-none"
67+
value={config.fontFamily ?? 'system'}
68+
onChange={(e) =>
69+
updateConfigField(
70+
'fontFamily',
71+
e.target.value as
72+
| 'system'
73+
| 'ubuntu'
74+
| 'comic-sans'
75+
| 'inter'
76+
| 'roboto',
77+
)
78+
}
79+
>
80+
<option value="system">System default</option>
81+
<option value="ubuntu">Ubuntu</option>
82+
<option value="comic-sans">Comic Sans</option>
83+
<option value="inter">Inter</option>
84+
<option value="roboto">Roboto</option>
85+
</select>
86+
</div>
87+
</section>
88+
5589
<AdminFeaturedReposForm
5690
value={config.featuredRepos ?? []}
5791
onChange={handleFeaturedReposChange}

src/index.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
@layer base {
66
body {
77
@apply min-h-screen bg-slate-50 text-slate-900 antialiased;
8+
font-family: var(
9+
--gf-font-family,
10+
system-ui,
11+
-apple-system,
12+
BlinkMacSystemFont,
13+
'Segoe UI',
14+
sans-serif
15+
);
816
}
917

1018
.dark body {

src/types/gitforgeConfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export interface GitforgeConfig {
3131
githubToken?: string | null
3232
featuredRepos?: string[]
3333
listedRepo?: ListedRepoConfig
34+
/** Global font family for the site (optional, defaults to system). */
35+
fontFamily?: 'system' | 'ubuntu' | 'comic-sans' | 'inter' | 'roboto'
3436
hero?: HeroConfig
3537
customLinks?: CustomLink[]
3638
// Section visibility toggles (all default to true when omitted)

0 commit comments

Comments
 (0)