From 467f34b42a401a1508fd5b6a2b13c21b5575815d Mon Sep 17 00:00:00 2001
From: Koncept Kit <63216427+konceptkit@users.noreply.github.com>
Date: Tue, 27 Jan 2026 21:32:22 +0700
Subject: [PATCH] - - New ThemeConfigContext provider that fetches theme on app
load and applies it to the DOM (title, meta description, favicon, CSS
variables, theme-color)/- - Admin Theme settings page under Settings >
Theme tab/- All logo references (5 components) now pull from the theme config
with fallback to default
---
src/App.js | 2 +
src/components/AdminSidebar.js | 4 +-
src/components/Navbar.js | 6 +-
src/components/PublicFooter.js | 4 +-
src/components/PublicNavbar.js | 6 +-
src/components/SettingsSidebar.js | 45 +-
src/context/ThemeConfigContext.js | 161 ++++++
src/index.js | 5 +-
src/layouts/SettingsLayout.js | 23 +-
src/pages/MissionValues.js | 4 +-
src/pages/admin/AdminMemberTiers.js | 11 +-
src/pages/admin/AdminRoles.js | 17 +-
src/pages/admin/AdminSettings.js | 13 +-
src/pages/admin/AdminTheme.js | 743 ++++++++++++++++++++++++++++
14 files changed, 979 insertions(+), 65 deletions(-)
create mode 100644 src/context/ThemeConfigContext.js
create mode 100644 src/pages/admin/AdminTheme.js
diff --git a/src/App.js b/src/App.js
index 82e87c1..f7219db 100644
--- a/src/App.js
+++ b/src/App.js
@@ -25,6 +25,7 @@ import AdminPermissions from './pages/admin/AdminPermissions';
import AdminSettings from './pages/admin/AdminSettings';
import AdminMemberTiers from './pages/admin/AdminMemberTiers';
import AdminRoles from './pages/admin/AdminRoles';
+import AdminTheme from './pages/admin/AdminTheme';
import AdminEvents from './pages/admin/AdminEvents';
import AdminEventAttendance from './pages/admin/AdminEventAttendance';
import AdminValidations from './pages/admin/AdminValidations';
@@ -302,6 +303,7 @@ function App() {
} />
} />
} />
+ } />
{/* 404 - Catch all undefined routes */}
diff --git a/src/components/AdminSidebar.js b/src/components/AdminSidebar.js
index 415f015..d976a20 100644
--- a/src/components/AdminSidebar.js
+++ b/src/components/AdminSidebar.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { useTheme } from 'next-themes';
import { useAuth } from '../context/AuthContext';
+import { useThemeConfig } from '../context/ThemeConfigContext';
import api from '../utils/api';
import { Badge } from './ui/badge';
import {
@@ -32,6 +33,7 @@ const AdminSidebar = ({ isOpen, onToggle, isMobile }) => {
const location = useLocation();
const navigate = useNavigate();
const { user, logout } = useAuth();
+ const { getLogoUrl } = useThemeConfig();
const { theme, setTheme } = useTheme();
const [pendingCount, setPendingCount] = useState(0);
const [storageUsed, setStorageUsed] = useState(0);
@@ -281,7 +283,7 @@ const AdminSidebar = ({ isOpen, onToggle, isMobile }) => {

{
const { user, logout } = useAuth();
+ const { getLogoUrl } = useThemeConfig();
const navigate = useNavigate();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
- // LOAF logo (local)
- const loafLogo = `${process.env.PUBLIC_URL}/loaf-logo.png`;
+ // Get logo URL from theme config (with fallback to default)
+ const loafLogo = getLogoUrl();
const handleLogout = () => {
logout();
diff --git a/src/components/PublicFooter.js b/src/components/PublicFooter.js
index 3648f3e..27c850c 100644
--- a/src/components/PublicFooter.js
+++ b/src/components/PublicFooter.js
@@ -1,9 +1,11 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Button } from './ui/button';
+import { useThemeConfig } from '../context/ThemeConfigContext';
const PublicFooter = () => {
- const loafLogo = `${process.env.PUBLIC_URL}/loaf-logo.png`;
+ const { getLogoUrl } = useThemeConfig();
+ const loafLogo = getLogoUrl();
return (
<>
diff --git a/src/components/PublicNavbar.js b/src/components/PublicNavbar.js
index 0575131..ba27c35 100644
--- a/src/components/PublicNavbar.js
+++ b/src/components/PublicNavbar.js
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { Link, useNavigate, useLocation } from 'react-router-dom';
import { Button } from './ui/button';
import { useAuth } from '../context/AuthContext';
+import { useThemeConfig } from '../context/ThemeConfigContext';
import { ChevronDown, Menu, X } from 'lucide-react';
import {
DropdownMenu,
@@ -12,6 +13,7 @@ import {
const PublicNavbar = () => {
const { user, logout } = useAuth();
+ const { getLogoUrl } = useThemeConfig();
const navigate = useNavigate();
const location = useLocation();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
@@ -30,8 +32,8 @@ const PublicNavbar = () => {
return location.pathname.startsWith('/about');
};
- // LOAF logo (local)
- const loafLogo = `${process.env.PUBLIC_URL}/loaf-logo.png`;
+ // Get logo URL from theme config (with fallback to default)
+ const loafLogo = getLogoUrl();
const handleAuthAction = () => {
if (user) {
diff --git a/src/components/SettingsSidebar.js b/src/components/SettingsSidebar.js
index 0cb1ee1..d08c781 100644
--- a/src/components/SettingsSidebar.js
+++ b/src/components/SettingsSidebar.js
@@ -1,46 +1,45 @@
import React from 'react';
-import { NavLink } from 'react-router-dom';
-import { CreditCard, Shield, Settings, Star } from 'lucide-react';
+import { NavLink, useLocation } from 'react-router-dom';
+import { CreditCard, Shield, Star, Palette } from 'lucide-react';
const settingsItems = [
- { label: 'Stripe Integration', path: '/admin/settings/stripe', icon: CreditCard },
+ { label: 'Stripe', path: '/admin/settings/stripe', icon: CreditCard },
{ label: 'Permissions', path: '/admin/settings/permissions', icon: Shield },
{ label: 'Member Tiers', path: '/admin/settings/member-tiers', icon: Star },
+ { label: 'Theme', path: '/admin/settings/theme', icon: Palette },
];
-const SettingsSidebar = () => {
+const SettingsTabs = () => {
+ const location = useLocation();
+
return (
-