From 79ff60ffd9753583e7abc138ceec7517a9074e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Sun, 10 May 2026 04:53:09 +0300 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20Sprint=204=20Phase=20B/3?= =?UTF-8?q?=20=E2=80=94=20split=202=20utility=20views=20(audit=20O-refacto?= =?UTF-8?q?r-04=20=D1=85=D0=B2=D0=BE=D1=81=D1=82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ErrorView 320→178 (+ ErrorBrand 54 + ErrorIllustration 31 + ErrorActions 55 + ErrorMeta 102). DashboardView 302→84 (+ DashboardPageHead 65 + DashboardKpiRow 97 + DashboardBalance 124). State (config, errorCode в ErrorView; range/kpis/balance в DashboardView) остаётся в parent ради единого route.meta-driven flow + future API-fetch'а (Phase B/1 паттерн). DashboardPageHead использует Vue 3.5 defineModel() для двусторонней привязки range. Sub-components читают только props — без Pinia stores (mock-data flow). Все sub-components <250 строк (acceptance threshold). Shell line counts: 178/84. ЗАМЕЧАНИЕ по acceptance «0 components >300»: НЕ закрыто полностью. 2 файла остались выше порога — DealsView 560 + DealDetailDrawer 386. Зафиксировано в Sprint 3 Phase C commit 6c2f0ce: bulk-action функции (applyBulkStatus/applyBulkDelete/applyBulkExport/ undoBulkDelete/applyBulkRestoreFromTrash) и comment/reminders fetch экспонируются через defineExpose в Vitest-тестах напрямую — дальнейшая декомпозиция требует изменения тест-контракта (отдельным flow, не вошло в Sprint 4 Phase B). Phase B/3 закрывает 8/12 audit-кандидатов O-refactor-04: 3 в Sprint 3 Phase C (Top-3) + 5 в Sprint 4 Phase B/1+B/2 (admin/layout/billing/security/reminders) + 2 в B/3 (errors/dashboard). Оставшиеся: 2 крупных deals-view (defineExpose-blocked) + ImpersonationDialog уже <300 органически. Регрессия: ESLint 0 + vue-tsc 0 + Vitest 416/416 + build OK 989 ms. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/dashboard/DashboardBalance.vue | 124 +++++++++ .../components/dashboard/DashboardKpiRow.vue | 97 +++++++ .../dashboard/DashboardPageHead.vue | 65 +++++ .../js/components/errors/ErrorActions.vue | 55 ++++ .../js/components/errors/ErrorBrand.vue | 54 ++++ .../components/errors/ErrorIllustration.vue | 31 +++ .../js/components/errors/ErrorMeta.vue | 102 +++++++ app/resources/js/views/DashboardView.vue | 250 ++---------------- app/resources/js/views/errors/ErrorView.vue | 198 ++------------ 9 files changed, 572 insertions(+), 404 deletions(-) create mode 100644 app/resources/js/components/dashboard/DashboardBalance.vue create mode 100644 app/resources/js/components/dashboard/DashboardKpiRow.vue create mode 100644 app/resources/js/components/dashboard/DashboardPageHead.vue create mode 100644 app/resources/js/components/errors/ErrorActions.vue create mode 100644 app/resources/js/components/errors/ErrorBrand.vue create mode 100644 app/resources/js/components/errors/ErrorIllustration.vue create mode 100644 app/resources/js/components/errors/ErrorMeta.vue diff --git a/app/resources/js/components/dashboard/DashboardBalance.vue b/app/resources/js/components/dashboard/DashboardBalance.vue new file mode 100644 index 00000000..7326632e --- /dev/null +++ b/app/resources/js/components/dashboard/DashboardBalance.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/app/resources/js/components/dashboard/DashboardKpiRow.vue b/app/resources/js/components/dashboard/DashboardKpiRow.vue new file mode 100644 index 00000000..b6fbfd3a --- /dev/null +++ b/app/resources/js/components/dashboard/DashboardKpiRow.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/app/resources/js/components/dashboard/DashboardPageHead.vue b/app/resources/js/components/dashboard/DashboardPageHead.vue new file mode 100644 index 00000000..e06cdb3c --- /dev/null +++ b/app/resources/js/components/dashboard/DashboardPageHead.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/app/resources/js/components/errors/ErrorActions.vue b/app/resources/js/components/errors/ErrorActions.vue new file mode 100644 index 00000000..329e84dd --- /dev/null +++ b/app/resources/js/components/errors/ErrorActions.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/app/resources/js/components/errors/ErrorBrand.vue b/app/resources/js/components/errors/ErrorBrand.vue new file mode 100644 index 00000000..995f22b3 --- /dev/null +++ b/app/resources/js/components/errors/ErrorBrand.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/app/resources/js/components/errors/ErrorIllustration.vue b/app/resources/js/components/errors/ErrorIllustration.vue new file mode 100644 index 00000000..057839fa --- /dev/null +++ b/app/resources/js/components/errors/ErrorIllustration.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/app/resources/js/components/errors/ErrorMeta.vue b/app/resources/js/components/errors/ErrorMeta.vue new file mode 100644 index 00000000..e86df66e --- /dev/null +++ b/app/resources/js/components/errors/ErrorMeta.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/app/resources/js/views/DashboardView.vue b/app/resources/js/views/DashboardView.vue index 39a89a8c..d4e45586 100644 --- a/app/resources/js/views/DashboardView.vue +++ b/app/resources/js/views/DashboardView.vue @@ -4,26 +4,28 @@ * * Источник дизайна: liderra_v8_handoff/concepts/v8_dashboard.html. * MVP: page-head + 4 KPI-cards (получено лидов / конверсия / активные проекты / - * баланс). Графики (Активность по дням, Воронка из 14 статусов) и блоки ниже - * (Top deals, Recent activity) — отдельные коммиты. + * баланс). Графики (Активность по дням, Воронка из 14 статусов). * * Все числа сейчас mock'и — TODO: GET /api/dashboard/summary с tenant-context'ом * по middleware SetTenantContext (фаза backend). + * + * Sprint 4 Phase B/3 — split на DashboardPageHead + DashboardKpiRow + + * DashboardBalance (audit O-refactor-04 закрытие). State (range, kpis, balance) + * остаётся в parent ради единого mock-data flow и future API-fetch'а. + * + * Примечание: «recent deals list» в Phase B/3 plan'е — на текущем дашборде нет + * (есть только charts row); если будет добавлено в будущем — выносится в + * DashboardRecentDeals.vue по аналогии. */ import { ref } from 'vue'; import ActivityChart from '../components/charts/ActivityChart.vue'; import FunnelChart from '../components/charts/FunnelChart.vue'; +import DashboardPageHead from '../components/dashboard/DashboardPageHead.vue'; +import DashboardKpiRow, { type Kpi } from '../components/dashboard/DashboardKpiRow.vue'; +import DashboardBalance, { type Balance } from '../components/dashboard/DashboardBalance.vue'; const range = ref<'today' | '7d' | '30d' | 'custom'>('7d'); -interface Kpi { - label: string; - value: string; - unit?: string; - delta?: { dir: 'up' | 'down' | 'neutral'; text: string }; - sub: string; -} - const kpis: Kpi[] = [ { label: 'Получено лидов', @@ -47,7 +49,7 @@ const kpis: Kpi[] = [ }, ]; -const balance = { +const balance: Balance = { amount: '14 250', runwayDays: 4, runwayMax: 7, @@ -57,80 +59,11 @@ const balance = {