Add customer and business user-product flows across dashboards.
Ship my-products / customer-products UI with gallery uploads, status controls, module gating, and related shared UI polish. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
c5bdaad16b
commit
1271d96539
@@ -5,6 +5,13 @@ import { resolveTenantByDomain } from '../services/tenantService'
|
||||
import { applyBusinessPrimaryColor, resetBusinessPrimaryColor } from '../utils/applyBusinessTheme'
|
||||
import { normalizeBusinessPrimaryColorId } from '../utils/businessPrimaryColors'
|
||||
|
||||
function applyThemeMode(mode: 'light' | 'dark' | undefined) {
|
||||
document.documentElement.setAttribute(
|
||||
'data-theme',
|
||||
mode === 'dark' ? 'dark' : 'light',
|
||||
)
|
||||
}
|
||||
|
||||
export function CustomerThemeProvider({ children }: { children: ReactNode }) {
|
||||
useEffect(() => {
|
||||
const controller = new AbortController()
|
||||
@@ -13,12 +20,15 @@ export function CustomerThemeProvider({ children }: { children: ReactNode }) {
|
||||
async function loadTheme() {
|
||||
try {
|
||||
const tenant = await resolveTenantByDomain(domain, controller.signal)
|
||||
if (controller.signal.aborted) return
|
||||
applyBusinessPrimaryColor(
|
||||
normalizeBusinessPrimaryColorId(tenant.primaryColor),
|
||||
)
|
||||
applyThemeMode(tenant.themeMode)
|
||||
} catch (err) {
|
||||
if (isAbortError(err)) return
|
||||
applyBusinessPrimaryColor(undefined)
|
||||
applyThemeMode('light')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,18 @@ import { isAbortError } from '../lib/api'
|
||||
import { getTenantDomain } from '../lib/config'
|
||||
import { getWebsiteBusinessInfo } from '../services/websiteService'
|
||||
import { resolveTenantByDomain } from '../services/tenantService'
|
||||
import {
|
||||
DEFAULT_ENABLED_BUSINESS_MODULES,
|
||||
normalizeEnabledBusinessModules,
|
||||
type BusinessModuleId,
|
||||
} from '../utils/businessModules'
|
||||
|
||||
interface TenantBrandingContextValue {
|
||||
businessName: string
|
||||
businessNameEn: string
|
||||
logoUrl: string | null
|
||||
faviconUrl: string | null
|
||||
enabledModules: BusinessModuleId[]
|
||||
}
|
||||
|
||||
const TenantBrandingContext = createContext<TenantBrandingContextValue | null>(null)
|
||||
@@ -39,6 +45,9 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
const [businessNameEn, setBusinessNameEn] = useState('')
|
||||
const [logoUrl, setLogoUrl] = useState<string | null>(null)
|
||||
const [faviconUrl, setFaviconUrl] = useState<string | null>(null)
|
||||
const [enabledModules, setEnabledModules] = useState<BusinessModuleId[]>(
|
||||
DEFAULT_ENABLED_BUSINESS_MODULES,
|
||||
)
|
||||
const defaultLocaleAppliedRef = useRef(false)
|
||||
const domain = getTenantDomain()
|
||||
|
||||
@@ -75,6 +84,7 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
setBusinessNameEn(nameEn || domain)
|
||||
setLogoUrl(nextLogo)
|
||||
setFaviconUrl(nextFavicon)
|
||||
setEnabledModules(normalizeEnabledBusinessModules(tenant.enabledModules))
|
||||
applyDocumentFavicon(nextFavicon)
|
||||
|
||||
if (!defaultLocaleAppliedRef.current) {
|
||||
@@ -91,6 +101,7 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
setBusinessNameEn(domain)
|
||||
setLogoUrl(null)
|
||||
setFaviconUrl(null)
|
||||
setEnabledModules([...DEFAULT_ENABLED_BUSINESS_MODULES])
|
||||
applyDocumentFavicon(null)
|
||||
}
|
||||
}
|
||||
@@ -103,8 +114,8 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
}, [domain, setLocale])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ businessName, businessNameEn, logoUrl, faviconUrl }),
|
||||
[businessName, businessNameEn, logoUrl, faviconUrl],
|
||||
() => ({ businessName, businessNameEn, logoUrl, faviconUrl, enabledModules }),
|
||||
[businessName, businessNameEn, logoUrl, faviconUrl, enabledModules],
|
||||
)
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user