Some checks failed
Architecture Governance / architecture (push) Has been cancelled
New nav entry, route, page. Renders the four-level tree (Company/Project/Store/PaymentPoint) via AdminPartnerHierarchyFacade on top of the core built in the previous commit - TEST/LIVE toggle, suspend/activate, disable behind a confirmation (terminal + cascading, per contract §2), and a read-only credentials list stating plainly that only the public key is ever held. Reload-after-action rather than local patch on suspend/activate/disable: disable cascades to descendants server-side, so a local patch would leave children showing a status they no longer have. Company id is a constant for now (DEFAULT_COMPANY_ID) - company creation is out of band per contract §4.3, and there is no company-selector UI yet. Verified: 139/139 unit tests, arch:check clean, production build succeeds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
398 lines
17 KiB
TypeScript
398 lines
17 KiB
TypeScript
import { Routes } from '@angular/router';
|
|
import { languageGuard } from './guards/language.guard';
|
|
import { projectEditorDirtyGuard } from './features/project-editor/guards/project-editor-dirty.guard';
|
|
import { adminAuthGuard } from '@marketplaces/auth';
|
|
import { requireAdminPermission } from './core/admin-auth/admin-auth.guard';
|
|
import { authRoutes } from './core/auth/auth.routes';
|
|
import { adminCategoryDirtyGuard } from './features/admin/categories/guards/admin-category-dirty.guard';
|
|
import { adminProductDirtyGuard } from './features/admin/products/guards/admin-product-dirty.guard';
|
|
import { environment } from '../environments/environment';
|
|
|
|
// Core routes (same across all brands)
|
|
const coreRoutes: Routes = [
|
|
{
|
|
path: '',
|
|
loadComponent: () => import('./pages/home/home.component').then(m => m.HomeComponent)
|
|
},
|
|
{
|
|
path: 'catalog',
|
|
loadComponent: () => import('./features/website/catalog/containers/catalog-container.component').then(m => m.CatalogContainerComponent)
|
|
},
|
|
{
|
|
path: 'catalog/:id',
|
|
loadComponent: () => import('./features/website/catalog/containers/catalog-container.component').then(m => m.CatalogContainerComponent)
|
|
},
|
|
{
|
|
path: 'category/:id',
|
|
redirectTo: 'catalog/:id',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'category/:id/items',
|
|
redirectTo: 'catalog/:id',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'product/:id',
|
|
loadComponent: () => import('./features/website/product/containers/product-details-container.component').then(m => m.ProductDetailsContainerComponent)
|
|
},
|
|
{
|
|
path: 'item/:id',
|
|
redirectTo: 'product/:id',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'search',
|
|
loadComponent: () => import('./features/website/catalog/containers/catalog-container.component').then(m => m.CatalogContainerComponent)
|
|
},
|
|
{
|
|
path: 'edit',
|
|
canActivate: [adminAuthGuard],
|
|
loadComponent: () => import('./features/project-editor/pages/builder-overview-page.component').then(m => m.BuilderOverviewPageComponent)
|
|
},
|
|
{
|
|
path: 'edit/:section',
|
|
canActivate: [adminAuthGuard],
|
|
loadComponent: () => import('./features/project-editor/pages/project-editor-page.component').then(m => m.ProjectEditorPageComponent),
|
|
canDeactivate: [projectEditorDirtyGuard]
|
|
},
|
|
{
|
|
path: 'backoffice',
|
|
canActivate: [adminAuthGuard],
|
|
loadComponent: () => import('./features/admin/shell/admin-layout.component').then(m => m.AdminLayoutComponent),
|
|
children: [
|
|
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
|
|
{
|
|
path: 'dashboard',
|
|
loadComponent: () => import('./features/admin/dashboard/pages/admin-dashboard-page.component').then(m => m.AdminDashboardPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.dashboard.title',
|
|
descriptionKey: 'adminShell.pages.dashboard.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.pages.dashboard.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'products',
|
|
loadComponent: () => import('./features/admin/products/pages/admin-products-list-page.component').then(m => m.AdminProductsListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.products.title',
|
|
descriptionKey: 'adminShell.pages.products.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.products' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'products/create',
|
|
loadComponent: () => import('./features/admin/products/pages/admin-product-editor-page.component').then(m => m.AdminProductEditorPageComponent),
|
|
canDeactivate: [adminProductDirtyGuard],
|
|
data: {
|
|
titleKey: 'adminShell.pages.productCreate.title',
|
|
descriptionKey: 'adminShell.pages.productCreate.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.products', path: ['products'] }, { labelKey: 'adminShell.pages.productCreate.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'products/:id/edit',
|
|
loadComponent: () => import('./features/admin/products/pages/admin-product-editor-page.component').then(m => m.AdminProductEditorPageComponent),
|
|
canDeactivate: [adminProductDirtyGuard],
|
|
data: {
|
|
titleKey: 'adminShell.pages.productEdit.title',
|
|
descriptionKey: 'adminShell.pages.productEdit.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.products', path: ['products'] }, { labelKey: 'adminShell.pages.productEdit.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'products/:id/duplicate',
|
|
loadComponent: () => import('./features/admin/products/pages/admin-product-editor-page.component').then(m => m.AdminProductEditorPageComponent),
|
|
canDeactivate: [adminProductDirtyGuard],
|
|
data: {
|
|
titleKey: 'adminShell.pages.productDuplicate.title',
|
|
descriptionKey: 'adminShell.pages.productDuplicate.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.products', path: ['products'] }, { labelKey: 'adminShell.pages.productDuplicate.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'categories',
|
|
loadComponent: () => import('./features/admin/categories/pages/admin-categories-list-page.component').then(m => m.AdminCategoriesListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.categories.title',
|
|
descriptionKey: 'adminShell.pages.categories.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.categories' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'categories/create',
|
|
loadComponent: () => import('./features/admin/categories/pages/admin-category-editor-page.component').then(m => m.AdminCategoryEditorPageComponent),
|
|
canDeactivate: [adminCategoryDirtyGuard],
|
|
data: {
|
|
titleKey: 'adminShell.pages.categoryCreate.title',
|
|
descriptionKey: 'adminShell.pages.categoryCreate.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.categories', path: ['categories'] }, { labelKey: 'adminShell.pages.categoryCreate.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'categories/:id/edit',
|
|
loadComponent: () => import('./features/admin/categories/pages/admin-category-editor-page.component').then(m => m.AdminCategoryEditorPageComponent),
|
|
canDeactivate: [adminCategoryDirtyGuard],
|
|
data: {
|
|
titleKey: 'adminShell.pages.categoryEdit.title',
|
|
descriptionKey: 'adminShell.pages.categoryEdit.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.categories', path: ['categories'] }, { labelKey: 'adminShell.pages.categoryEdit.title' }]
|
|
}
|
|
},
|
|
{
|
|
// Static Pages is a first-class Project Editor module (Sprint X+2), not a
|
|
// separate backoffice CRUD surface - redirect here rather than build a
|
|
// second UI over the same bootstrap.staticPages data.
|
|
path: 'static-pages',
|
|
redirectTo: '/edit/static-pages',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'transactions',
|
|
loadComponent: () => import('./features/admin/transactions/pages/admin-transactions-list-page.component').then(m => m.AdminTransactionsListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.transactions.title',
|
|
descriptionKey: 'adminShell.pages.transactions.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.transactions' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'orders',
|
|
loadComponent: () => import('./features/admin/orders/pages/admin-orders-list-page.component').then(m => m.AdminOrdersListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.orders.title',
|
|
descriptionKey: 'adminShell.pages.orders.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.orders' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'orders/:id',
|
|
loadComponent: () => import('./features/admin/orders/pages/admin-order-detail-page.component').then(m => m.AdminOrderDetailPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.orderDetail.title',
|
|
descriptionKey: 'adminShell.pages.orderDetail.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.orders', path: ['orders'] }, { labelKey: 'adminShell.pages.orderDetail.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'customers',
|
|
loadComponent: () => import('./features/admin/customers/pages/admin-customers-list-page.component').then(m => m.AdminCustomersListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.customers.title',
|
|
descriptionKey: 'adminShell.pages.customers.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.customers' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'customers/:email',
|
|
loadComponent: () => import('./features/admin/customers/pages/admin-customer-detail-page.component').then(m => m.AdminCustomerDetailPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.customerDetail.title',
|
|
descriptionKey: 'adminShell.pages.customerDetail.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.customers', path: ['customers'] }, { labelKey: 'adminShell.pages.customerDetail.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'notifications',
|
|
loadComponent: () => import('./features/admin/notifications/pages/admin-notifications-page.component').then(m => m.AdminNotificationsPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.notifications',
|
|
descriptionKey: 'adminShell.nav.notifications',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.notifications' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'integrations',
|
|
loadComponent: () => import('./features/admin/integrations/pages/admin-integrations-page.component').then(m => m.AdminIntegrationsPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.integrations',
|
|
descriptionKey: 'adminShell.nav.integrations',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.integrations' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'finance',
|
|
loadComponent: () => import('./features/admin/finance/pages/admin-finance-page.component').then(m => m.AdminFinancePageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.finance',
|
|
descriptionKey: 'adminShell.nav.finance',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.finance' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'marketplaces',
|
|
loadComponent: () => import('./features/admin/marketplaces/pages/admin-marketplaces-page.component').then(m => m.AdminMarketplacesPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.marketplaces',
|
|
descriptionKey: 'adminShell.nav.marketplaces',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.marketplaces' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'partner-hierarchy',
|
|
loadComponent: () => import('./features/admin/partner-hierarchy/pages/admin-partner-hierarchy-page.component').then(m => m.AdminPartnerHierarchyPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.partnerHierarchy',
|
|
descriptionKey: 'adminShell.nav.partnerHierarchy',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.partnerHierarchy' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'audit',
|
|
loadComponent: () => import('./features/admin/audit/pages/admin-audit-page.component').then(m => m.AdminAuditPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.nav.audit',
|
|
descriptionKey: 'adminShell.nav.audit',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.audit' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'moderation',
|
|
loadComponent: () => import('./features/admin/moderation/pages/admin-reviews-list-page.component').then(m => m.AdminReviewsListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.moderation.title',
|
|
descriptionKey: 'adminShell.pages.moderation.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.moderation' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'moderation/reports',
|
|
loadComponent: () => import('./features/admin/moderation/pages/admin-reports-list-page.component').then(m => m.AdminReportsListPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.reportsQueue.title',
|
|
descriptionKey: 'adminShell.pages.reportsQueue.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.moderation', path: ['moderation'] }, { labelKey: 'adminShell.pages.reportsQueue.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'moderation/:id',
|
|
loadComponent: () => import('./features/admin/moderation/pages/admin-review-detail-page.component').then(m => m.AdminReviewDetailPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.reviewDetail.title',
|
|
descriptionKey: 'adminShell.pages.reviewDetail.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.moderation', path: ['moderation'] }, { labelKey: 'adminShell.pages.reviewDetail.title' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'media',
|
|
loadComponent: () => import('./features/backoffice/media/media-library-page.component').then(m => m.MediaLibraryPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.media.title',
|
|
descriptionKey: 'adminShell.pages.media.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.mediaLibrary' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'users',
|
|
canActivate: [requireAdminPermission('users.manage')],
|
|
loadComponent: () => import('./features/admin/users/pages/admin-users-page.component').then(m => m.AdminUsersPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.users.title',
|
|
descriptionKey: 'adminShell.pages.users.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.users' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'monitoring',
|
|
loadComponent: () => import('./features/admin/monitoring/pages/admin-monitoring-page.component').then(m => m.AdminMonitoringPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.monitoring.title',
|
|
descriptionKey: 'adminShell.pages.monitoring.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.monitoring' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'analytics',
|
|
loadComponent: () => import('./features/admin/analytics/pages/admin-analytics-page.component').then(m => m.AdminAnalyticsPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.analytics.title',
|
|
descriptionKey: 'adminShell.pages.analytics.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.analytics' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'reports',
|
|
loadComponent: () => import('./features/admin/reports/pages/admin-reports-page.component').then(m => m.AdminReportsPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.reports.title',
|
|
descriptionKey: 'adminShell.pages.reports.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.reports' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'settings',
|
|
loadComponent: () => import('./features/admin/settings/pages/admin-settings-page.component').then(m => m.AdminSettingsPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.settings.title',
|
|
descriptionKey: 'adminShell.pages.settings.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.settings' }]
|
|
}
|
|
},
|
|
{
|
|
path: 'partners/seller-management',
|
|
loadComponent: () => import('./features/admin/seller-management/pages/admin-seller-management-page.component').then(m => m.AdminSellerManagementPageComponent),
|
|
data: {
|
|
titleKey: 'adminShell.pages.sellerManagement.title',
|
|
descriptionKey: 'adminShell.pages.sellerManagement.description',
|
|
breadcrumb: [{ labelKey: 'adminShell.nav.sellerManagement' }]
|
|
}
|
|
},
|
|
{ path: '**', redirectTo: 'dashboard' }
|
|
]
|
|
},
|
|
{
|
|
path: 'builder',
|
|
redirectTo: 'edit',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'project-editor',
|
|
redirectTo: 'edit',
|
|
pathMatch: 'full'
|
|
},
|
|
{
|
|
path: 'wishlist',
|
|
loadComponent: () => import('./features/website/user-experience/wishlist/containers/wishlist-page.component').then(m => m.WishlistPageComponent)
|
|
},
|
|
{
|
|
path: 'compare',
|
|
loadComponent: () => import('./features/website/user-experience/compare/containers/compare-page.component').then(m => m.ComparePageComponent)
|
|
},
|
|
{
|
|
path: 'cart',
|
|
loadComponent: () => import('./pages/cart/cart.component').then(m => m.CartComponent)
|
|
},
|
|
{
|
|
path: 'page/:key',
|
|
loadComponent: () => import('./pages/static-page/static-page.component').then(m => m.StaticPageComponent)
|
|
},
|
|
{
|
|
path: ':staticPath',
|
|
loadComponent: () => import('./pages/static-page/static-page.component').then(m => m.StaticPageComponent)
|
|
}
|
|
];
|
|
|
|
// TODO(CMS): Resolve informational/legal pages from backend content configuration here.
|
|
// Disabled hardcoded pages: about, contacts, faq, delivery, guarantee,
|
|
// company-details, payment-terms, return-policy, public-offer, privacy-policy.
|
|
const cmsContentRoutes: Routes = [];
|
|
|
|
// All routes sit under a :lang prefix (e.g. /ru/cart, /en/product/5)
|
|
export const routes: Routes = [
|
|
...(environment.production ? [] : [{
|
|
path: '__diagnostics',
|
|
loadComponent: () => import('./features/diagnostics/components/diagnostics-page.component').then(m => m.DiagnosticsPageComponent)
|
|
}]),
|
|
...authRoutes,
|
|
{
|
|
path: ':lang',
|
|
canActivate: [languageGuard],
|
|
children: [
|
|
...coreRoutes,
|
|
...cmsContentRoutes,
|
|
{ path: '**', redirectTo: '' }
|
|
]
|
|
},
|
|
// URLs without a language prefix → redirect to default language
|
|
{ path: '**', redirectTo: 'ru' }
|
|
]; |