feat(categories): implement professional category management experience

Categories dashboard (real total/visible/hidden/empty/root/subcategory/missing-image/missing-SEO/last-modified/completion% stats, recommended next action); tree view is now a real expand/collapse hierarchy (state persisted via LocalStorageService) with keyboard navigation (arrow keys, jump-to-parent), search that force-expands and keeps only matching branches + their ancestors/descendants instead of silently dropping deep matches; added Table/Cards views alongside the tree with density and saved column visibility; real bulk actions (show/hide/delete/assign parent/assign image via the Media Library picker/duplicate via the existing createCategory call/CSV export) plus the pre-existing single-item actions; reusable CategoryHealthWidget (image/SEO/description/valid-parent/visibility/products-assigned + completion%); editor reorganized into General/Media/SEO/Visibility/Navigation/Attributes/Advanced tabs, media now uses the shared ImageFieldComponent, SEO explains fields in plain language with a live preview, Navigation tab shows real breadcrumb/children/visibility-based nav status, Attributes uses the shared KeyValueEditorComponent. Filled in the adminCategories i18n namespace (previously only 2 of ~90 referenced keys existed) across en/ru/hy. Also fixed the pre-existing bug where a filtered/searched category list could silently drop a matched descendant whose ancestor's title didn't match, by loading the full catalog once and filtering client-side.
This commit is contained in:
sdarbinyan
2026-07-18 17:04:11 +04:00
parent aeb48504c5
commit ac615837ab
22 changed files with 1433 additions and 117 deletions

View File

@@ -1221,6 +1221,84 @@ export const en: Translations = {
adminCategories: {
chooseImage: 'Choose image',
replaceImage: 'Replace image',
search: 'Search categories…',
showDeleted: 'Show deleted',
create: 'Create category',
edit: 'Edit category',
title: 'Title',
slug: 'URL slug',
slugTaken: 'This slug is already used by another category.',
parent: 'Parent category',
noParent: 'No parent (top level)',
icon: 'Icon',
image: 'Image',
imageHint: 'Shown in category listings and navigation.',
description: 'Description',
items: 'products',
status: { draft: 'Draft', published: 'Published' },
restore: 'Restore',
saveDraft: 'Save draft',
publish: 'Publish',
confirmDelete: 'Delete this category? This cannot be undone.',
confirmLeaveUnsaved: 'You have unsaved changes. Leave without saving?',
deleteBlocked: 'This category can\'t be deleted while it has subcategories or assigned products.',
emptyTitle: 'No categories yet',
emptyDescription: 'Create your first category to start organizing products.',
emptyGuide: 'Categories help customers browse and find products. Start with a few broad top-level categories (e.g. Clothing, Electronics), then add subcategories as your catalog grows — avoid nesting more than 2-3 levels deep.',
viewTree: 'Tree',
viewCards: 'Cards',
expandAll: 'Expand all',
collapseAll: 'Collapse all',
expandNode: 'Expand',
collapseNode: 'Collapse',
jumpToParent: 'Jump to parent',
deletedBadge: 'Deleted',
column_slug: 'Slug',
column_items: 'Products',
column_status: 'Status',
column_visibility: 'Visibility',
column_updated: 'Last updated',
bulkAssignParent: 'Assign parent',
bulkAssignImage: 'Assign image',
groupGeneral: 'General',
groupMedia: 'Media',
groupSeo: 'SEO',
groupVisibility: 'Visibility',
groupNavigation: 'Navigation',
groupAttributes: 'Attributes',
groupAdvanced: 'Advanced',
visibilityExplain: 'A hidden category and its products stay out of the storefront navigation and search until you make it visible again.',
navBreadcrumb: 'Breadcrumb',
navRoot: 'This is a top-level category.',
navChildren: 'Subcategories',
navNoChildren: 'No subcategories yet.',
navAppearsIn: 'Where this appears',
navAppearsVisible: 'Visible in catalog navigation and search.',
navAppearsHidden: 'Hidden — not shown in catalog navigation while hidden.',
itemsCountLabel: 'Assigned products',
createdAtLabel: 'Created',
healthImage: 'Image',
healthSeo: 'SEO',
healthDescription: 'Description',
healthParent: 'Parent',
healthVisibility: 'Visibility',
healthProducts: 'Products assigned',
totalCategories: 'Total categories',
visibleCount: 'Visible',
hiddenCount: 'Hidden',
emptyCount: 'Empty',
rootCount: 'Root categories',
subCount: 'Subcategories',
missingImagesCount: 'Missing images',
missingSeoCount: 'Missing SEO',
lastModified: 'Last modified',
lastModifiedNever: 'Never',
completionLabel: 'Completion',
recommendedNext: 'Recommended next step',
recommendAddImage: 'A category has no image — add one so it looks trustworthy in listings.',
recommendAddSeo: 'A category is missing a search title or description — add one so it can be found.',
recommendFillEmpty: 'A category has no products assigned — add products or consider hiding it.',
recommendNone: 'Nice work — your category structure is in good shape.',
},
adminProducts: {
emptyTitle: 'No products found',