30ef61dff8
3 view'а с >300 строк разделены на shell + sub-components: AdminTenantsView 377→155 (+ TenantsStatsHeader 82 / TenantsFilters 93 / TenantsTable 116). AdminTenantDetailView 436→109 (+ TenantDetailHeader 158 / TenantDetailTabs 176 + adminTenantDetailFormatters 43 composable). AppLayout 466→78 (+ AppSidebar 155 / AppTopbar 269; R0.6 hard-стоп снят явным запросом заказчика 10.05.2026). State (filterStatuses, tenantsState, activeTab, tenant, drawerOpen) остаётся в parent view'ах ради `defineExpose`-контракта Vitest тестов. Sub-components читают Pinia stores напрямую (auth + notifications + reminders) — без prop-drilling. AppTopbar 269 строк <300 — acceptance threshold выдержан (можно дальше split на NotificationsDropdown + UserMenu в отдельном flow, не критично). Регрессия: ESLint 0 + vue-tsc 0 + Vitest 416/416 + build OK 1.17 сек. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
/**
|
||
* Sprint 4 Phase B/1 (audit O-refactor-04 хвост): formatters для AdminTenantDetailView
|
||
* + sub-components TenantDetailHeader / TenantDetailTabs.
|
||
*/
|
||
|
||
export function formatRub(v: number): string {
|
||
if (v === 0) return '0 ₽';
|
||
const sign = v < 0 ? '−' : '';
|
||
return sign + new Intl.NumberFormat('ru-RU').format(Math.abs(v)) + ' ₽';
|
||
}
|
||
|
||
export function formatDate(iso: string): string {
|
||
return new Date(iso).toLocaleString('ru-RU', { dateStyle: 'short', timeStyle: 'short' });
|
||
}
|
||
|
||
export function statusColor(s: string): string {
|
||
if (s === 'active') return 'success';
|
||
if (s === 'trial') return 'info';
|
||
if (s === 'overdue') return 'warning';
|
||
return 'error';
|
||
}
|
||
|
||
export function txTypeLabel(t: string): string {
|
||
return (
|
||
{
|
||
topup: 'Пополнение',
|
||
lead_charge: 'Списание за лид',
|
||
refund: 'Возврат',
|
||
tariff_charge: 'Списание тарифа',
|
||
manual_adjustment: 'Ручная корректировка',
|
||
}[t] ?? t
|
||
);
|
||
}
|
||
|
||
export function txTypeColor(t: string, amount: number): string {
|
||
if (amount > 0) return 'success';
|
||
if (t === 'manual_adjustment') return 'warning';
|
||
return 'error';
|
||
}
|
||
|
||
export function roleLabel(r: string): string {
|
||
return { admin: 'Администратор', manager: 'Менеджер', reader: 'Читатель' }[r] ?? r;
|
||
}
|