- - 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
This commit is contained in:
Koncept Kit
2026-01-27 21:32:22 +07:00
parent 85070cf77b
commit 467f34b42a
14 changed files with 979 additions and 65 deletions

View File

@@ -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 (
<aside className="w-full lg:w-64 shrink-0 bg-background border border-[var(--neutral-800)] rounded-2xl p-4 lg:sticky lg:top-8 h-max">
<div className="flex items-center gap-2 px-2 pb-3 border-b border-[var(--neutral-800)]">
<Settings className="h-4 w-4 text-[var(--purple-ink)]" />
<span className="text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Settings
</span>
</div>
<nav className="mt-3 space-y-1">
<div className="w-full border-b border-border">
<nav className="flex gap-1 overflow-x-auto pb-px -mb-px" aria-label="Settings tabs">
{settingsItems.map((item) => {
const Icon = item.icon;
const isActive = location.pathname === item.path;
return (
<NavLink
key={item.label}
to={item.path}
className={({ isActive }) =>
[
'flex items-center gap-3 px-3 py-2 rounded-lg text-sm font-medium transition-colors',
isActive
? 'bg-[var(--orange-light)]/10 text-[var(--purple-ink)]'
: 'text-[var(--purple-ink)] hover:bg-[var(--neutral-800)]/10',
].join(' ')
}
className={`
flex items-center gap-2 px-4 py-3 text-sm font-medium whitespace-nowrap
border-b-2 transition-all duration-200
${isActive
? 'border-primary text-primary bg-primary/5'
: 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'
}
`}
>
<Icon className="h-4 w-4" />
<Icon className={`h-4 w-4 ${isActive ? 'text-primary' : ''}`} />
<span>{item.label}</span>
</NavLink>
);
})}
</nav>
</aside>
</div>
);
};
export default SettingsSidebar;
export default SettingsTabs;