payload-plugin-marketing 0.9.1 → 0.9.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.
Files changed (80) hide show
  1. package/README.md +63 -25
  2. package/dist/admin/components/audience-buttons.d.ts +6 -0
  3. package/dist/admin/components/audience-buttons.d.ts.map +1 -0
  4. package/dist/admin/components/audience-detail.d.ts +6 -0
  5. package/dist/admin/components/audience-detail.d.ts.map +1 -0
  6. package/dist/admin/components/audience-list.d.ts +6 -0
  7. package/dist/admin/components/audience-list.d.ts.map +1 -0
  8. package/dist/admin/components/broadcast-list.d.ts +6 -0
  9. package/dist/admin/components/broadcast-list.d.ts.map +1 -0
  10. package/dist/admin/components/broadcasts-table.d.ts +14 -0
  11. package/dist/admin/components/broadcasts-table.d.ts.map +1 -0
  12. package/dist/admin/components/contacts-table.d.ts +12 -0
  13. package/dist/admin/components/contacts-table.d.ts.map +1 -0
  14. package/dist/admin/components/create-broadcast-button.d.ts +6 -0
  15. package/dist/admin/components/create-broadcast-button.d.ts.map +1 -0
  16. package/dist/admin/{components.d.ts → components/marketing-components.d.ts} +3 -2
  17. package/dist/admin/components/marketing-components.d.ts.map +1 -0
  18. package/dist/admin/components/marketing-view-shell.d.ts +8 -0
  19. package/dist/admin/components/marketing-view-shell.d.ts.map +1 -0
  20. package/dist/admin/components/payload-modal.d.ts +13 -0
  21. package/dist/admin/components/payload-modal.d.ts.map +1 -0
  22. package/dist/admin/components/provider-dashboard-link.d.ts +8 -0
  23. package/dist/admin/components/provider-dashboard-link.d.ts.map +1 -0
  24. package/dist/admin/components/view-params.d.ts +4 -0
  25. package/dist/admin/components/view-params.d.ts.map +1 -0
  26. package/dist/admin/components/views.d.ts +4 -0
  27. package/dist/admin/components/views.d.ts.map +1 -0
  28. package/dist/admin/date-format.d.ts +2 -0
  29. package/dist/admin/date-format.d.ts.map +1 -0
  30. package/dist/admin/index.cjs +1 -1
  31. package/dist/admin/index.cjs.map +1 -1
  32. package/dist/admin/index.d.ts +2 -2
  33. package/dist/admin/index.d.ts.map +1 -1
  34. package/dist/admin/index.js +1 -1
  35. package/dist/admin/index.js.map +1 -1
  36. package/dist/admin/paths.d.ts +4 -0
  37. package/dist/admin/paths.d.ts.map +1 -0
  38. package/dist/admin/use-marketing-api.d.ts +5 -0
  39. package/dist/admin/use-marketing-api.d.ts.map +1 -0
  40. package/dist/chunk-S2EABBIN.js +2 -0
  41. package/dist/chunk-S2EABBIN.js.map +1 -0
  42. package/dist/chunk-SX3OTOU2.js +2 -0
  43. package/dist/chunk-SX3OTOU2.js.map +1 -0
  44. package/dist/endpoints/marketing-endpoints.d.ts +3 -0
  45. package/dist/endpoints/marketing-endpoints.d.ts.map +1 -0
  46. package/dist/form-builder/fields.d.ts +3 -2
  47. package/dist/form-builder/fields.d.ts.map +1 -1
  48. package/dist/form-builder/index.cjs +1 -1
  49. package/dist/form-builder/index.cjs.map +1 -1
  50. package/dist/form-builder/index.js +1 -1
  51. package/dist/form-builder/mutate-collections.d.ts.map +1 -1
  52. package/dist/form-builder/normalize-placeholder-rows.d.ts +5 -0
  53. package/dist/form-builder/normalize-placeholder-rows.d.ts.map +1 -0
  54. package/dist/index.cjs +1 -1
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.ts +3 -2
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/marketing-integration.d.ts +15 -0
  61. package/dist/marketing-integration.d.ts.map +1 -0
  62. package/dist/plugin.d.ts.map +1 -1
  63. package/dist/types.d.ts +28 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/package.json +1 -6
  66. package/dist/actions/factories.d.ts +0 -18
  67. package/dist/actions/factories.d.ts.map +0 -1
  68. package/dist/actions/index.cjs +0 -2
  69. package/dist/actions/index.cjs.map +0 -1
  70. package/dist/actions/index.d.ts +0 -2
  71. package/dist/actions/index.d.ts.map +0 -1
  72. package/dist/actions/index.js +0 -2
  73. package/dist/actions/index.js.map +0 -1
  74. package/dist/admin/components.d.ts.map +0 -1
  75. package/dist/admin/views.d.ts +0 -4
  76. package/dist/admin/views.d.ts.map +0 -1
  77. package/dist/chunk-4RBNCG5Q.js +0 -2
  78. package/dist/chunk-4RBNCG5Q.js.map +0 -1
  79. package/dist/chunk-RBBHOL35.js +0 -2
  80. package/dist/chunk-RBBHOL35.js.map +0 -1
