fix: Single source nav + dark logo support + customer settings debug
## ✅ Issue 1: Single Source of Truth for Navigation **Problem:** Confusing dual nav sources (PHP + TypeScript fallback) **Solution:** Removed static TypeScript fallback tree **Result:** PHP NavigationRegistry is now the ONLY source - More flexible (can check WooCommerce settings, extend via addons) - Easier to maintain - Clear error if backend data missing ## ✅ Issue 2: Logo in All Modes **Already Working:** Header component renders in all modes - Standalone ✅ - WP-Admin normal ✅ - WP-Admin fullscreen ✅ ## ✅ Issue 5: Customer Settings 404 Debug **Added:** Debug logging to track endpoint calls **Note:** Routes are correctly registered - May need WordPress permalinks flush - Check debug.log for errors ## ✅ Issue 6: Dark Mode Logo Support **Implemented:** 1. **Backend:** - Added `store_logo_dark` to branding endpoint - Returns both light and dark logos 2. **Header Component:** - Detects dark mode via MutationObserver - Switches logo based on theme - Falls back to light logo if dark not set 3. **Login Screen:** - Same dark mode detection - Theme-aware logo display - Seamless theme switching 4. **SVG Support:** - Already supported via `accept="image/*"` - Works for all image formats **Result:** Perfect dark/light logo switching everywhere! 🌓 --- ## Files Modified: - `nav/tree.ts` - Removed static fallback - `App.tsx` - Dark logo in header - `Login.tsx` - Dark logo in login - `StoreController.php` - Dark logo in branding endpoint + debug logs - `Store.tsx` - Already has dark logo upload field - `StoreSettingsProvider.php` - Already has dark logo backend ## Testing: 1. Upload dark logo in Store settings 2. Switch theme - logo should change 3. Check customer-settings endpoint in browser console 4. Verify nav items from PHP only
This commit is contained in:
@@ -272,9 +272,30 @@ function AddonRoute({ config }: { config: any }) {
|
||||
function Header({ onFullscreen, fullscreen, showToggle = true, scrollContainerRef, onVisibilityChange }: { onFullscreen: () => void; fullscreen: boolean; showToggle?: boolean; scrollContainerRef?: React.RefObject<HTMLDivElement>; onVisibilityChange?: (visible: boolean) => void }) {
|
||||
const [siteTitle, setSiteTitle] = React.useState((window as any).wnw?.siteTitle || 'WooNooW');
|
||||
const [storeLogo, setStoreLogo] = React.useState('');
|
||||
const [storeLogoDark, setStoreLogoDark] = React.useState('');
|
||||
const [isVisible, setIsVisible] = React.useState(true);
|
||||
const lastScrollYRef = React.useRef(0);
|
||||
const isStandalone = window.WNW_CONFIG?.standaloneMode ?? false;
|
||||
const [isDark, setIsDark] = React.useState(false);
|
||||
|
||||
// Detect dark mode
|
||||
React.useEffect(() => {
|
||||
const checkDarkMode = () => {
|
||||
const htmlEl = document.documentElement;
|
||||
setIsDark(htmlEl.classList.contains('dark'));
|
||||
};
|
||||
|
||||
checkDarkMode();
|
||||
|
||||
// Watch for theme changes
|
||||
const observer = new MutationObserver(checkDarkMode);
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
// Notify parent of visibility changes
|
||||
React.useEffect(() => {
|
||||
@@ -289,6 +310,7 @@ function Header({ onFullscreen, fullscreen, showToggle = true, scrollContainerRe
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data.store_logo) setStoreLogo(data.store_logo);
|
||||
if (data.store_logo_dark) setStoreLogoDark(data.store_logo_dark);
|
||||
if (data.store_name) setSiteTitle(data.store_name);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -302,6 +324,7 @@ function Header({ onFullscreen, fullscreen, showToggle = true, scrollContainerRe
|
||||
React.useEffect(() => {
|
||||
const handleStoreUpdate = (event: CustomEvent) => {
|
||||
if (event.detail?.store_logo) setStoreLogo(event.detail.store_logo);
|
||||
if (event.detail?.store_logo_dark) setStoreLogoDark(event.detail.store_logo_dark);
|
||||
if (event.detail?.store_name) setSiteTitle(event.detail.store_name);
|
||||
};
|
||||
|
||||
@@ -358,11 +381,14 @@ function Header({ onFullscreen, fullscreen, showToggle = true, scrollContainerRe
|
||||
return null;
|
||||
}
|
||||
|
||||
// Choose logo based on theme
|
||||
const currentLogo = isDark && storeLogoDark ? storeLogoDark : storeLogo;
|
||||
|
||||
return (
|
||||
<header className={`h-16 border-b border-border flex items-center px-4 justify-between sticky ${fullscreen ? `top-0` : `top-[32px]`} z-40 bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60 transition-transform duration-300 ${fullscreen && !isVisible ? '-translate-y-full md:translate-y-0' : 'translate-y-0'}`}>
|
||||
<div className="flex items-center gap-3">
|
||||
{storeLogo ? (
|
||||
<img src={storeLogo} alt={siteTitle} className="h-8 object-contain" />
|
||||
{currentLogo ? (
|
||||
<img src={currentLogo} alt={siteTitle} className="h-8 object-contain" />
|
||||
) : (
|
||||
<div className="font-semibold">{siteTitle}</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user