Persist theme to file-backed content and add forest/sunset themes
This commit is contained in:
+31
-3
@@ -7,9 +7,10 @@ import type { Project } from './data/projects'
|
||||
const THEME_STORAGE_KEY = 'portfolio-theme-v1'
|
||||
const ADMIN_CONTENT_API = '/api/admin-content'
|
||||
|
||||
type ThemeName = 'sand' | 'ocean' | 'midnight'
|
||||
type ThemeName = 'sand' | 'ocean' | 'midnight' | 'forest' | 'sunset'
|
||||
|
||||
type SiteContent = {
|
||||
theme: ThemeName
|
||||
homeEyebrow: string
|
||||
homeTitle: string
|
||||
homeIntro: string
|
||||
@@ -19,6 +20,7 @@ type SiteContent = {
|
||||
}
|
||||
|
||||
const defaultSiteContent: SiteContent = {
|
||||
theme: 'sand',
|
||||
homeEyebrow: 'Siteforge',
|
||||
homeTitle: 'Sites and Apps I Build',
|
||||
homeIntro:
|
||||
@@ -107,7 +109,13 @@ function createEmptyProject(existing: Project[]): Project {
|
||||
|
||||
function readStoredTheme(): ThemeName {
|
||||
const saved = localStorage.getItem(THEME_STORAGE_KEY)
|
||||
if (saved === 'ocean' || saved === 'midnight' || saved === 'sand') {
|
||||
if (
|
||||
saved === 'ocean' ||
|
||||
saved === 'midnight' ||
|
||||
saved === 'sand' ||
|
||||
saved === 'forest' ||
|
||||
saved === 'sunset'
|
||||
) {
|
||||
return saved
|
||||
}
|
||||
|
||||
@@ -139,6 +147,14 @@ async function fetchAdminContent(): Promise<
|
||||
return {
|
||||
projects: payload.projects,
|
||||
siteContent: {
|
||||
theme:
|
||||
payload.siteContent.theme === 'ocean' ||
|
||||
payload.siteContent.theme === 'midnight' ||
|
||||
payload.siteContent.theme === 'sand' ||
|
||||
payload.siteContent.theme === 'forest' ||
|
||||
payload.siteContent.theme === 'sunset'
|
||||
? payload.siteContent.theme
|
||||
: defaultSiteContent.theme,
|
||||
homeEyebrow: payload.siteContent.homeEyebrow ?? defaultSiteContent.homeEyebrow,
|
||||
homeTitle: payload.siteContent.homeTitle ?? defaultSiteContent.homeTitle,
|
||||
homeIntro: payload.siteContent.homeIntro ?? defaultSiteContent.homeIntro,
|
||||
@@ -774,6 +790,8 @@ function AdminPage({
|
||||
<option value="sand">Sandstone</option>
|
||||
<option value="ocean">Ocean</option>
|
||||
<option value="midnight">Midnight</option>
|
||||
<option value="forest">Forest</option>
|
||||
<option value="sunset">Sunset</option>
|
||||
</select>
|
||||
|
||||
<div className="admin-grid">
|
||||
@@ -1026,6 +1044,7 @@ function App() {
|
||||
|
||||
setManagedProjects(loaded.projects)
|
||||
setSiteContent(loaded.siteContent)
|
||||
setTheme(loaded.siteContent.theme)
|
||||
})()
|
||||
}, [])
|
||||
|
||||
@@ -1093,10 +1112,19 @@ function App() {
|
||||
const handleResetSiteContent = () => {
|
||||
const updatedSiteContent = structuredClone(defaultSiteContent)
|
||||
setSiteContent(updatedSiteContent)
|
||||
setTheme(updatedSiteContent.theme)
|
||||
void persistAdminContent(managedProjects, updatedSiteContent)
|
||||
}
|
||||
|
||||
const handleSaveSiteContent = (updatedSiteContent: SiteContent) => {
|
||||
setSiteContent(updatedSiteContent)
|
||||
setTheme(updatedSiteContent.theme)
|
||||
void persistAdminContent(managedProjects, updatedSiteContent)
|
||||
}
|
||||
|
||||
const handleThemeChange = (nextTheme: ThemeName) => {
|
||||
setTheme(nextTheme)
|
||||
const updatedSiteContent = { ...siteContent, theme: nextTheme }
|
||||
setSiteContent(updatedSiteContent)
|
||||
void persistAdminContent(managedProjects, updatedSiteContent)
|
||||
}
|
||||
@@ -1122,7 +1150,7 @@ function App() {
|
||||
onDeleteProject={handleDeleteProject}
|
||||
onCreateProject={handleCreateProject}
|
||||
theme={theme}
|
||||
onThemeChange={setTheme}
|
||||
onThemeChange={handleThemeChange}
|
||||
siteContent={siteContent}
|
||||
onSaveSiteContent={handleSaveSiteContent}
|
||||
onResetSiteContent={handleResetSiteContent}
|
||||
|
||||
Reference in New Issue
Block a user