package/README.md CHANGED
@@ -54,8 +54,22 @@ marketingPlugin({
54
54
 
55
55
  ## Form Builder
56
56
 
57
- The plugin adds `url`, `phone`, and `acceptance` blocks to the generated forms collection. You can
58
- also spread the blocks into the form-builder `fields` option:
57
+ The plugin adds `url`, `phone`, and `acceptance` blocks to the generated forms collection. For the
58
+ built-in form-builder blocks it ships with (such as `text`, `textarea`, `email`, `number`,
59
+ `select`, `radio`, `date`, `state`, and `country`), it normalizes the second admin row to **width
60
+ (20%)**, **placeholder (40%)**, and **defaultValue (40%)**. `checkbox`, `message`,
61
+ `payment`, `upload`, and `acceptance` blocks keep their original layout. Placeholder fields are
62
+ **localized** (per-locale strings in the admin when your project has localization enabled). To turn
63
+ that off for a block, pass `formBuilder.fields.<blockSlug>.fields.placeholder` with
64
+ `{ localized: false }`.
65
+
66
+ If placeholders still never appear in the admin, check that you do **not** define a root-level
67
+ `config.blocks` entry with the **same `slug`** as a form-builder block (for example `text`). Payload
68
+ prefers `payload.blocks[slug]` over the inline blocks on the `forms` collection, so a global block
69
+ would hide fields only present on the mutated collection blocks. Expand each form field row in the
70
+ admin (Payload lazy-renders fields inside collapsed blocks).
71
+
72
+ You can also spread the blocks into the form-builder `fields` option:
59
73
 
60
74
  ```ts
61
75
  import { createMarketingFormFields } from "payload-plugin-marketing"
@@ -156,42 +170,68 @@ marketingPlugin({
156
170
 
157
171
  Components are also exported from `payload-plugin-marketing/admin`.
158
172
 
159
- ## Actions
173
+ ## Endpoint permissions
160
174
 
161
- Create adapter-backed actions with `createMarketingActions`:
175
+ Marketing REST routes (`GET /marketing/meta`, audiences, contacts, broadcasts) require an authenticated
176
+ admin user. You can narrow access with **`permissions`**: each of **`audiences`**, **`contacts`**, and
177
+ **`broadcasts`** accepts optional **`read`** and **`write`**. Omitted flags default to **`true`** for
178
+ that resource. If you omit **`permissions`** entirely, behavior matches previous releases (any signed-in
179
+ user can call all routes).
162
180
 
163
- ```ts
164
- import { createMarketingActions } from "payload-plugin-marketing"
165
- import { resendAdapter } from "payload-plugin-marketing/adapters/resend"
181
+ **`GET /marketing/meta`** is allowed when at least one resource has **`read: true`** after resolution.
166
182
 
167
- const actions = createMarketingActions({
183
+ ```ts
184
+ marketingPlugin({
168
185
  adapter: resendAdapter({ apiKey: process.env.RESEND_API_KEY }),
186
+ permissions: {
187
+ audiences: { read: true, write: true },
188
+ contacts: { read: true, write: false },
189
+ broadcasts: { read: true, write: true },
190
+ },
169
191
  })
192
+ ```
193
+
194
+ Denied requests respond with **403** and `{ message: "Forbidden" }`.
195
+
196
+ ## Using the adapter in your app
170
197
 
171
- await actions.createAudience({ name: "Newsletter" })
172
- await actions.newsletterSubscribe({ email: "person@example.com" })
198
+ The plugin attaches your **`MarketingAdapter`** to **`config.custom.payloadPluginMarketing`** (server-only; not sent to the admin client bundle). Resolve it from **`payload`** anywhere you already have **`Payload`**:
199
+
200
+ ```ts
201
+ import { getMarketingIntegration } from "payload-plugin-marketing"
202
+
203
+ const { adapter } = getMarketingIntegration(req.payload)
204
+ await adapter.audiences.create({ name: "Newsletter" })
205
+ ```
206
+
207
+ Subscribe an email to your first audience (pick a concrete **`audienceId`** if you prefer):
208
+
209
+ ```ts
210
+ const { adapter } = getMarketingIntegration(req.payload)
211
+ const audienceId = (await adapter.audiences.list())[0]?.id
212
+ if (!audienceId) {
213
+ throw new Error("No audience found. Create one in the admin first.")
214
+ }
215
+ await adapter.contacts.upsert({ audienceId, email: "person@example.com", subscribed: true })
173
216
  ```
174
217
 
175
218
  ## Broadcasts
176
219
 
177
- Use `createMarketingActions` with the same adapter as the plugin. `createBroadcast` and `sendBroadcast`
178
- return a boolean; `broadcastId` for send/delete comes from your provider (for example `adapter.broadcasts.list()` after create, or the provider dashboard).
220
+ Same adapter as **`marketingPlugin`**. **`broadcastId`** for send/delete comes from your provider (for example **`adapter.broadcasts.list()`** after create, or the provider dashboard).
179
221
 
180
222
  ### Resend (HTML or React)
181
223
 
182
224
  `defaultSender` on `resendAdapter` is sent as `from`. **`templateId` is not supported** and will throw.
183
225
 
184
226
  ```ts
185
- import { createMarketingActions } from "payload-plugin-marketing"
186
227
  import { resendAdapter } from "payload-plugin-marketing/adapters/resend"
187
228
 
188
229
  const adapter = resendAdapter({
189
230
  apiKey: process.env.RESEND_API_KEY!,
190
231
  defaultSender: "Acme <newsletter@example.com>",
191
232
  })
192
- const actions = createMarketingActions({ adapter })
193
233
 
194
- await actions.createBroadcast({
234
+ await adapter.broadcasts.create({
195
235
  audienceId: "<segment-or-audience-id>",
196
236
  name: "January update",
197
237
  subject: "What we shipped",
@@ -203,16 +243,15 @@ await actions.createBroadcast({
203
243
  const drafts = await adapter.broadcasts.list()
204
244
  const id = drafts[0]?.id
205
245
  if (id) {
206
- await actions.sendBroadcast({ broadcastId: id })
246
+ await adapter.broadcasts.send({ broadcastId: id })
207
247
  // optional ISO 8601 or natural language, depending on Resend SDK:
208
- // await actions.sendBroadcast({ broadcastId: id, scheduledAt: "2026-12-01T15:00:00.000Z" })
248
+ // await adapter.broadcasts.send({ broadcastId: id, scheduledAt: "2026-12-01T15:00:00.000Z" })
209
249
  }
210
250
  ```
211
251
 
212
252
  ### Mailchimp (HTML body)
213
253
 
214
254
  ```ts
215
- import { createMarketingActions } from "payload-plugin-marketing"
216
255
  import { mailchimpAdapter } from "payload-plugin-marketing/adapters/mailchimp"
217
256
 
218
257
  const adapter = mailchimpAdapter({
@@ -220,9 +259,8 @@ const adapter = mailchimpAdapter({
220
259
  defaultSender: "newsletter@example.com",
221
260
  siteName: "Acme",
222
261
  })
223
- const actions = createMarketingActions({ adapter })
224
262
 
225
- await actions.createBroadcast({
263
+ await adapter.broadcasts.create({
226
264
  audienceId: "<list-id>",
227
265
  name: "January update",
228
266
  subject: "What we shipped",
@@ -232,18 +270,18 @@ await actions.createBroadcast({
232
270
  const campaigns = await adapter.broadcasts.list()
233
271
  const id = campaigns[0]?.id
234
272
  if (id) {
235
- await actions.sendBroadcast({ broadcastId: id })
273
+ await adapter.broadcasts.send({ broadcastId: id })
236
274
  // or schedule:
237
- // await actions.sendBroadcast({ broadcastId: id, scheduledAt: "2026-12-01T15:00:00.000Z" })
275
+ // await adapter.broadcasts.send({ broadcastId: id, scheduledAt: "2026-12-01T15:00:00.000Z" })
238
276
  }
239
277
  ```
240
278
 
241
279
  ### Mailchimp (saved template)
242
280
 
243
- Use the numeric template id from your Mailchimp account as a string. Do not pass **`html`** in the same call. Reuse `actions` from the Mailchimp example above (same adapter and `createMarketingActions`).
281
+ Use the numeric template id from your Mailchimp account as a string. Do not pass **`html`** in the same call.
244
282
 
245
283
  ```ts
246
- await actions.createBroadcast({
284
+ await adapter.broadcasts.create({
247
285
  audienceId: "<list-id>",
248
286
  name: "Monthly newsletter",
249
287
  subject: "News from Acme",
@@ -254,5 +292,5 @@ await actions.createBroadcast({
254
292
  ### Delete a draft broadcast
255
293
 
256
294
  ```ts
257
- await actions.deleteBroadcast({ broadcastId: "<broadcast-or-campaign-id>" })
295
+ await adapter.broadcasts.delete({ broadcastId: "<broadcast-or-campaign-id>" })
258
296
  ```
@@ -0,0 +1,6 @@
1
+ export declare function CreateAudienceButton(): import("react/jsx-runtime").JSX.Element;
2
+ export declare function DeleteAudienceButton({ audienceId, audienceName, }: {
3
+ audienceId: string;
4
+ audienceName: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=audience-buttons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audience-buttons.d.ts","sourceRoot":"","sources":["../../../src/admin/components/audience-buttons.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,oBAAoB,4CAYnC;AA6DD,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,EACV,YAAY,GACb,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB,2CA4CA"}
@@ -0,0 +1,6 @@
1
+ import type { AdminViewServerProps } from "payload";
2
+ export type AudienceDetailViewProps = AdminViewServerProps & {
3
+ basePath?: string;
4
+ };
5
+ export default function AudienceDetail({ initPageResult, params, searchParams, }: AudienceDetailViewProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=audience-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audience-detail.d.ts","sourceRoot":"","sources":["../../../src/admin/components/audience-detail.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,GAAG;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,cAAc,EACd,MAAM,EACN,YAAY,GACb,EAAE,uBAAuB,2CAczB"}
@@ -0,0 +1,6 @@
1
+ import type { AdminViewServerProps } from "payload";
2
+ export type AudienceListViewProps = AdminViewServerProps & {
3
+ basePath?: string;
4
+ };
5
+ export default function AudienceList({ basePath, initPageResult, params, searchParams, }: AudienceListViewProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=audience-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audience-list.d.ts","sourceRoot":"","sources":["../../../src/admin/components/audience-list.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,GAAG;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,QAAa,EACb,cAAc,EACd,MAAM,EACN,YAAY,GACb,EAAE,qBAAqB,2CAQvB"}
@@ -0,0 +1,6 @@
1
+ import type { AdminViewServerProps } from "payload";
2
+ export type BroadcastListViewProps = AdminViewServerProps & {
3
+ basePath?: string;
4
+ };
5
+ export default function BroadcastList({ initPageResult, params, searchParams, }: BroadcastListViewProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=broadcast-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast-list.d.ts","sourceRoot":"","sources":["../../../src/admin/components/broadcast-list.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAGnD,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,GAAG;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,cAAc,EACd,MAAM,EACN,YAAY,GACb,EAAE,sBAAsB,2CAQxB"}
@@ -0,0 +1,14 @@
1
+ import type { MarketingBroadcast } from "../../types";
2
+ export interface MarketingBroadcastRow extends MarketingBroadcast {
3
+ externalDashboardUrl?: string;
4
+ }
5
+ interface BroadcastsTableProps {
6
+ broadcasts: MarketingBroadcastRow[];
7
+ }
8
+ export declare function BroadcastsTable({ broadcasts }: BroadcastsTableProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function SendBroadcastButton({ broadcastId, broadcastName, }: {
10
+ broadcastId: string;
11
+ broadcastName: string;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=broadcasts-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcasts-table.d.ts","sourceRoot":"","sources":["../../../src/admin/components/broadcasts-table.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGrD,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,UAAU,oBAAoB;IAC5B,UAAU,EAAE,qBAAqB,EAAE,CAAA;CACpC;AAED,wBAAgB,eAAe,CAAC,EAAE,UAAU,EAAE,EAAE,oBAAoB,2CAgFnE;AAsED,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,aAAa,GACd,EAAE;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;CACtB,2CAkEA"}
@@ -0,0 +1,12 @@
1
+ import type { MarketingContact } from "../../types";
2
+ interface ContactsTableProps {
3
+ audienceId: string;
4
+ contacts: MarketingContact[];
5
+ }
6
+ export declare function ContactsTable({ audienceId, contacts }: ContactsTableProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function EditContactButton({ audienceId, contact, }: {
8
+ audienceId: string;
9
+ contact: MarketingContact | null;
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=contacts-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts-table.d.ts","sourceRoot":"","sources":["../../../src/admin/components/contacts-table.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAInD,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC7B;AAED,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,kBAAkB,2CAgFzE;AAwDD,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,OAAO,GACR,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;CACjC,2CAgBA"}
@@ -0,0 +1,6 @@
1
+ import type { MarketingAudience } from "../../types";
2
+ export declare function CreateBroadcastButton({ audiences, provider, }: {
3
+ audiences: MarketingAudience[];
4
+ provider: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=create-broadcast-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-broadcast-button.d.ts","sourceRoot":"","sources":["../../../src/admin/components/create-broadcast-button.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAMpD,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;CACjB,2CAYA"}
@@ -1,4 +1,5 @@
1
- export declare function AudienceSelect(): null;
1
+ import type { TextFieldClientComponent } from "payload";
2
+ export declare const AudienceSelect: TextFieldClientComponent;
2
3
  export declare function MarketingMenu({ basePath }: {
3
4
  basePath?: string;
4
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -20,4 +21,4 @@ export declare function BroadcastsTable({ broadcasts, }: {
20
21
  name: string;
21
22
  }>;
22
23
  }): import("react/jsx-runtime").JSX.Element;
23
- //# sourceMappingURL=components.d.ts.map
24
+ //# sourceMappingURL=marketing-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketing-components.d.ts","sourceRoot":"","sources":["../../../src/admin/components/marketing-components.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAkBvD,eAAO,MAAM,cAAc,EAAE,wBA6C5B,CAAA;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAa,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,2CAWrE;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,2CAY9F;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,2CAY7F;AAED,wBAAgB,eAAe,CAAC,EAC9B,UAAU,GACX,EAAE;IACD,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChD,2CAYA"}
@@ -0,0 +1,8 @@
1
+ import type { AdminViewServerProps } from "payload";
2
+ import type { ReactNode } from "react";
3
+ type ShellProps = Pick<AdminViewServerProps, "initPageResult" | "params" | "searchParams"> & {
4
+ children: ReactNode;
5
+ };
6
+ export declare function MarketingViewShell({ children, initPageResult, params, searchParams }: ShellProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=marketing-view-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketing-view-shell.d.ts","sourceRoot":"","sources":["../../../src/admin/components/marketing-view-shell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,KAAK,UAAU,GAAG,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,GAAG,QAAQ,GAAG,cAAc,CAAC,GAAG;IAC3F,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,UAAU,2CAehG"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { Button, Modal } from "@payloadcms/ui";
3
+ interface PayloadModalProps extends React.ComponentProps<typeof Modal> {
4
+ children: React.ReactNode;
5
+ }
6
+ declare function PayloadModal({ children, className: _className, slug: modalSlug, ...props }: PayloadModalProps): import("react/jsx-runtime").JSX.Element;
7
+ declare function PayloadModalContent({ children, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
8
+ declare function PayloadModalBody({ children, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
9
+ declare function PayloadModalTitle({ children, ...props }: React.ComponentProps<"h1">): import("react/jsx-runtime").JSX.Element;
10
+ declare function PayloadModalFooter({ children, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
11
+ declare function PayloadModalClose({ children, className: _className, ...props }: React.ComponentProps<typeof Button>): import("react/jsx-runtime").JSX.Element;
12
+ export { PayloadModal, PayloadModalBody, PayloadModalClose, PayloadModalContent, PayloadModalFooter, PayloadModalTitle, };
13
+ //# sourceMappingURL=payload-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload-modal.d.ts","sourceRoot":"","sources":["../../../src/admin/components/payload-modal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,KAAK,EAA4B,MAAM,gBAAgB,CAAA;AAIxE,UAAU,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,OAAO,KAAK,CAAC;IACpE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,iBAAS,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,2CAgBtG;AAED,iBAAS,mBAAmB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAM/E;AAED,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAM5E;AAED,iBAAS,iBAAiB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,2CAM5E;AAED,iBAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAM9E;AAED,iBAAS,iBAAiB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,2CAmB5G;AAED,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,CAAA"}
@@ -0,0 +1,8 @@
1
+ export interface ProviderDashboardLinkProps {
2
+ children: React.ReactNode;
3
+ className?: string;
4
+ dashboardUrl?: string;
5
+ }
6
+ /** External link styled like the Acme template’s “powered by” row. Provider name is baked into anchor text via children. */
7
+ export declare function ProviderDashboardLink({ children, dashboardUrl }: ProviderDashboardLinkProps): import("react/jsx-runtime").JSX.Element | null;
8
+ //# sourceMappingURL=provider-dashboard-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-dashboard-link.d.ts","sourceRoot":"","sources":["../../../src/admin/components/provider-dashboard-link.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,4HAA4H;AAC5H,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,0BAA0B,kDAe3F"}
@@ -0,0 +1,4 @@
1
+ import type { AdminViewServerProps } from "payload";
2
+ /** Resolve audience id from custom admin view params (`:id` or URL segments). */
3
+ export declare function marketingAudienceIdFromParams(params: AdminViewServerProps["params"] | undefined): string | undefined;
4
+ //# sourceMappingURL=view-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-params.d.ts","sourceRoot":"","sources":["../../../src/admin/components/view-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAYnD,iFAAiF;AACjF,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,SAAS,GACjD,MAAM,GAAG,SAAS,CA+BpB"}
@@ -0,0 +1,4 @@
1
+ export { default as AudienceDetail } from "./audience-detail";
2
+ export { default as AudienceList } from "./audience-list";
3
+ export { default as BroadcastList } from "./broadcast-list";
4
+ //# sourceMappingURL=views.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../../src/admin/components/views.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function formatMarketingDate(iso?: string | null): string;
2
+ //# sourceMappingURL=date-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-format.d.ts","sourceRoot":"","sources":["../../src/admin/date-format.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAM/D"}
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var r in t)d(e,r,{get:t[r],enumerable:!0})},B=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of y(t))!x.call(e,i)&&i!==r&&d(e,i,{get:()=>t[i],enumerable:!(o=A(t,i))||o.enumerable});return e};var k=e=>B(d({},"__esModule",{value:!0}),e);var L={};v(L,{AudienceDetail:()=>f,AudienceList:()=>b,AudienceSelect:()=>u,AudienceTable:()=>l,BroadcastList:()=>g,BroadcastsTable:()=>p,ContactsTable:()=>m,MarketingMenu:()=>s,defaultAdminComponentPath:()=>T});module.exports=k(L);var n=require("react/jsx-runtime");function u(){return null}function c(e,t){return["/admin",e?.replace(/^\/+|\/+$/g,""),t].filter(Boolean).join("/")}function s({basePath:e=""}){return(0,n.jsxs)("nav",{children:[(0,n.jsx)("a",{href:c(e,"audience"),children:"Audience"}),(0,n.jsx)("a",{href:c(e,"broadcast"),children:"Broadcasts"})]})}function l({audiences:e}){return(0,n.jsx)("table",{children:(0,n.jsx)("tbody",{children:e.map(t=>(0,n.jsx)("tr",{children:(0,n.jsx)("td",{children:t.name})},t.id))})})}function m({contacts:e}){return(0,n.jsx)("table",{children:(0,n.jsx)("tbody",{children:e.map(t=>(0,n.jsx)("tr",{children:(0,n.jsx)("td",{children:t.email})},t.id))})})}function p({broadcasts:e}){return(0,n.jsx)("table",{children:(0,n.jsx)("tbody",{children:e.map(t=>(0,n.jsx)("tr",{children:(0,n.jsx)("td",{children:t.name})},t.id))})})}var a=require("react/jsx-runtime");function b(){return(0,a.jsx)("div",{children:"Audience"})}function f(){return(0,a.jsx)("div",{children:"Audience Detail"})}function g(){return(0,a.jsx)("div",{children:"Broadcasts"})}var T="payload-plugin-marketing/admin";0&&(module.exports={AudienceDetail,AudienceList,AudienceSelect,AudienceTable,BroadcastList,BroadcastsTable,ContactsTable,MarketingMenu,defaultAdminComponentPath});
1
+ "use strict";var We=Object.create;var W=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Ke=Object.getOwnPropertyNames;var Qe=Object.getPrototypeOf,Xe=Object.prototype.hasOwnProperty;var Ze=(e,t)=>{for(var a in t)W(e,a,{get:t[a],enumerable:!0})},Me=(e,t,a,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ke(t))!Xe.call(e,r)&&r!==a&&W(e,r,{get:()=>t[r],enumerable:!(n=Ye(t,r))||n.enumerable});return e};var L=(e,t,a)=>(a=e!=null?We(Qe(e)):{},Me(t||!e||!e.__esModule?W(a,"default",{value:e,enumerable:!0}):a,e)),et=e=>Me(W({},"__esModule",{value:!0}),e);var ht={};Ze(ht,{AudienceDetail:()=>Z,AudienceList:()=>ee,AudienceSelect:()=>we,AudienceTable:()=>Se,BroadcastList:()=>ne,BroadcastsTable:()=>Ce,ContactsTable:()=>xe,MarketingMenu:()=>ve,defaultAdminComponentPath:()=>bt});module.exports=et(ht);var K=L(require("react"),1),E=require("@payloadcms/ui");var ke=require("@payloadcms/ui"),Y=require("react");function S(){let e=(0,ke.useConfig)(),t=(0,Y.useMemo)(()=>`${e.serverURL??""}${e.routes?.api??"/api"}`,[e.routes?.api,e.serverURL]),a=(0,Y.useCallback)(async(n,r)=>{let{headers:o,...i}=r??{},d=new Headers(r?.headers);i.body!==void 0&&i.body!==""&&i.body!==null&&(d.has("Content-Type")||d.set("Content-Type","application/json"));let c=await fetch(`${t}${n}`,{...i,credentials:"include",headers:d});if(!c.ok){let M=`${c.status} ${c.statusText}`;try{let v=await c.json();typeof v.message=="string"&&(M=v.message)}catch{}throw new Error(M)}if(c.status!==204)try{return await c.json()}catch{return}},[t]);return{base:t,requestJson:a}}function tt(e,...t){let a=e.replace(/\/+$/,"")||"",n=t.flatMap(o=>String(o).split("/")).map(o=>o.replace(/^\/+|\/+$/g,"")).filter(Boolean).join("/");return(a===""?`/${n}`:`${a}/${n}`).replace(/\/{2,}/g,"/")}function U(e,...t){let n=[e?.replace(/^\/+|\/+$/g,"")??"",...t].filter(Boolean);return tt("/admin",...n)}var h=require("react/jsx-runtime");function at(e){if(!Array.isArray(e))return[];let t=[];for(let a of e){if(!a||typeof a!="object")continue;let n=a,r=n.id,o=n.name;typeof r=="string"&&typeof o=="string"&&t.push({id:r,name:o})}return t}var we=({field:e,path:t,readOnly:a})=>{let{requestJson:n}=S(),[r,o]=K.default.useState([]),[i,d]=K.default.useState(null);return K.default.useEffect(()=>{let c=!1;return(async()=>{try{let M=await n("/marketing/audiences");c||(o(at(M)),d(null))}catch(M){c||d(M instanceof Error?M.message:"Failed to load audiences")}})(),()=>{c=!0}},[n]),(0,h.jsxs)("div",{className:"field-type relative",children:[i?(0,h.jsx)("p",{className:"text-red-500",role:"alert",children:i}):null,(0,h.jsx)(E.SelectField,{field:{label:typeof e.label=="string"?e.label:"Audience",name:e.name,options:r.map(c=>({label:c.name,value:c.id})),required:e.required===!0,type:"select"},path:t,readOnly:a})]})};function ve({basePath:e=""}){return(0,h.jsxs)(E.NavGroup,{isOpen:!0,label:"Marketing",children:[(0,h.jsx)(E.Link,{className:"nav__link",href:U(e,"audience"),children:"Audience"}),(0,h.jsx)(E.Link,{className:"nav__link",href:U(e,"broadcast"),children:"Broadcast"})]})}function Se({audiences:e}){return(0,h.jsx)("table",{children:(0,h.jsx)("tbody",{children:e.map(t=>(0,h.jsx)("tr",{children:(0,h.jsx)("td",{children:t.name})},t.id))})})}function xe({contacts:e}){return(0,h.jsx)("table",{children:(0,h.jsx)("tbody",{children:e.map(t=>(0,h.jsx)("tr",{children:(0,h.jsx)("td",{children:t.email})},t.id))})})}function Ce({broadcasts:e}){return(0,h.jsx)("table",{children:(0,h.jsx)("tbody",{children:e.map(t=>(0,h.jsx)("tr",{children:(0,h.jsx)("td",{children:t.name})},t.id))})})}var Ee=require("react"),qe=require("next/navigation"),X=require("@payloadcms/ui");var Ae="payloadPluginMarketing";function oe(e){return{read:e?.read??!0,write:e?.write??!0}}function V(e){return e?{audiences:oe(e.audiences),contacts:oe(e.contacts),broadcasts:oe(e.broadcasts)}:{audiences:{read:!0,write:!0},broadcasts:{read:!0,write:!0},contacts:{read:!0,write:!0}}}function Be(e){let t=e.config.custom;if(!t||typeof t!="object")return;let a=t[Ae];if(a?.adapter)return a}function C(e){let t=Be(e);if(!t)throw new Error(`${Ae}: adapter missing on Payload config. Is marketingPlugin() registered?`);return t}function $(e){return Be(e)}var Q=L(require("react"),1),u=require("@payloadcms/ui"),ie=require("next/navigation"),Ne=L(require("react"),1),Te=require("react");function G(e){if(!e)return"\u2014";let t=new Date(e);return Number.isNaN(t.valueOf())?String(e):new Intl.DateTimeFormat(void 0,{dateStyle:"medium"}).format(t)}var J=L(require("react"),1),F=require("@payloadcms/ui"),I=require("react/jsx-runtime"),Re=J.default.createContext({modalSlug:""});function A({children:e,className:t,slug:a,...n}){let[r,o]=J.default.useState(!1);return J.default.useEffect(()=>{o(!0)},[]),(0,I.jsx)(Re.Provider,{value:{modalSlug:a},children:r&&(0,I.jsx)(F.Modal,{slug:a,...n,children:e})})}function B({children:e,...t}){return(0,I.jsx)("div",{"data-slot":"payload-modal-content",...t,children:e})}function R({children:e,...t}){return(0,I.jsx)("div",{"data-slot":"payload-modal-body",...t,children:e})}function H({children:e,...t}){return(0,I.jsx)("h1",{"data-slot":"payload-modal-title",...t,children:e})}function N({children:e,...t}){return(0,I.jsx)("div",{"data-slot":"payload-modal-footer",...t,children:e})}function T({children:e,className:t,...a}){let{t:n}=(0,F.useTranslation)(),{modalSlug:r}=J.default.useContext(Re),o=(0,F.useModal)();return(0,I.jsx)(F.Button,{buttonStyle:"secondary","data-slot":"payload-modal-close",size:"large",...a,onClick:i=>{o.closeModal(r),a.onClick?.(i)},children:e??n("general:cancel")})}var l=require("react/jsx-runtime");function Ie({audienceId:e,contacts:t}){let[a,n]=Q.default.useState(1),[r]=Q.default.useState(100),o=Q.default.useMemo(()=>t.slice((a-1)*r,a*r),[t,r,a]);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(u.Table,{columns:[{Heading:"First name",accessor:"firstName",active:!0,field:{name:"firstName",type:"text"},renderedCells:o.map(i=>(0,l.jsx)("div",{children:i.firstName??"\u2014"},i.id))},{Heading:"Last name",accessor:"lastName",active:!0,field:{name:"lastName",type:"text"},renderedCells:o.map(i=>(0,l.jsx)("div",{children:i.lastName??"\u2014"},i.id))},{Heading:"Email",accessor:"email",active:!0,field:{name:"email",type:"text"},renderedCells:o.map(i=>(0,l.jsx)("div",{children:i.email},i.id))},{Heading:"Created",accessor:"createdAt",active:!0,field:{name:"createdAt",type:"text"},renderedCells:o.map(i=>(0,l.jsx)("div",{children:G(i.createdAt)},i.id))},{Heading:"Status",accessor:"subscribed",active:!0,field:{name:"subscribed",type:"text"},renderedCells:o.map(i=>(0,l.jsxs)("div",{className:"flex items-center gap-4 flex-wrap",children:[(0,l.jsx)("span",{children:i.subscribed!==!1?"\u2705 subscribed":"\u274C unsubscribed"}),(0,l.jsx)(se,{audienceId:e,contact:i}),(0,l.jsx)(nt,{audienceId:e,contactEmail:i.email,contactId:i.id})]},i.id))}],data:o}),(0,l.jsx)(u.Pagination,{hasNextPage:a*r<t.length,hasPrevPage:a>1,limit:r,onChange:i=>{n(i)},page:a,totalPages:Math.ceil(t.length/r)})]})}function nt({audienceId:e,contactId:t,contactEmail:a}){let n=(0,u.useModal)(),{t:r}=(0,u.useTranslation)(),o=(0,ie.useRouter)(),{requestJson:i}=S(),d=`delete-contact_${t}`;async function c(){await i(`/marketing/audiences/${encodeURIComponent(e)}/contacts/${encodeURIComponent(t)}`,{method:"DELETE"}),u.toast.success(r("general:deletedSuccessfully")),n.closeModal(d),o.refresh()}return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(A,{slug:d,children:(0,l.jsxs)(B,{children:[(0,l.jsxs)(R,{children:[(0,l.jsx)("h1",{children:r("general:confirmDeletion")}),(0,l.jsx)("p",{children:`Remove contact ${a}?`})]}),(0,l.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,l.jsx)(T,{}),(0,l.jsx)(u.Button,{buttonStyle:"error",onClick:()=>{c().catch(M=>u.toast.error(M instanceof Error?M.message:"Delete failed"))},children:r("general:confirm")})]})]})}),(0,l.jsx)("button",{onClick:()=>n.openModal(d),type:"button",children:r("general:delete")})]})}function se({audienceId:e,contact:t}){let a=(0,u.useModal)(),{t:n}=(0,u.useTranslation)(),r=Ne.default.useId(),o=t?`edit-contact_${t.id}`:`create-contact_${e}_${r}`;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(rt,{audienceId:e,contact:t,modalSlug:o}),(0,l.jsx)(t?"button":u.Button,{...t?{}:{size:"large"},onClick:()=>a.openModal(o),type:"button",children:n(t?"general:edit":"general:createNew")})]})}function rt({audienceId:e,contact:t,modalSlug:a}){let n=(0,u.useModal)(),{t:r}=(0,u.useTranslation)(),o=(0,ie.useRouter)(),{requestJson:i}=S(),[,d]=(0,Te.useTransition)(),c=(M,v)=>{let x=v.email,k=String(v.firstName??""),D=String(v.lastName??""),j=!!v.subscribed;d(()=>{(async()=>{try{await i("/marketing/contacts",{body:JSON.stringify({audienceId:e,email:x,firstName:k,id:t?.id,lastName:D,subscribed:j}),method:"POST"}),u.toast.success(t?"Contact updated.":"Contact created."),n.closeModal(a),o.refresh()}catch(O){u.toast.error(O instanceof Error?O.message:"Save failed")}})()})};return(0,l.jsx)(A,{slug:a,children:(0,l.jsx)(B,{style:{width:"100%",maxWidth:"32rem"},children:(0,l.jsxs)(R,{children:[(0,l.jsx)("h1",{children:r(t?"general:edit":"general:createNew")}),(0,l.jsxs)(u.Form,{className:"flex w-full flex-col gap-6",initialState:{email:{value:t?.email??""},firstName:{value:t?.firstName??""},lastName:{value:t?.lastName??""},subscribed:{value:t?.subscribed!==!1}},onSubmit:c,waitForAutocomplete:!0,children:[(0,l.jsx)(u.TextField,{field:{label:r("general:email"),name:"email",required:!0,type:"text"},path:"email",validate:M=>typeof M=="string"&&M.includes("@")?!0:"Valid email required"}),(0,l.jsx)(u.TextField,{field:{label:"First name",name:"firstName",type:"text"},path:"firstName"}),(0,l.jsx)(u.TextField,{field:{label:"Last name",name:"lastName",type:"text"},path:"lastName"}),(0,l.jsx)(u.CheckboxField,{field:{label:"Subscribed",name:"subscribed"},path:"subscribed"}),(0,l.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,l.jsx)(T,{}),(0,l.jsx)(u.Button,{size:"large",type:"submit",children:r(t?"general:save":"general:create")})]})]})]})})})}var Fe=require("@payloadcms/next/templates"),De=require("react/jsx-runtime");function _({children:e,initPageResult:t,params:a,searchParams:n}){return(0,De.jsx)(Fe.DefaultTemplate,{i18n:t.req.i18n,locale:t.locale,params:a,payload:t.req.payload,permissions:t.permissions,searchParams:n,user:t.req.user??void 0,visibleEntities:t.visibleEntities,children:e})}function ot(e){if(typeof e=="string"&&e.trim())return e.trim();if(Array.isArray(e)&&typeof e[0]=="string"&&e[0].trim())return e[0].trim()}function Le(e){if(!e)return;let t=ot(e.id);if(t)return t;let a=e.segments,n=Array.isArray(a)?a.filter(i=>typeof i=="string"&&i.length>0):typeof a=="string"?a.split("/").filter(Boolean):[];if(n.length===0)return;let r=n.lastIndexOf("audience");if(r>=0&&n[r+1])return n[r+1];let o=n[n.length-1];if(o!=="audience")return o}var b=require("react/jsx-runtime");function Z({initPageResult:e,params:t,searchParams:a}){let n=Le(t);if(!n)throw new Error("No audience id in route params");return(0,b.jsx)(_,{initPageResult:e,params:t,searchParams:a,children:(0,b.jsx)(X.Gutter,{children:(0,b.jsx)(it,{audienceId:n,initPageResult:e})})})}async function it({audienceId:e,initPageResult:t}){let a=$(t.req.payload);if(!a)return(0,b.jsx)("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let n=V(a.permissions);if(!n.audiences.read)return(0,b.jsx)("p",{role:"alert",children:"You do not have permission to view this audience."});let{adapter:r}=C(t.req.payload),o=await r.audiences.get(e);o||(0,qe.notFound)();let i=r.urls?.audience?.(e);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("header",{className:"flex flex-col gap-4",children:[(0,b.jsx)("h1",{children:o.name}),i?(0,b.jsxs)(X.Link,{href:i,rel:"noreferrer noopener",target:"_blank",children:["Open this audience in ",r.label]}):null]}),(0,b.jsxs)("div",{className:"mt-12 flex flex-col gap-6",children:[n.contacts.write?(0,b.jsx)("div",{children:(0,b.jsx)(se,{audienceId:e,contact:null})}):null,n.contacts.read?(0,b.jsx)(Ee.Suspense,{fallback:(0,b.jsx)("div",{"aria-busy":!0,style:{minHeight:"12rem"}}),children:(0,b.jsx)(st,{audienceId:e,initPageResult:t})}):(0,b.jsx)("p",{role:"alert",children:"You do not have permission to list contacts."})]})]})}async function st({audienceId:e,initPageResult:t}){let{adapter:a}=C(t.req.payload),n=await a.contacts.list({audienceId:e});return(0,b.jsx)(Ie,{audienceId:e,contacts:n})}var _e=require("react"),q=require("@payloadcms/ui");var Ve=require("react"),P=require("@payloadcms/ui"),de=require("next/navigation");var p=require("react/jsx-runtime"),le="create-audience";function $e(){let e=(0,P.useModal)(),{t}=(0,P.useTranslation)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(lt,{}),(0,p.jsx)(P.Button,{onClick:()=>e.openModal(le),size:"large",type:"button",children:t("general:createNew")})]})}function lt(){let e=(0,P.useModal)(),{t}=(0,P.useTranslation)(),a=(0,de.useRouter)(),{requestJson:n}=S(),[r,o]=(0,Ve.useTransition)();return(0,p.jsx)(A,{closeOnBlur:!0,slug:le,children:(0,p.jsx)(B,{style:{width:"100%",maxWidth:"24rem"},children:(0,p.jsx)(P.Form,{initialState:{},onSubmit:(d,c)=>{let v=c.audienceName,x=typeof v=="string"?v.trim():"";o(()=>{(async()=>{try{if(!x)throw new Error("Name is required.");await n("/marketing/audiences",{body:JSON.stringify({name:x}),method:"POST"}),e.closeModal(le),P.toast.success(t("general:successfullyCreated")),a.refresh()}catch(k){P.toast.error(k instanceof Error?k.message:"Create failed")}})()})},waitForAutocomplete:!0,children:(0,p.jsxs)(R,{children:[(0,p.jsx)(H,{children:t("general:createNew")}),(0,p.jsx)(P.TextField,{field:{name:"audienceName",required:!0,type:"text"},path:"audienceName",validate:d=>typeof d=="string"&&d.trim().length>0?!0:"Name is required"}),(0,p.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,p.jsx)(T,{}),(0,p.jsx)(P.Button,{disabled:r,size:"large",type:"submit",children:t("general:confirm")})]})]})})})})}function He({audienceId:e,audienceName:t}){let a=(0,P.useModal)(),{t:n}=(0,P.useTranslation)(),r=(0,de.useRouter)(),{requestJson:o}=S(),i=`delete-audience_${e}`;async function d(){await o(`/marketing/audiences/${encodeURIComponent(e)}`,{method:"DELETE"}),P.toast.success(n("general:deletedSuccessfully")),a.closeModal(i),r.refresh()}return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(A,{slug:i,children:(0,p.jsxs)(B,{children:[(0,p.jsxs)(R,{children:[(0,p.jsx)(H,{children:n("general:confirmDeletion")}),(0,p.jsx)("p",{children:`Remove audience "${t}"?`})]}),(0,p.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,p.jsx)(T,{}),(0,p.jsx)(P.Button,{buttonStyle:"error",onClick:()=>{d().catch(c=>P.toast.error(c instanceof Error?c.message:"Delete failed"))},children:n("general:confirm")})]})]})}),(0,p.jsx)("button",{onClick:()=>a.openModal(i),type:"button",children:n("general:delete")})]})}var g=require("react/jsx-runtime");function ee({basePath:e="",initPageResult:t,params:a,searchParams:n}){return(0,g.jsx)(_,{initPageResult:t,params:a,searchParams:n,children:(0,g.jsx)(q.Gutter,{children:(0,g.jsx)(dt,{basePath:e,initPageResult:t})})})}function dt({basePath:e,initPageResult:t}){let a=$(t.req.payload);if(!a)return(0,g.jsx)("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let n=V(a.permissions);if(!n.audiences.read)return(0,g.jsx)("p",{role:"alert",children:"You do not have permission to view audiences."});let r=a.adapter.urls?.audiences;return(0,g.jsxs)(g.Fragment,{children:[(0,g.jsxs)("header",{className:"flex flex-col gap-4",children:[(0,g.jsx)("h1",{children:"Audiences"}),r?(0,g.jsxs)(q.Link,{href:r,rel:"noreferrer noopener",target:"_blank",children:["View audiences in ",a.adapter.label]}):null]}),(0,g.jsxs)("div",{className:"mt-4 flex flex-col gap-8",children:[n.audiences.write?(0,g.jsx)("div",{children:(0,g.jsx)($e,{})}):null,(0,g.jsx)(_e.Suspense,{fallback:(0,g.jsx)("div",{"aria-busy":!0,style:{minHeight:"4rem"}}),children:(0,g.jsx)(ct,{audiencesWrite:n.audiences.write,basePath:e,initPageResult:t})})]})]})}async function ct({audiencesWrite:e,basePath:t,initPageResult:a}){let{adapter:n}=C(a.req.payload),r=await n.audiences.list(),o={Heading:"Name",accessor:"name",active:!0,field:{name:"name",type:"text"},renderedCells:r.map(d=>(0,g.jsx)("div",{children:(0,g.jsx)(q.Link,{href:U(t,"audience",d.id),children:d.name})},d.id))},i={Heading:"",accessor:"",active:!0,field:{name:"_delete",type:"text"},renderedCells:r.map(d=>(0,g.jsx)("div",{children:(0,g.jsx)(He,{audienceId:d.id,audienceName:d.name})},d.id))};return(0,g.jsx)(q.Table,{columns:e?[o,i]:[o],data:r})}var me=require("react"),ae=require("@payloadcms/ui");var te=L(require("react"),1),m=require("@payloadcms/ui"),Oe=L(require("next/link"),1),ce=require("next/navigation");var s=require("react/jsx-runtime");function Ue({broadcasts:e}){let[t,a]=te.default.useState(1),[n]=te.default.useState(100),r=te.default.useMemo(()=>e.slice((t-1)*n,t*n),[e,n,t]);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(m.Table,{columns:[{Heading:"Campaign name",accessor:"name",active:!0,field:{name:"name",type:"text"},renderedCells:r.map(o=>(0,s.jsx)("div",{children:o.name},o.id))},{Heading:"Schedule date",accessor:"scheduledAt",active:!0,field:{name:"scheduledAt",type:"text"},renderedCells:r.map(o=>(0,s.jsx)("div",{children:G(o.scheduledAt)},o.id))},{Heading:"Sent date",accessor:"sentAt",active:!0,field:{name:"sentAt",type:"text"},renderedCells:r.map(o=>(0,s.jsx)("div",{children:G(o.sentAt)},o.id))},{Heading:"Status",accessor:"status",active:!0,field:{name:"status",type:"text"},renderedCells:r.map(o=>(0,s.jsx)("div",{children:(0,s.jsx)(ut,{status:o.status})},o.id))},{Heading:"",accessor:"",active:!0,field:{name:"_",type:"text"},renderedCells:r.map(o=>(0,s.jsxs)("div",{className:"flex items-center gap-4 flex-wrap",children:[o.externalDashboardUrl?(0,s.jsx)(Oe.default,{href:o.externalDashboardUrl,rel:"noreferrer noopener",target:"_blank",children:(0,s.jsx)(m.Pill,{children:"dashboard \u2197"})}):null,o.status==="draft"||o.status==="save"?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(mt,{broadcastId:o.id,broadcastName:o.name}),(0,s.jsx)(pt,{broadcastId:o.id,broadcastName:o.name})]}):null]},o.id))}],data:r}),(0,s.jsx)(m.Pagination,{hasNextPage:t*n<e.length,hasPrevPage:t>1,limit:n,onChange:o=>a(o),page:t,totalPages:Math.ceil(e.length/n)})]})}function ut({status:e}){switch(e){case"draft":case"save":return(0,s.jsx)(m.Pill,{pillStyle:"light-gray",children:"Draft"});case"queued":return(0,s.jsx)(m.Pill,{pillStyle:"white",children:"Queued"});case"sent":return(0,s.jsx)(m.Pill,{pillStyle:"success",children:"Sent"});default:return(0,s.jsx)(m.Pill,{children:e})}}function mt({broadcastId:e,broadcastName:t}){let a=(0,m.useModal)(),{t:n}=(0,m.useTranslation)(),r=(0,ce.useRouter)(),{requestJson:o}=S(),i=`delete-broadcast_${e}`;async function d(){await o(`/marketing/broadcasts/${encodeURIComponent(e)}`,{method:"DELETE"}),m.toast.success(n("general:deletedSuccessfully")),a.closeModal(i),r.refresh()}return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A,{slug:i,children:(0,s.jsxs)(B,{children:[(0,s.jsxs)(R,{children:[(0,s.jsx)(H,{children:n("general:confirmDeletion")}),(0,s.jsx)("p",{children:`Delete draft broadcast "${t}"?`})]}),(0,s.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,s.jsx)(T,{}),(0,s.jsx)(m.Button,{buttonStyle:"error",onClick:()=>{d().catch(c=>m.toast.error(c instanceof Error?c.message:"Delete failed"))},children:n("general:confirm")})]})]})}),(0,s.jsx)("button",{onClick:()=>a.openModal(i),type:"button",children:n("general:delete")})]})}function pt({broadcastId:e,broadcastName:t}){let a=(0,m.useModal)(),{t:n}=(0,m.useTranslation)(),r=(0,ce.useRouter)(),{requestJson:o}=S(),i=`send-broadcast_${e}`,d=(c,M)=>{let x=M.scheduledAt,k="";typeof x=="string"?k=x:x instanceof Date&&(k=x.toISOString()),(async()=>{try{await o(`/marketing/broadcasts/${encodeURIComponent(e)}/send`,{body:JSON.stringify({...k&&k.trim()!==""?{scheduledAt:k.trim()}:{}}),method:"POST"}),a.closeModal(i),m.toast.success(n("general:success")),r.refresh()}catch(D){m.toast.error(D instanceof Error?D.message:"Send failed")}})()};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A,{slug:i,children:(0,s.jsx)(B,{style:{width:"100%",maxWidth:"24rem"},children:(0,s.jsxs)(R,{children:[(0,s.jsx)(H,{children:`Send \u201C${t}\u201D`}),(0,s.jsxs)(m.Form,{initialState:{},onSubmit:d,waitForAutocomplete:!0,children:[(0,s.jsx)(m.DateTimeField,{field:{label:"Schedule at (optional)",name:"scheduledAt",required:!1},path:"scheduledAt"}),(0,s.jsxs)(N,{style:{display:"flex",gap:"8px",justifyContent:"flex-end"},children:[(0,s.jsx)(T,{}),(0,s.jsx)(m.Button,{size:"large",type:"submit",children:"Send"})]})]})]})})}),(0,s.jsx)(m.Pill,{pillStyle:"dark",onClick:()=>a.openModal(i),size:"small",children:"Send"})]})}var Ge=L(require("react"),1),f=require("@payloadcms/ui"),Je=require("next/navigation");var w=require("react/jsx-runtime"),ue="create-marketing-broadcast";function je({audiences:e,provider:t}){let a=(0,f.useModal)(),{t:n}=(0,f.useTranslation)();return(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(ft,{audiences:e,provider:t}),(0,w.jsx)(f.Button,{onClick:()=>a.openModal(ue),size:"large",type:"button",children:n("general:createNew")})]})}function ft({audiences:e,provider:t}){let a=(0,Je.useRouter)(),n=(0,f.useModal)(),{t:r}=(0,f.useTranslation)(),{requestJson:o}=S(),[i,d]=Ge.default.useState(!1),c=t==="mailchimp",M=(v,x)=>{let k=x,D=k.audienceId,j=k.name,O=k.subject,pe=k.htmlBody,fe=k.templateId,ge=k.replyTo,ye=typeof D=="string"?D:"",Pe=typeof j=="string"?j.trim():"",be=typeof O=="string"?O.trim():"",z=typeof pe=="string"?pe.trim():"",re=typeof fe=="string"?fe.trim():"",ze=typeof ge=="string"?ge.trim():"";d(!0),(async()=>{try{if(!ye||!Pe||!be)throw new Error("Audience, name, and subject are required.");if(c){if(!re&&!z)throw new Error("Provide an HTML body or Mailchimp template id.");if(re&&z)throw new Error("Use either HTML body or Mailchimp template id, not both.")}else if(!z)throw new Error("HTML body is required for this provider.");await o("/marketing/broadcasts",{body:JSON.stringify({audienceId:ye,html:z,name:Pe,replyTo:ze,subject:be,templateId:re||void 0}),method:"POST"}),n.closeModal(ue),f.toast.success(r("general:successfullyCreated",{label:"Broadcast"})),a.refresh()}catch(he){f.toast.error(he instanceof Error?he.message:"Create failed")}finally{d(!1)}})()};return(0,w.jsx)(f.Drawer,{slug:ue,title:r("general:createNew"),children:(0,w.jsxs)(f.Form,{className:"flex w-full flex-col gap-8",initialState:{},onSubmit:M,waitForAutocomplete:!0,children:[(0,w.jsx)(f.SelectField,{field:{label:"Audience",name:"audienceId",options:e.map(v=>({label:v.name,value:v.id})),required:!0},path:"audienceId"}),(0,w.jsx)(f.TextField,{field:{label:"Campaign name",name:"name",required:!0,type:"text"},path:"name"}),(0,w.jsx)(f.TextField,{field:{label:"Subject",name:"subject",required:!0,type:"text"},path:"subject"}),(0,w.jsx)(f.TextField,{field:{label:"Reply-to (optional)",name:"replyTo",type:"text"},path:"replyTo"}),c?(0,w.jsx)(f.TextField,{field:{admin:{description:"Optional Mailchimp saved-template id (numeric string). Leave HTML empty when using templates."},label:"Template id",name:"templateId",required:!1,type:"text"},path:"templateId"}):null,(0,w.jsx)(f.TextareaField,{field:{admin:{description:c?"Optional plain HTML alternative to a Mailchimp template.":"HTML broadcast body."},label:c?"HTML body (optional with Mailchimp)":"HTML body",name:"htmlBody",required:!c},path:"htmlBody"}),(0,w.jsx)(f.Button,{className:"w-full",disabled:i,type:"submit",children:r("general:create")})]})})}var y=require("react/jsx-runtime");function ne({initPageResult:e,params:t,searchParams:a}){return(0,y.jsx)(_,{initPageResult:e,params:t,searchParams:a,children:(0,y.jsx)(ae.Gutter,{children:(0,y.jsx)(gt,{initPageResult:e})})})}function gt({initPageResult:e}){let t=$(e.req.payload);if(!t)return(0,y.jsx)("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let a=V(t.permissions);if(!a.broadcasts.read)return(0,y.jsx)("p",{role:"alert",children:"You do not have permission to view broadcasts."});let{adapter:n}=C(e.req.payload),r=n.urls?.broadcasts;return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)("header",{className:"flex flex-col gap-4",children:[(0,y.jsx)("h1",{children:"Campaigns"}),r?(0,y.jsxs)(ae.Link,{href:r,rel:"noreferrer noopener",target:"_blank",children:["View campaigns in ",n.label]}):null]}),(0,y.jsxs)("div",{className:"mt-4 flex flex-col gap-8",children:[a.broadcasts.write?(0,y.jsx)("div",{children:(0,y.jsx)(me.Suspense,{fallback:(0,y.jsx)("div",{"aria-busy":!0,style:{minHeight:"2.5rem"}}),children:(0,y.jsx)(yt,{initPageResult:e})})}):null,(0,y.jsx)(me.Suspense,{fallback:(0,y.jsx)("div",{"aria-busy":!0,style:{minHeight:"4rem"}}),children:(0,y.jsx)(Pt,{initPageResult:e})})]})]})}async function yt({initPageResult:e}){let{adapter:t}=C(e.req.payload),a=await t.audiences.list();return(0,y.jsx)(je,{audiences:a,provider:t.provider})}async function Pt({initPageResult:e}){let{adapter:t}=C(e.req.payload),n=(await t.broadcasts.list()).map(r=>({...r,externalDashboardUrl:t.urls?.broadcast?.(r.id)}));return(0,y.jsx)(Ue,{broadcasts:n})}var bt="payload-plugin-marketing/admin";0&&(module.exports={AudienceDetail,AudienceList,AudienceSelect,AudienceTable,BroadcastList,BroadcastsTable,ContactsTable,MarketingMenu,defaultAdminComponentPath});
2
2
  //# sourceMappingURL=index.cjs.map