import React, { useState, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { useDemoStore } from '../../mock/store'; import { BUSINESS_PROFILES } from '../../core/profiles/profiles'; import { CATALOG_MODULES, CATALOG_CATEGORIES, CatalogModuleItem, } from './catalogData'; import { ModuleCard } from './ModuleCard'; import { ModuleInfoModal } from './ModuleInfoModal'; import { CatalogFilterDrawer } from './CatalogFilterDrawer'; import { Search, X, Sparkles, Layers, Filter, Building, RotateCcw, BarChart3, Grid, Zap, LayoutGrid, List, SlidersHorizontal, Users, ShoppingBag, Store, Package, CreditCard, CheckSquare, } from 'lucide-react'; import { Button } from '../../shared/ui/Button'; import { DynamicDashboard } from '../dashboard/DynamicDashboard'; export const ModulesCatalog: React.FC = () => { const navigate = useNavigate(); const { currentProfileId, catalogProfileFilter, setCatalogProfileFilter, catalogCategoryFilter, setCatalogCategoryFilter, catalogStatusFilter, setCatalogStatusFilter, catalogSearchQuery, setCatalogSearchQuery, resetCatalogFilters, } = useDemoStore(); const [activeViewMode, setActiveViewMode] = useState<'catalog' | 'dashboard'>('catalog'); const [selectedModuleForModal, setSelectedModuleForModal] = useState(null); const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false); const [displayDensity, setDisplayDensity] = useState<'compact' | 'detailed'>(() => { if (typeof window !== 'undefined' && window.innerWidth < 768) { return 'compact'; } return 'detailed'; }); const activeFiltersCount = (catalogProfileFilter !== 'all' ? 1 : 0) + (catalogCategoryFilter !== 'all' ? 1 : 0) + (catalogStatusFilter !== 'all' ? 1 : 0) + (catalogSearchQuery.trim() ? 1 : 0); const activeProfile = BUSINESS_PROFILES[currentProfileId] || BUSINESS_PROFILES.restaurant_hall_delivery; // Search and Category filtering const filteredModules = useMemo(() => { return CATALOG_MODULES.filter((m) => { // Category filter if (catalogCategoryFilter !== 'all' && m.category !== catalogCategoryFilter) { return false; } // Status filter if (catalogStatusFilter !== 'all' && m.readiness !== catalogStatusFilter) { return false; } // Search filter if (catalogSearchQuery.trim()) { const q = catalogSearchQuery.toLowerCase(); const matchTitle = m.title.toLowerCase().includes(q); const matchDesc = m.description.toLowerCase().includes(q); const matchFeatures = m.features.some((f) => f.toLowerCase().includes(q)); if (!matchTitle && !matchDesc && !matchFeatures) { return false; } } return true; }); }, [catalogCategoryFilter, catalogStatusFilter, catalogSearchQuery]); // Split into recommended vs other when a specific profile or "recommended" is active const isProfileFilterActive = catalogProfileFilter !== 'all'; const effectiveProfileId = catalogProfileFilter === 'recommended' ? currentProfileId : catalogProfileFilter; const { recommendedList, otherList } = useMemo(() => { if (!isProfileFilterActive) { return { recommendedList: [], otherList: filteredModules }; } const rec: CatalogModuleItem[] = []; const oth: CatalogModuleItem[] = []; for (const m of filteredModules) { if (m.recommendedProfiles.includes(effectiveProfileId)) { rec.push(m); } else { oth.push(m); } } return { recommendedList: rec, otherList: oth }; }, [isProfileFilterActive, effectiveProfileId, filteredModules]); const stats = useMemo(() => { const ready = CATALOG_MODULES.filter((m) => m.readiness === 'ready').length; const target = CATALOG_MODULES.filter((m) => m.readiness === 'ui_prepared').length; const planned = CATALOG_MODULES.filter((m) => m.readiness === 'planned').length; const service = CATALOG_MODULES.filter((m) => m.readiness === 'service_required').length; return { total: CATALOG_MODULES.length, ready, target, planned, service }; }, []); return (
{/* View Mode Switcher Header: Catalog vs KPI Dashboard */}
Обзор платформы Krona Business OS
Единый каталог всех 18 модулей и функциональных блоков
{/* Tab switch between Catalog and Dashboard */}
{/* If Dashboard mode is active, render DynamicDashboard */} {activeViewMode === 'dashboard' ? ( ) : ( /* Catalog Mode */
{/* Main Hero Header */}
Все возможности бизнес-платформы

Единый каталог модулей Krona

Платформа открыта для изучения целиком без предварительного выбора отрасли. Исследуйте Pilot 1 транзакции, интерактивные прототипы и перспективные блоки экосистемы.

Все 18 модулей единой бизнес-платформы

{/* Stats badges */}
{stats.ready}
Работает в демо
{stats.target}
Интерфейс готов
{stats.planned}
Запланирован
{stats.service}
Сервисные
{/* Live Search Input */}
setCatalogSearchQuery(e.target.value)} placeholder="Быстрый поиск по названию, возможностям или описанию модуля..." data-testid="catalog-search-input" className="w-full pl-10 pr-10 py-2.5 text-xs bg-krona-workspace border border-krona-border rounded-xl text-krona-primary placeholder:text-krona-secondary focus:outline-none focus:border-krona-gold shadow-inner" /> {catalogSearchQuery && ( )}
{/* Quick Controls Bar: Mobile Filter Button + Density Toggle */}
{/* Filter Drawer Trigger Button */} {/* Density Toggle */}
{/* Quick Access Block */}
Быстрый доступ
Ключевые модули платформы
{[ { id: 'crm', title: 'CRM', path: '/crm', icon: Users, color: 'text-sky-500' }, { id: 'pos', title: 'Продажи', path: '/sales', icon: ShoppingBag, color: 'text-emerald-500' }, { id: 'operations', title: 'Касса и операции', path: '/operations', icon: Store, color: 'text-amber-500' }, { id: 'inventory', title: 'Склад', path: '/inventory', icon: Package, color: 'text-blue-500' }, { id: 'finance', title: 'Финансы', path: '/finance', icon: CreditCard, color: 'text-purple-500' }, { id: 'tasks', title: 'Задачи', path: '/tasks', icon: CheckSquare, color: 'text-rose-500' }, ].map((item) => { const Icon = item.icon; return ( ); })}
{/* Industry Profiles Filter Bar */}
Отраслевой фокус (не скрывает остальные модули):
{isProfileFilterActive && ( )}
{/* Все модули (По умолчанию) */} {/* Рекомендовано для текущей отрасли */} {/* Specific profiles */} {Object.values(BUSINESS_PROFILES).map((p) => ( ))}
{/* Categories and Status Filters Bar */}
{/* Categories horizontal selector */}
{CATALOG_CATEGORIES.map((cat) => { const isSelected = catalogCategoryFilter === cat.id; const count = cat.id === 'all' ? CATALOG_MODULES.length : CATALOG_MODULES.filter((m) => m.category === cat.id).length; return ( ); })}
{/* Status & Reset filter row */}
Статус готовности:
{[ { id: 'all', label: 'Все статусы' }, { id: 'ready', label: 'Работает в демо' }, { id: 'ui_prepared', label: 'Интерфейс подготовлен' }, { id: 'planned', label: 'Запланирован' }, { id: 'service_required', label: 'Требует подключения' }, ].map((st) => ( ))}
{(catalogCategoryFilter !== 'all' || catalogStatusFilter !== 'all' || catalogSearchQuery || catalogProfileFilter !== 'all') && ( )}
{/* Module Cards Sections */} {isProfileFilterActive ? ( /* When an industry profile is selected: 2 sections */
{/* Section 1: Recommended */}

Рекомендовано для вашей отрасли ({ catalogProfileFilter === 'recommended' ? activeProfile.name : BUSINESS_PROFILES[catalogProfileFilter]?.name || 'Выбранная отрасль' })

{recommendedList.length}
{recommendedList.length > 0 ? (
{recommendedList.map((mod) => ( ))}
) : (
По текущим фильтрам нет рекомендованных модулей
)}
{/* Section 2: Other platform capabilities */}

Все остальные возможности платформы (доступны для подключения)

{otherList.length}
{otherList.length > 0 ? (
{otherList.map((mod) => ( ))}
) : (
По текущим фильтрам нет дополнительных модулей
)}
) : ( /* Unified Grid of All Modules */

Все модули платформы Krona

Найдено: {filteredModules.length}
{filteredModules.length > 0 ? (
{filteredModules.map((mod) => ( ))}
) : (

По запросу «{catalogSearchQuery}» ничего не найдено.

)}
)}
)} {/* Mobile Bottom-Sheet Filter Drawer */} setIsFilterDrawerOpen(false)} profileFilter={catalogProfileFilter} onSelectProfileFilter={(id) => setCatalogProfileFilter(id)} categoryFilter={catalogCategoryFilter} onSelectCategoryFilter={(id) => setCatalogCategoryFilter(id as any)} statusFilter={catalogStatusFilter} onSelectStatusFilter={(id) => setCatalogStatusFilter(id)} onReset={() => { resetCatalogFilters(); }} resultsCount={isProfileFilterActive ? recommendedList.length + otherList.length : filteredModules.length} /> {/* Module Info Modal */} setSelectedModuleForModal(null)} />
); };