@adatechnology/notification-ui 0.1.0-rc.1 → 0.1.0-rc.3

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.
@@ -1,14 +1,16 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
+ import * as _adatechnology_notification_client from '@adatechnology/notification-client';
3
4
  import { NotificationClient } from '@adatechnology/notification-client';
4
5
  import * as _tanstack_react_query from '@tanstack/react-query';
5
6
  import * as _adatechnology_notification_contracts from '@adatechnology/notification-contracts';
6
- import { NotificationSummary, NotificationPreference } from '@adatechnology/notification-contracts';
7
+ import { NotificationSummary, NotificationPreference, NotificationTemplate, RenderedTemplatePreview } from '@adatechnology/notification-contracts';
7
8
 
8
9
  var ptBR = {
9
10
  "bell.label": "Notificações",
10
11
  "bell.unreadSuffix": "não lidas",
11
- "list.title": "Notificações",
12
+ "list.title": "Caixa de entrada",
13
+ "list.unread": "não lidas",
12
14
  "list.empty": "Nenhuma notificação por aqui.",
13
15
  "list.loading": "Carregando…",
14
16
  "list.error": "Não foi possível carregar suas notificações.",
@@ -30,7 +32,27 @@ var ptBR = {
30
32
  "channel.push": "Push",
31
33
  "channel.email": "E-mail",
32
34
  "channel.whatsapp": "WhatsApp",
33
- "channel.sms": "SMS"
35
+ "channel.sms": "SMS",
36
+ "workspace.title": "Notificações",
37
+ "workspace.description": "O que foi avisado, e por quais canais.",
38
+ "workspace.settingsLink": "Configurações",
39
+ "settings.title": "Configurações de notificação",
40
+ "settings.description": "Por onde avisar, e o texto exato que chega.",
41
+ "settings.channelsTitle": "Canais",
42
+ "settings.channelsHint": "Desligar um canal não apaga o histórico — o aviso deixa de sair por ali daqui em diante.",
43
+ "settings.templatesTitle": "Mensagens",
44
+ "settings.templatesHint": "Uma versão nova é criada a cada gravação; a anterior fica no histórico.",
45
+ "settings.templatesEmpty": "Nenhuma mensagem cadastrada.",
46
+ "settings.pickTemplate": "Escolha uma mensagem para editar.",
47
+ "settings.subject": "Título",
48
+ "settings.subjectHint": "O que aparece na lista. Vazio, o título é derivado da primeira linha do texto.",
49
+ "settings.body": "Texto",
50
+ "settings.previewTitle": "Como o destinatário vê",
51
+ "settings.save": "Salvar nova versão",
52
+ "settings.saving": "Salvando…",
53
+ "settings.unchanged": "Nada mudou ainda.",
54
+ "settings.close": "Fechar",
55
+ "settings.version": "v"
34
56
  };
35
57
 
36
58
  /**
@@ -52,6 +74,12 @@ type NotificationTheme = {
52
74
  };
53
75
  type NotificationContextValue = {
54
76
  readonly client: NotificationClient;
77
+ /**
78
+ * O idioma resolvido, e não só os textos dele: data e número não vivem no arquivo de locale —
79
+ * quem os formata é `Intl`, e `Intl` precisa da tag do idioma. Sem isto o item da lista teria de
80
+ * chutar um locale fixo, e a inbox mostraria "5 minutes ago" numa tela em português.
81
+ */
82
+ readonly locale: NotificationLocale;
55
83
  readonly messages: NotificationMessages;
56
84
  readonly theme: NotificationTheme;
57
85
  /** Polling de fallback quando o SSE não está disponível (segundos); `0` desliga. */
@@ -69,18 +97,12 @@ type NotificationProviderProps = {
69
97
  declare function NotificationProvider({ client, locale, messageOverrides, theme, pollIntervalSeconds, children, }: NotificationProviderProps): react.JSX.Element;
70
98
  declare function useNotificationContext(): NotificationContextValue;
71
99
 
72
- type ListNotificationsPage = {
73
- readonly data: readonly NotificationSummary[];
74
- readonly nextCursor?: string;
75
- readonly unreadCount: number;
76
- };
77
-
78
100
  type UseNotificationsOptions = {
79
101
  readonly category?: string;
80
102
  readonly read?: boolean;
81
103
  readonly perPage?: number;
82
104
  };
83
- declare function useNotifications(options?: UseNotificationsOptions): _tanstack_react_query.UseInfiniteQueryResult<_tanstack_react_query.InfiniteData<ListNotificationsPage, unknown>, Error>;
105
+ declare function useNotifications(options?: UseNotificationsOptions): _tanstack_react_query.UseInfiniteQueryResult<_tanstack_react_query.InfiniteData<_adatechnology_notification_client.ListNotificationsPage, unknown>, Error>;
84
106
  declare function useUnreadCount(): _tanstack_react_query.UseQueryResult<number, Error>;
85
107
  declare function useMarkAsRead(): _tanstack_react_query.UseMutationResult<NotificationSummary, Error, string, {
86
108
  previousCount: number | undefined;
@@ -114,6 +136,23 @@ declare function useNotificationStream(options?: UseNotificationStreamOptions):
114
136
  declare function usePreferences(): _tanstack_react_query.UseQueryResult<NoInfer<readonly NotificationPreference[]>, Error>;
115
137
  declare function useUpdatePreferences(): _tanstack_react_query.UseMutationResult<readonly NotificationPreference[], Error, readonly NotificationPreference[], unknown>;
116
138
  declare function useTemplates(): _tanstack_react_query.UseQueryResult<NoInfer<readonly _adatechnology_notification_contracts.NotificationTemplate[]>, Error>;
139
+ /**
140
+ * Salva uma VERSÃO nova do template. É o que a tela de configuração usa para o lojista mudar a copy
141
+ * sem deploy.
142
+ *
143
+ * Invalida em vez de escrever no cache: o servidor decide o número da versão, então o objeto salvo
144
+ * traz um campo que o otimista não teria como prever — e mostrar "versão 3" quando o banco gravou 4
145
+ * confunde exatamente quem está tentando conferir o que salvou.
146
+ */
147
+ declare function useUpsertTemplate(): _tanstack_react_query.UseMutationResult<_adatechnology_notification_contracts.NotificationTemplate, Error, {
148
+ locale: string;
149
+ channel: "inbox" | "push" | "email" | "whatsapp" | "sms";
150
+ key: string;
151
+ body: string;
152
+ active: boolean;
153
+ subject?: string | undefined;
154
+ whatsappTemplateName?: string | undefined;
155
+ }, unknown>;
117
156
 
118
157
  /**
119
158
  * Copyright (c) 2026 Ada Technology. MIT License.
@@ -136,4 +175,67 @@ declare const NOTIFICATION_QUERY_KEYS: {
136
175
  readonly templates: () => readonly ["notifications", "templates"];
137
176
  };
138
177
 
139
- export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, type NotificationContextValue, type NotificationLocale, type NotificationMessages, NotificationProvider, type NotificationProviderProps, type NotificationTheme, type UseNotificationStreamOptions, type UseNotificationsOptions, flattenNotificationPages, resolveMessages, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplates, useUnreadCount, useUpdatePreferences };
178
+ /**
179
+ * Copyright (c) 2026 Ada Technology. MIT License.
180
+ *
181
+ * Quando o aviso chegou, dito do jeito que se diz em voz alta.
182
+ *
183
+ * `Intl` faz o trabalho de idioma — o pacote não guarda "há", "ago" nem nome de mês em lugar nenhum,
184
+ * o que manteria `web.md` §6 de pé e ainda assim quebraria no primeiro locale novo. O que é decisão
185
+ * nossa são as faixas: segundo, minuto, hora, dia, e a virada para data absoluta.
186
+ */
187
+ declare function formatNotificationTime(isoTimestamp: string, locale: string, now: Date): string;
188
+ /** O instante inteiro, para o `title` — é a hora que o texto relativo esconde. */
189
+ declare function formatNotificationTimestamp(isoTimestamp: string, locale: string): string;
190
+
191
+ /**
192
+ * Copyright (c) 2026 Ada Technology. MIT License.
193
+ *
194
+ * A lógica do editor de template, que estava reimplementada no host.
195
+ *
196
+ * Ela veio de `quickcart/modules/notifications/hooks/useNotificationSettings.hook.ts` — 207 linhas
197
+ * que o segundo produto reescreveria, com as mesmas quatro decisões sutis para redescobrir. Elas
198
+ * são o motivo de isto ser pacote e não exemplo:
199
+ *
200
+ * 1. **Versão ativa mais alta.** A rota devolve o histórico inteiro, correto para auditoria; na tela
201
+ * isso faz a mesma mensagem aparecer três vezes e ninguém sabe qual está no ar.
202
+ * 2. **Seleção pelo id, não pelo objeto.** Salvar cria versão nova no servidor; segurando o objeto,
203
+ * o editor mostra a versão que já não é a ativa e a gravação seguinte parte de um texto velho.
204
+ * 3. **Campo vazio é ausência.** Gravar `subject: ''` faz o renderer tratar como subject existente e
205
+ * derivar título vazio, em vez de cair no fallback que usa o corpo.
206
+ * 4. **Preview pelo `renderTemplate` do contracts**, o mesmo do envio. Reimplementar a interpolação
207
+ * dá um preview que confere hoje e mente quando o renderer mudar.
208
+ */
209
+
210
+ type TemplateDraft = {
211
+ readonly key: string;
212
+ readonly channel: string;
213
+ readonly locale: string;
214
+ readonly subject: string;
215
+ readonly body: string;
216
+ readonly whatsappTemplateName: string;
217
+ };
218
+ type UseTemplateEditorParams = {
219
+ /**
220
+ * Valores de exemplo do preview. É do produto: só ele sabe que `{{shortCode}}` é "QC-1042".
221
+ * Ausente, o preview mostra os campos vazios — que é o que o destinatário veria mesmo.
222
+ */
223
+ readonly previewPayload?: Readonly<Record<string, unknown>>;
224
+ };
225
+ type UseTemplateEditorResult = {
226
+ readonly templates: readonly NotificationTemplate[];
227
+ readonly isLoading: boolean;
228
+ readonly isSaving: boolean;
229
+ readonly error: string | undefined;
230
+ readonly selected: NotificationTemplate | undefined;
231
+ readonly draft: TemplateDraft | undefined;
232
+ readonly preview: RenderedTemplatePreview | undefined;
233
+ readonly isDirty: boolean;
234
+ select: (template: NotificationTemplate) => void;
235
+ update: (patch: Partial<TemplateDraft>) => void;
236
+ save: () => void;
237
+ clear: () => void;
238
+ };
239
+ declare function useTemplateEditor(params?: UseTemplateEditorParams): UseTemplateEditorResult;
240
+
241
+ export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, type NotificationContextValue, type NotificationLocale, type NotificationMessages, NotificationProvider, type NotificationProviderProps, type NotificationTheme, type TemplateDraft, type UseNotificationStreamOptions, type UseNotificationsOptions, type UseTemplateEditorParams, type UseTemplateEditorResult, flattenNotificationPages, formatNotificationTime, formatNotificationTimestamp, resolveMessages, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplateEditor, useTemplates, useUnreadCount, useUpdatePreferences, useUpsertTemplate };
package/dist/headless.js CHANGED
@@ -1,298 +1,31 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
- // src/NotificationProvider.tsx
5
- import { createContext, useContext, useMemo } from "react";
6
-
7
- // src/locales/pt-BR.json
8
- var pt_BR_default = {
9
- "bell.label": "Notifica\xE7\xF5es",
10
- "bell.unreadSuffix": "n\xE3o lidas",
11
- "list.title": "Notifica\xE7\xF5es",
12
- "list.empty": "Nenhuma notifica\xE7\xE3o por aqui.",
13
- "list.loading": "Carregando\u2026",
14
- "list.error": "N\xE3o foi poss\xEDvel carregar suas notifica\xE7\xF5es.",
15
- "list.retry": "Tentar de novo",
16
- "list.loadMore": "Carregar mais",
17
- "list.markAllAsRead": "Marcar todas como lidas",
18
- "item.markAsRead": "Marcar como lida",
19
- "item.delete": "Excluir",
20
- "item.unread": "N\xE3o lida",
21
- "preferences.title": "Prefer\xEAncias de notifica\xE7\xE3o",
22
- "preferences.description": "Escolha por onde voc\xEA quer ser avisado em cada assunto.",
23
- "preferences.save": "Salvar prefer\xEAncias",
24
- "preferences.saved": "Prefer\xEAncias salvas.",
25
- "preferences.error": "N\xE3o foi poss\xEDvel salvar. Tente de novo.",
26
- "preferences.empty": "Nenhuma prefer\xEAncia configurada ainda.",
27
- "preferences.quietHours": "Sil\xEAncio entre",
28
- "preferences.quietHoursTo": "e",
29
- "channel.inbox": "No app",
30
- "channel.push": "Push",
31
- "channel.email": "E-mail",
32
- "channel.whatsapp": "WhatsApp",
33
- "channel.sms": "SMS"
34
- };
35
-
36
- // src/locales/en.json
37
- var en_default = {
38
- "bell.label": "Notifications",
39
- "bell.unreadSuffix": "unread",
40
- "list.title": "Notifications",
41
- "list.empty": "Nothing here yet.",
42
- "list.loading": "Loading\u2026",
43
- "list.error": "We couldn't load your notifications.",
44
- "list.retry": "Try again",
45
- "list.loadMore": "Load more",
46
- "list.markAllAsRead": "Mark all as read",
47
- "item.markAsRead": "Mark as read",
48
- "item.delete": "Delete",
49
- "item.unread": "Unread",
50
- "preferences.title": "Notification preferences",
51
- "preferences.description": "Choose how you want to be notified about each topic.",
52
- "preferences.save": "Save preferences",
53
- "preferences.saved": "Preferences saved.",
54
- "preferences.error": "Couldn't save. Try again.",
55
- "preferences.empty": "No preferences configured yet.",
56
- "preferences.quietHours": "Quiet between",
57
- "preferences.quietHoursTo": "and",
58
- "channel.inbox": "In app",
59
- "channel.push": "Push",
60
- "channel.email": "Email",
61
- "channel.whatsapp": "WhatsApp",
62
- "channel.sms": "SMS"
63
- };
64
-
65
- // src/locales/index.ts
66
- var DEFAULT_LOCALE = "pt-BR";
67
- var MESSAGES_BY_LOCALE = {
68
- "pt-BR": pt_BR_default,
69
- en: en_default
70
- };
71
- function resolveMessages(locale) {
72
- return MESSAGES_BY_LOCALE[locale] ?? MESSAGES_BY_LOCALE[DEFAULT_LOCALE];
73
- }
74
- __name(resolveMessages, "resolveMessages");
75
-
76
- // src/NotificationProvider.tsx
77
- var NotificationContext = /* @__PURE__ */ createContext(null);
78
- function NotificationProvider({ client, locale = DEFAULT_LOCALE, messageOverrides, theme = {}, pollIntervalSeconds = 60, children }) {
79
- const value = useMemo(() => ({
80
- client,
81
- messages: {
82
- ...resolveMessages(locale),
83
- ...messageOverrides
84
- },
85
- theme,
86
- pollIntervalSeconds
87
- }), [
88
- client,
89
- locale,
90
- messageOverrides,
91
- theme,
92
- pollIntervalSeconds
93
- ]);
94
- return /* @__PURE__ */ React.createElement(NotificationContext.Provider, {
95
- value
96
- }, children);
97
- }
98
- __name(NotificationProvider, "NotificationProvider");
99
- function useNotificationContext() {
100
- const context = useContext(NotificationContext);
101
- if (!context) throw new Error("notification-ui: componente usado fora de <NotificationProvider>");
102
- return context;
103
- }
104
- __name(useNotificationContext, "useNotificationContext");
105
-
106
- // src/hooks/useNotifications.ts
107
- import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
108
-
109
- // src/hooks/queryKeys.ts
110
- var NOTIFICATION_QUERY_KEYS = {
111
- all: [
112
- "notifications"
113
- ],
114
- list: /* @__PURE__ */ __name((filters) => [
115
- "notifications",
116
- "list",
117
- filters
118
- ], "list"),
119
- unreadCount: /* @__PURE__ */ __name(() => [
120
- "notifications",
121
- "unread-count"
122
- ], "unreadCount"),
123
- preferences: /* @__PURE__ */ __name(() => [
124
- "notifications",
125
- "preferences"
126
- ], "preferences"),
127
- templates: /* @__PURE__ */ __name(() => [
128
- "notifications",
129
- "templates"
130
- ], "templates")
131
- };
132
-
133
- // src/hooks/useNotifications.ts
134
- function useNotifications(options = {}) {
135
- const { client } = useNotificationContext();
136
- return useInfiniteQuery({
137
- queryKey: NOTIFICATION_QUERY_KEYS.list({
138
- category: options.category,
139
- read: options.read
140
- }),
141
- initialPageParam: void 0,
142
- queryFn: /* @__PURE__ */ __name(({ pageParam }) => client.listNotifications({
143
- category: options.category,
144
- read: options.read,
145
- cursor: pageParam,
146
- perPage: options.perPage
147
- }), "queryFn"),
148
- getNextPageParam: /* @__PURE__ */ __name((lastPage) => lastPage.nextCursor, "getNextPageParam")
149
- });
150
- }
151
- __name(useNotifications, "useNotifications");
152
- function useUnreadCount() {
153
- const { client, pollIntervalSeconds } = useNotificationContext();
154
- return useQuery({
155
- queryKey: NOTIFICATION_QUERY_KEYS.unreadCount(),
156
- queryFn: /* @__PURE__ */ __name(() => client.countUnread(), "queryFn"),
157
- // Polling é o fallback de quem não ligou o SSE. Com o stream ativo,
158
- // `useNotificationStream` invalida esta chave e o refetch acontece na hora.
159
- refetchInterval: pollIntervalSeconds > 0 ? pollIntervalSeconds * 1e3 : false
160
- });
161
- }
162
- __name(useUnreadCount, "useUnreadCount");
163
- function useMarkAsRead() {
164
- const { client } = useNotificationContext();
165
- const queryClient = useQueryClient();
166
- return useMutation({
167
- mutationFn: /* @__PURE__ */ __name((id) => client.markAsRead(id), "mutationFn"),
168
- async onMutate(id) {
169
- await queryClient.cancelQueries({
170
- queryKey: NOTIFICATION_QUERY_KEYS.all
171
- });
172
- const previousCount = queryClient.getQueryData(NOTIFICATION_QUERY_KEYS.unreadCount());
173
- queryClient.setQueryData(NOTIFICATION_QUERY_KEYS.unreadCount(), (current) => current === void 0 ? current : Math.max(0, current - 1));
174
- return {
175
- previousCount,
176
- id
177
- };
178
- },
179
- onError(_error, _id, context) {
180
- if (context?.previousCount !== void 0) {
181
- queryClient.setQueryData(NOTIFICATION_QUERY_KEYS.unreadCount(), context.previousCount);
182
- }
183
- },
184
- onSettled() {
185
- void queryClient.invalidateQueries({
186
- queryKey: NOTIFICATION_QUERY_KEYS.all
187
- });
188
- }
189
- });
190
- }
191
- __name(useMarkAsRead, "useMarkAsRead");
192
- function useMarkAllAsRead() {
193
- const { client } = useNotificationContext();
194
- const queryClient = useQueryClient();
195
- return useMutation({
196
- mutationFn: /* @__PURE__ */ __name(() => client.markAllAsRead(), "mutationFn"),
197
- onSettled() {
198
- void queryClient.invalidateQueries({
199
- queryKey: NOTIFICATION_QUERY_KEYS.all
200
- });
201
- }
202
- });
203
- }
204
- __name(useMarkAllAsRead, "useMarkAllAsRead");
205
- function useDeleteNotification() {
206
- const { client } = useNotificationContext();
207
- const queryClient = useQueryClient();
208
- return useMutation({
209
- mutationFn: /* @__PURE__ */ __name((id) => client.deleteNotification(id), "mutationFn"),
210
- onSettled() {
211
- void queryClient.invalidateQueries({
212
- queryKey: NOTIFICATION_QUERY_KEYS.all
213
- });
214
- }
215
- });
216
- }
217
- __name(useDeleteNotification, "useDeleteNotification");
218
- function flattenNotificationPages(pages) {
219
- return pages?.flatMap((page) => page.data) ?? [];
220
- }
221
- __name(flattenNotificationPages, "flattenNotificationPages");
222
-
223
- // src/hooks/useNotificationStream.ts
224
- import { useEffect } from "react";
225
- import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
226
- import { subscribeToNotificationStream } from "@adatechnology/notification-client";
227
- function useNotificationStream(options = {}) {
228
- const { client } = useNotificationContext();
229
- const queryClient = useQueryClient2();
230
- const enabled = options.enabled ?? false;
231
- const onEvent = options.onEvent;
232
- useEffect(() => {
233
- if (!enabled) return;
234
- let subscription;
235
- let cancelled = false;
236
- void client.resolveStreamRequest().then(({ url, headers }) => {
237
- if (cancelled) return;
238
- subscription = subscribeToNotificationStream({
239
- url,
240
- headers,
241
- onEvent: /* @__PURE__ */ __name((event) => {
242
- onEvent?.(event);
243
- void queryClient.invalidateQueries({
244
- queryKey: NOTIFICATION_QUERY_KEYS.all
245
- });
246
- }, "onEvent")
247
- });
248
- });
249
- return () => {
250
- cancelled = true;
251
- subscription?.close();
252
- };
253
- }, [
254
- client,
255
- queryClient,
256
- enabled,
257
- onEvent
258
- ]);
259
- }
260
- __name(useNotificationStream, "useNotificationStream");
261
-
262
- // src/hooks/usePreferences.ts
263
- import { useMutation as useMutation2, useQuery as useQuery2, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
264
- function usePreferences() {
265
- const { client } = useNotificationContext();
266
- return useQuery2({
267
- queryKey: NOTIFICATION_QUERY_KEYS.preferences(),
268
- queryFn: /* @__PURE__ */ __name(() => client.getPreferences(), "queryFn")
269
- });
270
- }
271
- __name(usePreferences, "usePreferences");
272
- function useUpdatePreferences() {
273
- const { client } = useNotificationContext();
274
- const queryClient = useQueryClient3();
275
- return useMutation2({
276
- mutationFn: /* @__PURE__ */ __name((preferences) => client.updatePreferences(preferences), "mutationFn"),
277
- onSuccess(saved) {
278
- queryClient.setQueryData(NOTIFICATION_QUERY_KEYS.preferences(), saved);
279
- }
280
- });
281
- }
282
- __name(useUpdatePreferences, "useUpdatePreferences");
283
- function useTemplates() {
284
- const { client } = useNotificationContext();
285
- return useQuery2({
286
- queryKey: NOTIFICATION_QUERY_KEYS.templates(),
287
- queryFn: /* @__PURE__ */ __name(() => client.listTemplates(), "queryFn")
288
- });
289
- }
290
- __name(useTemplates, "useTemplates");
1
+ import {
2
+ DEFAULT_LOCALE,
3
+ NOTIFICATION_QUERY_KEYS,
4
+ NotificationProvider,
5
+ flattenNotificationPages,
6
+ formatNotificationTime,
7
+ formatNotificationTimestamp,
8
+ resolveMessages,
9
+ useDeleteNotification,
10
+ useMarkAllAsRead,
11
+ useMarkAsRead,
12
+ useNotificationContext,
13
+ useNotificationStream,
14
+ useNotifications,
15
+ usePreferences,
16
+ useTemplateEditor,
17
+ useTemplates,
18
+ useUnreadCount,
19
+ useUpdatePreferences,
20
+ useUpsertTemplate
21
+ } from "./chunk-I6WQKOCP.js";
291
22
  export {
292
23
  DEFAULT_LOCALE,
293
24
  NOTIFICATION_QUERY_KEYS,
294
25
  NotificationProvider,
295
26
  flattenNotificationPages,
27
+ formatNotificationTime,
28
+ formatNotificationTimestamp,
296
29
  resolveMessages,
297
30
  useDeleteNotification,
298
31
  useMarkAllAsRead,
@@ -301,8 +34,10 @@ export {
301
34
  useNotificationStream,
302
35
  useNotifications,
303
36
  usePreferences,
37
+ useTemplateEditor,
304
38
  useTemplates,
305
39
  useUnreadCount,
306
- useUpdatePreferences
40
+ useUpdatePreferences,
41
+ useUpsertTemplate
307
42
  };
308
43
  //# sourceMappingURL=headless.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/NotificationProvider.tsx","../src/locales/pt-BR.json","../src/locales/en.json","../src/locales/index.ts","../src/hooks/useNotifications.ts","../src/hooks/queryKeys.ts","../src/hooks/useNotificationStream.ts","../src/hooks/usePreferences.ts"],"sourcesContent":["/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n *\n * Provider do pacote. **Não instancia `QueryClient`** — usa o do host (regra de módulos\n * plugáveis §4.2). Instanciar o próprio criaria dois caches na mesma página: a inbox invalidaria\n * um, e a tela do produto continuaria lendo o outro.\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport type { NotificationClient } from '@adatechnology/notification-client'\n\nimport { DEFAULT_LOCALE, resolveMessages, type NotificationLocale, type NotificationMessages } from './locales'\n\nexport type NotificationTheme = {\n /** Classe aplicada na raiz de cada componente — é por onde o host injeta os tokens dele. */\n readonly rootClassName?: string\n readonly components?: Partial<Record<string, string>>\n}\n\nexport type NotificationContextValue = {\n readonly client: NotificationClient\n readonly messages: NotificationMessages\n readonly theme: NotificationTheme\n /** Polling de fallback quando o SSE não está disponível (segundos); `0` desliga. */\n readonly pollIntervalSeconds: number\n}\n\nconst NotificationContext = createContext<NotificationContextValue | null>(null)\n\nexport type NotificationProviderProps = {\n readonly client: NotificationClient\n readonly locale?: NotificationLocale\n /** Sobrescreve textos pontuais sem trocar o locale inteiro. */\n readonly messageOverrides?: Partial<NotificationMessages>\n readonly theme?: NotificationTheme\n readonly pollIntervalSeconds?: number\n readonly children: ReactNode\n}\n\nexport function NotificationProvider({\n client,\n locale = DEFAULT_LOCALE,\n messageOverrides,\n theme = {},\n pollIntervalSeconds = 60,\n children,\n}: NotificationProviderProps) {\n const value = useMemo<NotificationContextValue>(\n () => ({\n client,\n messages: { ...resolveMessages(locale), ...messageOverrides },\n theme,\n pollIntervalSeconds,\n }),\n [client, locale, messageOverrides, theme, pollIntervalSeconds],\n )\n\n return <NotificationContext.Provider value={value}>{children}</NotificationContext.Provider>\n}\n\nexport function useNotificationContext(): NotificationContextValue {\n const context = useContext(NotificationContext)\n if (!context) throw new Error('notification-ui: componente usado fora de <NotificationProvider>')\n return context\n}\n","{\n \"bell.label\": \"Notificações\",\n \"bell.unreadSuffix\": \"não lidas\",\n \"list.title\": \"Notificações\",\n \"list.empty\": \"Nenhuma notificação por aqui.\",\n \"list.loading\": \"Carregando…\",\n \"list.error\": \"Não foi possível carregar suas notificações.\",\n \"list.retry\": \"Tentar de novo\",\n \"list.loadMore\": \"Carregar mais\",\n \"list.markAllAsRead\": \"Marcar todas como lidas\",\n \"item.markAsRead\": \"Marcar como lida\",\n \"item.delete\": \"Excluir\",\n \"item.unread\": \"Não lida\",\n \"preferences.title\": \"Preferências de notificação\",\n \"preferences.description\": \"Escolha por onde você quer ser avisado em cada assunto.\",\n \"preferences.save\": \"Salvar preferências\",\n \"preferences.saved\": \"Preferências salvas.\",\n \"preferences.error\": \"Não foi possível salvar. Tente de novo.\",\n \"preferences.empty\": \"Nenhuma preferência configurada ainda.\",\n \"preferences.quietHours\": \"Silêncio entre\",\n \"preferences.quietHoursTo\": \"e\",\n \"channel.inbox\": \"No app\",\n \"channel.push\": \"Push\",\n \"channel.email\": \"E-mail\",\n \"channel.whatsapp\": \"WhatsApp\",\n \"channel.sms\": \"SMS\"\n}\n","{\n \"bell.label\": \"Notifications\",\n \"bell.unreadSuffix\": \"unread\",\n \"list.title\": \"Notifications\",\n \"list.empty\": \"Nothing here yet.\",\n \"list.loading\": \"Loading…\",\n \"list.error\": \"We couldn't load your notifications.\",\n \"list.retry\": \"Try again\",\n \"list.loadMore\": \"Load more\",\n \"list.markAllAsRead\": \"Mark all as read\",\n \"item.markAsRead\": \"Mark as read\",\n \"item.delete\": \"Delete\",\n \"item.unread\": \"Unread\",\n \"preferences.title\": \"Notification preferences\",\n \"preferences.description\": \"Choose how you want to be notified about each topic.\",\n \"preferences.save\": \"Save preferences\",\n \"preferences.saved\": \"Preferences saved.\",\n \"preferences.error\": \"Couldn't save. Try again.\",\n \"preferences.empty\": \"No preferences configured yet.\",\n \"preferences.quietHours\": \"Quiet between\",\n \"preferences.quietHoursTo\": \"and\",\n \"channel.inbox\": \"In app\",\n \"channel.push\": \"Push\",\n \"channel.email\": \"Email\",\n \"channel.whatsapp\": \"WhatsApp\",\n \"channel.sms\": \"SMS\"\n}\n","/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n *\n * Nenhum texto visível vive em tag ou prop (`web.md` §6). O host sobrescreve chaves pontuais via\n * `messageOverrides` sem precisar fornecer um locale inteiro.\n */\n\nimport ptBR from './pt-BR.json'\nimport en from './en.json'\n\nexport type NotificationMessages = typeof ptBR\nexport type NotificationLocale = 'pt-BR' | 'en'\n\nexport const DEFAULT_LOCALE: NotificationLocale = 'pt-BR'\n\nconst MESSAGES_BY_LOCALE: Record<NotificationLocale, NotificationMessages> = {\n 'pt-BR': ptBR,\n en: en as NotificationMessages,\n}\n\nexport function resolveMessages(locale: NotificationLocale): NotificationMessages {\n return MESSAGES_BY_LOCALE[locale] ?? MESSAGES_BY_LOCALE[DEFAULT_LOCALE]\n}\n","/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n *\n * Camada headless — a válvula de escape do item 4 da §4 da regra de módulos plugáveis: quando a\n * tela default não serve, o produto monta a própria sobre estes mesmos hooks e continua herdando\n * upgrades de lógica.\n */\n\nimport { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { NotificationSummary } from '@adatechnology/notification-contracts'\n\nimport { useNotificationContext } from '../NotificationProvider'\nimport { NOTIFICATION_QUERY_KEYS } from './queryKeys'\n\nexport type UseNotificationsOptions = {\n readonly category?: string\n readonly read?: boolean\n readonly perPage?: number\n}\n\nexport function useNotifications(options: UseNotificationsOptions = {}) {\n const { client } = useNotificationContext()\n\n return useInfiniteQuery({\n queryKey: NOTIFICATION_QUERY_KEYS.list({ category: options.category, read: options.read }),\n initialPageParam: undefined as string | undefined,\n queryFn: ({ pageParam }) =>\n client.listNotifications({\n category: options.category,\n read: options.read,\n cursor: pageParam,\n perPage: options.perPage,\n }),\n getNextPageParam: (lastPage) => lastPage.nextCursor,\n })\n}\n\nexport function useUnreadCount() {\n const { client, pollIntervalSeconds } = useNotificationContext()\n\n return useQuery({\n queryKey: NOTIFICATION_QUERY_KEYS.unreadCount(),\n queryFn: () => client.countUnread(),\n // Polling é o fallback de quem não ligou o SSE. Com o stream ativo,\n // `useNotificationStream` invalida esta chave e o refetch acontece na hora.\n refetchInterval: pollIntervalSeconds > 0 ? pollIntervalSeconds * 1000 : false,\n })\n}\n\nexport function useMarkAsRead() {\n const { client } = useNotificationContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: string) => client.markAsRead(id),\n async onMutate(id: string) {\n // Atualização otimista: marcar como lida é ação de um clique, e esperar o round-trip para\n // o badge cair faz a interface parecer travada.\n await queryClient.cancelQueries({ queryKey: NOTIFICATION_QUERY_KEYS.all })\n const previousCount = queryClient.getQueryData<number>(NOTIFICATION_QUERY_KEYS.unreadCount())\n\n queryClient.setQueryData<number>(NOTIFICATION_QUERY_KEYS.unreadCount(), (current) =>\n current === undefined ? current : Math.max(0, current - 1),\n )\n return { previousCount, id }\n },\n onError(_error, _id, context) {\n // Rollback: sem isto o badge ficaria mentindo até o próximo refetch.\n if (context?.previousCount !== undefined) {\n queryClient.setQueryData(NOTIFICATION_QUERY_KEYS.unreadCount(), context.previousCount)\n }\n },\n onSettled() {\n void queryClient.invalidateQueries({ queryKey: NOTIFICATION_QUERY_KEYS.all })\n },\n })\n}\n\nexport function useMarkAllAsRead() {\n const { client } = useNotificationContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: () => client.markAllAsRead(),\n onSettled() {\n void queryClient.invalidateQueries({ queryKey: NOTIFICATION_QUERY_KEYS.all })\n },\n })\n}\n\nexport function useDeleteNotification() {\n const { client } = useNotificationContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: string) => client.deleteNotification(id),\n onSettled() {\n void queryClient.invalidateQueries({ queryKey: NOTIFICATION_QUERY_KEYS.all })\n },\n })\n}\n\n/** Achata as páginas do infinite query — a lista quase sempre quer o array direto. */\nexport function flattenNotificationPages(\n pages: readonly { data: readonly NotificationSummary[] }[] | undefined,\n): readonly NotificationSummary[] {\n return pages?.flatMap((page) => page.data) ?? []\n}\n","/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n *\n * Chaves centralizadas: o sino e a lista leem o mesmo `unreadCount`, e uma invalidação precisa\n * atingir os dois. Chave montada inline em cada hook é como badge e lista passam a mostrar\n * números diferentes.\n */\n\nexport const NOTIFICATION_QUERY_KEYS = {\n all: ['notifications'] as const,\n list: (filters: { category?: string; read?: boolean }) => ['notifications', 'list', filters] as const,\n unreadCount: () => ['notifications', 'unread-count'] as const,\n preferences: () => ['notifications', 'preferences'] as const,\n templates: () => ['notifications', 'templates'] as const,\n} as const\n","/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n */\n\nimport { useEffect } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { subscribeToNotificationStream } from '@adatechnology/notification-client'\n\nimport { useNotificationContext } from '../NotificationProvider'\nimport { NOTIFICATION_QUERY_KEYS } from './queryKeys'\n\nexport type UseNotificationStreamOptions = {\n /** Desligado por omissão: abrir SSE é decisão do host, que sabe se o backend expõe a rota. */\n readonly enabled?: boolean\n readonly onEvent?: (event: { event: string; data: unknown }) => void\n}\n\n/**\n * Liga o SSE do inbox ao cache do TanStack: cada evento invalida as chaves, e o badge e a lista\n * atualizam juntos. `useEffect` aqui é o uso correto do hook — sincronizar com um sistema externo\n * (`react.md`, \"useEffect só para sincronizar com sistemas externos\"), não transformar dado.\n */\nexport function useNotificationStream(options: UseNotificationStreamOptions = {}): void {\n const { client } = useNotificationContext()\n const queryClient = useQueryClient()\n const enabled = options.enabled ?? false\n const onEvent = options.onEvent\n\n useEffect(() => {\n if (!enabled) return\n\n let subscription: { close(): void } | undefined\n let cancelled = false\n\n void client.resolveStreamRequest().then(({ url, headers }) => {\n // A resolução do token é assíncrona; se o componente desmontou nesse meio-tempo, não abre\n // conexão nenhuma — senão sobraria um stream órfão a cada navegação rápida.\n if (cancelled) return\n\n subscription = subscribeToNotificationStream({\n url,\n headers,\n onEvent: (event) => {\n onEvent?.(event)\n void queryClient.invalidateQueries({ queryKey: NOTIFICATION_QUERY_KEYS.all })\n },\n })\n })\n\n return () => {\n cancelled = true\n subscription?.close()\n }\n }, [client, queryClient, enabled, onEvent])\n}\n","/**\n * Copyright (c) 2026 Ada Technology. MIT License.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport type { NotificationPreference } from '@adatechnology/notification-contracts'\n\nimport { useNotificationContext } from '../NotificationProvider'\nimport { NOTIFICATION_QUERY_KEYS } from './queryKeys'\n\nexport function usePreferences() {\n const { client } = useNotificationContext()\n\n return useQuery({\n queryKey: NOTIFICATION_QUERY_KEYS.preferences(),\n queryFn: () => client.getPreferences(),\n })\n}\n\nexport function useUpdatePreferences() {\n const { client } = useNotificationContext()\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (preferences: readonly NotificationPreference[]) => client.updatePreferences(preferences),\n onSuccess(saved) {\n // A resposta já é o estado persistido — usar direto evita um refetch e o piscar do painel\n // entre o valor otimista e o confirmado.\n queryClient.setQueryData(NOTIFICATION_QUERY_KEYS.preferences(), saved)\n },\n })\n}\n\nexport function useTemplates() {\n const { client } = useNotificationContext()\n\n return useQuery({\n queryKey: NOTIFICATION_QUERY_KEYS.templates(),\n queryFn: () => client.listTemplates(),\n })\n}\n"],"mappings":"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","names":["createContext","useContext","useMemo","DEFAULT_LOCALE","MESSAGES_BY_LOCALE","ptBR","en","resolveMessages","locale","NotificationContext","createContext","NotificationProvider","client","locale","DEFAULT_LOCALE","messageOverrides","theme","pollIntervalSeconds","children","value","useMemo","messages","resolveMessages","Provider","useNotificationContext","context","useContext","Error","useInfiniteQuery","useMutation","useQuery","useQueryClient","NOTIFICATION_QUERY_KEYS","all","list","filters","unreadCount","preferences","templates","useNotifications","options","client","useNotificationContext","useInfiniteQuery","queryKey","NOTIFICATION_QUERY_KEYS","list","category","read","initialPageParam","undefined","queryFn","pageParam","listNotifications","cursor","perPage","getNextPageParam","lastPage","nextCursor","useUnreadCount","pollIntervalSeconds","useQuery","unreadCount","countUnread","refetchInterval","useMarkAsRead","queryClient","useQueryClient","useMutation","mutationFn","id","markAsRead","onMutate","cancelQueries","all","previousCount","getQueryData","setQueryData","current","Math","max","onError","_error","_id","context","onSettled","invalidateQueries","useMarkAllAsRead","markAllAsRead","useDeleteNotification","deleteNotification","flattenNotificationPages","pages","flatMap","page","data","useEffect","useQueryClient","subscribeToNotificationStream","useNotificationStream","options","client","useNotificationContext","queryClient","useQueryClient","enabled","onEvent","useEffect","subscription","cancelled","resolveStreamRequest","then","url","headers","subscribeToNotificationStream","event","invalidateQueries","queryKey","NOTIFICATION_QUERY_KEYS","all","close","useMutation","useQuery","useQueryClient","usePreferences","client","useNotificationContext","useQuery","queryKey","NOTIFICATION_QUERY_KEYS","preferences","queryFn","getPreferences","useUpdatePreferences","queryClient","useQueryClient","useMutation","mutationFn","updatePreferences","onSuccess","saved","setQueryData","useTemplates","templates","listTemplates"]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}