Add FA/EN locale, home activity charts, and theme-aware polish.
Ship shared LocaleProvider, business/customer i18n, branding defaultLocale, curated home tiles with dual 30-day charts, and chart/page aura tokens; refresh PROJECT_CONTEXT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
f5b2193ba1
commit
66004a0fba
@@ -4,10 +4,12 @@ import {
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type ReactNode,
|
||||
} from 'react'
|
||||
import { applyDocumentFavicon } from '@meshkee/dashboard-core'
|
||||
import { useLocale } from '@meshkee/dashboard-ui'
|
||||
import { isAbortError } from '../lib/api'
|
||||
import { getBusinessDomain } from '../lib/config'
|
||||
import { BUSINESS_PROFILE_UPDATED_EVENT } from '../lib/businessContext'
|
||||
@@ -34,10 +36,13 @@ function pickBusinessName(
|
||||
}
|
||||
|
||||
export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
const [businessName, setBusinessName] = useState('')
|
||||
const { locale, setLocale } = useLocale()
|
||||
const [nameEn, setNameEn] = useState('')
|
||||
const [nameFa, setNameFa] = useState('')
|
||||
const [logoUrl, setLogoUrl] = useState<string | null>(null)
|
||||
const [faviconUrl, setFaviconUrl] = useState<string | null>(null)
|
||||
const [refreshToken, setRefreshToken] = useState(0)
|
||||
const defaultLocaleAppliedRef = useRef(false)
|
||||
|
||||
const refreshBranding = useCallback(() => {
|
||||
setRefreshToken((value) => value + 1)
|
||||
@@ -52,7 +57,8 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
const tenant = await resolveTenantByDomain(domain)
|
||||
if (controller.signal.aborted) return
|
||||
|
||||
let name = pickBusinessName(tenant.name, tenant.nameFa, domain)
|
||||
let nextNameEn = pickBusinessName(tenant.name, domain)
|
||||
let nextNameFa = pickBusinessName(tenant.nameFa, tenant.name, domain)
|
||||
let nextLogo = tenant.logoUrl?.trim() || null
|
||||
let nextFavicon =
|
||||
tenant.faviconUrl?.trim() || tenant.logoUrl?.trim() || null
|
||||
@@ -60,10 +66,15 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
try {
|
||||
const profile = await getBusinessProfile(controller.signal)
|
||||
if (!controller.signal.aborted) {
|
||||
name = pickBusinessName(
|
||||
nextNameEn = pickBusinessName(
|
||||
profile.profile.nameEn,
|
||||
nextNameEn,
|
||||
domain,
|
||||
)
|
||||
nextNameFa = pickBusinessName(
|
||||
profile.profile.nameFa,
|
||||
name,
|
||||
profile.profile.nameEn,
|
||||
nextNameFa,
|
||||
domain,
|
||||
)
|
||||
nextLogo = profile.profile.logoUrl?.trim() || nextLogo
|
||||
@@ -79,14 +90,25 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
if (!controller.signal.aborted) {
|
||||
setBusinessName(name || domain)
|
||||
setNameEn(nextNameEn || domain)
|
||||
setNameFa(nextNameFa || nextNameEn || domain)
|
||||
setLogoUrl(nextLogo)
|
||||
setFaviconUrl(nextFavicon)
|
||||
applyDocumentFavicon(nextFavicon)
|
||||
if (!defaultLocaleAppliedRef.current) {
|
||||
defaultLocaleAppliedRef.current = true
|
||||
if (tenant.defaultLocale === 'en' || tenant.defaultLocale === 'fa') {
|
||||
setLocale(tenant.defaultLocale)
|
||||
} else {
|
||||
setLocale('fa')
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (isAbortError(err) || controller.signal.aborted) return
|
||||
setBusinessName(domain)
|
||||
const domain = getBusinessDomain()
|
||||
setNameEn(domain)
|
||||
setNameFa(domain)
|
||||
setLogoUrl(null)
|
||||
setFaviconUrl(null)
|
||||
applyDocumentFavicon(null)
|
||||
@@ -104,7 +126,14 @@ export function TenantBrandingProvider({ children }: { children: ReactNode }) {
|
||||
controller.abort()
|
||||
window.removeEventListener(BUSINESS_PROFILE_UPDATED_EVENT, handleProfileUpdated)
|
||||
}
|
||||
}, [refreshToken, refreshBranding])
|
||||
}, [refreshToken, refreshBranding, setLocale])
|
||||
|
||||
const businessName = useMemo(() => {
|
||||
if (locale === 'fa') {
|
||||
return nameFa.trim() || nameEn.trim() || getBusinessDomain()
|
||||
}
|
||||
return nameEn.trim() || nameFa.trim() || getBusinessDomain()
|
||||
}, [locale, nameEn, nameFa])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ businessName, logoUrl, faviconUrl, refreshBranding }),
|
||||
|
||||
Reference in New Issue
Block a user