@fayz-ai/plugin-marketing 0.13.1 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +146 -3
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/views/GapScreens.d.ts +14 -0
- package/dist/views/GapScreens.d.ts.map +1 -0
- package/dist/views/MarketingPage.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React9, { useState, useEffect, useMemo, useCallback } from 'react';
|
|
2
2
|
import { connectionSettings, connectionStatus, settingsStatus, createConnectionStore, getActiveTenantId, registerTranslations, createSafeDataProvider, getSupabaseClientOptional, countByTenant, useTranslation, useDataChanged, resolveDataProvider } from '@fayz-ai/core';
|
|
3
3
|
import { createPluginContext, fayzConnectorOAuth, PluginSettingsPanel, useModuleNavigation, createViewRouter, ModuleActionBar, SettingsGroup, SelectRow, ToggleRow, askAI, PageActions, useLimitGuard, useOrganizationStore, CrudFormPage, RightRailPage, invalidateLimit, CrudListView } from '@fayz-ai/admin';
|
|
4
|
-
import { defineKpiWidget, defineCustomWidget, defineTableWidget, ModulePage, PageToolbar, DataTable, SubpageHeader, RowActions, PageHeaderActions, Button, Skeleton, ConfirmDialog, ContentSplit, ContentSplitTrigger, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, MarkdownEditor, DashboardCanvas, RangeControl, cn, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, SegmentedControl, ModalFooter, SheetBody, Badge, SheetFooter, SelectSeparator, Checkbox, toast, KpiCard as KpiCard$1, Card, CardHeader, CardTitle, CardContent, TableWidget } from '@fayz-ai/ui';
|
|
4
|
+
import { defineKpiWidget, defineCustomWidget, defineTableWidget, ModulePage, PageToolbar, DataTable, SubpageHeader, RowActions, PageHeaderActions, Button, Skeleton, ConfirmDialog, ContentSplit, ContentSplitTrigger, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, MarkdownEditor, ComingSoon, DashboardCanvas, RangeControl, cn, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, SegmentedControl, ModalFooter, SheetBody, Badge, SheetFooter, SelectSeparator, Checkbox, toast, KpiCard as KpiCard$1, Card, CardHeader, CardTitle, CardContent, TableWidget } from '@fayz-ai/ui';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { History, CheckCircle2, AlertCircle, ChevronRight, Users, Target, Percent, DollarSign, Trash2, WandSparkles, SlidersHorizontal, Workflow, ExternalLink, Sparkles, Pencil, Plus, Layers, MousePointerClick, NotebookPen, ArrowUpRight, ArrowDownRight, Send, Megaphone, Settings2, Columns3, CalendarDays, List, ChevronLeft, Loader2, ImagePlus, X, Bike, Utensils, DoorOpen, MessageCircle, Instagram, Mail, Globe, Search, Link2, AtSign, Pin, Twitter, Linkedin, Facebook, Youtube, Music2, Repeat2, Heart, BarChart2, Share2, ThumbsUp, MoreHorizontal, Bookmark, GripVertical, Image, Trophy } from 'lucide-react';
|
|
7
7
|
import { createStore } from 'zustand/vanilla';
|
|
@@ -30,6 +30,97 @@ function OverviewView() {
|
|
|
30
30
|
}
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
|
+
function SegmentsView() {
|
|
34
|
+
return /* @__PURE__ */ jsx(
|
|
35
|
+
ComingSoon,
|
|
36
|
+
{
|
|
37
|
+
title: "Segmentos",
|
|
38
|
+
summary: "Recortes salvos da base \u2014 \xABquem comprou nos \xFAltimos 90 dias\xBB, \xABquem nunca voltou\xBB, \xABquem gasta acima de X\xBB \u2014 para a campanha falar com um grupo e n\xE3o com todo mundo.",
|
|
39
|
+
v1Path: "Marketing \u2192 Segmenta\xE7\xE3o \u2192 Segmentos de Clientes",
|
|
40
|
+
measured: "65 segmentos no V1 e 8 da Artorius. \xC9 o que ela mais tem de marketing \u2014 e o que mais falta aqui.",
|
|
41
|
+
missing: [
|
|
42
|
+
"O construtor de recorte: campo, operador, valor \u2014 e a contagem ao vivo de quantos caem nele",
|
|
43
|
+
"O segmento tem de ser DIN\xC2MICO (recalcula ao usar) ou congelado por escolha, e a diferen\xE7a precisa ficar clara na tela",
|
|
44
|
+
"Ligar o segmento \xE0 campanha \xE9 o que d\xE1 sentido aos dois"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
function MessageTemplatesView() {
|
|
50
|
+
return /* @__PURE__ */ jsx(
|
|
51
|
+
ComingSoon,
|
|
52
|
+
{
|
|
53
|
+
title: "Modelos de mensagem",
|
|
54
|
+
summary: "O texto pronto que a campanha usa, com os campos que se trocam por nome, data ou valor na hora do envio.",
|
|
55
|
+
v1Path: "Marketing \u2192 Campanhas \u2192 Modelos de Mensagem",
|
|
56
|
+
measured: "43 modelos no V1, nenhum da Artorius. Existe tamb\xE9m `whatsapp_templates`, que \xE9 outra coisa: o modelo APROVADO pela Meta.",
|
|
57
|
+
missing: [
|
|
58
|
+
"As vari\xE1veis e a pr\xE9-visualiza\xE7\xE3o com dado real \u2014 modelo sem pr\xE9via erra em produ\xE7\xE3o",
|
|
59
|
+
"Separar o modelo livre (e-mail, SMS) do modelo aprovado pela Meta (WhatsApp): as regras s\xE3o outras"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
function SendHistoryView() {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
ComingSoon,
|
|
67
|
+
{
|
|
68
|
+
title: "Hist\xF3rico de envios",
|
|
69
|
+
summary: "O que saiu, para quem, quando, e o que aconteceu depois \u2014 entregue, lido, respondido, recusado.",
|
|
70
|
+
v1Path: "Marketing \u2192 Hist\xF3rico de Envios",
|
|
71
|
+
measured: "Vista de leitura no V1 sobre a fila de mensagens.",
|
|
72
|
+
missing: [
|
|
73
|
+
"O evento por destinat\xE1rio, e n\xE3o s\xF3 o total da campanha \u2014 \xE9 onde se descobre que metade da lista tem n\xFAmero errado",
|
|
74
|
+
"O recusado tem de virar regra: quem pediu para n\xE3o receber n\xE3o pode entrar na pr\xF3xima"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
function QuickTriggersView() {
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
ComingSoon,
|
|
82
|
+
{
|
|
83
|
+
title: "Gatilhos r\xE1pidos",
|
|
84
|
+
summary: "O disparo de uma mensagem quando algo acontece \u2014 anivers\xE1rio, primeira compra, sumi\xE7o \u2014 sem montar uma campanha inteira para isso.",
|
|
85
|
+
v1Path: "Marketing \u2192 Gatilhos R\xE1pidos",
|
|
86
|
+
measured: "No V1 \xE9 um atalho para automa\xE7\xF5es j\xE1 prontas, e n\xE3o um cadastro pr\xF3prio.",
|
|
87
|
+
missing: [
|
|
88
|
+
"As Cad\xEAncias daqui j\xE1 fazem a parte dif\xEDcil; falta a porta de um clique",
|
|
89
|
+
"Os aniversariantes do CRM s\xE3o o primeiro gatilho \xF3bvio, e os dois agora est\xE3o no mesmo menu"
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function BrandView() {
|
|
95
|
+
return /* @__PURE__ */ jsx(
|
|
96
|
+
ComingSoon,
|
|
97
|
+
{
|
|
98
|
+
title: "Marca",
|
|
99
|
+
summary: "As cores, as fontes e o logotipo da casa num lugar s\xF3 \u2014 para a pe\xE7a sair com a cara certa sem ningu\xE9m procurar o arquivo.",
|
|
100
|
+
v1Path: "Marketing \u2192 Marca",
|
|
101
|
+
measured: "6 kits de marca no V1 e UM da Artorius. Ela j\xE1 tem a identidade cadastrada l\xE1.",
|
|
102
|
+
missing: [
|
|
103
|
+
"O kit tem cores, gradientes, fontes e arquivos: s\xE3o quatro tabelas no V1, n\xE3o um formul\xE1rio",
|
|
104
|
+
"As Configura\xE7\xF5es daqui j\xE1 guardam a cor e o logotipo do tenant \u2014 decidir se este \xE9 o mesmo lugar antes de criar o segundo"
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
function AuthorizedImagesView() {
|
|
110
|
+
return /* @__PURE__ */ jsx(
|
|
111
|
+
ComingSoon,
|
|
112
|
+
{
|
|
113
|
+
title: "Imagens autorizadas",
|
|
114
|
+
summary: "As fotos que a casa PODE usar: quem aparece nelas assinou a autoriza\xE7\xE3o, e o prazo dela ainda n\xE3o venceu.",
|
|
115
|
+
v1Path: "Marketing \u2192 Imagens autorizadas",
|
|
116
|
+
measured: "No V1 vive junto do cadastro do cliente, onde a autoriza\xE7\xE3o \xE9 dada.",
|
|
117
|
+
missing: [
|
|
118
|
+
"A autoriza\xE7\xE3o \xE9 jur\xEDdica e tem prazo \u2014 o que falta n\xE3o \xE9 a galeria, \xE9 a data de validade e o pedido",
|
|
119
|
+
"Usar foto de cliente sem isso \xE9 risco real, e \xE9 por isso que a tela existe"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
}
|
|
33
124
|
|
|
34
125
|
// src/lib/format.ts
|
|
35
126
|
var DEFAULT_CURRENCY = { code: "USD", locale: "en-US", symbol: "$" };
|
|
@@ -2888,13 +2979,34 @@ function buildNav(config, view, navigate, hasCadenceSurface, t) {
|
|
|
2888
2979
|
});
|
|
2889
2980
|
}
|
|
2890
2981
|
if (config.modules.campaigns) {
|
|
2891
|
-
items.push({
|
|
2982
|
+
items.push({
|
|
2983
|
+
id: "campaigns",
|
|
2984
|
+
label: config.labels.campaigns ?? t("marketing.nav.campaigns"),
|
|
2985
|
+
icon: "Megaphone",
|
|
2986
|
+
active: ["campaigns", "message-templates", "send-history"].includes(view),
|
|
2987
|
+
children: [
|
|
2988
|
+
{ id: "campaigns", label: config.labels.campaigns ?? t("marketing.nav.campaigns"), defaultChild: true, active: view === "campaigns", onClick: () => navigate("campaigns") },
|
|
2989
|
+
{ id: "message-templates", label: t("marketing.nav.messageTemplates"), active: view === "message-templates", onClick: () => navigate("message-templates") },
|
|
2990
|
+
{ id: "send-history", label: t("marketing.nav.sendHistory"), active: view === "send-history", onClick: () => navigate("send-history") }
|
|
2991
|
+
]
|
|
2992
|
+
});
|
|
2993
|
+
items.push({ id: "segments", label: t("marketing.nav.segments"), icon: "Users", active: view === "segments", onClick: () => navigate("segments") });
|
|
2892
2994
|
}
|
|
2893
2995
|
if (config.modules.funnel) {
|
|
2894
2996
|
items.push({ id: "funnel", label: config.labels.funnel ?? t("marketing.nav.funnel"), icon: "Filter", active: view === "funnel", onClick: () => navigate("funnel") });
|
|
2895
2997
|
}
|
|
2896
2998
|
if (config.modules.cadences && hasCadenceSurface) {
|
|
2897
|
-
items.push({
|
|
2999
|
+
items.push({
|
|
3000
|
+
id: "cadences",
|
|
3001
|
+
label: config.labels.cadences ?? t("marketing.cadences.title"),
|
|
3002
|
+
icon: "Workflow",
|
|
3003
|
+
active: view === "cadences" || view === "quick-triggers",
|
|
3004
|
+
children: [
|
|
3005
|
+
{ id: "cadences", label: config.labels.cadences ?? t("marketing.cadences.title"), defaultChild: true, active: view === "cadences", onClick: () => navigate("cadences") },
|
|
3006
|
+
// O gatilho é a cadência de um passo só, com a porta de um clique.
|
|
3007
|
+
{ id: "quick-triggers", label: t("marketing.nav.quickTriggers"), active: view === "quick-triggers", onClick: () => navigate("quick-triggers") }
|
|
3008
|
+
]
|
|
3009
|
+
});
|
|
2898
3010
|
}
|
|
2899
3011
|
if (config.modules.landingPages) {
|
|
2900
3012
|
items.push({ id: "landing-pages", label: config.labels.landingPages ?? t("marketing.nav.landingPages"), icon: "LayoutTemplate", active: view === "landing-pages", onClick: () => navigate("landing-pages") });
|
|
@@ -2917,6 +3029,18 @@ function buildNav(config, view, navigate, hasCadenceSurface, t) {
|
|
|
2917
3029
|
onClick: () => navigate("blog")
|
|
2918
3030
|
});
|
|
2919
3031
|
}
|
|
3032
|
+
{
|
|
3033
|
+
items.push({
|
|
3034
|
+
id: "brand",
|
|
3035
|
+
label: t("marketing.nav.brand"),
|
|
3036
|
+
icon: "Palette",
|
|
3037
|
+
active: view === "brand" || view === "authorized-images",
|
|
3038
|
+
children: [
|
|
3039
|
+
{ id: "brand", label: t("marketing.nav.brand"), defaultChild: true, active: view === "brand", onClick: () => navigate("brand") },
|
|
3040
|
+
{ id: "authorized-images", label: t("marketing.nav.authorizedImages"), active: view === "authorized-images", onClick: () => navigate("authorized-images") }
|
|
3041
|
+
]
|
|
3042
|
+
});
|
|
3043
|
+
}
|
|
2920
3044
|
return items;
|
|
2921
3045
|
}
|
|
2922
3046
|
function MarketingPage({ config, provider: provider2, store: store3, contentProvider, contentStore, cadenceSurface }) {
|
|
@@ -2966,6 +3090,13 @@ function MarketingPage({ config, provider: provider2, store: store3, contentProv
|
|
|
2966
3090
|
{ id: "blog-post", render: ({ id }) => /* @__PURE__ */ jsx(BlogEntityForm, { entity: blogPostEntity, editId: id, parentLabel: config.labels.blog ?? t("marketing.nav.blog"), onDone: () => navigate("blog") }) },
|
|
2967
3091
|
{ id: "blog-cat-new", render: () => /* @__PURE__ */ jsx(BlogEntityForm, { entity: blogCategoryEntity, parentLabel: config.labels.blogCategories ?? t("marketing.nav.blogCategories"), onDone: () => navigate("blog") }) },
|
|
2968
3092
|
{ id: "blog-cat", render: ({ id }) => /* @__PURE__ */ jsx(BlogEntityForm, { entity: blogCategoryEntity, editId: id, parentLabel: config.labels.blogCategories ?? t("marketing.nav.blogCategories"), onDone: () => navigate("blog") }) },
|
|
3093
|
+
// As telas que ainda não existem — ver ./GapScreens.
|
|
3094
|
+
{ id: "segments", render: () => /* @__PURE__ */ jsx(SegmentsView, {}) },
|
|
3095
|
+
{ id: "message-templates", render: () => /* @__PURE__ */ jsx(MessageTemplatesView, {}) },
|
|
3096
|
+
{ id: "send-history", render: () => /* @__PURE__ */ jsx(SendHistoryView, {}) },
|
|
3097
|
+
{ id: "quick-triggers", render: () => /* @__PURE__ */ jsx(QuickTriggersView, {}) },
|
|
3098
|
+
{ id: "brand", render: () => /* @__PURE__ */ jsx(BrandView, {}) },
|
|
3099
|
+
{ id: "authorized-images", render: () => /* @__PURE__ */ jsx(AuthorizedImagesView, {}) },
|
|
2969
3100
|
{ id: "overview", render: () => /* @__PURE__ */ jsx(OverviewView, {}) }
|
|
2970
3101
|
], "overview");
|
|
2971
3102
|
return /* @__PURE__ */ jsx(MarketingContextProvider, { config, provider: provider2, store: store3, children: /* @__PURE__ */ jsx(ContentPlannerContextProvider, { config, provider: contentProvider, store: contentStore, children: /* @__PURE__ */ jsx(
|
|
@@ -6629,6 +6760,12 @@ var en = {
|
|
|
6629
6760
|
"marketing.purpose.survey.hint": "Only reaches people who opted in to surveys.",
|
|
6630
6761
|
"marketing.purpose.transactional.hint": "Reaches everyone: talking about something they bought is not marketing. Still respects the channel block.",
|
|
6631
6762
|
"marketing.nav.blogCategories": "Categories",
|
|
6763
|
+
"marketing.nav.segments": "Segments",
|
|
6764
|
+
"marketing.nav.messageTemplates": "Message Templates",
|
|
6765
|
+
"marketing.nav.sendHistory": "Send History",
|
|
6766
|
+
"marketing.nav.quickTriggers": "Quick Triggers",
|
|
6767
|
+
"marketing.nav.brand": "Brand",
|
|
6768
|
+
"marketing.nav.authorizedImages": "Authorized Images",
|
|
6632
6769
|
"marketing.nav.overview": "Overview",
|
|
6633
6770
|
"marketing.nav.channels": "Channels",
|
|
6634
6771
|
"marketing.nav.campaigns": "Campaigns",
|
|
@@ -6905,6 +7042,12 @@ var ptBR = {
|
|
|
6905
7042
|
"marketing.purpose.survey.hint": "S\xF3 alcan\xE7a quem aceitou responder pesquisas.",
|
|
6906
7043
|
"marketing.purpose.transactional.hint": "Alcan\xE7a todo mundo: falar de algo que a pessoa j\xE1 comprou n\xE3o \xE9 marketing. Ainda respeita o bloqueio do canal.",
|
|
6907
7044
|
"marketing.nav.blogCategories": "Categorias",
|
|
7045
|
+
"marketing.nav.segments": "Segmentos",
|
|
7046
|
+
"marketing.nav.messageTemplates": "Modelos de Mensagem",
|
|
7047
|
+
"marketing.nav.sendHistory": "Hist\xF3rico de Envios",
|
|
7048
|
+
"marketing.nav.quickTriggers": "Gatilhos R\xE1pidos",
|
|
7049
|
+
"marketing.nav.brand": "Marca",
|
|
7050
|
+
"marketing.nav.authorizedImages": "Imagens Autorizadas",
|
|
6908
7051
|
"marketing.nav.overview": "Vis\xE3o geral",
|
|
6909
7052
|
"marketing.nav.channels": "Canais",
|
|
6910
7053
|
"marketing.nav.campaigns": "Campanhas",
|