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:
Alireza Hassani
2026-08-01 09:35:27 +03:30
co-authored by Cursor
parent f5b2193ba1
commit 66004a0fba
112 changed files with 4338 additions and 1061 deletions
+24 -17
View File
@@ -1,32 +1,35 @@
import { useEffect, useState } from 'react'
import { NavLink, useNavigate } from 'react-router-dom'
import { Home, User, MapPin, ShoppingBag, ShoppingCart, Heart, HelpCircle, LogOut } from 'lucide-react'
import { Home, User, MapPin, ShoppingBag, Heart, HelpCircle, LogOut } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import { useAuth } from '../context/AuthContext'
import { useT } from '../i18n/useT'
import { getActiveBusinessDomain } from '../lib/businessContext'
import { isAbortError } from '../lib/api'
import { getWebsiteBusinessInfo } from '../services/websiteService'
import meshkeeLogo from '../assets/meshkee-logo.png'
import styles from './Sidebar.module.css'
const navItems = [
{ icon: Home, label: 'Home', to: '/' },
{ icon: ShoppingCart, label: 'Shopping Cart', to: '/checkout' },
{ icon: User, label: 'My Profile', to: '/profile' },
{ icon: MapPin, label: 'My Addresses', to: '/addresses' },
{ icon: ShoppingBag, label: 'My Orders', to: '/orders' },
{ icon: Heart, label: 'My Favorites', to: '/favorites' },
]
export function Sidebar() {
const navigate = useNavigate()
const { user, logout } = useAuth()
const { locale } = useLocale()
const t = useT()
const [brandName, setBrandName] = useState('')
const [logoUrl, setLogoUrl] = useState<string | null>(null)
const businessDomain = getActiveBusinessDomain()
const fallbackBusinessName = user?.customerBusinesses[0]?.name ?? 'Store'
const fallbackBusinessName = user?.customerBusinesses[0]?.name ?? t('app.storeFallback')
const displayName = brandName || fallbackBusinessName
const navItems = [
{ icon: Home, label: t('nav.home'), to: '/' },
{ icon: User, label: t('nav.profile'), to: '/profile' },
{ icon: MapPin, label: t('nav.addresses'), to: '/addresses' },
{ icon: ShoppingBag, label: t('nav.orders'), to: '/orders' },
{ icon: Heart, label: t('nav.favorites'), to: '/favorites' },
]
useEffect(() => {
const controller = new AbortController()
@@ -34,7 +37,11 @@ export function Sidebar() {
try {
const info = await getWebsiteBusinessInfo(businessDomain, controller.signal)
if (controller.signal.aborted) return
setBrandName(info.nameFa?.trim() || info.name.trim() || fallbackBusinessName)
const localized =
locale === 'fa'
? info.nameFa?.trim() || info.name.trim()
: info.name.trim() || info.nameFa?.trim()
setBrandName(localized || fallbackBusinessName)
setLogoUrl(info.logoUrl?.trim() || null)
} catch (err) {
if (isAbortError(err)) return
@@ -48,7 +55,7 @@ export function Sidebar() {
return () => {
controller.abort()
}
}, [businessDomain, fallbackBusinessName])
}, [businessDomain, fallbackBusinessName, locale])
return (
<aside className={styles.sidebar}>
@@ -59,15 +66,15 @@ export function Sidebar() {
className={styles.brandLogo}
/>
<div className={styles.brandText}>
<span className={styles.brandDomain}>{businessDomain}</span>
<span className={styles.brandName}>{displayName}</span>
<span className={styles.brandDomain}>{businessDomain}</span>
</div>
</div>
<nav className={styles.nav}>
{navItems.map((item) => (
<NavLink
key={item.label}
key={item.to}
to={item.to}
end={item.to === '/'}
className={({ isActive }) =>
@@ -83,7 +90,7 @@ export function Sidebar() {
<div className={styles.footer}>
<button type="button" className={styles.navItem}>
<HelpCircle size={20} />
<span>Help Center</span>
<span>{t('nav.help')}</span>
</button>
<button
type="button"
@@ -94,7 +101,7 @@ export function Sidebar() {
}}
>
<LogOut size={20} />
<span>Logout</span>
<span>{t('nav.logout')}</span>
</button>
</div>
</aside>