feat(products): implement professional product management experience

Products dashboard (real total/published/drafts/out-of-stock/hidden/missing-images/missing-SEO/low-quality counts, recently-edited list, recommended next action); list gains table/grid view toggle, density, saved column visibility and saved sort (persisted via LocalStorageService), plus real bulk assign-category/assign-tags/duplicate/CSV-export alongside existing publish/hide/delete; per-row and per-editor reusable ProductHealthWidget (images/SEO/price/category/description/inventory checklist + completion %); editor reorganized into General/Media/Pricing/Inventory/Categories/Attributes/SEO/Visibility/Advanced tabs, media now uses the shared MediaPickerComponent/ImageFieldComponent (primary image + reorderable gallery) instead of raw URL textareas, specifications/attributes/variants moved off pipe-delimited textareas onto the shared KeyValueEditorComponent, SEO tab explains fields in plain language with a live search-result preview, inventory relabeled in business language, toggles/badges use the shared Toggle/Badge components. Filled in the adminProducts i18n namespace (previously ~98% missing, rendering raw translation keys) across en/ru/hy.
This commit is contained in:
sdarbinyan
2026-07-18 16:34:06 +04:00
parent 5d52d81c7d
commit aeb48504c5
19 changed files with 1561 additions and 212 deletions

View File

@@ -1225,6 +1225,141 @@ export const en: Translations = {
adminProducts: {
emptyTitle: 'No products found',
emptyDescription: 'Try adjusting your filters, or create a new product.',
emptyGuide: 'Good products have a clear title, at least one photo, a price, and a short description — that\'s enough to publish. You can always add more detail later.',
search: 'Search products…',
category: 'Category',
allCategories: 'All categories',
visibility: 'Visibility',
allVisibility: 'All visibility',
visible: 'Visible',
hidden: 'Hidden',
stockStatus: 'Stock status',
allStock: 'All stock levels',
inStock: 'In stock',
lowStock: 'Low stock',
outOfStock: 'Out of stock',
sortTitle: 'Name',
sortPrice: 'Price',
sortPriority: 'Priority',
sortStock: 'Stock',
sortUpdated: 'Last updated',
showArchived: 'Show archived',
infiniteScroll: 'Infinite scroll',
viewMode: 'View',
viewTable: 'Table',
viewGrid: 'Grid',
density: 'Density',
densityComfortable: 'Comfortable',
densityCompact: 'Compact',
columns: 'Columns',
column_sku: 'SKU',
column_brand: 'Brand',
column_price: 'Price',
column_stock: 'Stock',
column_visibility: 'Visibility',
column_updated: 'Last updated',
create: 'Create product',
edit: 'Edit product',
duplicate: 'Duplicate',
selectedCount: 'selected',
bulkShow: 'Publish',
bulkHide: 'Hide',
bulkAssignCategory: 'Assign category',
bulkAssignTags: 'Assign tags',
bulkDuplicateAction: 'Duplicate',
bulkExportAction: 'Export',
bulkDelete: 'Delete',
tagsPlaceholder: 'e.g. summer, sale',
name: 'Name',
brand: 'Brand',
healthColumn: 'Health',
actions: 'Actions',
archive: 'Archive',
delete: 'Delete',
items: 'products',
loadMore: 'Load more',
noImage: 'No image',
slug: 'URL slug',
barcode: 'Barcode',
priority: 'Priority',
shortDescription: 'Short description',
translations: 'Translations',
primaryImage: 'Primary image',
primaryImageHint: 'The main photo shown in listings and search results.',
gallery: 'Gallery',
galleryHint: 'Additional photos shown on the product page. Drag order with the arrows.',
moveLeft: 'Move earlier',
moveRight: 'Move later',
videos: 'Videos (one URL per line)',
discount: 'Discount %',
currency: 'Currency',
stockQuantity: 'Stock quantity',
stockQuantityHint: 'How many units are available to sell right now.',
availabilityStatus: 'Availability',
availabilityStatusHint: 'What customers see: in stock, running low, or out of stock.',
availabilityNote: 'Availability note',
availabilityNoteHint: 'Optional extra detail shown to customers, e.g. "Ships in 3 days".',
reservedNote: 'Reserved stock isn\'t tracked separately yet — quantity shown here is total available stock.',
relatedProducts: 'Related products',
specifications: 'Specifications',
attributes: 'Attributes',
addRow: 'Add row',
removeRow: 'Remove',
rowKey: 'Name',
rowValue: 'Value',
addVariant: 'Add variant',
variantName: 'Variant name',
variantsHint: 'Each variant is a purchasable option of this product, e.g. a size or color, with its own price and stock.',
seoExplain: 'This is what shows up in search results — a clear title and description help customers find this product.',
searchTitle: 'Search title',
searchTitleHint: 'The headline shown in search results. Keep it short and descriptive.',
searchDescription: 'Search description',
searchDescriptionHint: 'A short summary shown under the title in search results.',
seoMissingTitle: 'Add a search title so this product can be found.',
seoMissingDescription: 'Add a search description to improve how this product appears in results.',
keywords: 'Keywords',
featured: 'Featured',
recommended: 'Recommended',
new: 'New',
bestseller: 'Bestseller',
badges: 'Badges (comma-separated)',
htmlDescription: 'Detailed description',
customer: 'Customer feedback',
reviewsReadonly: 'Reviews',
noReviews: 'No reviews yet.',
questionsReadonly: 'Questions',
noQuestions: 'No questions yet.',
save: 'Save product',
groupGeneral: 'General',
groupMedia: 'Media',
groupPricing: 'Pricing',
groupInventory: 'Inventory',
groupCategories: 'Categories',
groupAttributes: 'Attributes',
groupSeo: 'SEO',
groupVisibility: 'Visibility',
groupAdvanced: 'Advanced',
healthImages: 'Images',
healthSeo: 'SEO',
healthPrice: 'Price',
healthCategory: 'Category',
healthDescription: 'Description',
healthInventory: 'Inventory',
totalProducts: 'Total products',
publishedCount: 'Published',
draftsCount: 'Drafts',
outOfStockCount: 'Out of stock',
hiddenCount: 'Hidden',
missingImagesCount: 'Missing images',
missingSeoCount: 'Missing SEO',
lowQualityCount: 'Low-quality',
recentlyEdited: 'Recently edited',
recommendedNext: 'Recommended next step',
openAction: 'Open',
recommendAddImages: 'A product has no photos — add at least one image so it looks trustworthy.',
recommendAddSeo: 'A product is missing a search title or description — add one so it can be found.',
recommendRestock: 'A product is out of stock — restock it or mark it unavailable.',
recommendNone: 'Nice work — your catalog is in good shape.',
},
adminUsers: {
emptyTitle: 'No users found',