Add multilanguage catalog translations UI for products and categories.

Include AI translate-all with locale picker, count badges, MultiLanguage Data module gating, and shared modal action layout polish.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-04 09:51:11 +03:30
co-authored by Cursor
parent 8c187b18be
commit 2a32c46b2e
43 changed files with 1624 additions and 78 deletions
+26 -1
View File
@@ -1,8 +1,10 @@
import { FolderPlus, Layers, Trash2, ChevronRight, ClipboardList, Pencil } from 'lucide-react'
import { FolderPlus, Globe, Layers, Trash2, ChevronRight, ClipboardList, Pencil } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import type { Category } from '../types/category'
import { useT } from '../i18n/useT'
import { Tooltip } from './Tooltip'
import { useTenantBranding } from '../context/TenantBrandingContext'
import { hasBusinessModule } from '../utils/businessModules'
import styles from './CategoryRow.module.css'
interface CategoryRowProps {
@@ -17,6 +19,7 @@ interface CategoryRowProps {
onVariations: (id: string) => void
onTechnicalForm: (id: string) => void
onEdit: (id: string) => void
onTranslate: (id: string) => void
onRemove: (id: string) => void
}
@@ -32,11 +35,15 @@ export function CategoryRow({
onVariations,
onTechnicalForm,
onEdit,
onTranslate,
onRemove,
}: CategoryRowProps) {
const t = useT()
const { locale } = useLocale()
const isFa = locale === 'fa'
const { enabledModules } = useTenantBranding()
const showTranslationControls = hasBusinessModule(enabledModules, 'multilanguage_data')
const translationCount = category.translationCount ?? 0
const primaryName = isFa ? category.nameFa || category.nameEn : category.nameEn
const secondaryName = isFa
? category.nameFa
@@ -121,6 +128,24 @@ export function CategoryRow({
)}
</button>
</Tooltip>
{showTranslationControls ? (
<Tooltip label={t('categories.tooltip.translate')}>
<button
className={`${styles.controlBtn} ${styles.iconBtn}`}
onClick={() => onTranslate(category.id)}
aria-label={
translationCount > 0
? `${t('categories.tooltip.translate')} (${translationCount})`
: t('categories.tooltip.translate')
}
>
<Globe size={17} />
{translationCount > 0 && (
<span className={styles.translateBadge}>{translationCount}</span>
)}
</button>
</Tooltip>
) : null}
<Tooltip label={t('categories.tooltip.edit')}>
<button
className={styles.controlBtn}