This commit is contained in:
root
2026-01-08 00:47:36 +05:00
parent e1666dd523
commit 9d57e38222
3 changed files with 444 additions and 57 deletions
+431 -51
View File
@@ -117,19 +117,46 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Индекс онлайн-спроса" :value="marketDemandIndexValue" subtitle="высокий онлайн-потенциал" icon="pi-search" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Индекс онлайн-спроса"
:value="marketDemandIndexValue"
subtitle="высокий онлайн-потенциал"
icon="pi-search"
:accentColor="PPT_BLUE"
description="Коэффициент востребованности в сети (отношение текущего спроса к базисному). Показывает, насколько активен спрос на ваш продукт/услугу в цифровых каналах."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Темп изменения спроса" :value="marketYoYGrowthValue" subtitle="рост за год" icon="pi-arrow-up-right" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Темп изменения спроса"
:value="marketYoYGrowthValue"
subtitle="рост за год"
icon="pi-arrow-up-right"
:accentColor="PPT_ORANGE"
description="Процент роста спроса по сравнению с прошлым годом. Положительное значение означает рост интереса к продукту/услуге."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Коэффициент сезонности" :value="marketSeasonalityValue" :subtitle="`диапазон ${seasonalityRangeValue}`" icon="pi-calendar" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Коэффициент сезонности"
:value="marketSeasonalityValue"
:subtitle="`диапазон ${seasonalityRangeValue}`"
icon="pi-calendar"
:accentColor="PPT_GREEN"
description="Индекс активности спроса в весенний период. Например, 1.15x означает рост на 15% выше среднего. Помогает планировать маркетинговые кампании с учетом сезонности."
/>
</div>
<div class="col-span-12 lg:col-span-8">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="flex items-center justify-between gap-3 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Динамика онлайн-спроса</div>
<div class="flex items-center gap-1.5">
<div class="text-[16px] font-semibold text-slate-800">Динамика онлайн-спроса</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Массив числовых значений интереса по конкретным месяцам. Показывает сезонные колебания спроса и помогает планировать рекламные кампании.'"
></i>
</div>
<div class="text-[14px] font-semibold text-green-700">{{ marketYoYGrowthValue }}</div>
</div>
<div class="h-[260px]">
@@ -140,16 +167,46 @@
<div class="col-span-12 lg:col-span-4">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">География онлайн-интереса за год</div>
<div class="rounded-xl border border-dashed border-slate-300 bg-slate-50/70 px-4 py-6 text-center text-slate-500">
<div class="text-sm">{{ report?.sections?.market_overview?.geography }}</div>
<div class="mt-4 flex items-center justify-center gap-3 text-[12px]">
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">География онлайн-интереса за год</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Список приоритетных регионов, где зафиксирован наибольший спрос. Помогает определить географию для фокусировки маркетинговых усилий.'"
></i>
</div>
<div v-if="geographyRows.length > 0" class="space-y-3">
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="divide-y divide-slate-200/70">
<div v-for="(row, idx) in geographyRows" :key="row.city" class="px-4 py-3">
<div class="flex items-center justify-between gap-3 mb-2">
<div class="flex items-center gap-2">
<div class="h-2 w-2 rounded-full" :style="{ background: getGeographyColor(row.percentage, idx) }"></div>
<div class="text-[14px] font-medium text-slate-800">{{ row.city }}</div>
</div>
<div class="text-[14px] font-semibold text-slate-800">{{ row.value }}</div>
</div>
<div class="h-2.5 rounded-full bg-slate-200/70 overflow-hidden">
<div
class="h-full rounded-full transition-all duration-500"
:style="{
width: `${row.percentage}%`,
background: getGeographyGradient(row.percentage, idx)
}"
></div>
</div>
</div>
</div>
</div>
<div class="flex items-center justify-center gap-3 text-[12px] text-slate-500">
<span class="inline-flex items-center gap-2">
<span class="h-2.5 w-10 rounded-full" style="background: linear-gradient(90deg, #ff8e4f, #52c41a)"></span>
<span>Высокий Низкий</span>
</span>
</div>
</div>
<div v-else class="rounded-xl border border-dashed border-slate-300 bg-slate-50/70 px-4 py-6 text-center text-slate-500">
<div class="text-sm">Нет данных</div>
</div>
</div>
</div>
@@ -165,18 +222,45 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Размер аудитории" :value="audienceTotalValue" subtitle="высокий онлайн-потенциал" icon="pi-users" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Размер аудитории"
:value="audienceTotalValue"
subtitle="высокий онлайн-потенциал"
icon="pi-users"
:accentColor="PPT_BLUE"
description="Оценочное количество потенциальных клиентов в выбранных регионах. Помогает оценить масштаб рынка и потенциал для роста."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Лидирующий сегмент" :value="audienceLeadingSegmentValue" subtitle="рост за год" icon="pi-user" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Лидирующий сегмент"
:value="audienceLeadingSegmentValue"
subtitle="рост за год"
icon="pi-user"
:accentColor="PPT_ORANGE"
description="Название самого активного или многочисленного сегмента. Показывает, на какую группу потребителей стоит фокусировать маркетинговый бюджет."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Доход" :value="audienceIncomeAboveAvgText" subtitle="доход выше среднего" icon="pi-wallet" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Доход"
:value="audienceIncomeAboveAvgText"
subtitle="доход выше среднего"
icon="pi-wallet"
:accentColor="PPT_GREEN"
description="Процент аудитории с уровнем дохода «выше среднего». Показывает платёжеспособность целевой аудитории."
/>
</div>
<div class="col-span-12 lg:col-span-5">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">Сегменты аудитории для рекламы</div>
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Сегменты аудитории для рекламы</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Массив ключевых групп потребителей с указанием их названия и процентной доли в общей массе. Помогает определить приоритетные сегменты для таргетинга.'"
></i>
</div>
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
@@ -202,7 +286,13 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Возрастная структура</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Возрастная структура</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Процентное распределение аудитории по возрастным категориям (от 18 до 55+). Помогает адаптировать рекламные сообщения под возрастные группы.'"
></i>
</div>
<div class="h-[240px]">
<Chart type="bar" :data="ageBarData" :options="compactBarOptions" />
</div>
@@ -210,7 +300,13 @@
</div>
<div class="col-span-12">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Доход и платёжеспособность</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Доход и платёжеспособность</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Распределение аудитории по уровню дохода. Показывает, какая доля аудитории имеет доход выше среднего и может позволить себе ваш продукт/услугу.'"
></i>
</div>
<div class="h-[220px]">
<Chart type="bar" :data="incomeBarData" :options="compactBarOptions" />
</div>
@@ -231,19 +327,46 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Ваш рынок (доля трафика)" :value="competitionMarketShareValue" subtitle="" icon="pi-sitemap" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Ваш рынок (доля трафика)"
:value="competitionMarketShareValue"
subtitle=""
icon="pi-sitemap"
:accentColor="PPT_BLUE"
description="Оценочная доля онлайн-трафика, которую занимает текущий бизнес. Показывает вашу позицию на рынке относительно общего объема трафика в нише."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Место в видимости" :value="competitionRankValue" subtitle="" icon="pi-chart-bar" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Место в видимости"
:value="competitionRankValue"
subtitle=""
icon="pi-chart-bar"
:accentColor="PPT_GREEN"
description="Позиция бренда в поисковой выдаче и рекламных каналах относительно конкурентов. Чем ниже число, тем выше позиция."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Доля конкурентов в контекстной рекламе" :value="competitionCompetitorShareValue" :subtitle="`Бенчмарк (Астана) ${competitionBenchmarkValue}`" icon="pi-wallet" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Доля конкурентов в контекстной рекламе"
:value="competitionCompetitorShareValue"
:subtitle="`Бенчмарк (Астана) ${competitionBenchmarkValue}`"
icon="pi-wallet"
:accentColor="PPT_ORANGE"
description="Активность конкурентов в платной рекламе. Показывает уровень конкуренции в контекстной рекламе и необходимость инвестиций в этот канал."
/>
</div>
<div class="col-span-12 lg:col-span-7">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="flex items-center justify-between gap-3 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Digital-видимость: топ конкурентов</div>
<div class="flex items-center gap-1.5">
<div class="text-[16px] font-semibold text-slate-800">Digital-видимость: топ конкурентов</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Сравнительный индекс видимости (баллы от 0 до 100) для вашего бизнеса и конкурентов. Показывает, насколько хорошо вы заметны в цифровых каналах по сравнению с конкурентами.'"
></i>
</div>
<div class="text-[12px] text-slate-500">Бенчмарк</div>
</div>
<div class="h-[280px]">
@@ -253,7 +376,13 @@
</div>
<div class="col-span-12 lg:col-span-5">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">Ключевые сильные стороны основных конкурентов</div>
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Ключевые сильные стороны основных конкурентов</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Список конкретных преимуществ для каждого игрока рынка (включая ваш бизнес). Помогает понять конкурентные преимущества и слабые места.'"
></i>
</div>
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
<div class="col-span-5 px-3 py-2">Конкурент</div>
@@ -284,18 +413,45 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Поиск в Яндекс/Google" :value="behaviorSearchGrowthValue" subtitle="" icon="pi-search" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Поиск в Яндекс/Google"
:value="behaviorSearchGrowthValue"
subtitle=""
icon="pi-search"
:accentColor="PPT_BLUE"
description="Динамика роста поисковых запросов в нише. Показывает, растет ли интерес к продукту/услуге в поисковых системах."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Взаимодействия до покупки" :value="behaviorInteractionsValue" subtitle="" icon="pi-send" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Взаимодействия до покупки"
:value="behaviorInteractionsValue"
subtitle=""
icon="pi-send"
:accentColor="PPT_ORANGE"
description="Среднее количество касаний (визитов, кликов), необходимых клиенту для принятия решения. Помогает понять длину пути клиента и необходимое количество контактов."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Вероятность повторного отказа" :value="behaviorRepeatRefusalValue" subtitle="" icon="pi-refresh" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Вероятность повторного отказа"
:value="behaviorRepeatRefusalValue"
subtitle=""
icon="pi-refresh"
:accentColor="PPT_GREEN"
description="Вероятность того, что клиент не вернется после первого опыта. Высокое значение указывает на проблемы с качеством сервиса или продукта."
/>
</div>
<div class="col-span-12 lg:col-span-5">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Типы поисковых запросов</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Типы поисковых запросов</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Структура запросов: каталожные, информационные, брендовые. Показывает, как пользователи ищут ваш продукт/услугу и какие типы контента им нужны.'"
></i>
</div>
<div class="h-[260px]">
<Chart type="doughnut" :data="queryTypesDonutData" :options="compactDonutOptions" />
</div>
@@ -305,7 +461,13 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Факторы принятия решения</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Факторы принятия решения</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Что важнее всего для клиента при выборе: Цена, Отзывы, Сервис и т.д. Помогает понять приоритеты клиентов и адаптировать оффер.'"
></i>
</div>
<div class="h-[220px]">
<Chart type="bar" :data="decisionFactorsBarData" :options="compactBarOptions" />
</div>
@@ -313,7 +475,13 @@
</div>
<div class="col-span-12">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Причины отказов</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Причины отказов</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Барьеры, которые мешают завершить покупку (например, «непонятный оффер», высокая цена, отсутствие отзывов). Помогает выявить и устранить препятствия на пути к конверсии.'"
></i>
</div>
<div class="h-[200px]">
<Chart type="bar" :data="refusalReasonsBarData" :options="compactBarOptions" />
</div>
@@ -334,21 +502,52 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Конверсия лид → запись" :value="report?.sections?.customer_journey?.conversion_rates?.lead_to_booking" subtitle="" icon="pi-comments" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Конверсия лид → запись"
:value="report?.sections?.customer_journey?.conversion_rates?.lead_to_booking"
subtitle=""
icon="pi-comments"
:accentColor="PPT_BLUE"
description="Процент перехода от лида к записи. Показывает эффективность работы отдела продаж на этапе конверсии лида в клиента."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Конверсия запись → оплата" :value="report?.sections?.customer_journey?.conversion_rates?.booking_to_payment" subtitle="" icon="pi-comment" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Конверсия запись → оплата"
:value="report?.sections?.customer_journey?.conversion_rates?.booking_to_payment"
subtitle=""
icon="pi-comment"
:accentColor="PPT_ORANGE"
description="Процент перехода от записи к оплате. Показывает, сколько клиентов, сделавших запись, завершают покупку."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Конверсия лид → оплата" :value="report?.sections?.customer_journey?.conversion_rates?.lead_to_payment_total" subtitle="" icon="pi-wallet" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Конверсия лид → оплата"
:value="report?.sections?.customer_journey?.conversion_rates?.lead_to_payment_total"
subtitle=""
icon="pi-wallet"
:accentColor="PPT_ORANGE"
description="Общая конверсия от лида до оплаты. Показывает эффективность всей воронки продаж от первого контакта до завершения сделки."
/>
</div>
<div class="col-span-12 lg:col-span-8">
<PptFunnel :steps="pptFunnelSteps" title="Потери на воронке" />
<PptFunnel
:steps="pptFunnelSteps"
title="Потери на воронке"
description="Абсолютные показатели воронки: сколько человек пришло с рекламы, сколько стали лидами, сколько купили. Визуализирует потери клиентов на каждом этапе."
/>
</div>
<div class="col-span-12 lg:col-span-4">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">Основные проблемы на воронке</div>
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Основные проблемы на воронке</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Текстовая расшифровка причин потерь клиентов на каждом этапе. Помогает понять, где именно теряются клиенты и что нужно исправить.'"
></i>
</div>
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
<div class="col-span-5 px-3 py-2">Этап</div>
@@ -380,18 +579,45 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Доля поискового трафика" :value="channelsSearchShareValue" subtitle="" icon="pi-search" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Доля поискового трафика"
:value="channelsSearchShareValue"
subtitle=""
icon="pi-search"
:accentColor="PPT_BLUE"
description="Процент клиентов, приходящих из поисковых систем. Показывает важность SEO и контекстной рекламы для вашего бизнеса."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Средняя стоимость лида" :value="channelsLeadCostValue" subtitle="" icon="pi-chart-bar" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Средняя стоимость лида"
:value="channelsLeadCostValue"
subtitle=""
icon="pi-chart-bar"
:accentColor="PPT_GREEN"
description="Средняя стоимость одного лида (CPL) в валюте региона. Помогает оценить эффективность инвестиций в маркетинг и сравнить каналы."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Потенциал каналов к росту" :value="channelsGrowthPotentialValue" subtitle="" icon="pi-arrow-up-right" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Потенциал каналов к росту"
:value="channelsGrowthPotentialValue"
subtitle=""
icon="pi-arrow-up-right"
:accentColor="PPT_ORANGE"
description="Оценка возможности роста в различных каналах привлечения. Помогает определить, в какие каналы стоит инвестировать больше."
/>
</div>
<div class="col-span-12 lg:col-span-7">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-2">Доли каналов</div>
<div class="flex items-center gap-1.5 mb-2">
<div class="text-[16px] font-semibold text-slate-800">Доли каналов</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Процентное распределение трафика/бюджета по источникам (SEO, Instagram, Контекст). Показывает, какие каналы приносят больше всего клиентов.'"
></i>
</div>
<div class="h-[280px]">
<Chart type="bar" :data="channelSharesBarData" :options="channelSharesBarOptions" />
</div>
@@ -399,7 +625,13 @@
</div>
<div class="col-span-12 lg:col-span-5">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">Стоимость привлечения</div>
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Стоимость привлечения</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Детальная оценка каждого канала: стоимость привлечения (cost) и качественный статус (status: Эффективный, Средний, Низкий). Помогает оптимизировать распределение бюджета.'"
></i>
</div>
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
<div class="col-span-5 px-3 py-2">Канал</div>
@@ -429,27 +661,60 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Стоимость клиента" :value="cacValue" subtitle="" icon="pi-wallet" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Стоимость клиента"
:value="cacValue"
subtitle=""
icon="pi-wallet"
:accentColor="PPT_BLUE"
description="Стоимость привлечения одного платящего клиента (CAC). Рассчитывается как отношение маркетинговых расходов к количеству новых клиентов. Показывает эффективность маркетинговых инвестиций."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Конверсия в повторные продажи" :value="repeatSalesConversionValue" subtitle="" icon="pi-refresh" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Конверсия в повторные продажи"
:value="repeatSalesConversionValue"
subtitle=""
icon="pi-refresh"
:accentColor="PPT_GREEN"
description="Доля клиентов, совершающих вторую и последующие покупки. Показывает эффективность удержания клиентов и потенциал для увеличения LTV (lifetime value)."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Возврат инвестиций в маркетинг" :value="roiValue" subtitle="" icon="pi-chart-line" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Возврат инвестиций в маркетинг"
:value="roiValue"
subtitle=""
icon="pi-chart-line"
:accentColor="PPT_ORANGE"
description="Коэффициент возврата инвестиций (ROI). Показывает, во сколько раз выручка превышает вложения в маркетинг. Рассчитывается как (Прибыль / Инвестиции) × 100%."
/>
</div>
<div class="col-span-12">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4">
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-3">
<div class="rounded-xl border border-slate-200/70 bg-slate-50/70 p-3">
<div class="text-[12px] font-semibold text-slate-500">CAC</div>
<div class="flex items-center gap-1.5">
<div class="text-[12px] font-semibold text-slate-500">CAC</div>
<i
class="pi pi-question-circle text-[10px] text-slate-400 cursor-help"
v-tooltip.top="'Customer Acquisition Cost - стоимость привлечения одного нового клиента. Рассчитывается как: Маркетинговые расходы / Количество новых клиентов.'"
></i>
</div>
<div class="mt-2 katex-box" v-html="cacKatex"></div>
<div class="mt-2 text-[12px] text-slate-600">
Значение: <span class="font-semibold text-slate-800">{{ cacValue }}</span>
</div>
</div>
<div class="rounded-xl border border-slate-200/70 bg-slate-50/70 p-3">
<div class="text-[12px] font-semibold text-slate-500">ROI</div>
<div class="flex items-center gap-1.5">
<div class="text-[12px] font-semibold text-slate-500">ROI</div>
<i
class="pi pi-question-circle text-[10px] text-slate-400 cursor-help"
v-tooltip.top="'Return on Investment - возврат инвестиций. Рассчитывается как: (Прибыль / Инвестиции) × 100%. Показывает эффективность маркетинговых вложений.'"
></i>
</div>
<div class="mt-2 katex-box" v-html="roiKatex"></div>
<div class="mt-2 text-[12px] text-slate-600">
Значение: <span class="font-semibold text-slate-800">{{ roiValue }}</span>
@@ -471,7 +736,13 @@
<div class="col-span-12 lg:col-span-7">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 h-full">
<div class="text-[16px] font-semibold text-slate-800 mb-3">Основные показатели</div>
<div class="flex items-center gap-1.5 mb-3">
<div class="text-[16px] font-semibold text-slate-800">Основные показатели</div>
<i
class="pi pi-question-circle text-[12px] text-slate-400 cursor-help"
v-tooltip.top="'Сравнение расходов, количества клиентов, CAC, выручки и прибыли в разрезе Месяц против Год. Показывает динамику ключевых финансовых метрик.'"
></i>
</div>
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
<div class="col-span-6 px-3 py-2">Показатель</div>
@@ -520,13 +791,34 @@
<div class="grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Проблемы на лендингах" :value="bottlenecksLandingIssuesValue" subtitle="" icon="pi-exclamation-triangle" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Проблемы на лендингах"
:value="bottlenecksLandingIssuesValue"
subtitle=""
icon="pi-exclamation-triangle"
:accentColor="PPT_BLUE"
description="Процентное влияние проблем на лендингах (сайтах). Показывает, насколько сильно проблемы с сайтом мешают конверсии клиентов."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Медленные ответы менеджеров" :value="bottlenecksSlowResponsesValue" subtitle="" icon="pi-refresh" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Медленные ответы менеджеров"
:value="bottlenecksSlowResponsesValue"
subtitle=""
icon="pi-refresh"
:accentColor="PPT_GREEN"
description="Процентное влияние медленных ответов менеджеров на потери клиентов. Показывает важность скорости обработки лидов отделом продаж."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Отказ на повторных касаниях" :value="bottlenecksRepeatRefusalValue" subtitle="" icon="pi-plus" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Отказ на повторных касаниях"
:value="bottlenecksRepeatRefusalValue"
subtitle=""
icon="pi-plus"
:accentColor="PPT_ORANGE"
description="Процентное влияние проблем с удержанием клиентов. Показывает, насколько сильно проблемы с ретеншном мешают повторным продажам."
/>
</div>
<div class="col-span-12">
@@ -538,7 +830,13 @@
<div class="h-8 w-8 rounded-xl flex items-center justify-center" :style="{ background: 'rgba(91,137,255,0.14)', color: PPT_BLUE }">
<i class="pi pi-cog"></i>
</div>
<div class="text-[15px] font-semibold text-slate-800">Лендинг</div>
<div class="flex items-center gap-1.5">
<div class="text-[15px] font-semibold text-slate-800">Лендинг</div>
<i
class="pi pi-question-circle text-[11px] text-slate-400 cursor-help"
v-tooltip.top="'Конкретные списки недоработок на сайте/лендинге. Показывает проблемы, которые мешают конверсии посетителей в клиентов.'"
></i>
</div>
</div>
<ul class="list-disc pl-5 space-y-2 text-[13px] text-slate-600">
<li v-for="t in bottlenecksDetails.landing" :key="t">{{ t }}</li>
@@ -551,7 +849,13 @@
<div class="h-8 w-8 rounded-xl flex items-center justify-center" :style="{ background: 'rgba(255,142,79,0.16)', color: PPT_ORANGE }">
<i class="pi pi-clock"></i>
</div>
<div class="text-[15px] font-semibold text-slate-800">Работа с лидами</div>
<div class="flex items-center gap-1.5">
<div class="text-[15px] font-semibold text-slate-800">Работа с лидами</div>
<i
class="pi pi-question-circle text-[11px] text-slate-400 cursor-help"
v-tooltip.top="'Конкретные списки недоработок в отделе продаж (Lead Management). Показывает проблемы в обработке лидов и работе с потенциальными клиентами.'"
></i>
</div>
</div>
<ul class="list-disc pl-5 space-y-2 text-[13px] text-slate-600">
<li v-for="t in bottlenecksDetails.lead_management" :key="t">{{ t }}</li>
@@ -564,7 +868,13 @@
<div class="h-8 w-8 rounded-xl flex items-center justify-center" :style="{ background: 'rgba(255,107,107,0.14)', color: '#FF6B6B' }">
<i class="pi pi-chart-pie"></i>
</div>
<div class="text-[15px] font-semibold text-slate-800">Ретеншн</div>
<div class="flex items-center gap-1.5">
<div class="text-[15px] font-semibold text-slate-800">Ретеншн</div>
<i
class="pi pi-question-circle text-[11px] text-slate-400 cursor-help"
v-tooltip.top="'Конкретные списки недоработок в удержании клиентов (Retention). Показывает проблемы, которые мешают повторным покупкам и долгосрочным отношениям с клиентами.'"
></i>
</div>
</div>
<ul class="list-disc pl-5 space-y-2 text-[13px] text-slate-600">
<li v-for="t in bottlenecksDetails.retention" :key="t">{{ t }}</li>
@@ -585,18 +895,47 @@
<section class="space-y-3">
<div class="rounded-2xl bg-white shadow-sm border border-slate-200/60 p-4 md:p-6">
<div class="text-[13px] text-slate-500 mb-1">Маркетинг <span class="mx-1"></span> Рекомендации</div>
<div class="text-3xl font-semibold tracking-wide text-center text-slate-800">РЕКОМЕНДАЦИИ</div>
<div class="flex items-center justify-center gap-2">
<div class="text-3xl font-semibold tracking-wide text-center text-slate-800">РЕКОМЕНДАЦИИ</div>
<i
class="pi pi-question-circle text-[14px] text-slate-400 cursor-help"
v-tooltip.top="
'Массив ключевых стратегий развития. Каждая содержит название направления (например, «Оптимизация сайта») и конкретное описание действий для реализации. Финальный прогноз эффективности при условии внедрения рекомендаций.'
"
></i>
</div>
<div class="text-center text-slate-500 text-sm mt-1">итоги маркетингового анализа для интернет-продвижения</div>
<div class="mt-6 grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Стоимость клиента" :value="cacValue" subtitle="" icon="pi-wallet" :accentColor="PPT_BLUE" />
<PptKpiCard
title="Стоимость клиента"
:value="cacValue"
subtitle=""
icon="pi-wallet"
:accentColor="PPT_BLUE"
description="Стоимость привлечения одного платящего клиента (CAC). Рассчитывается как отношение маркетинговых расходов к количеству новых клиентов."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Конверсия в повторные продажи" :value="repeatSalesConversionValue" subtitle="" icon="pi-refresh" :accentColor="PPT_GREEN" />
<PptKpiCard
title="Конверсия в повторные продажи"
:value="repeatSalesConversionValue"
subtitle=""
icon="pi-refresh"
:accentColor="PPT_GREEN"
description="Доля клиентов, совершающих вторую и последующие покупки. Показывает эффективность удержания клиентов."
/>
</div>
<div class="col-span-12 md:col-span-4">
<PptKpiCard title="Возврат инвестиций" :value="roiValue" subtitle="" icon="pi-chart-line" :accentColor="PPT_ORANGE" />
<PptKpiCard
title="Возврат инвестиций"
:value="roiValue"
subtitle=""
icon="pi-chart-line"
:accentColor="PPT_ORANGE"
description="Коэффициент возврата инвестиций (ROI). Показывает, во сколько раз выручка превышает вложения в маркетинг."
/>
</div>
<div class="col-span-12 grid grid-cols-12 gap-4">
@@ -968,6 +1307,47 @@ const segmentRows = computed(() => {
.sort((a, b) => b.value - a.value);
});
// Geography rows
const geographyRows = computed(() => {
const geo = report.value?.sections?.market_overview?.geography ?? {};
if (typeof geo !== 'object' || geo === null) return [];
const entries = Object.entries(geo)
.map(([city, value]) => ({
city: String(city),
value: typeof value === 'number' ? value : Number(String(value).replace(/[^\d.]/g, '')) || 0
}))
.filter((item) => item.value > 0)
.sort((a, b) => b.value - a.value);
if (entries.length === 0) return [];
const maxValue = entries[0].value;
return entries.map((item) => ({
...item,
percentage: maxValue > 0 ? Math.round((item.value / maxValue) * 100) : 0
}));
});
// Geography color helpers
function getGeographyColor(percentage, index) {
// High values (orange/red) -> Low values (green)
if (percentage >= 80) return '#ff8e4f';
if (percentage >= 60) return '#ffa366';
if (percentage >= 40) return '#ffb880';
if (percentage >= 20) return '#7dd87d';
return '#52c41a';
}
function getGeographyGradient(percentage, index) {
const color = getGeographyColor(percentage, index);
// Create a subtle gradient from the color to a lighter version
if (percentage >= 60) {
return `linear-gradient(90deg, ${color}, ${color}dd)`;
}
return `linear-gradient(90deg, ${color}, ${color}aa)`;
}
// Competitive: visibility horizontal bar
const comparisonRows = computed(() => {
const bench = report.value?.sections?.competitive_environment?.digital_visibility_benchmarks ?? {};