feat(admin): implement analytics and monitoring center
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> - Business Dashboard: revenue/orders/customers/AOV/top products/low stock/recent activity/warnings/completion% (Overview tab) - Marketplace Health: real completion checks (images, SEO, categories, reviews, orders, translations, homepage, backend, performance) with clickable recommendations - Product Analytics: top selling/most reviewed/worst rated/hidden/archived counts; top-viewed honestly marked Unknown (no view tracking exists) - Customer Analytics: new/returning customers, average spend, retention - derived from real order data - Search & Traffic tabs: honest 'Unknown - available after backend integration' placeholders, no fabricated numbers - Recommendations engine: actionable cards (missing images/SEO/category, empty categories, incomplete homepage, unpublished static pages) linking to the relevant admin page - System Monitoring: added real draft/publish/sync/backend-connectivity state from AdminDashboardFacade - CSV export extended to top products and health checks; added print action - New adminAnalytics.* and adminMarketplaceHealth.* i18n namespaces (en/ru/hy), no raw i18n keys - Reused existing shared UI (app-table/app-badge/app-skeleton/app-empty-state) and content-health-widget completion-meter pattern - no new backend APIs, no storage changes
This commit is contained in:
@@ -1594,10 +1594,100 @@ export const en: Translations = {
|
||||
adminMonitoring: {
|
||||
eventsEmptyTitle: 'No events found',
|
||||
eventsEmptyDescription: 'Try a different category filter or search term.',
|
||||
systemState: 'System state',
|
||||
backendConnectivity: 'Backend',
|
||||
connected: 'Connected',
|
||||
loading: 'Loading',
|
||||
draftState: 'Draft',
|
||||
unsavedChanges: 'Unsaved changes',
|
||||
noDraft: 'No draft',
|
||||
lastSaved: 'Last saved',
|
||||
lastPublished: 'Last published',
|
||||
syncStatus: 'Sync',
|
||||
},
|
||||
adminAnalytics: {
|
||||
topProductsEmptyTitle: 'No product sales in this period',
|
||||
topProductsEmptyDescription: 'Try a wider date range.',
|
||||
print: 'Print',
|
||||
tabsLabel: 'Analytics sections',
|
||||
tab: {
|
||||
overview: 'Overview',
|
||||
health: 'Health',
|
||||
products: 'Products',
|
||||
customers: 'Customers',
|
||||
search: 'Search',
|
||||
traffic: 'Traffic',
|
||||
recommendations: 'Recommendations',
|
||||
},
|
||||
revenue: 'Revenue',
|
||||
orders: 'Orders',
|
||||
customers: 'Customers',
|
||||
avgOrderValue: 'Avg. Order Value',
|
||||
conversion: 'Conversion',
|
||||
completionPercent: 'Completion',
|
||||
unknown: 'Unknown',
|
||||
salesChart: 'Sales',
|
||||
quantitySold: 'Qty sold',
|
||||
lowStock: 'Low stock',
|
||||
lowStockEmptyTitle: 'No low-stock products',
|
||||
quantity: 'Quantity',
|
||||
status: 'Status',
|
||||
recentActivity: 'Recent activity',
|
||||
recentActivityEmptyTitle: 'No recent activity',
|
||||
activityDraftSaved: 'Draft saved',
|
||||
activityPublished: 'Published',
|
||||
warnings: 'Warnings',
|
||||
topViewed: 'Top viewed',
|
||||
hiddenProducts: 'Hidden products',
|
||||
archivedProducts: 'Archived products',
|
||||
mostReviewed: 'Most reviewed',
|
||||
worstRated: 'Worst rated',
|
||||
noReviewedProducts: 'No reviewed products yet',
|
||||
reviewCount: 'Reviews',
|
||||
avgRating: 'Avg. rating',
|
||||
newCustomers: 'New customers',
|
||||
returningCustomers: 'Returning customers',
|
||||
averageSpend: 'Average spend',
|
||||
retention: 'Retention',
|
||||
searchAnalytics: 'Search analytics',
|
||||
trafficAnalytics: 'Traffic',
|
||||
availableAfterBackend: 'Available after backend integration.',
|
||||
pendingBackend: 'Pending backend',
|
||||
pendingBackendHint: 'No search-query tracking exists yet.',
|
||||
funnelsHeatmaps: 'Funnels & heatmaps',
|
||||
visitors: 'Visitors',
|
||||
products: 'Products',
|
||||
categories: 'Categories',
|
||||
},
|
||||
adminMarketplaceHealth: {
|
||||
title: 'Marketplace health',
|
||||
complete: 'complete',
|
||||
recommendationsTitle: 'Recommendations',
|
||||
recommendNone: 'Everything looks good.',
|
||||
checkImages: 'Products have images',
|
||||
checkSeo: 'Products have SEO metadata',
|
||||
checkCategories: 'Categories have products',
|
||||
checkReviews: 'Reviews are moderated',
|
||||
checkOrders: 'Orders are processed',
|
||||
checkTranslations: 'Translations are complete',
|
||||
checkHomepage: 'Homepage is configured',
|
||||
checkBackend: 'Backend connectivity',
|
||||
checkPerformance: 'Performance',
|
||||
recommendImages: 'Add images to products missing them',
|
||||
recommendImagesCount: 'Products without images hurt conversion.',
|
||||
recommendSeo: 'Add SEO metadata to products missing it',
|
||||
recommendSeoCount: 'Missing SEO titles/descriptions hurt search visibility.',
|
||||
recommendCategory: 'Assign a category to uncategorized products',
|
||||
recommendCategoryCount: 'Products without a category are harder to discover.',
|
||||
recommendEmptyCategories: 'Categories without products',
|
||||
recommendEmptyCategoriesCount: 'Consider merging or removing empty categories.',
|
||||
recommendHomepage: 'Homepage is incomplete',
|
||||
recommendStaticPages: 'Static pages are unpublished',
|
||||
severity: {
|
||||
info: 'Info',
|
||||
warning: 'Warning',
|
||||
critical: 'Critical',
|
||||
},
|
||||
},
|
||||
adminShell: {
|
||||
skipToContent: 'Skip to content',
|
||||
|
||||
@@ -1589,10 +1589,100 @@ export const hy: Translations = {
|
||||
adminMonitoring: {
|
||||
eventsEmptyTitle: 'Իրադարձություններ չեն գտնվել',
|
||||
eventsEmptyDescription: 'Փորձեք այլ կատեգորիայի ֆիլտր կամ որոնման բառ։',
|
||||
systemState: 'Համակարգի վիճակ',
|
||||
backendConnectivity: 'Բեքենդ',
|
||||
connected: 'Կապակցված է',
|
||||
loading: 'Բեռնվում է',
|
||||
draftState: 'Սևագիր',
|
||||
unsavedChanges: 'Չպահպանված փոփոխություններ',
|
||||
noDraft: 'Սևագիր չկա',
|
||||
lastSaved: 'Վերջին պահպանում',
|
||||
lastPublished: 'Վերջին հրապարակում',
|
||||
syncStatus: 'Համաժամացում',
|
||||
},
|
||||
adminAnalytics: {
|
||||
topProductsEmptyTitle: 'Այս ժամանակահատվածում ապրանքների վաճառք չկա',
|
||||
topProductsEmptyDescription: 'Փորձեք ընտրել ավելի լայն ամսաթվերի միջակայք։',
|
||||
print: 'Տպել',
|
||||
tabsLabel: 'Վերլուծության բաժիններ',
|
||||
tab: {
|
||||
overview: 'Ընդհանուր',
|
||||
health: 'Առողջություն',
|
||||
products: 'Ապրանքներ',
|
||||
customers: 'Հաճախորդներ',
|
||||
search: 'Որոնում',
|
||||
traffic: 'Թրաֆիք',
|
||||
recommendations: 'Առաջարկություններ',
|
||||
},
|
||||
revenue: 'Եկամուտ',
|
||||
orders: 'Պատվերներ',
|
||||
customers: 'Հաճախորդներ',
|
||||
avgOrderValue: 'Միջին պատվեր',
|
||||
conversion: 'Փոխարկում',
|
||||
completionPercent: 'Ավարտվածություն',
|
||||
unknown: 'Անհայտ',
|
||||
salesChart: 'Վաճառքներ',
|
||||
quantitySold: 'Վաճառված քանակ',
|
||||
lowStock: 'Ցածր պաշար',
|
||||
lowStockEmptyTitle: 'Ցածր պաշարով ապրանքներ չկան',
|
||||
quantity: 'Քանակ',
|
||||
status: 'Կարգավիճակ',
|
||||
recentActivity: 'Վերջին ակտիվություն',
|
||||
recentActivityEmptyTitle: 'Վերջին ակտիվություն չկա',
|
||||
activityDraftSaved: 'Սևագիրը պահպանվեց',
|
||||
activityPublished: 'Հրապարակվեց',
|
||||
warnings: 'Զգուշացումներ',
|
||||
topViewed: 'Ամենադիտված',
|
||||
hiddenProducts: 'Թաքցված ապրանքներ',
|
||||
archivedProducts: 'Արխիվացված ապրանքներ',
|
||||
mostReviewed: 'Ամենաշատ գնահատված',
|
||||
worstRated: 'Ամենացածր վարկանիշ',
|
||||
noReviewedProducts: 'Դեռ գնահատված ապրանքներ չկան',
|
||||
reviewCount: 'Կարծիքներ',
|
||||
avgRating: 'Միջին վարկանիշ',
|
||||
newCustomers: 'Նոր հաճախորդներ',
|
||||
returningCustomers: 'Կրկնվող հաճախորդներ',
|
||||
averageSpend: 'Միջին ծախս',
|
||||
retention: 'Պահպանում',
|
||||
searchAnalytics: 'Որոնման վերլուծություն',
|
||||
trafficAnalytics: 'Թրաֆիք',
|
||||
availableAfterBackend: 'Հասանելի կլինի բեքենդի ինտեգրումից հետո։',
|
||||
pendingBackend: 'Սպասում է բեքենդին',
|
||||
pendingBackendHint: 'Որոնման հարցումների հետագծում դեռ չկա։',
|
||||
funnelsHeatmaps: 'Ձագարներ և ջերմային քարտեզներ',
|
||||
visitors: 'Այցելուներ',
|
||||
products: 'Ապրանքներ',
|
||||
categories: 'Կատեգորիաներ',
|
||||
},
|
||||
adminMarketplaceHealth: {
|
||||
title: 'Շուկայի առողջություն',
|
||||
complete: 'ավարտված',
|
||||
recommendationsTitle: 'Առաջարկություններ',
|
||||
recommendNone: 'Ամեն ինչ կարգին է։',
|
||||
checkImages: 'Ապրանքներն ունեն նկարներ',
|
||||
checkSeo: 'Ապրանքներն ունեն SEO տվյալներ',
|
||||
checkCategories: 'Կատեգորիաներն ունեն ապրանքներ',
|
||||
checkReviews: 'Կարծիքները մոդերացվում են',
|
||||
checkOrders: 'Պատվերները մշակվում են',
|
||||
checkTranslations: 'Թարգմանությունները լրացված են',
|
||||
checkHomepage: 'Գլխավոր էջը կարգավորված է',
|
||||
checkBackend: 'Կապ բեքենդի հետ',
|
||||
checkPerformance: 'Արտադրողականություն',
|
||||
recommendImages: 'Ավելացրեք նկարներ դրանք չունեցող ապրանքներին',
|
||||
recommendImagesCount: 'Նկարներ չունեցող ապրանքները նվազեցնում են փոխարկումը։',
|
||||
recommendSeo: 'Լրացրեք SEO տվյալները դրանք չունեցող ապրանքների համար',
|
||||
recommendSeoCount: 'SEO-ի բացակայությունը վատացնում է որոնման տեսանելիությունը։',
|
||||
recommendCategory: 'Նշանակեք կատեգորիա առանց կատեգորիայի ապրանքներին',
|
||||
recommendCategoryCount: 'Կատեգորիա չունեցող ապրանքներն ավելի դժվար են գտնվում։',
|
||||
recommendEmptyCategories: 'Ապրանք չունեցող կատեգորիաներ',
|
||||
recommendEmptyCategoriesCount: 'Դիտարկեք դատարկ կատեգորիաների միավորումը կամ հեռացումը։',
|
||||
recommendHomepage: 'Գլխավոր էջը թերի է',
|
||||
recommendStaticPages: 'Կան չհրապարակված ստատիկ էջեր',
|
||||
severity: {
|
||||
info: 'Տեղեկատվություն',
|
||||
warning: 'Ուշադրություն',
|
||||
critical: 'Կրիտիկական',
|
||||
},
|
||||
},
|
||||
adminShell: {
|
||||
skipToContent: 'Անցնել բովանդակությանը',
|
||||
|
||||
@@ -1589,10 +1589,100 @@ export const ru: Translations = {
|
||||
adminMonitoring: {
|
||||
eventsEmptyTitle: 'События не найдены',
|
||||
eventsEmptyDescription: 'Попробуйте изменить фильтр категории или поисковый запрос.',
|
||||
systemState: 'Состояние системы',
|
||||
backendConnectivity: 'Бэкенд',
|
||||
connected: 'Подключено',
|
||||
loading: 'Загрузка',
|
||||
draftState: 'Черновик',
|
||||
unsavedChanges: 'Есть несохранённые изменения',
|
||||
noDraft: 'Черновика нет',
|
||||
lastSaved: 'Последнее сохранение',
|
||||
lastPublished: 'Последняя публикация',
|
||||
syncStatus: 'Синхронизация',
|
||||
},
|
||||
adminAnalytics: {
|
||||
topProductsEmptyTitle: 'Нет продаж товаров за этот период',
|
||||
topProductsEmptyDescription: 'Попробуйте выбрать более широкий диапазон дат.',
|
||||
print: 'Печать',
|
||||
tabsLabel: 'Разделы аналитики',
|
||||
tab: {
|
||||
overview: 'Обзор',
|
||||
health: 'Здоровье',
|
||||
products: 'Товары',
|
||||
customers: 'Клиенты',
|
||||
search: 'Поиск',
|
||||
traffic: 'Трафик',
|
||||
recommendations: 'Рекомендации',
|
||||
},
|
||||
revenue: 'Выручка',
|
||||
orders: 'Заказы',
|
||||
customers: 'Клиенты',
|
||||
avgOrderValue: 'Средний чек',
|
||||
conversion: 'Конверсия',
|
||||
completionPercent: 'Готовность',
|
||||
unknown: 'Неизвестно',
|
||||
salesChart: 'Продажи',
|
||||
quantitySold: 'Продано, шт.',
|
||||
lowStock: 'Мало на складе',
|
||||
lowStockEmptyTitle: 'Нет товаров с низким остатком',
|
||||
quantity: 'Количество',
|
||||
status: 'Статус',
|
||||
recentActivity: 'Недавняя активность',
|
||||
recentActivityEmptyTitle: 'Нет недавней активности',
|
||||
activityDraftSaved: 'Черновик сохранён',
|
||||
activityPublished: 'Опубликовано',
|
||||
warnings: 'Предупреждения',
|
||||
topViewed: 'Самые просматриваемые',
|
||||
hiddenProducts: 'Скрытые товары',
|
||||
archivedProducts: 'Архивные товары',
|
||||
mostReviewed: 'Больше всего отзывов',
|
||||
worstRated: 'Худший рейтинг',
|
||||
noReviewedProducts: 'Пока нет товаров с отзывами',
|
||||
reviewCount: 'Отзывы',
|
||||
avgRating: 'Средний рейтинг',
|
||||
newCustomers: 'Новые клиенты',
|
||||
returningCustomers: 'Повторные клиенты',
|
||||
averageSpend: 'Средние траты',
|
||||
retention: 'Удержание',
|
||||
searchAnalytics: 'Аналитика поиска',
|
||||
trafficAnalytics: 'Трафик',
|
||||
availableAfterBackend: 'Будет доступно после интеграции с бэкендом.',
|
||||
pendingBackend: 'Ожидает бэкенд',
|
||||
pendingBackendHint: 'Отслеживание поисковых запросов пока не реализовано.',
|
||||
funnelsHeatmaps: 'Воронки и тепловые карты',
|
||||
visitors: 'Посетители',
|
||||
products: 'Товары',
|
||||
categories: 'Категории',
|
||||
},
|
||||
adminMarketplaceHealth: {
|
||||
title: 'Здоровье маркетплейса',
|
||||
complete: 'готово',
|
||||
recommendationsTitle: 'Рекомендации',
|
||||
recommendNone: 'Всё в порядке.',
|
||||
checkImages: 'У товаров есть изображения',
|
||||
checkSeo: 'У товаров заполнено SEO',
|
||||
checkCategories: 'В категориях есть товары',
|
||||
checkReviews: 'Отзывы модерируются',
|
||||
checkOrders: 'Заказы обрабатываются',
|
||||
checkTranslations: 'Переводы заполнены',
|
||||
checkHomepage: 'Главная страница настроена',
|
||||
checkBackend: 'Связь с бэкендом',
|
||||
checkPerformance: 'Производительность',
|
||||
recommendImages: 'Добавьте изображения товарам без них',
|
||||
recommendImagesCount: 'Товары без изображений снижают конверсию.',
|
||||
recommendSeo: 'Заполните SEO для товаров без него',
|
||||
recommendSeoCount: 'Отсутствие SEO ухудшает видимость в поиске.',
|
||||
recommendCategory: 'Назначьте категорию товарам без категории',
|
||||
recommendCategoryCount: 'Товары без категории труднее найти.',
|
||||
recommendEmptyCategories: 'Категории без товаров',
|
||||
recommendEmptyCategoriesCount: 'Рассмотрите объединение или удаление пустых категорий.',
|
||||
recommendHomepage: 'Главная страница не заполнена',
|
||||
recommendStaticPages: 'Есть неопубликованные статические страницы',
|
||||
severity: {
|
||||
info: 'Инфо',
|
||||
warning: 'Внимание',
|
||||
critical: 'Критично',
|
||||
},
|
||||
},
|
||||
adminShell: {
|
||||
skipToContent: 'Перейти к содержимому',
|
||||
|
||||
@@ -1601,10 +1601,100 @@ export interface Translations {
|
||||
adminMonitoring: {
|
||||
eventsEmptyTitle: string;
|
||||
eventsEmptyDescription: string;
|
||||
systemState: string;
|
||||
backendConnectivity: string;
|
||||
connected: string;
|
||||
loading: string;
|
||||
draftState: string;
|
||||
unsavedChanges: string;
|
||||
noDraft: string;
|
||||
lastSaved: string;
|
||||
lastPublished: string;
|
||||
syncStatus: string;
|
||||
};
|
||||
adminAnalytics: {
|
||||
topProductsEmptyTitle: string;
|
||||
topProductsEmptyDescription: string;
|
||||
print: string;
|
||||
tabsLabel: string;
|
||||
tab: {
|
||||
overview: string;
|
||||
health: string;
|
||||
products: string;
|
||||
customers: string;
|
||||
search: string;
|
||||
traffic: string;
|
||||
recommendations: string;
|
||||
};
|
||||
revenue: string;
|
||||
orders: string;
|
||||
customers: string;
|
||||
avgOrderValue: string;
|
||||
conversion: string;
|
||||
completionPercent: string;
|
||||
unknown: string;
|
||||
salesChart: string;
|
||||
quantitySold: string;
|
||||
lowStock: string;
|
||||
lowStockEmptyTitle: string;
|
||||
quantity: string;
|
||||
status: string;
|
||||
recentActivity: string;
|
||||
recentActivityEmptyTitle: string;
|
||||
activityDraftSaved: string;
|
||||
activityPublished: string;
|
||||
warnings: string;
|
||||
topViewed: string;
|
||||
hiddenProducts: string;
|
||||
archivedProducts: string;
|
||||
mostReviewed: string;
|
||||
worstRated: string;
|
||||
noReviewedProducts: string;
|
||||
reviewCount: string;
|
||||
avgRating: string;
|
||||
newCustomers: string;
|
||||
returningCustomers: string;
|
||||
averageSpend: string;
|
||||
retention: string;
|
||||
searchAnalytics: string;
|
||||
trafficAnalytics: string;
|
||||
availableAfterBackend: string;
|
||||
pendingBackend: string;
|
||||
pendingBackendHint: string;
|
||||
funnelsHeatmaps: string;
|
||||
visitors: string;
|
||||
products: string;
|
||||
categories: string;
|
||||
};
|
||||
adminMarketplaceHealth: {
|
||||
title: string;
|
||||
complete: string;
|
||||
recommendationsTitle: string;
|
||||
recommendNone: string;
|
||||
checkImages: string;
|
||||
checkSeo: string;
|
||||
checkCategories: string;
|
||||
checkReviews: string;
|
||||
checkOrders: string;
|
||||
checkTranslations: string;
|
||||
checkHomepage: string;
|
||||
checkBackend: string;
|
||||
checkPerformance: string;
|
||||
recommendImages: string;
|
||||
recommendImagesCount: string;
|
||||
recommendSeo: string;
|
||||
recommendSeoCount: string;
|
||||
recommendCategory: string;
|
||||
recommendCategoryCount: string;
|
||||
recommendEmptyCategories: string;
|
||||
recommendEmptyCategoriesCount: string;
|
||||
recommendHomepage: string;
|
||||
recommendStaticPages: string;
|
||||
severity: {
|
||||
info: string;
|
||||
warning: string;
|
||||
critical: string;
|
||||
};
|
||||
};
|
||||
adminShell: {
|
||||
skipToContent: string;
|
||||
|
||||
Reference in New Issue
Block a user