Plugin Directory

Changeset 3788740


Ignore:
Timestamp:
11/06/2026 09:26:47 PM (less than one hour ago)
Author:
alexstandiford
Message:

Update trunk to version 3.6.267 from GitHub (part 1)

Location:
siren-affiliates/trunk
Files:
115 added
40 deleted
94 edited

Legend:

Unmodified
Added
Removed
  • siren-affiliates/trunk/frontend-source/lite-paid-sources.json

    r3775642 r3788740  
    55    "src/core/schemas/custom-currency.schema.ts",
    66    "src/core/schemas/distribution.schema.ts",
     7    "src/core/schemas/metric.schema.ts",
    78    "src/core/types/api-key.ts",
    89    "src/core/types/autofulfiller.ts",
    … …  
    1112    "src/core/types/distribution.ts",
    1213    "src/core/types/distributor.ts",
     14    "src/core/types/metric.ts",
    1315    "src/core/types/program-group.ts",
    1416    "src/core/types/webhook.ts",
    … …  
    1921    "src/service/api/distributions.ts",
    2022    "src/service/api/integrations.ts",
     23    "src/service/api/metrics.ts",
    2124    "src/service/api/webhooks.ts",
    2225    "src/service/components/payouts/email.ts",
    … …  
    2427    "src/service/screens/collaborator-groups",
    2528    "src/service/screens/integrations",
     29    "src/service/screens/metrics",
    2630    "src/service/screens/main-menu/CutoverWarnings.tsx",
    2731    "src/service/screens/main-menu/DeleteLocalDataCard.tsx",
    … …  
    3337    "src/service/stores/integrationCatalog.ts",
    3438    "src/service/stores/metric-calculations.ts",
     39    "src/service/stores/metrics.ts",
    3540    "src/service/stores/program-groups.ts"
    3641  ],
  • siren-affiliates/trunk/frontend-source/package-lock.json

    r3775642 r3788740  
    2222        "@radix-ui/react-tabs": "^1.1.2",
    2323        "@radix-ui/react-tooltip": "^1.2.8",
     24        "@shikijs/langs": "4.5.0",
    2425        "@tiptap/core": "^3.32.0",
    2526        "@tiptap/extension-bold": "^3.32.0",
    … …  
    4445        "react-router-dom": "^7.1.1",
    4546        "recharts": "^3.7.0",
     47        "shiki": "4.5.0",
    4648        "sonner": "^2.0.7",
    4749        "tailwind-merge": "^2.6.0",
    … …  
    23742376      ]
    23752377    },
     2378    "node_modules/@shikijs/core": {
     2379      "version": "4.5.0",
     2380      "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.5.0.tgz",
     2381      "integrity": "sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==",
     2382      "license": "MIT",
     2383      "dependencies": {
     2384        "@shikijs/primitive": "4.5.0",
     2385        "@shikijs/types": "4.5.0",
     2386        "@shikijs/vscode-textmate": "^10.0.2",
     2387        "@types/hast": "^3.0.5",
     2388        "hast-util-to-html": "^9.0.5"
     2389      },
     2390      "engines": {
     2391        "node": ">=20"
     2392      }
     2393    },
     2394    "node_modules/@shikijs/engine-javascript": {
     2395      "version": "4.5.0",
     2396      "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.5.0.tgz",
     2397      "integrity": "sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==",
     2398      "license": "MIT",
     2399      "dependencies": {
     2400        "@shikijs/types": "4.5.0",
     2401        "@shikijs/vscode-textmate": "^10.0.2",
     2402        "oniguruma-to-es": "^4.3.6"
     2403      },
     2404      "engines": {
     2405        "node": ">=20"
     2406      }
     2407    },
     2408    "node_modules/@shikijs/engine-oniguruma": {
     2409      "version": "4.5.0",
     2410      "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.5.0.tgz",
     2411      "integrity": "sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==",
     2412      "license": "MIT",
     2413      "dependencies": {
     2414        "@shikijs/types": "4.5.0",
     2415        "@shikijs/vscode-textmate": "^10.0.2"
     2416      },
     2417      "engines": {
     2418        "node": ">=20"
     2419      }
     2420    },
     2421    "node_modules/@shikijs/langs": {
     2422      "version": "4.5.0",
     2423      "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.5.0.tgz",
     2424      "integrity": "sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==",
     2425      "license": "MIT",
     2426      "dependencies": {
     2427        "@shikijs/types": "4.5.0"
     2428      },
     2429      "engines": {
     2430        "node": ">=20"
     2431      }
     2432    },
     2433    "node_modules/@shikijs/primitive": {
     2434      "version": "4.5.0",
     2435      "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.5.0.tgz",
     2436      "integrity": "sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==",
     2437      "license": "MIT",
     2438      "dependencies": {
     2439        "@shikijs/types": "4.5.0",
     2440        "@shikijs/vscode-textmate": "^10.0.2",
     2441        "@types/hast": "^3.0.5"
     2442      },
     2443      "engines": {
     2444        "node": ">=20"
     2445      }
     2446    },
     2447    "node_modules/@shikijs/themes": {
     2448      "version": "4.5.0",
     2449      "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.5.0.tgz",
     2450      "integrity": "sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==",
     2451      "license": "MIT",
     2452      "dependencies": {
     2453        "@shikijs/types": "4.5.0"
     2454      },
     2455      "engines": {
     2456        "node": ">=20"
     2457      }
     2458    },
     2459    "node_modules/@shikijs/types": {
     2460      "version": "4.5.0",
     2461      "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz",
     2462      "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==",
     2463      "license": "MIT",
     2464      "dependencies": {
     2465        "@shikijs/vscode-textmate": "^10.0.2",
     2466        "@types/hast": "^3.0.5"
     2467      },
     2468      "engines": {
     2469        "node": ">=20"
     2470      }
     2471    },
     2472    "node_modules/@shikijs/vscode-textmate": {
     2473      "version": "10.1.0",
     2474      "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.1.0.tgz",
     2475      "integrity": "sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==",
     2476      "license": "MIT"
     2477    },
    23762478    "node_modules/@standard-schema/spec": {
    23772479      "version": "1.1.0",
    … …  
    27852887    },
    27862888    "node_modules/@types/hast": {
    2787       "version": "3.0.4",
    2788       "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
    2789       "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
     2889      "version": "3.0.5",
     2890      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
     2891      "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
    27902892      "license": "MIT",
    27912893      "dependencies": {
    … …  
    42834385      }
    42844386    },
     4387    "node_modules/oniguruma-parser": {
     4388      "version": "0.12.2",
     4389      "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
     4390      "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==",
     4391      "license": "MIT"
     4392    },
     4393    "node_modules/oniguruma-to-es": {
     4394      "version": "4.3.6",
     4395      "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz",
     4396      "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==",
     4397      "license": "MIT",
     4398      "dependencies": {
     4399        "oniguruma-parser": "^0.12.2",
     4400        "regex": "^6.1.0",
     4401        "regex-recursion": "^6.0.2"
     4402      }
     4403    },
    42854404    "node_modules/orderedmap": {
    42864405      "version": "2.1.1",
    … …  
    50225141        "url": "https://github.com/sponsors/wooorm"
    50235142      }
     5143    },
     5144    "node_modules/regex": {
     5145      "version": "6.1.0",
     5146      "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
     5147      "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
     5148      "license": "MIT",
     5149      "dependencies": {
     5150        "regex-utilities": "^2.3.0"
     5151      }
     5152    },
     5153    "node_modules/regex-recursion": {
     5154      "version": "6.0.2",
     5155      "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz",
     5156      "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
     5157      "license": "MIT",
     5158      "dependencies": {
     5159        "regex-utilities": "^2.3.0"
     5160      }
     5161    },
     5162    "node_modules/regex-utilities": {
     5163      "version": "2.3.0",
     5164      "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
     5165      "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
     5166      "license": "MIT"
    50245167    },
    50255168    "node_modules/rehype": {
    … …  
    52335376      "license": "MIT"
    52345377    },
     5378    "node_modules/shiki": {
     5379      "version": "4.5.0",
     5380      "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.5.0.tgz",
     5381      "integrity": "sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==",
     5382      "license": "MIT",
     5383      "dependencies": {
     5384        "@shikijs/core": "4.5.0",
     5385        "@shikijs/engine-javascript": "4.5.0",
     5386        "@shikijs/engine-oniguruma": "4.5.0",
     5387        "@shikijs/langs": "4.5.0",
     5388        "@shikijs/themes": "4.5.0",
     5389        "@shikijs/types": "4.5.0",
     5390        "@shikijs/vscode-textmate": "^10.0.2",
     5391        "@types/hast": "^3.0.5"
     5392      },
     5393      "engines": {
     5394        "node": ">=20"
     5395      }
     5396    },
    52355397    "node_modules/sonner": {
    52365398      "version": "2.0.7",
  • siren-affiliates/trunk/frontend-source/package.json

    r3775642 r3788740  
    2121    "@radix-ui/react-tabs": "^1.1.2",
    2222    "@radix-ui/react-tooltip": "^1.2.8",
     23    "@shikijs/langs": "4.5.0",
    2324    "@tiptap/core": "^3.32.0",
    2425    "@tiptap/extension-bold": "^3.32.0",
    … …  
    4344    "react-router-dom": "^7.1.1",
    4445    "recharts": "^3.7.0",
     46    "shiki": "4.5.0",
    4547    "sonner": "^2.0.7",
    4648    "tailwind-merge": "^2.6.0",
  • siren-affiliates/trunk/frontend-source/src/core/schemas/collaborator.schema.ts

    r3775642 r3788740  
    22
    33/**
    4  * Collaborator status values.
     4 * Collaborator status values. An invited person has been sent an invitation
     5 * and has not accepted it yet.
    56 */
    6 export const CollaboratorStatusSchema = z.enum(['active', 'pending', 'inactive', 'rejected', 'deleted'])
     7export const CollaboratorStatusSchema = z.enum(['active', 'pending', 'inactive', 'rejected', 'deleted', 'invited'])
     8
     9/**
     10 * Where an invited person's invitation stands. Sent only for invited people,
     11 * when fields=invitation is requested.
     12 */
     13export const CollaboratorInvitationStateSchema = z.object({
     14  state: z.enum(['held', 'sending', 'sent', 'expired', 'failed']).catch('sent'),
     15  sentAt: z.string().nullish(),
     16  expiresAt: z.string().nullish(),
     17})
     18
     19/**
     20 * The custom fields the merchant keeps about a collaborator, by key. An
     21 * empty set may arrive as an empty list, which reads as no fields.
     22 */
     23export const CollaboratorCustomFieldsSchema = z.preprocess(
     24  (value) => (Array.isArray(value) && value.length === 0 ? {} : value),
     25  z.record(z.string(), z.string()),
     26)
    727
    828/**
    … …  
    4161  distributorId: z.number().nullish(),
    4262  distributorName: z.string().nullish(),
     63  invitation: CollaboratorInvitationStateSchema.nullish(),
     64  fields: CollaboratorCustomFieldsSchema.nullish(),
    4365})
    4466
  • siren-affiliates/trunk/frontend-source/src/core/schemas/transaction.schema.ts

    r3775642 r3788740  
    5858  source: z.string().nullish(),
    5959  sourceId: z.string().nullish(),
     60  sourcePropertyId: z.number().nullish(),
    6061  details: z.array(TransactionDetailSchema).nullish(),
    6162  totalValue: z.number().nullish(),
  • siren-affiliates/trunk/frontend-source/src/core/types/api.ts

    r3754739 r3788740  
    3434   */
    3535  onUnauthorized?: (failedToken?: string) => Promise<boolean>
     36  /**
     37   * Called when a request comes back 403 with a refusal code. A platform
     38   * where some actions wait for the person to do something first, such as
     39   * confirm their email address, sets this. It resolves true once that is
     40   * done, and the client then sends the request once more, so the action
     41   * finishes. Unset, a 403 is an error like any other.
     42   */
     43  onRefusal?: (code: string) => Promise<boolean>
    3644}
  • siren-affiliates/trunk/frontend-source/src/core/types/collaborator-dashboard.ts

    r3775642 r3788740  
    9090  /** The site's base URL */
    9191  baseUrl: string
     92  /**
     93   * The organization sells only in person, at a storefront with no website.
     94   * A referral link has nowhere to point, so the dashboard offers the
     95   * collaborator's coupon code instead.
     96   */
     97  inPersonOnly?: boolean
    9298}
    9399
  • siren-affiliates/trunk/frontend-source/src/core/types/collaborator.ts

    r3775642 r3788740  
    11/**
    2  * Collaborator status values.
     2 * Collaborator status values. An invited person has been sent an invitation
     3 * and has not accepted it yet, so they earn nothing and have no referral link.
    34 */
    4 export type CollaboratorStatus = 'active' | 'pending' | 'inactive' | 'rejected' | 'deleted'
     5export type CollaboratorStatus = 'active' | 'pending' | 'inactive' | 'rejected' | 'deleted' | 'invited'
     6
     7/**
     8 * Where an invited person's invitation stands.
     9 *
     10 * - held: waiting for the merchant to confirm their own email address
     11 * - sending: on its way
     12 * - sent: delivered, and its link still works
     13 * - expired: its link stopped working after 7 days
     14 * - failed: it could not be delivered
     15 */
     16export interface CollaboratorInvitationState {
     17  state: 'held' | 'sending' | 'sent' | 'expired' | 'failed'
     18  sentAt?: string | null
     19  expiresAt?: string | null
     20}
    521
    622/**
    … …  
    4258  distributorId?: number
    4359  distributorName?: string
     60  /** Only for invited people, when fields=invitation is requested. */
     61  invitation?: CollaboratorInvitationState | null
     62  /**
     63   * The custom fields the merchant keeps about them, by key, when
     64   * fields=fields is requested. Null for a collaborator reading their own
     65   * record.
     66   */
     67  fields?: CollaboratorCustomFields | null
    4468}
     69
     70/**
     71 * A collaborator's custom fields, by key. A key is lower case letters,
     72 * digits and underscores, up to 64 characters, starting with a letter. A
     73 * value is text of up to 1000 characters.
     74 */
     75export type CollaboratorCustomFields = Record<string, string>
    4576
    4677/**
  • siren-affiliates/trunk/frontend-source/src/core/types/inbound.ts

    r3775642 r3788740  
    4141   */
    4242  storefrontPending?: boolean
     43  /** What reached the connection, for sources that report their deliveries. */
     44  deliveries?: InboundDeliveries
     45  /** The store's saved address and handle, for sources whose stores have their own addresses. */
     46  store?: InboundStore
     47}
     48
     49/** One event type a source reads, and when deliveries of it were verified. */
     50export interface InboundDeliveryTopic {
     51  /** The platform's name for the event, such as `orders/paid`. */
     52  topic: string
     53  /** Whether the connection needs it. Product events only keep names current. */
     54  required: boolean
     55  /** ISO time of the first delivery whose signature matched the saved key, or null. */
     56  firstVerifiedAt: string | null
     57  lastVerifiedAt: string | null
     58}
     59
     60/** Why a delivery was refused: no key saved yet, or a signature that did not match. */
     61export type InboundRefusalReason = 'no_key' | 'signature'
     62
     63export interface InboundDeliveries {
     64  topics: InboundDeliveryTopic[]
     65  /** The store the earliest verified delivery named, such as `example.myshopify.com`. */
     66  sender: string | null
     67  lastVerifiedAt: string | null
     68  lastRefused: {
     69    at: string
     70    topic: string | null
     71    reason: InboundRefusalReason | null
     72    /** The store the refused delivery named. Not verified. */
     73    sender: string | null
     74  } | null
     75  /** True when the last refusal came after every verified delivery. */
     76  refusedSinceVerified: boolean
     77}
     78
     79export interface InboundStore {
     80  /** The address saved on the Property, or null. */
     81  address: string | null
     82  /** The platform's handle for the store, when Siren knows it. */
     83  handle: string | null
     84}
     85
     86/** The answer to saving a store's address. */
     87export interface InboundStoreAddressResult {
     88  siteUrl: string
     89  handle: string | null
     90  /** Whether the store's home page asks for a password. */
     91  passwordProtected: boolean
     92  /** Whether Siren could read the home page. */
     93  checked: boolean
     94  /** Why the page could not be read, or null. */
     95  problem: string | null
    4396}
    4497
  • siren-affiliates/trunk/frontend-source/src/core/types/transaction.ts

    r3775642 r3788740  
    2828  source?: string       // e.g., 'woocommerce', 'edd', 'manual'
    2929  sourceId?: string     // e.g., WooCommerce order ID
     30  sourcePropertyId?: number | null // Property whose connected store supplied the order
    3031
    3132  // Extended fields - joined from TransactionDetail or computed
  • siren-affiliates/trunk/frontend-source/src/index.css

    r3775642 r3788740  
    113113}
    114114
     115/* Syntax colours for CodeBlock. Each token carries a light and a dark colour. */
     116.code-token {
     117  color: var(--code-light, inherit);
     118}
     119.dark .code-token {
     120  color: var(--code-dark, inherit);
     121}
     122
    115123/* Code editor (manifest editor) dark mode overrides */
    116124.dark [data-color-mode="dark"] .w-tc-editor-text,
    … …  
    244252  white-space: nowrap;
    245253}
     254
     255/*
     256 * While the product tour shows example rows in place of an empty list, the
     257 * list's own footer ("Showing 0 to 0 of 0 results", page size, Trash) would
     258 * contradict them, so it is hidden until the tour moves on.
     259 */
     260[data-tour-sample='true'] + div {
     261  display: none;
     262}
  • siren-affiliates/trunk/frontend-source/src/platform/wordpress/entries/collaborators.tsx

    r3590633 r3788740  
    44import { configureApi } from '@service/api/client'
    55import { CollaboratorsListScreen, CollaboratorsEditScreen, CollaboratorViewScreen } from '@service/screens/collaborators'
     6import { CollaboratorImportScreen } from '@service/screens/collaborators/import'
    67import { Toaster } from '@service/components/ui'
    78import { WordPressRouter } from '../WordPressRouter'
    … …  
    2829            <Route path="/collaborators" element={<CollaboratorsListScreen />} />
    2930            <Route path="/collaborators/new" element={<CollaboratorsEditScreen />} />
     31            <Route path="/collaborators/import" element={<CollaboratorImportScreen />} />
    3032            <Route path="/collaborators/:id" element={<CollaboratorViewScreen />} />
    3133            <Route path="/collaborators/:id/view" element={<CollaboratorViewScreen />} />
  • siren-affiliates/trunk/frontend-source/src/platform/wordpress/entries/programs.tsx

    r3590633 r3788740  
    2323  createRoot(container).render(
    2424    <StrictMode>
    25       <WordPressRouter defaultRoute="/programs">
     25      <WordPressRouter defaultRoute="/programs" capabilities={window.sirenConfig?.capabilities}>
    2626        <Toaster position="top-right" richColors />
    2727        <div className="p-4">
  • siren-affiliates/trunk/frontend-source/src/service/api/client.ts

    r3775642 r3788740  
    104104
    105105/**
     106 * The code a refusal carries in `{ error: { code } }`, read from a copy so the
     107 * response can still be read after. Null when it carries none.
     108 */
     109export async function refusalCode(response: Response): Promise<string | null> {
     110  try {
     111    const json = await response.clone().json()
     112    const code = json?.error?.code
     113
     114    return typeof code === 'string' && code !== '' ? code : null
     115  } catch {
     116    return null
     117  }
     118}
     119
     120/**
    106121 * Make an API request.
    107122 */
    … …  
    163178
    164179    if (renewed) {
     180      response = await send(apiConfig.token)
     181    }
     182  }
     183
     184  // A refusal the platform can clear, such as an action that waits for the
     185  // person to confirm their email address. Once cleared, the request goes
     186  // out once more with the session as it is now.
     187  if (response.status === 403 && apiConfig.onRefusal) {
     188    const code = await refusalCode(response)
     189
     190    if (code !== null && (await apiConfig.onRefusal(code))) {
    165191      response = await send(apiConfig.token)
    166192    }
    … …  
    227253  options?.onHeaders?.(response.headers)
    228254
    229   return response.json()
     255  try {
     256    return await response.json()
     257  } catch {
     258    // An empty or broken body, such as a server restarting mid-request.
     259    throw new ApiRequestError(
     260      'invalid_response',
     261      'Siren could not finish that. Refresh the page and try again.',
     262      response.status
     263    )
     264  }
    230265}
    231266
  • siren-affiliates/trunk/frontend-source/src/service/api/collaborators.ts

    r3775642 r3788740  
    22import type { DeletionBlockers } from '@service/components/DeleteConfirmDialog'
    33import type { ApiListResponse } from '@core/types/api'
    4 import type { Collaborator, CollaboratorInput } from '@core/types/collaborator'
    5 import { CollaboratorSchema } from '@core/schemas/collaborator.schema'
     4import type { Collaborator, CollaboratorCustomFields, CollaboratorInput } from '@core/types/collaborator'
     5import { CollaboratorCustomFieldsSchema, CollaboratorSchema } from '@core/schemas/collaborator.schema'
    66import { createApiListResponseSchema } from '@core/schemas/api.schema'
    77
    … …  
    4242  'engagementsCount',
    4343  'dateCreated',
     44  // Where an invited person's invitation stands. Null for everyone else.
     45  'invitation',
    4446]
    4547
    … …  
    6870  'dateCreated',
    6971  'dateModified',
     72  // The custom fields the merchant keeps about them, by key.
     73  'fields',
    7074]
    7175
    … …  
    132136    api.put<Collaborator>(`/collaborators/${id}`, transformInputForApi(input))
    133137      .then(response => collaboratorResponse.parse(response) as Collaborator),
     138
     139  /**
     140   * Set custom fields on a collaborator. Keys left out keep their values,
     141   * and an empty value removes its key. Resolves with every custom field
     142   * the collaborator now holds.
     143   */
     144  updateFields: (id: number, fields: CollaboratorCustomFields) =>
     145    api.put<{ fields?: unknown }>(`/collaborators/${id}`, { fields })
     146      .then(response => CollaboratorCustomFieldsSchema.parse(response.fields ?? {}) as CollaboratorCustomFields),
    134147
    135148  /**
    … …  
    173186
    174187  /**
     188   * Send an invited person their invitation again, with a fresh link. It
     189   * counts toward the day's invitation allowance.
     190   */
     191  resendInvitation: (id: number) =>
     192    api.post<{ queued: number; remaining: number }>(`/collaborators/${id}/invitation/resend`, {}),
     193
     194  /**
     195   * Cancel an invitation. The invited person comes off the list and the
     196   * link in their email stops working.
     197   */
     198  cancelInvitation: (id: number) => api.delete<void>(`/collaborators/${id}/invitation`),
     199
     200  /**
    175201   * Generate a random, unique referral code.
    176202   * The server validates the code is safe to use.
  • siren-affiliates/trunk/frontend-source/src/service/api/fulfillments.ts

    r3775642 r3788740  
    6767      orderBy: params?.orderBy,
    6868      order: params?.order,
    69       fields: 'id,status,dateCreated,dateModified,payoutCount,paidCount,unpaidCount,failedCount,totalValue,currency',
     69      fields: 'id,status,dateCreated,dateModified,payoutCount,paidCount,unpaidCount,failedCount,waitingCount,totalValue,currency',
    7070    }).then(response => fulfillmentListResponse.parse(response) as ApiListResponse<Fulfillment>)
    7171  },
  • siren-affiliates/trunk/frontend-source/src/service/api/inbound.ts

    r3775642 r3788740  
    55  InboundMode,
    66  InboundTestDelivery,
     7  InboundStoreAddressResult,
    78} from '@core/types/inbound'
    89
    … …  
    6162  clearTestDeliveries: (sourceSlug: string) =>
    6263    api.delete<{ success: boolean }>(`${sourcePath(sourceSlug)}/test-deliveries`),
     64
     65  /** Saves the store's address on the connection's Property and reads which store it is. Setup must have started. */
     66  setStoreAddress: (sourceSlug: string, address: string) =>
     67    api.put<InboundStoreAddressResult>(`${sourcePath(sourceSlug)}/store`, { address }),
    6368}
  • siren-affiliates/trunk/frontend-source/src/service/api/products.ts

    r3775642 r3788740  
    2727  /** When a save, an import, a webhook or a sale last confirmed it. */
    2828  lastSeenAt: string | null
     29  parentPlatformId?: string | null
    2930}
    3031
    … …  
    3839  name: string
    3940  mergedIntoId: number | null
     41  /** The Siren product this variation belongs to. */
     42  parentId?: number | null
    4043  listings: ProductListing[]
    4144  owners: ProductOwnerRef[]
  • siren-affiliates/trunk/frontend-source/src/service/api/properties.ts

    r3775642 r3788740  
     1import type { PropertyKind } from '@core/types/property-kind'
    12import { api } from './client'
    23
    … …  
    78 * platform. What it is connected to is its list of integrations: the WordPress
    89 * connector, Shopify, Stripe, the hosted tracker, and any source added later,
    9  * in any combination.
     10 * in any combination. A storefront is a shop people visit in person, with no
     11 * address, where collaborators share coupon codes instead of links.
    1012 */
    1113
     14export type { PropertyKind }
     15
    1216/** One thing a Property is connected to. */
     17/** A plugin a connected WordPress site runs, such as WooCommerce, as the site last reported it. */
     18export interface SiteIntegration {
     19  /** The integration's own id, such as `wc`. */
     20  id: string
     21  /** Its name, such as `WooCommerce`. */
     22  name: string
     23  /** The Siren features it provides, such as `coupons` and `renewals`. */
     24  supports: string[]
     25}
     26
    1327export interface PropertyIntegration {
    1428  /** What it connects to: `wordpress` for the connector, else an inbound source's slug such as `shopify`. */
    … …  
    2438  /** True when it's only shown for the integration preview. It's never connected. */
    2539  preview?: boolean
     40  /**
     41   * On the WordPress connector only: what its site runs, without WordPress itself.
     42   * Left out until the site reports, and by older servers. Empty when it runs nothing Siren works with.
     43   */
     44  runs?: SiteIntegration[]
    2645}
    2746
    … …  
    3150  siteUrl: string
    3251  status: string
     52  /** A website or a storefront. Older servers leave it out, and those are websites. */
     53  kind?: PropertyKind
    3354  /** Present where the server lists integrations. */
    3455  integrations?: PropertyIntegration[]
    3556}
    3657
    37 /** What a Property's name, address and status are changed to. */
     58/** What a Property's name, address, status and kind are changed to. */
    3859export interface PropertyInput {
    3960  name: string
    4061  siteUrl: string
    4162  status: PropertyStatus
     63  /** Left out, it keeps the kind it has. A storefront drops its address. */
     64  kind?: PropertyKind
    4265}
    4366
    … …  
    90113  get: (id: number) => api.get<Property>(`/properties/${id}`),
    91114
    92   /** Adds a Property. It needs only a name and an address. */
    93   create: (name: string, url: string) => api.post<Property>('/properties', { name, url }),
     115  /** Adds a Property. A website needs a name and an address, and a storefront only a name. */
     116  create: (name: string, url: string, kind: PropertyKind = 'site') =>
     117    api.post<Property>('/properties', kind === 'storefront' ? { name, kind } : { name, url }),
    94118
    95119  /** Changes a Property's name, address and status. Its integrations stay as they are. */
  • siren-affiliates/trunk/frontend-source/src/service/api/recipes.ts

    r3775642 r3788740  
    5353}
    5454
     55/** A link from a collaborator to a program, distributor or collaborator group. */
     56export interface CollaboratorBinding {
     57  targetType: 'program' | 'distributor' | 'collaboratorGroup'
     58  /** A record the recipe creates, by its recipe key. */
     59  targetKey?: string
     60  /** A record that already exists, by its id. */
     61  targetId?: number
     62}
     63
     64/** What happens to someone the recipe names who is already in Siren, matched by email. */
     65export type CollaboratorOnExisting = 'merge' | 'update' | 'skip'
     66
     67/** Emails the collaborator a link to set up their account. */
     68export interface CollaboratorInvitationDefinition {
     69  /** The organization's own words, as plain text. */
     70  message?: string
     71  /** The status an invited collaborator gets when they accept. */
     72  statusOnAccept?: 'active' | 'pending'
     73}
     74
    5575export interface CollaboratorDefinition {
    5676  email: string
    5777  firstName?: string
    5878  lastName?: string
     79  fullName?: string
    5980  status?: string
     81  /** Set exactly as given. */
     82  referralCode?: string
    6083  aliases?: Array<{ type: string; value: string }>
    61   bindings?: Array<{
    62     programs?: string[]
    63     distributors?: string[]
    64   }>
     84  coupons?: Array<{ code: string; integration?: string; propertyId?: number }>
     85  bindings?: Array<CollaboratorBinding | { programs?: string[]; distributors?: string[] }>
     86  /** Custom fields, key to text value. */
     87  meta?: Record<string, string>
     88  onExisting?: CollaboratorOnExisting
     89  invitation?: CollaboratorInvitationDefinition
    6590  [key: string]: unknown
     91}
     92
     93/** Who owns a product: a collaborator by email, referral code, id, or recipe key. */
     94export type ProductOwnerReference = { email: string } | { referralCode: string } | { collaboratorId: number } | { collaboratorKey: string }
     95
     96/**
     97 * One product, found by its SKU or by its store's id with the integration.
     98 * Products come from stores, so a bare SKU never makes one.
     99 */
     100export interface ProductDefinition {
     101  sku?: string
     102  platformId?: string
     103  integration?: string
     104  /** The store (Property). Left out, every store, as on a WordPress site. */
     105  propertyId?: number
     106  name?: string
     107  /** Up to ten. Never empty. */
     108  owners?: ProductOwnerReference[]
     109  /** `replace`, the default, makes these the product's whole list. `add` keeps the ones it has. */
     110  ownersMode?: 'replace' | 'add'
     111  onExisting?: 'update' | 'skip'
    66112}
    67113
    … …  
    122168  autofulfillers?: Record<string, AutofulfillerDefinition>
    123169  collaborators?: Record<string, CollaboratorDefinition>
     170  products?: Record<string, ProductDefinition>
    124171  mappings?: RecipeMapping[]
    125172  tracking?: RecipeTrackingSettings
    … …  
    135182  | 'autofulfillers'
    136183  | 'collaborators'
     184  | 'products'
    137185  | 'mappings'
    138186  | 'tracking'
    … …  
    146194  name: string
    147195  meta: string[]
     196}
     197
     198/** One problem or notice the preview found on a collaborator entry. */
     199export interface PreviewEntryMessage {
     200  field: string
     201  message: string
     202}
     203
     204/** What the preview found for one collaborator entry, by its recipe key. */
     205export interface CollaboratorPreviewEntry {
     206  /** Products also answer `missing` (no store sends it) and `ambiguous` (a SKU several products share), with a problem. */
     207  match: 'new' | 'existing' | 'missing' | 'ambiguous'
     208  /** The matched collaborator's status, when they are already in Siren. */
     209  existingStatus: string | null
     210  /** Errors: the entry can't be imported as it stands. */
     211  problems: PreviewEntryMessage[]
     212  /** Information only. */
     213  notices: PreviewEntryMessage[]
     214  coupons?: Array<{ code: string; state: 'store' | 'waiting' | 'taken' }>
     215  invitation?: 'send' | 'alreadyInvited' | 'hasAccount' | null
     216}
     217
     218/** What the import's invitation emails would do. */
     219export interface PreviewInvitations {
     220  /** False when this site can't send invitation emails. */
     221  available: boolean
     222  /** True when the emails wait for the owner to confirm their email address. */
     223  held: boolean
     224  /** Exactly how many emails the import sends. */
     225  count: number
    148226}
    149227
    … …  
    154232  samples: PreviewSample[]
    155233  category: PreviewSectionCategory
     234  /** The collaborators section only: what each entry would do, by recipe key. */
     235  entries?: Record<string, CollaboratorPreviewEntry>
     236  /** The collaborators section only. */
     237  invitations?: PreviewInvitations
    156238}
    157239
    … …  
    163245    version: number
    164246    sections: PreviewSection[]
     247    invitations?: PreviewInvitations
    165248  }
     249  invitations?: PreviewInvitations
    166250}
    167251
    … …  
    188272  programGroups: CreatedEntity[]
    189273  distributors: CreatedEntity[]
     274  collaboratorGroups?: CreatedEntity[]
    190275  collaborators?: CreatedEntity[]
    191276  currencies?: CreatedCurrency[]
    … …  
    196281
    197282export type ImportStanzaType = PreviewSectionType
     283
     284/** Where an import came from. A CSV import keeps its file name and column mapping. */
     285export interface RecipeImportSource {
     286  kind: 'csv'
     287  fileName: string
     288  /** Each column header to the field it filled, such as `email` or `meta:tier`. */
     289  mapping: Record<string, string>
     290}
     291
     292/** What happened to one collaborator entry. */
     293export interface CollaboratorImportResult {
     294  key: string
     295  email: string
     296  outcome: 'added' | 'updated' | 'skipped' | 'failed'
     297  /** Why, for skipped and failed. */
     298  reason: string | null
     299  /** Smaller problems on an entry that was still imported. */
     300  notes: Array<string | PreviewEntryMessage>
     301  emailed: 'queued' | 'alreadyInvited' | 'hasAccount' | null
     302}
     303
     304export interface CollaboratorImportSummary {
     305  added: number
     306  updated: number
     307  skipped: number
     308  failed: number
     309  emailed: number
     310}
     311
     312/** What happened to one product entry. */
     313export interface ProductImportResult {
     314  key: string
     315  /** What the row goes by, such as its SKU or name. */
     316  label: string
     317  outcome: 'added' | 'updated' | 'skipped' | 'failed'
     318  reason: string | null
     319  notes: Array<string | PreviewEntryMessage>
     320}
     321
     322export interface ProductImportSummary {
     323  added: number
     324  updated: number
     325  skipped: number
     326  failed: number
     327}
    198328
    199329export interface ImportJobSnapshot {
    … …  
    209339  errorMessage: string | null
    210340  dateCreated: string | null
     341  collaboratorResults?: CollaboratorImportResult[]
     342  collaboratorSummary?: CollaboratorImportSummary
     343  productResults?: ProductImportResult[]
     344  productSummary?: ProductImportSummary
     345  source?: RecipeImportSource | null
    211346}
    212347
    … …  
    222357  completedDate: string | null
    223358  errorMessage: string | null
     359  source?: RecipeImportSource | null
    224360}
    225361
    … …  
    237373  autofulfillers: 'Autofulfillers',
    238374  collaborators: 'Collaborators',
     375  products: 'Products',
    239376  mappings: 'External mappings',
    240377  tracking: 'Tracking settings',
    … …  
    280417
    281418/**
    282  * Preview what a recipe would create (validation + summary) without persisting anything.
    283  */
    284 export function previewRecipe(recipe: RecipeData): Promise<PreviewResult> {
    285   return api.post<PreviewResult>('/recipes/preview', recipe)
     419 * How an import should run, sent beside the recipe. The server takes these
     420 * off before it reads the recipe.
     421 * - `configurationOnly` leaves out the recipe's collaborators, the members of
     422 *   its collaborator groups and its mappings, such as sample people.
     423 * - `paused` creates its programs and distributors inactive.
     424 * - `importKey` names the import. A named import applies once per
     425 *   organization, and a second apply under the same key answers 409 with the
     426 *   earlier job. An apply with no key runs every time.
     427 * - `source` says where the recipe came from, such as a CSV file and its
     428 *   column mapping. The job keeps it, so the next CSV import can reuse it.
     429 */
     430export interface RecipeImportOptions {
     431  configurationOnly?: boolean
     432  paused?: boolean
     433  importKey?: string
     434  source?: RecipeImportSource
     435}
     436
     437/** The error type a second apply under the same import key answers with. */
     438export const RECIPE_ALREADY_APPLIED = 'RECIPE_ALREADY_APPLIED'
     439
     440/**
     441 * Preview what a recipe would create (validation + summary) without persisting
     442 * anything. Pass the same options the apply will use, so the preview shows
     443 * what that import brings in.
     444 */
     445export function previewRecipe(recipe: RecipeData, options: RecipeImportOptions = {}): Promise<PreviewResult> {
     446  return api.post<PreviewResult>('/recipes/preview', { ...recipe, ...options })
    286447}
    287448
    … …  
    294455 * polls {@link getRecipeImport} until status reaches `complete` or `failed`.
    295456 */
    296 export function applyRecipe(recipe: RecipeData): Promise<ImportJobSnapshot> {
    297   return api.post<ImportJobSnapshot>('/recipes/apply', recipe)
     457export function applyRecipe(recipe: RecipeData, options: RecipeImportOptions = {}): Promise<ImportJobSnapshot> {
     458  return api.post<ImportJobSnapshot>('/recipes/apply', { ...recipe, ...options })
    298459}
    299460
  • siren-affiliates/trunk/frontend-source/src/service/api/transactions.ts

    r3775642 r3788740  
    1818  search?: string
    1919  status?: string
     20  /** True for sales a conversion credits to a collaborator, false for the rest. */
     21  credited?: boolean
    2022  orderBy?: string
    2123  order?: 'asc' | 'desc'
    … …  
    5557      s: params?.search,
    5658      status: params?.status,
     59      credited: params?.credited === undefined ? undefined : params.credited ? '1' : '0',
    5760      orderBy: params?.orderBy,
    5861      order: params?.order,
    59       fields: 'id,status,dateCreated,details,totalValue,totalsByCurrency,currency,source,isTest',
     62      fields: 'id,status,dateCreated,details,totalValue,totalsByCurrency,currency,source,sourceId,sourcePropertyId,isTest',
    6063    }).then(response => transactionListResponse.parse(response) as ApiListResponse<Transaction>)
    6164  },
    … …  
    6568   */
    6669  get: (id: number) => api.get<Transaction>(`/transactions/${id}`, {
    67     fields: 'id,status,dateCreated,details,detailCount,totalValue,totalsByCurrency,totalQuantity,currency,refunds,refundedValue,isTest',
     70    fields: 'id,status,dateCreated,details,detailCount,totalValue,totalsByCurrency,totalQuantity,currency,refunds,refundedValue,isTest,source,sourceId,sourcePropertyId',
    6871  }).then(response => transactionResponse.parse(response) as Transaction),
    6972
  • siren-affiliates/trunk/frontend-source/src/service/components/ActivityTimeline.tsx

    r3775642 r3788740  
    207207      ? (SOURCE_TYPE_PLURAL[sourceType] ?? `all ${sourceType}s`)
    208208      : (SOURCE_TYPE_NOUN[sourceType] ?? `this ${sourceType}`))
     209  // A zoomed-out feed covers more than one record, and in Siren Cloud the
     210  // programs feed also lists what happened to the organization itself.
     211  const description = isZoomedOut ? 'What happened, newest first' : 'Events that touched this record'
    209212  const [notes, setNotes] = useState<Note[]>([])
    210213  const [total, setTotal] = useState(0)
    … …  
    394397            <>
    395398              <h2 className="text-lg font-semibold">Activity for {subjectLabel}</h2>
    396               <p className="text-sm text-muted-foreground">Events that touched this record</p>
     399              <p className="text-sm text-muted-foreground">{description}</p>
    397400            </>
    398401          ) : (
    399402            <>
    400403              <CardTitle>Activity for {subjectLabel}</CardTitle>
    401               <CardDescription>Events that touched this record</CardDescription>
     404              <CardDescription>{description}</CardDescription>
    402405            </>
    403406          )}
  • siren-affiliates/trunk/frontend-source/src/service/components/collaborator-dashboard/ReferralUrlGenerator.tsx

    r3754739 r3788740  
    88import type { ReferralConfig } from '@core/types/collaborator-dashboard'
    99import { buildReferralUrl } from '@service/utils/referral-url'
     10import { writeClipboard } from '@service/lib/clipboard'
    1011
    1112interface ReferralUrlGeneratorProps {
    … …  
    6667
    6768    try {
    68       await navigator.clipboard.writeText(referralUrl)
     69      await writeClipboard(referralUrl)
    6970      setCopied(true)
    7071      toast.success(translate('Copied to clipboard!'))
  • siren-affiliates/trunk/frontend-source/src/service/components/data-table/BulkActionBar.tsx

    r3775642 r3788740  
    11import * as React from 'react'
     2import { TourSampleBadge } from '@service/components/tour-sample'
    23import { X } from 'lucide-react'
    34import { useTranslation } from '@service/i18n'
    … …  
    3233  onClear: () => void
    3334  isProcessing?: boolean
     35  /** The product tour's example selection: shown, marked as an example, and not usable. */
     36  sample?: boolean
    3437}
    3538
    … …  
    3942  onClear,
    4043  isProcessing = false,
     44  sample = false,
    4145}: BulkActionBarProps) {
    4246  const { translate } = useTranslation()
    … …  
    8892  }
    8993
    90   const busy = isProcessing || isExecuting
     94  const busy = isProcessing || isExecuting || sample
    9195
    9296  return (
    9397    <>
    94       <div className="sticky top-0 z-10 flex items-center gap-4 px-4 py-3 bg-primary/10 border border-primary/20 rounded-lg mb-4">
     98      <div
     99        className="sticky top-0 z-10 flex items-center gap-4 px-4 py-3 bg-primary/10 border border-primary/20 rounded-lg mb-4"
     100        data-tour="bulk-actions"
     101      >
    95102        <div className="flex items-center gap-2">
     103          {sample && <TourSampleBadge />}
    96104          <span className="text-sm font-medium">
    97105            {selectedCount} {translate('selected')}
    … …  
    122130          ))}
    123131        </div>
    124         {busy && (
     132        {busy && !sample && (
    125133          <span className="ml-auto text-sm text-muted-foreground">
    126134            {translate('Processing...')}
  • siren-affiliates/trunk/frontend-source/src/service/components/data-table/DataTable.tsx

    r3775642 r3788740  
    1414} from '@service/components/ui'
    1515import { cn } from '@service/components/lib/utils'
     16import { useTourSample } from '@service/contexts/tour-sample'
     17import { TourSampleBadge, TourSampleBanner } from '@service/components/tour-sample'
    1618
    1719export interface ColumnDef<T> {
    … …  
    3638  data: T[]
    3739  isLoading?: boolean
    38   emptyMessage?: string
     40  /** What the table says with no rows: plain text, or a block such as an empty state. */
     41  emptyMessage?: React.ReactNode
    3942
    4043  // Selection
    … …  
    5356  getRowLabel?: (item: T) => string
    5457
     58  /**
     59   * The kind of records this list holds, such as `obligations`, so the
     60   * product tour can show its example records in place of an empty list.
     61   */
     62  sampleKey?: string
     63  /** The rows are the product tour's example records, drawn as examples. */
     64  sample?: boolean
     65
    5566  // Hover actions
    5667  getRowHref?: (item: T) => string
    … …  
    7384export function DataTable<T extends { id: number }>({
    7485  columns,
    75   data,
     86  data: records,
    7687  isLoading = false,
    7788  emptyMessage = 'No items found.',
    … …  
    8293  getRowLabel = defaultRowLabel,
    8394  getRowHref,
    84   onEdit,
    85   onDelete,
     95  onEdit: editRecord,
     96  onDelete: deleteRecord,
    8697  sortField,
    8798  sortOrder,
    8899  onSort,
    89100  renderExpanded,
     101  sampleKey,
     102  sample = false,
    90103}: DataTableProps<T>) {
     104  // The tour's example records stand in for an empty list, and never for
     105  // real ones. They can't be selected, opened or changed.
     106  const tourRows = useTourSample<T[]>(sampleKey)
     107  const showsSample = sample || (tourRows !== null && !isLoading && records.length === 0)
     108  const data = !sample && showsSample && tourRows ? tourRows : records
     109  const onEdit = showsSample ? undefined : editRecord
     110  const onDelete = showsSample ? undefined : deleteRecord
    91111  const hasHoverActions = !!(onEdit || onDelete)
    92112  const selectableRows = isRowSelectable ? data.filter(isRowSelectable) : data
    … …  
    137157
    138158  return (
    139     <div className="border rounded-lg">
     159    // The product tour points at a list once it has rows.
     160    <div
     161      className="border rounded-lg"
     162      data-tour={data.length > 0 ? 'list' : 'list-empty'}
     163      data-tour-sample={showsSample ? 'true' : undefined}
     164    >
     165      {/* A screen that passes its own example rows shows its own notice. */}
     166      {showsSample && !sample && <TourSampleBanner className="rounded-t-lg border-b" />}
    140167      <Table>
    141168        <TableHeader>
    … …  
    145172                <Checkbox
    146173                  checked={allSelected}
    147                   disabled={selectableRows.length === 0}
     174                  disabled={selectableRows.length === 0 || showsSample}
    148175                  aria-label="Select all rows"
    149176                  ref={(el) => {
    … …  
    224251                    onDelete={onDelete}
    225252                    hasHoverActions={hasHoverActions}
     253                    isSample={showsSample}
    226254                  />
    227255                  {expanded !== null && expanded !== undefined && (
    … …  
    256284  onDelete?: (item: T) => void
    257285  hasHoverActions?: boolean
     286  /** An example record from the product tour: marked, shaded, and not interactive. */
     287  isSample?: boolean
    258288}
    259289
    … …  
    283313  onDelete,
    284314  hasHoverActions,
     315  isSample = false,
    285316}: DataTableRowProps<T>) {
    286317  const [isHovered, setIsHovered] = React.useState(false)
     318  // An example row shows a ticked box where the tour explains selecting.
     319  const sampleSelected = isSample && (item as { tourSelected?: boolean }).tourSelected === true
    287320
    288321  return (
    289322    <TableRow
    290       data-state={isSelected ? 'selected' : undefined}
     323      data-state={isSelected || sampleSelected ? 'selected' : undefined}
    291324      onMouseEnter={() => setIsHovered(true)}
    292325      onMouseLeave={() => setIsHovered(false)}
    293       className="group"
     326      className={cn('group', isSample && 'bg-primary/5 hover:bg-primary/5')}
     327      // Nothing in an example row can be clicked or reached with the keyboard.
     328      {...(isSample ? { inert: '', 'data-tour-sample-row': 'true' } : {})}
    294329    >
    295330      {selectable && (
    … …  
    297332          {canSelect && (
    298333            <Checkbox
    299               checked={isSelected}
     334              checked={isSelected || sampleSelected}
     335              disabled={isSample}
    300336              aria-label={`Select ${rowLabel}`}
    301337              onCheckedChange={(checked) => onSelect(checked === true)}
    … …  
    306342      {columns.map((column, index) => (
    307343        <TableCell key={column.id} className={column.className}>
    308           {index === 0 && getRowHref ? (
     344          {index === 0 && isSample ? (
     345            <span className="inline-flex items-center gap-2">
     346              {column.cell(item)}
     347              <TourSampleBadge />
     348            </span>
     349          ) : index === 0 && getRowHref ? (
    309350            <Link
    310351              to={getRowHref(item)}
  • siren-affiliates/trunk/frontend-source/src/service/components/help/ProgramFlowDiagram.tsx

    r3775642 r3788740  
    116116 * Get commission display text based on incentive type and config
    117117 */
    118 function getCommissionText(
     118// eslint-disable-next-line react-refresh/only-export-components
     119export function getCommissionText(
    119120  incentiveType: string,
    120121  config?: ProgramFlowDiagramProps['commissionConfig'],
  • siren-affiliates/trunk/frontend-source/src/service/components/help/help-content.ts

    r3775642 r3788740  
    1616  | 'what-is-fulfillment'
    1717  | 'what-is-distributor'
     18  | 'what-is-metric'
    1819  | 'what-is-payout'
    1920  // Collaborator Dashboard
    … …  
    225226  | 'lifetime-attribution'
    226227  // end of moved screen help (type)
     228  // Siren Cloud usage
     229  | 'engine-activity'
    227230
    228231export interface HelpTooltipContent {
    … …  
    285288    title: 'What is a Conversion?',
    286289    summary:
    287       'A conversion occurs when an engaged customer completes a desired action, like making a purchase. The system uses engagements to determine which collaborator(s) should be credited.',
     290      'A conversion is credit: one collaborator earning from one program for a sale or a lead they brought in, decided from their engagements. Unlike a transaction, which is the order itself, it has an approval status, and one order can make several conversions or none, while a lead makes one with no order.',
    288291    learnMoreTopic: 'what-is-conversion',
    289292  },
    … …  
    299302    title: 'What is a Transaction?',
    300303    summary:
    301       'A transaction represents a customer purchase or order from your store. Transactions contain line items (products, fees, discounts) that are used to calculate commissions.',
     304      'A transaction is an order your store sends, with the line items (products, fees, discounts) that commissions are calculated from. Unlike a conversion, which is the credit a collaborator earns, a transaction is recorded for every order, whether or not anyone earns from it.',
    302305    learnMoreTopic: 'what-is-transaction',
    303306  },
    … …  
    313316    title: 'What is a Distributor?',
    314317    summary:
    315       'A distributor is a parent account that manages multiple collaborators and receives their payouts. Useful for agencies, networks, or multi-level marketing structures.',
     318      'A distributor shares a reward among collaborators on a schedule, such as a monthly bonus or a share of revenue. It tracks how each collaborator does over the period, then splits the reward by the rule you choose.',
     319    learnMoreTopic: 'what-is-distributor',
     320  },
     321
     322  'what-is-metric': {
     323    title: 'What is a Metric?',
     324    summary:
     325      "A metric is a collaborator's points in one period of a distributor. Each action the distributor counts, such as a site visit, a sale or a manual credit, adds points. When the period closes, the distributor splits its pool using those points and its split rule.",
    316326    learnMoreTopic: 'what-is-distributor',
    317327  },
    … …  
    15881598    title: 'Reply-to address',
    15891599    summary:
    1590       'When a collaborator replies to one of your emails, the reply goes to this address. Every email also shows it at the bottom as your contact address. Leave it empty to use your first admin.',
     1600      'When a collaborator replies to one of your emails, the reply goes to this address. Leave it empty to use your first admin. Add it to an email with the Contact email merge tag.',
    15911601  },
    15921602  'notification-editor': {
    15931603    title: 'Writing an email',
    15941604    summary:
    1595       'Siren opens each email with the facts of the event, such as the reward and its program, and ends it with your name, your contact address and a link to the reader\'s email preferences. You write what goes between. Keep it to the update itself: wording that sells, such as a sale or a discount, can make it marketing mail under some countries\' rules, and Siren warns when it sees some.',
     1605      'You write every word of each email, and it goes out as you wrote it. Siren adds one line below it, a link to the reader\'s email preferences. A line whose merge tags are all empty is left out, so a line that introduces a value goes when the value does. Keep it to the update itself: wording that sells, such as a sale or a discount, can make it marketing mail under some countries\' rules, and Siren warns when it sees some.',
    15961606  },
    15971607  'notification-new': {
    … …  
    16861696  // end of moved screen help
    16871697
     1698  'engine-activity': {
     1699    title: 'Engine activity',
     1700    summary:
     1701      'The work Siren does for your programs each month. Each engagement it records, such as a referred visit or a coupon use, counts once, and so does each metric it updates, such as a collaborator’s totals. Test sales never count. The count starts again on the first of each month. Past your plan’s allowance, your overage setting under Billing & Usage decides what happens: usage credits pay for more, or new activity waits in a queue until the month resets.',
     1702  },
     1703
    16881704  'siren-cloud-connector': {
    16891705    title: 'What the connector does',
    16901706    summary:
    1691       'It moves your programs, collaborators and history from the Siren plugin to Siren Cloud, then sends your plugins’ sales and activity there in the background. It brings back what Siren Cloud does, such as approved commissions and store credit, and keeps coupon panels, store credit at checkout and the collaborator portal on your store.',
     1707      'It sends your store’s sales and activity to Siren Cloud in the background. On a site that already runs the Siren plugin, it first moves your programs, collaborators and history there. It brings back what Siren Cloud does, such as approved commissions and store credit, and keeps coupon panels, store credit at checkout and the collaborator portal on your store.',
    16921708  },
    16931709
  • siren-affiliates/trunk/frontend-source/src/service/components/sidebar/GroupNav.tsx

    r3775642 r3788740  
    148148
    149149        return (
    150           <li key={group.key}>
     150          <li key={group.key} data-tour={`nav-${group.key}`}>
    151151            <button
    152152              type="button"
    … …  
    184184                        to={page.to}
    185185                        aria-current={isActive ? 'page' : undefined}
     186                        data-tour-page={page.to}
     187                        data-tour={`nav-link-${page.to.replace(/^\//, '').replace(/\//g, '-')}`}
    186188                        className={cn(
    187189                          'flex items-center gap-2 rounded-md pl-9 pr-2.5 transition-colors hover:bg-accent hover:text-accent-foreground',
    … …  
    327329    <ul className="space-y-px px-2">
    328330      {groups.map((group) => (
    329         <li key={group.key}>
     331        <li key={group.key} data-tour={`nav-${group.key}`}>
    330332          <GroupFlyout group={group} isCurrent={group.key === currentKey} navBadges={navBadges} />
    331333        </li>
  • siren-affiliates/trunk/frontend-source/src/service/components/sidebar/Sidebar.tsx

    r3775642 r3788740  
    1717  PanelLeftClose,
    1818  PanelLeftOpen,
     19  Compass,
    1920} from 'lucide-react'
    2021import { useNavigate } from 'react-router-dom'
    … …  
    3435  TooltipTrigger,
    3536} from '@service/components/ui'
     37import { BrandLink } from './BrandLink'
    3638import { SIDEBAR_ID } from './constants'
    3739import { visibleGroups } from './groups'
    … …  
    107109export interface SidebarProps {
    108110  currentOrgName?: string
    109   currentOrgSlug?: string
     111  currentOrgId?: number
    110112  userEmail?: string
    111113  memberships?: OrgMembership[]
    … …  
    138140   * Show Products and Coupon codes under Track. They
    139141   * list every Property's products and codes, with a filter for each
    140    * Property. Siren Cloud turns on the ones the person may open.
     142   * Property. Siren Cloud turns on the ones the person may open, whichever
     143   * integrations the org runs.
    141144   */
    142145  showCouponCodes?: boolean
    143   showProductOwners?: boolean
    144   /**
    145    * Show Customers under Track. The platform turns it on where an active
    146    * integration provides customers, or customers are kept from before.
     146  showProducts?: boolean
     147  /**
     148   * Show Customers under Track. It lists the org's customers from every
     149   * store. Siren Cloud turns it on whichever integrations the org runs.
    147150   */
    148151  showCustomers?: boolean
    … …  
    199202   */
    200203  onMobileClose?: () => void
     204  /** Holds the account menu open, for the product tour. */
     205  accountMenuOpen?: boolean
     206  /** Starts the product tour. With it, the account menu offers "Take the tour". */
     207  onStartTour?: () => void
    201208}
    202209
    … …  
    264271  isCollapsed,
    265272  currentOrgName,
    266   currentOrgSlug,
     273  currentOrgId,
    267274  userEmail,
    268275  memberships,
    … …  
    282289  isDark,
    283290  setIsDark,
     291  forceOpen = false,
     292  onStartTour,
    284293}: {
    285294  isCollapsed: boolean
    286295  currentOrgName?: string
    287   currentOrgSlug?: string
     296  currentOrgId?: number
    288297  userEmail?: string
    289298  memberships?: OrgMembership[]
    … …  
    303312  isDark: boolean
    304313  setIsDark: (value: boolean) => void
     314  forceOpen?: boolean
     315  onStartTour?: () => void
    305316}) {
    306317  const navigate = useNavigate()
     318  const [open, setOpen] = useState(false)
    307319  const { translate } = useTranslation()
    308320  // Developer holds API keys, Webhooks and Logs. It shows while the person may open one of them.
    309321  const showDeveloper = canManageApiKeys || canManageWebhooks || canUseSiteTools
    310   const otherOrgs = (memberships ?? []).filter((m) => m.orgSlug !== currentOrgSlug)
     322  const otherOrgs = (memberships ?? []).filter((m) => m.orgId !== currentOrgId)
    311323  const accountName = currentOrgName ?? translate('Account')
    312324  // Properties and Currencies are settings, so they sit here with the rest.
    … …  
    316328
    317329  return (
    318     <DropdownMenu>
     330    // The product tour holds the menu open while it shows the pages in it. It
     331    // is not modal then, so the tour's own popover keeps the keyboard.
     332    <DropdownMenu open={forceOpen || open} onOpenChange={(next) => !forceOpen && setOpen(next)} modal={!forceOpen}>
    319333      <RailTooltip label={accountName} show={isCollapsed}>
    320334        <DropdownMenuTrigger asChild>
    … …  
    323337            size="sm"
    324338            aria-label={isCollapsed ? accountName : undefined}
     339            data-tour="account-menu"
    325340            className={cn('h-9 w-full', isCollapsed ? 'justify-center px-0' : 'justify-between px-2.5')}
    326341          >
    … …  
    374389        {choosePlanUrl ? (
    375390          <>
    376             <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer">
     391            <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" data-tour-account="/settings/integrations">
    377392              <Plug className="h-4 w-4" />
    378393              <span className="ml-2">{translate('Integrations')}</span>
    379394            </DropdownMenuItem>
    380395            {showProperties && (
    381               <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer">
     396              <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" data-tour-account="/properties">
    382397                <Globe className="h-4 w-4" />
    383398                <span className="ml-2">{translate('Properties')}</span>
    … …  
    385400            )}
    386401            {canManageBilling && (
    387               <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer">
     402              <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" data-tour-account="/settings/billing">
    388403                <CreditCard className="h-4 w-4" />
    389404                <span className="ml-2">{translate('Billing & Usage')}</span>
    … …  
    399414        ) : (
    400415          <>
    401         <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer">
     416        <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" data-tour-account="/settings/integrations">
    402417          <Plug className="h-4 w-4" />
    403418          <span className="ml-2">{translate('Integrations')}</span>
    404419        </DropdownMenuItem>
    405420        {showPropertiesLink && (
    406           <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer">
     421          <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" data-tour-account="/properties">
    407422            <Globe className="h-4 w-4" />
    408423            <span className="ml-2">{translate('Properties')}</span>
    … …  
    410425        )}
    411426        {showCurrenciesLink && (
    412           <DropdownMenuItem onClick={() => navigate('/currencies')} className="cursor-pointer">
     427          <DropdownMenuItem onClick={() => navigate('/currencies')} className="cursor-pointer" data-tour-account="/currencies">
    413428            <Coins className="h-4 w-4" />
    414429            <span className="ml-2">{translate('Currencies')}</span>
    … …  
    416431        )}
    417432        {canManageOrganization && (
    418           <DropdownMenuItem onClick={() => navigate('/settings/organization')} className="cursor-pointer">
     433          <DropdownMenuItem onClick={() => navigate('/settings/organization')} className="cursor-pointer" data-tour-account="/settings/organization">
    419434            <Building2 className="h-4 w-4" />
    420435            <span className="ml-2">{translate('Organization')}</span>
    … …  
    422437        )}
    423438        {canManageMembers && (
    424           <DropdownMenuItem onClick={() => navigate('/settings/members')} className="cursor-pointer">
     439          <DropdownMenuItem onClick={() => navigate('/settings/members')} className="cursor-pointer" data-tour-account="/settings/members">
    425440            <UsersRound className="h-4 w-4" />
    426441            <span className="ml-2">{translate('Members')}</span>
    … …  
    428443        )}
    429444        {canManageNotifications && (
    430           <DropdownMenuItem onClick={() => navigate('/settings/notifications')} className="cursor-pointer">
     445          <DropdownMenuItem onClick={() => navigate('/settings/notifications')} className="cursor-pointer" data-tour-account="/settings/notifications">
    431446            <Bell className="h-4 w-4" />
    432447            <span className="ml-2">{translate('Notifications')}</span>
    … …  
    434449        )}
    435450        {canManageBilling && (
    436           <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer">
     451          <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" data-tour-account="/settings/billing">
    437452            <CreditCard className="h-4 w-4" />
    438453            <span className="ml-2">{translate('Billing & Usage')}</span>
    … …  
    440455        )}
    441456        {showDeveloper && (
    442           <DropdownMenuItem onClick={() => navigate('/settings/developer')} className="cursor-pointer">
     457          <DropdownMenuItem onClick={() => navigate('/settings/developer')} className="cursor-pointer" data-tour-account="/settings/developer">
    443458            <Code className="h-4 w-4" />
    444459            <span className="ml-2">{translate('Developer')}</span>
    445460          </DropdownMenuItem>
    446461        )}
    447         <DropdownMenuItem onClick={() => navigate('/import')} className="cursor-pointer">
     462        <DropdownMenuItem onClick={() => navigate('/import')} className="cursor-pointer" data-tour-account="/import">
    448463          <ArrowLeftRight className="h-4 w-4" />
    449464          <span className="ml-2">{translate('Import & Export')}</span>
    450465        </DropdownMenuItem>
     466          </>
     467        )}
     468        {onStartTour && (
     469          <>
     470            <DropdownMenuSeparator />
     471            <DropdownMenuItem onClick={() => onStartTour()} className="cursor-pointer" data-tour-account="tour">
     472              <Compass className="h-4 w-4" />
     473              <span className="ml-2">{translate('Take the tour')}</span>
     474            </DropdownMenuItem>
    451475          </>
    452476        )}
    … …  
    468492export function Sidebar({
    469493  currentOrgName,
    470   currentOrgSlug,
     494  currentOrgId,
    471495  userEmail,
    472496  memberships,
    … …  
    485509  showProperties,
    486510  showCouponCodes,
    487   showProductOwners,
     511  showProducts,
    488512  showCustomers,
    489513  showApplicationForms,
    … …  
    494518  mobileOpen = false,
    495519  onMobileClose,
     520  accountMenuOpen = false,
     521  onStartTour,
    496522}: SidebarProps) {
    497523  const [collapsedPreference, setIsCollapsed] = useCollapsedPreference()
    … …  
    535561          showProperties: showProperties === true,
    536562          showCouponCodes: showCouponCodes === true,
    537           showProductOwners: showProductOwners === true,
     563          showProducts: showProducts === true,
    538564          showCustomers: showCustomers === true,
    539565          showApplicationForms: showApplicationForms === true,
    … …  
    592618        ) : (
    593619          <>
    594             <img
    595               src={isDark ? sirenLogoDark : sirenLogoLight}
    596               alt="Siren"
    597               className="h-6 w-6 flex-shrink-0"
    598             />
    599             <span className="font-semibold text-foreground">Siren</span>
     620            {/* On the dashboard already, the path doesn't change, so the drawer is closed here. */}
     621            <BrandLink className="flex min-w-0 items-center gap-2" onClick={() => onMobileClose?.()}>
     622              <img
     623                src={isDark ? sirenLogoDark : sirenLogoLight}
     624                alt=""
     625                className="h-6 w-6 flex-shrink-0"
     626              />
     627              <span className="font-semibold text-foreground">Siren</span>
     628            </BrandLink>
    600629            <Button
    601630              variant="ghost"
    … …  
    681710            isCollapsed={isCollapsed}
    682711            currentOrgName={currentOrgName}
    683             currentOrgSlug={currentOrgSlug}
     712            currentOrgId={currentOrgId}
    684713            userEmail={userEmail}
    685714            memberships={memberships}
    … …  
    699728            isDark={isDark}
    700729            setIsDark={setIsDark}
     730            forceOpen={accountMenuOpen}
     731            onStartTour={onStartTour}
    701732          />
    702733        )}
  • siren-affiliates/trunk/frontend-source/src/service/components/sidebar/groups.ts

    r3775642 r3788740  
    1010  showProperties: boolean
    1111  showCouponCodes: boolean
    12   showProductOwners: boolean
     12  showProducts: boolean
    1313  showCustomers: boolean
    1414  showApplicationForms: boolean
    … …  
    6868    icon: Target,
    6969    pages: [
     70      { to: '/engagements', label: 'Engagements', shows: () => !!supports.engagements },
     71      { to: '/metrics', label: 'Metrics', shows: () => !!supports.distributors },
    7072      { to: '/conversions', label: 'Conversions', shows: () => !!supports.conversions },
    71       { to: '/engagements', label: 'Engagements', shows: () => !!supports.engagements },
    7273      { to: '/transactions', label: 'Transactions', shows: () => !!supports.transactions },
    7374      { to: '/customers', label: 'Customers', shows: (flags) => flags.showCustomers },
    74       { to: '/products', label: 'Products', shows: (flags) => flags.showProperties && flags.showProductOwners },
     75      { to: '/products', label: 'Products', shows: (flags) => flags.showProperties && flags.showProducts },
    7576      { to: '/coupon-codes', label: 'Coupon codes', shows: (flags) => flags.showProperties && flags.showCouponCodes },
    7677    ],
  • siren-affiliates/trunk/frontend-source/src/service/components/sidebar/index.ts

    r3754739 r3788740  
     1export { BrandLink } from './BrandLink'
    12export { Sidebar } from './Sidebar'
    23export { SIDEBAR_ID } from './constants'
  • siren-affiliates/trunk/frontend-source/src/service/components/ui/index.ts

    r3590633 r3788740  
    1616export * from './tabs'
    1717export * from './tooltip'
     18export * from './code-block'
     19export * from './copy-button'
  • siren-affiliates/trunk/frontend-source/src/service/components/ui/sonner.tsx

    r3590633 r3788740  
    77    <Sonner
    88      className="toaster group"
     9      closeButton
    910      toastOptions={{
    1011        classNames: {
  • siren-affiliates/trunk/frontend-source/src/service/contexts/platform.tsx

    r3775642 r3788740  
    5555export type PlanCheck = (capability: string) => boolean
    5656
     57/** What the CSV import hands the platform's invitation message editor. */
     58export interface ImportInvitationEditorProps {
     59  /** The merchant's own words. Empty keeps Siren's wording. */
     60  value: string
     61  onChange: (text: string) => void
     62  /** The programs everyone joins, for Siren's wording. */
     63  programNames: string[]
     64  /** Smaller, for a screen with no room to scroll. */
     65  compact?: boolean
     66}
     67
    5768/**
    5869 * Screens a platform adds to the shared ones. The shared screens render a
    … …  
    6576  /** Links in the header of the Programs list. */
    6677  programsListLinks?: ComponentType
     78  /** Actions in the header of the Collaborators list, such as inviting people by email. */
     79  collaboratorsListLinks?: ComponentType
     80  /** A notice above the Collaborators list, such as the move email a store's moved collaborators wait for. */
     81  collaboratorsListNotice?: ComponentType
     82  /** A line under a collaborator's status on the Collaborators list, such as sending them the move email. */
     83  collaboratorStatusExtra?: ComponentType<{ collaboratorId: number }>
     84  /**
     85   * The editor for the email a CSV import sends, with a preview of the email
     86   * as people get it. Only a platform that sends invitation emails supplies
     87   * it, and without it the import offers no email.
     88   */
     89  collaboratorImportInvitation?: ComponentType<ImportInvitationEditorProps>
    6790  /**
    6891   * A card on a collaborator's page: what they answered on the platform's
  • siren-affiliates/trunk/frontend-source/src/service/screens/collaborator-dashboard/CollaboratorCouponsScreen.tsx

    r3775642 r3788740  
    1111import { useTranslation } from '@service/i18n'
    1212import type { CollaboratorCoupon } from '@core/types/collaborator-dashboard'
     13import { writeClipboard } from '@service/lib/clipboard'
    1314
    1415// =============================================================================
    … …  
    140141  const copyToClipboard = async () => {
    141142    try {
    142       await navigator.clipboard.writeText(coupon.code)
     143      await writeClipboard(coupon.code)
    143144      setCopied(true)
    144145      toast.success(translate('Coupon code copied!'))
  • siren-affiliates/trunk/frontend-source/src/service/screens/collaborator-dashboard/CollaboratorDashboardScreen.tsx

    r3775642 r3788740  
    282282
    283283      {/* Referral URL Generator */}
    284       {referralConfig && referralConfig.trackingId && (
     284      {referralConfig && referralConfig.trackingId && !referralConfig.inPersonOnly && (
    285285        <ReferralUrlGenerator config={referralConfig} />
     286      )}
     287      {referralConfig?.inPersonOnly && (
     288        <p className="rounded-md border bg-muted/40 px-4 py-3 text-sm text-muted-foreground" data-testid="in-person-only">
     289          {translate('This business sells in person, so there’s no link to share. Share your coupon code instead, and each sale with it counts for you.')}
     290        </p>
    286291      )}
    287292
  • siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorViewScreen.tsx

    r3775642 r3788740  
    4949import { CollaboratorProductsCard } from '@service/screens/products/CollaboratorProductsCard'
    5050import { LifetimeAttributionCard } from './LifetimeAttributionCard'
     51import { CustomFieldsCard } from './CustomFieldsCard'
     52import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    5153
    5254const statusColors: Record<CollaboratorStatus, string> = {
    … …  
    5658  rejected: 'status-badge status-red',
    5759  deleted: 'status-badge status-red',
     60  invited: 'status-badge status-blue',
    5861}
    5962
    … …  
    8386  rejected: translate('Rejected'),
    8487  deleted: translate('Trashed'),
     88  invited: translate('Invited'),
    8589}
    8690  const { id } = useParams<{ id: string }>()
    … …  
    169173      // Conversions have no collaboratorId column. The API resolves this filter through
    170174      // the engagement each conversion belongs to.
    171       fetchConversions({ collaboratorId, perPage: 10, status: 'pending,approved,complete,rejected' })
    172       fetchObligations({ collaboratorId, perPage: 10, status: 'approved,complete,rejected' })
     175      fetchConversions({ collaboratorId, perPage: 10, status: 'pending,approved,complete,rejected', orderBy: 'dateCreated', order: 'desc' })
     176      fetchObligations({ collaboratorId, perPage: 10, status: 'approved,complete,rejected', orderBy: 'dateCreated', order: 'desc' })
    173177      if (supports.customerOwnership) {
    174178        fetchOwnedByCollaborator(collaboratorId)
    … …  
    309313          </Button>
    310314        )}
    311         <div className="flex-1 min-w-[min(100%,14rem)]">
     315        <div className="flex-1 min-w-[min(100%,14rem)]" data-tour="collaborator-heading">
    312316          <div className="flex flex-wrap items-center gap-3">
    313             <h1 className="text-2xl font-semibold">{current.fullName}</h1>
     317            <h1 className="text-2xl font-semibold">{collaboratorDisplayName(current)}</h1>
    314318            <span className={statusColors[current.status]}>
    315319              {statusLabels[current.status]}
    … …  
    319323        </div>
    320324        <div className="flex items-center gap-2">
    321           <ActivityDrawer sourceType="collaborator" sourceId={current.id} contextLabel={current.fullName} />
     325          <ActivityDrawer sourceType="collaborator" sourceId={current.id} contextLabel={collaboratorDisplayName(current)} />
    322326          <Button asChild>
    323327            <Link to={`/collaborators/${current.id}/edit`}>
    … …  
    334338            collaboratorId={current.id}
    335339            status={current.status}
    336             name={current.fullName || current.email}
     340            name={collaboratorDisplayName(current)}
    337341            onChanged={() => fetchOne(current.id)}
    338342          />
    339343        )}
    340344        {!isWordPress && <CollaboratorPropertiesCard collaboratorId={current.id} />}
    341         <CollaboratorCouponsCard collaboratorId={current.id} name={current.fullName || current.email} />
     345        <CollaboratorCouponsCard collaboratorId={current.id} name={collaboratorDisplayName(current)} />
    342346        {!isWordPress && <CollaboratorProductsCard collaboratorId={current.id} />}
    343         <Card>
     347        <Card data-tour="collaborator-profile">
    344348          <CardHeader>
    345349            <CardTitle>{translate('Profile')}</CardTitle>
    … …  
    374378        </Card>
    375379
    376         <Card>
     380        {/* Null only for a collaborator reading their own record. */}
     381        {current.fields !== null && (
     382          <CustomFieldsCard key={current.id} collaboratorId={current.id} fields={current.fields ?? {}} />
     383        )}
     384
     385        <Card data-tour="collaborator-rewards">
    377386          <CardHeader>
    378387            <CardTitle>{translate('Rewards Statistics')}</CardTitle>
    … …  
    514523        )}
    515524
    516         <Card>
     525        <Card data-tour="collaborator-enrolled-programs">
    517526          <CardHeader>
    518527            <CardTitle>{programsTitle}</CardTitle>
  • siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorsEditScreen.tsx

    r3775642 r3788740  
    5656    rejected: translate('Rejected'),
    5757    deleted: translate('Trashed'),
     58    invited: translate('Invited'),
    5859  }
    5960
     61  // Only an invitation makes someone invited, and only accepting it moves
     62  // them on, so neither is offered here.
    6063  const editableStatuses = (Object.entries(statusLabels) as [CollaboratorStatus, string][])
    61     .filter(([value]) => value !== 'deleted')
     64    .filter(([value]) => value !== 'deleted' && value !== 'invited')
    6265
    6366  const { id } = useParams<{ id: string }>()
    … …  
    500503              }
    501504            >
    502               <Select
    503                 value={formData.status}
    504                 onValueChange={(value: CollaboratorStatus) => updateField('status', value)}
    505               >
    506                 <SelectTrigger id="status">
    507                   <SelectValue />
    508                 </SelectTrigger>
    509                 <SelectContent>
    510                   {editableStatuses.map(([value, label]) => (
    511                     <SelectItem key={value} value={value}>
    512                       {label}
    513                     </SelectItem>
    514                   ))}
    515                 </SelectContent>
    516               </Select>
     505              {formData.status === 'invited' ? (
     506                <p id="status" className="text-sm text-muted-foreground" data-testid="invited-status">
     507                  {translate('Invited. They become a collaborator when they accept the invitation.')}
     508                </p>
     509              ) : (
     510                <Select
     511                  value={formData.status}
     512                  onValueChange={(value: CollaboratorStatus) => updateField('status', value)}
     513                >
     514                  <SelectTrigger id="status">
     515                    <SelectValue />
     516                  </SelectTrigger>
     517                  <SelectContent>
     518                    {editableStatuses.map(([value, label]) => (
     519                      <SelectItem key={value} value={value}>
     520                        {label}
     521                      </SelectItem>
     522                    ))}
     523                  </SelectContent>
     524                </Select>
     525              )}
    517526            </FormField>
    518527          </CardContent>
  • siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorsListScreen.tsx

    r3775642 r3788740  
    22import { useNavigate, useSearchParams } from 'react-router-dom'
    33import { Link } from '@service/components/Link'
    4 import { Plus, Search } from 'lucide-react'
     4import { Plus, Search, Upload } from 'lucide-react'
    55import { useCollaboratorsStore } from '@service/stores/collaborators'
    66import { useProgramsStore } from '@service/stores/programs'
    … …  
    2929import { ActivityDrawer } from '@service/components/ActivityDrawer'
    3030import { useTranslation } from '@service/i18n'
     31import { usePlatform } from '@service/contexts/platform'
    3132import { DeleteConfirmDialog } from '@service/components/DeleteConfirmDialog'
    3233import { collaboratorsApi } from '@service/api/collaborators'
    3334import { useListRequest } from '@service/hooks/useListRequest'
     35import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
     36import { InvitedStatus } from './InvitedStatus'
    3437
    3538// The columns GET /collaborators can order by. Keep in step with GetCollaborators::SORTABLE_COLUMNS.
    … …  
    4346  rejected: 'status-badge status-red',
    4447  deleted: 'status-badge status-red',
     48  invited: 'status-badge status-blue',
    4549}
    4650
    4751export function CollaboratorsListScreen() {
    4852  const { translate } = useTranslation()
     53  const { extensions, capabilities } = usePlatform()
     54  const CollaboratorsListLinks = extensions.collaboratorsListLinks
     55  const CollaboratorsListNotice = extensions.collaboratorsListNotice
     56  const CollaboratorStatusExtra = extensions.collaboratorStatusExtra
     57  // The import runs as a recipe. A platform that says this person can't import hides it.
     58  const canImport = capabilities.recipeImport !== false
    4959
    5060  const statusLabels: Record<CollaboratorStatus, string> = {
    … …  
    5464  rejected: translate('Rejected'),
    5565  deleted: translate('Trashed'),
     66  invited: translate('Invited'),
    5667}
    5768  const navigate = useNavigate()
    … …  
    8192    bulkRestore,
    8293    bulkSendSignupEmail,
     94    resendInvitation,
     95    cancelInvitation,
    8396    update,
    8497  } = useCollaboratorsStore()
    … …  
    101114  const [distributorIdFilter, setDistributorIdFilter] = useState<string>(initialDistributorId)
    102115  const [deleteTarget, setDeleteTarget] = useState<Collaborator | null>(null)
     116  // The invited person whose invitation the merchant is about to cancel.
     117  const [cancelTarget, setCancelTarget] = useState<Collaborator | null>(null)
    103118  const [localPerPage, setLocalPerPage] = useState(10)
    104119  const [sortField, setSortField] = useState<SortField>('fullName')
    … …  
    164179    orderBy: sortField,
    165180    order: sortOrder,
    166     status: statusFilter === 'all' ? 'active,pending,inactive,rejected' : statusFilter,
     181    // Everyone the merchant has invited shows too, until they accept.
     182    status: statusFilter === 'all' ? 'active,pending,inactive,rejected,invited' : statusFilter,
    167183    programId: programIdFilter ? parseInt(programIdFilter) : undefined,
    168184    distributorId: distributorIdFilter ? parseInt(distributorIdFilter) : undefined,
    … …  
    228244  const selectedNames = items
    229245    .filter((collaborator) => selectedIds.has(collaborator.id))
    230     .map((collaborator) => collaborator.fullName || collaborator.email)
     246    .map((collaborator) => collaboratorDisplayName(collaborator))
    231247
    232248  const handleEdit = (collaborator: Collaborator) => {
    … …  
    319335      header: translate('Name'),
    320336      sortable: true,
    321       cell: (collaborator) => collaborator.fullName,
     337      cell: (collaborator) => collaboratorDisplayName(collaborator),
    322338    },
    323339    {
    … …  
    366382      header: translate('Programs'),
    367383      cell: (collaborator) => (
    368         <div className="flex flex-wrap gap-1">
     384        <div className="flex flex-wrap gap-1" data-tour="collaborator-programs">
    369385          {collaborator.programs?.map((program) => (
    370386            <Link
    … …  
    448464      sortable: true,
    449465      cell: (collaborator) => (
    450         <FilterLink filterKey="status" filterValue={collaborator.status}>
    451           <span className={statusColors[collaborator.status]}>
    452             {statusLabels[collaborator.status]}
    453           </span>
    454         </FilterLink>
     466        <>
     467          <FilterLink filterKey="status" filterValue={collaborator.status}>
     468            <span className={statusColors[collaborator.status]}>
     469              {statusLabels[collaborator.status]}
     470            </span>
     471          </FilterLink>
     472          {collaborator.status === 'invited' && (
     473            <InvitedStatus
     474              collaborator={collaborator}
     475              disabled={isSubmitting}
     476              onResend={(invited) => resendInvitation(invited.id)}
     477              onCancel={setCancelTarget}
     478            />
     479          )}
     480          {CollaboratorStatusExtra && !isDeletedView && <CollaboratorStatusExtra collaboratorId={collaborator.id} />}
     481        </>
    455482      ),
    456483    },
    … …  
    593620        <div className="flex flex-wrap items-center gap-2">
    594621          <ActivityDrawer sourceType="collaborator" contextLabel="all collaborators" />
    595           <Button asChild>
     622          {CollaboratorsListLinks && <CollaboratorsListLinks />}
     623          {canImport && (
     624            <Button variant="outline" asChild data-tour="import-collaborators">
     625              <Link to="/collaborators/import">
     626                <Upload className="h-4 w-4" />
     627                {translate('Import')}
     628              </Link>
     629            </Button>
     630          )}
     631          <Button asChild data-tour="add-collaborator">
    596632            <Link to="/collaborators/new">
    597633              <Plus className="h-4 w-4" />
    … …  
    610646      )}
    611647
    612       <div className="flex gap-2 mb-4">
     648      <div className="flex gap-2 mb-4" data-tour="collaborators-filters">
    613649        <div className="relative flex-1 max-w-sm">
    614650          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
    … …  
    631667            <SelectItem value="inactive">{translate('Inactive')}</SelectItem>
    632668            <SelectItem value="rejected">{translate('Rejected')}</SelectItem>
     669            <SelectItem value="invited">{translate('Invited')}</SelectItem>
    633670            <SelectItem value="deleted">{translate('Trashed')}</SelectItem>
    634671          </SelectContent>
    … …  
    650687      )}
    651688
     689      {CollaboratorsListNotice && !isDeletedView && <CollaboratorsListNotice />}
     690
    652691      <BulkActionBar
    653692        selectedCount={selectedIds.size}
    … …  
    660699        columns={columns}
    661700        data={items}
     701        sampleKey="collaborators"
    662702        isLoading={isLoading}
    663703        emptyMessage={translate('No collaborators found.')}
    … …  
    728768        onClose={() => setDeleteTarget(null)}
    729769        noun={translate('collaborator')}
    730         name={deleteTarget?.fullName || deleteTarget?.email || ''}
     770        name={deleteTarget ? collaboratorDisplayName(deleteTarget) : ''}
    731771        permanent={isDeletedView}
    732772        title={isDeletedView ? translate('Delete Collaborator Permanently') : translate('Delete Collaborator')}
    … …  
    734774        loadBlockers={deleteTarget ? () => collaboratorsApi.deletionBlockers(deleteTarget.id) : undefined}
    735775      />
     776
     777      {/* Cancel Invitation Dialog */}
     778      <Dialog open={cancelTarget !== null} onOpenChange={(open) => !open && setCancelTarget(null)}>
     779        <DialogContent>
     780          <DialogHeader>
     781            <DialogTitle>{translate('Cancel this invitation?')}</DialogTitle>
     782            <DialogDescription>
     783              {cancelTarget
     784                ? `${cancelTarget.email} ${translate('comes off the list, and the link in their email stops working. You can invite them again later.')}`
     785                : ''}
     786            </DialogDescription>
     787          </DialogHeader>
     788          <DialogFooter>
     789            <Button variant="outline" onClick={() => setCancelTarget(null)}>
     790              {translate('Keep it')}
     791            </Button>
     792            <Button
     793              variant="destructive"
     794              disabled={isSubmitting}
     795              onClick={async () => {
     796                if (cancelTarget) {
     797                  await cancelInvitation(cancelTarget.id)
     798                }
     799                setCancelTarget(null)
     800              }}
     801            >
     802              {translate('Cancel invitation')}
     803            </Button>
     804          </DialogFooter>
     805        </DialogContent>
     806      </Dialog>
    736807
    737808      {/* Program Selection Dialog */}
  • siren-affiliates/trunk/frontend-source/src/service/screens/conversions/ConversionDetailScreen.tsx

    r3775642 r3788740  
    223223        </div>
    224224        <div className="ml-auto flex flex-wrap items-center gap-3">
    225           <span className={statusColors[current.status]}>
     225          <span className={statusColors[current.status]} data-tour="conversion-status">
    226226            {statusLabels[current.status]}
    227227          </span>
    228228          {current.status === 'pending' && (
    229229            <>
    230               <Button size="sm" onClick={() => decide('approve')} disabled={deciding !== null}>
     230              <Button size="sm" onClick={() => decide('approve')} disabled={deciding !== null} data-tour="conversion-approve">
    231231                <Check className="h-4 w-4 mr-1" />
    232232                {deciding === 'approve' ? translate('Approving...') : translate('Approve')}
    … …  
    278278
    279279        {/* Collaborator */}
    280         <Card>
     280        <Card data-tour="conversion-collaborator">
    281281          <CardHeader>
    282282            <CardTitle>{translate('Collaborator')}</CardTitle>
    … …  
    322322
    323323        {/* Transaction Details */}
    324         <Card>
     324        <Card data-tour="conversion-transaction">
    325325          <CardHeader>
    326326            <CardTitle>{translate('Transaction')}</CardTitle>
    … …  
    373373
    374374        {/* Engagement Details */}
    375         <Card>
     375        <Card data-tour="conversion-attribution">
    376376          <CardHeader>
    377377            <CardTitle>{translate('Engagement')}</CardTitle>
    … …  
    414414
    415415        {/* Obligations Table */}
    416         <Card>
     416        <Card data-tour="conversion-rewards">
    417417          <CardHeader>
    418418            <CardTitle>{translate('Obligations')}</CardTitle>
  • siren-affiliates/trunk/frontend-source/src/service/screens/conversions/ConversionsListScreen.tsx

    r3775642 r3788740  
    2323type SortOrder = 'asc' | 'desc'
    2424
     25const normalizeStatusFilter = (status: string) => status === 'approved' ? 'complete' : status
     26
    2527const statusColors: Record<ConversionStatus, string> = {
    2628  pending: 'status-badge status-yellow',
    … …  
    4345  pending: translate('Pending'),
    4446  approved: translate('Approved'),
    45   complete: translate('Complete'),
     47  complete: translate('Approved'),
    4648  rejected: translate('Rejected'),
    4749  deleted: translate('Trashed'),
    … …  
    6870
    6971  // Initialize from URL params
    70   const initialStatus = searchParams.get('status') || 'all'
     72  const initialStatus = normalizeStatusFilter(searchParams.get('status') || 'all')
    7173  const initialType = searchParams.get('type') || 'all'
    7274  const initialTransactionId = searchParams.get('transactionId') || ''
    … …  
    8890
    8991  useEffect(() => {
    90     const status = searchParams.get('status')
     92    const status = normalizeStatusFilter(searchParams.get('status') || '')
    9193    const type = searchParams.get('type')
    9294    const transactionId = searchParams.get('transactionId')
    … …  
    409411      )}
    410412
    411       <div className="flex gap-2 mb-4 flex-wrap">
     413      <div className="flex gap-2 mb-4 flex-wrap" data-tour="conversions-filters">
    412414        <Select value={statusFilter} onValueChange={handleStatusChange}>
    413415          <SelectTrigger aria-label={translate('Filter by status')} className="w-[140px]">
    … …  
    417419            <SelectItem value="all">{translate('All Statuses')}</SelectItem>
    418420            <SelectItem value="pending">{translate('Pending')}</SelectItem>
    419             <SelectItem value="approved">{translate('Approved')}</SelectItem>
    420             <SelectItem value="complete">{translate('Complete')}</SelectItem>
     421            <SelectItem value="complete">{translate('Approved')}</SelectItem>
    421422            <SelectItem value="rejected">{translate('Rejected')}</SelectItem>
    422423            <SelectItem value="deleted">{translate('Trashed')}</SelectItem>
    … …  
    464465        columns={columns}
    465466        data={items}
     467        sampleKey="conversions"
    466468        isLoading={isLoading}
    467469        emptyMessage={translate('No conversions found.')}
  • siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CollaboratorCouponsCard.tsx

    r3775642 r3788740  
    4545  const load = useCallback(async () => {
    4646    try {
    47       setCoupons((await listCoupons({ holderId: collaboratorId, perPage: 100 })).items)
     47      const items: Coupon[] = []
     48      let page = 1
     49
     50      while (true) {
     51        const response = await listCoupons({ holderId: collaboratorId, page, perPage: 100 })
     52        items.push(...response.items)
     53
     54        if (response.items.length < response.perPage || items.length >= response.total) break
     55        page += 1
     56      }
     57
     58      setCoupons(items)
    4859      setFailed(false)
    4960    } catch {
    … …  
    8899
    89100  return (
    90     <Card data-testid="collaborator-coupon-codes">
     101    <Card data-testid="collaborator-coupon-codes" data-tour="collaborator-coupons">
    91102      <CardHeader className="flex flex-row flex-wrap items-start justify-between gap-2">
    92103        <div>
  • siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CollaboratorPicker.tsx

    r3775642 r3788740  
    33import { useTranslation } from '@service/i18n'
    44import { collaboratorsApi } from '@service/api/collaborators'
     5import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    56
    67/** How many collaborators a search shows at once. */
    … …  
    4142    const timer = window.setTimeout(() => {
    4243      collaboratorsApi
    43         .list({ search: query.trim() || undefined, number: SEARCH_RESULTS, fields: ['id', 'fullName', 'nickname', 'email', 'status'] })
     44        // Collaborators only: not the trash, and not anyone only invited.
     45        .list({ search: query.trim() || undefined, number: SEARCH_RESULTS, status: 'active,pending,inactive,rejected', fields: ['id', 'fullName', 'nickname', 'email', 'status'] })
    4446        .then((list) => {
    4547          if (cancelled) return
    … …  
    4749            (list.items ?? []).map((collaborator) => ({
    4850              id: Number(collaborator.id),
    49               name: collaborator.fullName || collaborator.nickname || collaborator.email || `#${collaborator.id}`,
     51              name: collaboratorDisplayName(collaborator),
    5052              email: collaborator.email ?? null,
    5153              status: collaborator.status ?? null,
  • siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CouponCodesScreen.tsx

    r3775642 r3788740  
    2424import { ActivityDrawer } from '@service/components/ActivityDrawer'
    2525import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview'
     26import { RecordsEmptyState } from '@service/components/RecordsEmptyState'
    2627import { previewLabel } from '@service/hooks/useIntegrationPreview'
    2728import { Link } from '@service/components/Link'
    … …  
    8586 * The list can be narrowed by address: `?property=5&integration=wc`. On a
    8687 * Property's page it is fixed to that Property and drops its heading.
     88 *
     89 * Siren keeps one list of coupons for the whole organization, so the screen
     90 * shows whichever integrations the org runs. With no coupons yet, it says how
     91 * they arrive. When nothing provides coupons any more, a banner says the
     92 * coupons are kept from before.
    8793 */
    8894export function CouponCodesScreen({
    … …  
    403409  const total = data?.total ?? rows.length
    404410  const selectedCoupons = rows.filter((coupon) => selected.has(coupon.id))
    405   const hidden = capability !== undefined && !capability.shown
     411  // The server counts the org's coupons at boot. Without its answer, an empty
     412  // list with no filters reads as no coupons at all.
     413  const noCoupons = capability === undefined || !capability.hasRecords
    406414  const orphaned = capability !== undefined && !capability.available && capability.hasRecords
    407415  const filteredStore = propertyFilter !== undefined ? stores.find((store) => store.id === propertyFilter) : undefined
    … …  
    409417    filteredStore !== undefined && filteredStore.integrations.length > 0 && filteredStore.integrations.every((integration) => integration.slug === 'shopify')
    410418  const canAdd = !credit && stores.some((store) => store.integrations.length > 0)
    411 
    412   if (hidden && !embedded) {
    413     return (
    414       <div className="space-y-4">
    415         <h1 className="text-2xl font-semibold">{translate('Coupon codes')}</h1>
    416         <div className="rounded-md border p-6 text-sm text-muted-foreground" data-testid="coupon-codes-unavailable">
    417           <p>{translate('No active integration provides coupons. Turn on a store integration that has coupons to manage them here.')}</p>
    418           {isWordPress ? null : (
    419             <p className="mt-2">
    420               <Link to="/settings/integrations" className="text-primary hover:underline">
    421                 {translate('Go to integrations')}
    422               </Link>
    423             </p>
    424           )}
    425         </div>
    426       </div>
    427     )
    428   }
    429419
    430420  return (
    … …  
    576566          columns={columns}
    577567          data={rows}
     568        sampleKey="couponCodes"
    578569          isLoading={loading}
    579570          selectable={!credit}
    … …  
    581572          onSelectionChange={setSelected}
    582573          emptyMessage={
    583             filtered
    584               ? translate('No coupon codes match these filters.')
    585               : embedded
    586                 ? translate('No coupon codes from this Property yet.')
    587                 : translate('No coupon codes yet. Coupon codes appear here when your store saves one or a shopper uses one.')
     574            filtered ? (
     575              translate('No coupon codes match these filters.')
     576            ) : embedded ? (
     577              translate('No coupon codes from this Property yet.')
     578            ) : noCoupons && !credit ? (
     579              <RecordsEmptyState kind="coupon" />
     580            ) : (
     581              translate('No coupon codes yet. Coupon codes appear here when your store saves one or a shopper uses one.')
     582            )
    588583          }
    589584          getRowLabel={(coupon) => coupon.code}
  • siren-affiliates/trunk/frontend-source/src/service/screens/currencies/CustomCurrenciesManager.tsx

    r3775642 r3788740  
    295295        fields: ['id', 'name', 'status'],
    296296        units: code,
     297        status: 'active',
    297298        perPage: 100,
    298299      })
    299       setAffectedPrograms(response.items.filter((p: Program) => p.status !== 'inactive'))
     300      setAffectedPrograms(response.items)
    300301    } catch {
    301302      setAffectedPrograms([])
    … …  
    523524            columns={columns}
    524525            data={rows}
     526        sampleKey="currencies"
    525527            emptyMessage={translate('No custom currencies. Create one to get started.')}
    526528            getRowLabel={(currency) => currency.name}
  • siren-affiliates/trunk/frontend-source/src/service/screens/customers/CustomersBanner.tsx

    r3775642 r3788740  
    2323  )
    2424}
    25 
    26 /**
    27  * What the Customers screen says when no integration provides customers and
    28  * none are kept: it is never redirected.
    29  */
    30 export function NoCustomersProvided() {
    31   const { translate } = useTranslation()
    32 
    33   return (
    34     <p className="py-8 text-center text-sm text-muted-foreground">
    35       {translate('No active integration provides customers. Turn on a store integration that records customers to manage them here.')}
    36     </p>
    37   )
    38 }
  • siren-affiliates/trunk/frontend-source/src/service/screens/customers/CustomersListScreen.tsx

    r3775642 r3788740  
    1919import { ActivityDrawer } from '@service/components/ActivityDrawer'
    2020import { Link } from '@service/components/Link'
     21import { RecordsEmptyState } from '@service/components/RecordsEmptyState'
    2122import { useRecordCapability } from '@service/hooks/useRecordCapability'
    2223import { useTranslation } from '@service/i18n'
    2324import { customersApi, customerTitle, type Customer, type CustomerList, type SuggestionPair } from '@service/api/customers'
    2425import { identityDescription, integrationName, knownIntegrations, useCollaboratorNames, usePropertyNames } from './helpers'
    25 import { CustomersBanner, NoCustomersProvided } from './CustomersBanner'
     26import { CustomersBanner } from './CustomersBanner'
    2627import { MergeCustomersDialog } from './MergeCustomersDialog'
    2728import { MergeWithDialog } from './MergeWithDialog'
    … …  
    4344 * Rows can be selected for a bulk Merge, and each has "Merge with…". The
    4445 * filters live in the address, so `/customers?linked=1` opens the linked
    45  * customers. Only merchants see this screen, and only they see names.
     46 * customers, and `?property=5` one store's. Only merchants see this screen,
     47 * and only they see names.
     48 *
     49 * Siren keeps one list of customers for the whole organization, so the
     50 * screen shows whichever integrations the org runs. With no customers yet,
     51 * it says how they arrive.
    4652 */
    4753export function CustomersListScreen({ canConfirmCrossStore = false }: { canConfirmCrossStore?: boolean } = {}) {
    … …  
    7076  const nameOf = useCollaboratorNames((data?.customers ?? []).flatMap((customer) => customer.collaboratorIds))
    7177
    72   const hidden = capability !== undefined && !capability.shown
     78  // The server counts the org's customers at boot. Without its answer, an
     79  // empty list with no filters reads as no customers at all.
     80  const noCustomers = capability === undefined || !capability.hasRecords
    7381
    7482  useEffect(() => {
    75     if (hidden) return
    7683    let cancelled = false
    7784    setLoading(true)
    … …  
    107114      cancelled = true
    108115    }
    109   }, [hidden, appliedSearch, property, integration, linked, matchesOnly, page, reload, translate])
     116  }, [appliedSearch, property, integration, linked, matchesOnly, page, reload, translate])
    110117
    111118  const setParam = useCallback(
    … …  
    218225  )
    219226
    220   if (hidden) {
    221     return (
    222       <div>
    223         <h1 className="mb-2 text-2xl font-semibold">{translate('Customers')}</h1>
    224         <NoCustomersProvided />
    225       </div>
    226     )
    227   }
    228 
    229227  const filterItems = [
    230228    {
    … …  
    381379          columns={columns}
    382380          data={data?.customers ?? []}
     381        sampleKey="customers"
    383382          isLoading={loading}
    384383          selectable
    … …  
    386385          onSelectionChange={setSelected}
    387386          emptyMessage={
    388             appliedSearch || integration || linked || matchesOnly || property !== null
    389               ? translate('No customers match these filters.')
    390               : translate('No customers yet. Customers appear here when they buy, sign in after a referral, or are linked to a collaborator.')
     387            appliedSearch || integration || linked || matchesOnly || property !== null ? (
     388              translate('No customers match these filters.')
     389            ) : noCustomers ? (
     390              <RecordsEmptyState kind="customer" />
     391            ) : (
     392              translate('No customers yet. Customers appear here when they buy, sign in after a referral, or are linked to a collaborator.')
     393            )
    391394          }
    392395          getRowLabel={(customer) => customerTitle(customer)}
  • siren-affiliates/trunk/frontend-source/src/service/screens/customers/LinkCollaboratorDialog.tsx

    r3775642 r3788740  
    55import { useTranslation } from '@service/i18n'
    66import type { Collaborator } from '@core/types/collaborator'
     7import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    78
    89/**
    … …  
    3435
    3536    collaboratorsApi
    36       .list({ search: params.search || undefined, page: params.page, perPage: params.perPage })
     37      // Collaborators only: not the trash, and not anyone only invited.
     38      .list({ search: params.search || undefined, page: params.page, perPage: params.perPage, status: 'active,pending,inactive,rejected' })
    3739      .then((response) => {
    3840        if (cancelled) return
    … …  
    5355
    5456  const columns: ColumnDef<Collaborator>[] = [
    55     { id: 'name', header: translate('Collaborator'), cell: (collaborator) => collaborator.fullName || collaborator.email },
     57    { id: 'name', header: translate('Collaborator'), cell: (collaborator) => collaboratorDisplayName(collaborator) },
    5658    { id: 'email', header: translate('Email'), cell: (collaborator) => collaborator.email },
    5759  ]
  • siren-affiliates/trunk/frontend-source/src/service/screens/customers/helpers.ts

    r3775642 r3788740  
    44import { usePlatform } from '@service/contexts/platform'
    55import type { CustomerIdentity } from '@service/api/customers'
     6import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    67
    78const INTEGRATIONS: Record<string, string> = {
    … …  
    8788        collaboratorsApi
    8889          .get(id)
    89           .then((collaborator) => [id, collaborator.fullName || collaborator.email || `#${id}`] as const)
     90          .then((collaborator) => [id, collaboratorDisplayName(collaborator)] as const)
    9091          .catch(() => [id, `#${id}`] as const)
    9192      )
  • siren-affiliates/trunk/frontend-source/src/service/screens/engagements/EngagementsListScreen.tsx

    r3754739 r3788740  
    271271        columns={columns}
    272272        data={items}
     273        sampleKey="engagements"
    273274        isLoading={isLoading}
    274275        emptyMessage={translate('No engagements found.')}
  • siren-affiliates/trunk/frontend-source/src/service/screens/fulfillments/FulfillmentDetailScreen.tsx

    r3775642 r3788740  
    66import { useFulfillmentsStore } from '@service/stores/fulfillments'
    77import { useAutofulfillersStore } from '@service/stores/autofulfillers'
    8 import type { AutofulfillResult, Payout, PayoutStatus } from '@core/types/fulfillment'
     8import type { AutofulfillResult, Fulfillment, Payout, PayoutStatus } from '@core/types/fulfillment'
    99import type { FulfillmentMethod } from '@core/types/autofulfiller'
    1010import { DataTable, BulkActionBar } from '@service/components/data-table'
    … …  
    1414import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter'
    1515import { isWaitingOnCollaborator, waitingMethodName } from '@service/utils/payout-waiting'
     16import { automaticMethodFor, payoutMaySendSoon } from '@service/utils/payout-refresh'
     17import { useBoundedRefresh } from '@service/hooks/useBoundedRefresh'
    1618import {
    1719  Button,
    … …  
    2628import { ActivityDrawer } from '@service/components/ActivityDrawer'
    2729import { AutofulfillResultNotice } from './AutofulfillResultNotice'
     30import { useTourSample } from '@service/contexts/tour-sample'
     31import { TourSampleBanner } from '@service/components/tour-sample'
    2832
    2933const statusColors: Record<PayoutStatus, string> = {
    … …  
    4953
    5054  const {
    51     current,
    52     isLoading,
     55    current: storedCurrent,
     56    isLoading: storeLoading,
    5357    isSubmitting,
    54     error,
     58    error: storeError,
    5559    fetchOne,
     60    refreshCurrent,
    5661    clearCurrent,
    5762    fulfillPayouts,
    … …  
    6772  } = useAutofulfillersStore()
    6873
     74  // The product tour opens an example fulfillment here. It never comes from
     75  // the API, and nothing on it can be changed.
     76  const tourSample = useTourSample<Fulfillment>('fulfillmentDetail')
     77  const isSample = tourSample !== null
     78  const current = tourSample ?? storedCurrent
     79  const isLoading = isSample ? false : storeLoading
     80  const error = isSample ? null : storeError
     81
    6982  const [selectedPayoutIds, setSelectedPayoutIds] = useState<Set<number>>(new Set())
    7083  const [showFulfillConfirm, setShowFulfillConfirm] = useState(false)
    … …  
    8598
    8699  useEffect(() => {
    87     if (id) {
     100    // Only a real fulfillment's id is asked for. The tour's example page has none.
     101    if (id && !isSample && /^\d+$/.test(id)) {
    88102      fetchOne(parseInt(id))
    89103    }
    … …  
    92106      clearCurrent()
    93107    }
    94   }, [id, fetchOne, clearCurrent])
     108  }, [id, fetchOne, clearCurrent, isSample])
     109
     110  // The background worker sends an automatic payout seconds after it appears,
     111  // so the screen reads it again until it lands. A merchant paying by hand has
     112  // nothing that changes on its own, and this stays off. A load clears this
     113  // for a moment, so sending payouts from here starts a new period.
     114  const payoutsMaySendSoon =
     115    Boolean(import.meta.env.FEATURE_AUTOFULFILLERS) &&
     116    !isSample &&
     117    !storeLoading &&
     118    (storedCurrent?.payouts ?? []).some((payout) => payoutMaySendSoon(payout, autofulfillers, fulfillmentMethods))
     119
     120  useBoundedRefresh(payoutsMaySendSoon, () => (storedCurrent ? refreshCurrent(storedCurrent.id) : undefined))
    95121
    96122  const formatDate = (dateString: string | undefined) => {
    … …  
    252278          )}
    253279          {import.meta.env.FEATURE_AUTOFULFILLERS && payout.status === 'failed' && (
    254             <div className="mt-1 max-w-md" data-testid={`payout-failure-${payout.id}`}>
     280            <div className="mt-1 max-w-md" data-testid={`payout-failure-${payout.id}`} data-tour="payout-failed">
    255281              <p className="text-sm text-destructive break-words">
    256282                {payout.failureReason || translate('No reason was recorded for this failure.')}
    … …  
    301327            variant="outline"
    302328            size="sm"
    303             disabled={isSubmitting}
     329            disabled={isSubmitting || isSample}
    304330            onClick={() => retryPayout(current.id, payout.id)}
    305331          >
    … …  
    311337  }
    312338
    313   /**
    314    * The payout method that sends a currency automatically, the way the
    315    * server decides it: an autofulfiller for the currency, a method that is
    316    * installed, and a plan that includes it.
    317    */
    318   const methodFor = (currency: string): FulfillmentMethod | null => {
    319     const autofulfiller = autofulfillers.find(
    320       (candidate) => candidate.currency.toUpperCase() === currency.toUpperCase()
    321     )
    322     if (!autofulfiller) return null
    323     const method = fulfillmentMethods.find((candidate) => candidate.id === autofulfiller.method)
    324     if (!method || method.entitled === false) return null
    325     return method
    326   }
     339  const methodFor = (currency: string): FulfillmentMethod | null =>
     340    automaticMethodFor(currency, autofulfillers, fulfillmentMethods)
    327341
    328342  // The payouts the primary action would send: unpaid ones, and failed ones,
    … …  
    356370  return (
    357371    <div>
     372      {isSample && <TourSampleBanner className="mb-4 rounded-lg border" />}
    358373      <div className="flex flex-wrap items-center gap-x-4 gap-y-2 mb-6">
    359374        {!isWordPress && (
    … …  
    366381          <Button
    367382            onClick={() => setShowAutofulfillConfirm(true)}
    368             disabled={isSubmitting}
     383            disabled={isSubmitting || isSample}
     384            data-tour="fulfillment-send-automatically"
    369385          >
    370386            <Send className="h-4 w-4 mr-2" />
    … …  
    375391          variant="outline"
    376392          onClick={() => setShowFulfillConfirm(true)}
    377           disabled={isSubmitting}
     393          disabled={isSubmitting || isSample}
     394          data-tour="fulfill-payouts"
    378395        >
    379396          {isSubmitting
    … …  
    386403          {payouts.length} item{payouts.length !== 1 ? 's' : ''}
    387404        </span>
    388         <ActivityDrawer
    389           sourceType="fulfillment"
    390           sourceId={current.id}
    391           contextLabel={`fulfillment #${current.id}`}
    392         />
     405        {!isSample && (
     406          <ActivityDrawer
     407            sourceType="fulfillment"
     408            sourceId={current.id}
     409            contextLabel={`fulfillment #${current.id}`}
     410          />
     411        )}
    393412      </div>
    394413
    395       <div className="grid gap-4 md:grid-cols-4 mb-4">
     414      <div className="grid gap-4 md:grid-cols-4 mb-4" data-tour="fulfillment-totals">
    396415        <div className="rounded-lg border bg-muted/30 px-4 py-3">
    397416          <div className="text-xs text-muted-foreground">Total Value</div>
    … …  
    444463        columns={columns}
    445464        data={payouts}
     465        sample={isSample}
    446466        isLoading={false}
    447467        emptyMessage={translate('No payouts in this fulfillment.')}
  • siren-affiliates/trunk/frontend-source/src/service/screens/fulfillments/FulfillmentsListScreen.tsx

    r3775642 r3788740  
    2020import { AutofulfillersModal } from './AutofulfillersModal'
    2121import { AutofulfillResultNotice } from './AutofulfillResultNotice'
     22import { FulfillmentsAutoRefresh } from './FulfillmentsAutoRefresh'
    2223
    2324type SortField = 'dateCreated'
    … …  
    207208        <ActivityDrawer sourceType="fulfillment" contextLabel="all fulfillments" />
    208209        {import.meta.env.FEATURE_AUTOFULFILLERS ? (
    209           <Button variant="outline" onClick={() => setShowAutofulfillers(true)}>
     210          <Button variant="outline" onClick={() => setShowAutofulfillers(true)} data-tour="autofulfillers">
    210211            <Settings2 className="h-4 w-4 mr-2" />
    211212            {translate('Manage Autofulfillers')}
    212213          </Button>
    213214        ) : (
    214           <Button variant="ghost" disabled className="opacity-60">
     215          <Button variant="ghost" disabled className="opacity-60" data-tour="autofulfillers">
    215216            <Sparkles className="h-4 w-4 mr-2" />
    216217            {translate('Manage Autofulfillers')}
    … …  
    226227        <AutofulfillersModal open={showAutofulfillers} onOpenChange={setShowAutofulfillers} />
    227228      )}
     229      {import.meta.env.FEATURE_AUTOFULFILLERS && <FulfillmentsAutoRefresh />}
    228230
    229231      {error && (
    … …  
    233235      )}
    234236
    235       <div className="flex gap-2 mb-4 flex-wrap">
     237      <div className="flex gap-2 mb-4 flex-wrap" data-tour="fulfillments-filters">
    236238        <Select value={statusFilter} onValueChange={(value) => setStatusFilter(value as StatusFilter)}>
    237239          <SelectTrigger className="w-[190px]" aria-label={translate('Filter fulfillments')}>
    … …  
    274276        columns={columns}
    275277        data={items}
     278        sampleKey="fulfillments"
    276279        isLoading={isLoading}
    277280        selectable={import.meta.env.FEATURE_AUTOFULFILLERS}
  • siren-affiliates/trunk/frontend-source/src/service/screens/main-menu/LogsTab.tsx

    r3775642 r3788740  
    1414  SelectTrigger,
    1515  SelectValue,
     16  CodeBlock,
    1617} from '@service/components/ui'
    1718import { useTranslation } from '@service/i18n'
    … …  
    2425  type LogResponse,
    2526} from '@service/api/utilities'
     27import { toast } from 'sonner'
     28import { writeClipboard } from '@service/lib/clipboard'
    2629
    2730const PAGE_SIZE = 100
    … …  
    124127    const payload = formatEntryForClipboard(entry)
    125128    try {
    126       await navigator.clipboard.writeText(payload)
     129      await writeClipboard(payload)
    127130    } catch {
    128       // Fallback for environments without clipboard permissions
    129       // (older browsers, insecure contexts).
    130       const ta = document.createElement('textarea')
    131       ta.value = payload
    132       ta.style.position = 'fixed'
    133       ta.style.opacity = '0'
    134       document.body.appendChild(ta)
    135       ta.select()
    136       try {
    137         document.execCommand('copy')
    138       } finally {
    139         document.body.removeChild(ta)
    140       }
     131      toast.error(translate('Copy failed. Select the text and copy it.'))
     132      return
    141133    }
    142134    setCopiedId(entry.id)
    … …  
    312304                  </button>
    313305                  {open && hasContext && (
    314                     <pre className="mt-2 overflow-x-auto rounded-md bg-muted/50 p-2 text-[10px] text-muted-foreground">
    315                       {JSON.stringify(entry.context, null, 2)}
    316                     </pre>
     306                    <CodeBlock
     307                      className="mt-2"
     308                      code={JSON.stringify(entry.context, null, 2)}
     309                      language="json"
     310                      copy={false}
     311                      maxHeight="sm"
     312                    />
    317313                  )}
    318314                </li>
  • siren-affiliates/trunk/frontend-source/src/service/screens/main-menu/UtilitiesTab.tsx

    r3775642 r3788740  
    3232  type StatusSection,
    3333} from '@service/api/utilities'
     34import { writeClipboard } from '@service/lib/clipboard'
    3435
    3536/**
    … …  
    8182    if (!status || !info) return
    8283    try {
    83       await navigator.clipboard.writeText(formatDump(status, info))
     84      await writeClipboard(formatDump(status, info))
    8485      setCopied(true)
    8586      setTimeout(() => setCopied(false), 2000)
  • siren-affiliates/trunk/frontend-source/src/service/screens/obligations/ObligationsListScreen.tsx

    r3775642 r3788740  
    2424import { TestSaleBadge } from '@service/components/TestSaleBadge'
    2525import { useTranslation } from '@service/i18n'
     26import { useTourSample } from '@service/contexts/tour-sample'
    2627import { linkedRecordName } from '@service/utils/linked-record'
    2728import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter'
    … …  
    249250    })
    250251  }
     252
     253  // While the product tour shows example obligations in place of an empty list.
     254  const tourRows = useTourSample<Array<Obligation & { tourSelected?: boolean }>>('obligations')
     255  const tourSelectedCount =
     256    tourRows && !isLoading && items.length === 0 ? tourRows.filter((row) => row.tourSelected).length : 0
    251257
    252258  const columns: ColumnDef<Obligation>[] = [
    … …  
    447453      )}
    448454
    449       <div className="flex gap-2 mb-4 flex-wrap">
     455      <div className="flex gap-2 mb-4 flex-wrap" data-tour="obligations-filters">
    450456        <Select value={statusFilter} onValueChange={handleStatusChange}>
    451457          <SelectTrigger aria-label={translate('Filter by status')} className="w-[240px]">
    … …  
    470476      />
    471477
     478      {/* The product tour's example rows show the action that turns Approved obligations into payouts, unusable. */}
     479      {tourSelectedCount > 0 && (
     480        <BulkActionBar
     481          sample
     482          selectedCount={tourSelectedCount}
     483          actions={[{ label: translate('Create Fulfillments'), onClick: () => undefined }]}
     484          onClear={() => undefined}
     485        />
     486      )}
     487
    472488      <DataTable
    473489        columns={columns}
    474490        data={items}
     491        sampleKey="obligations"
    475492        isLoading={isLoading}
    476493        emptyMessage={translate('No obligations found.')}
  • siren-affiliates/trunk/frontend-source/src/service/screens/products/CollaboratorProductsCard.tsx

    r3775642 r3788740  
    188188  ]
    189189
     190  const unavailableIds = new Set(excluded)
     191  items.forEach((product) => {
     192    if (product.owners.length >= MAX_PRODUCT_OWNERS) unavailableIds.add(product.id)
     193  })
     194
    190195  return (
    191196    <BulkPickerModal
    … …  
    194199      title={translate('Link to a product')}
    195200      description={translate('This collaborator earns from the products you pick, on every store that sells them.')}
    196       excludedIds={excluded}
     201      excludedIds={unavailableIds}
    197202      items={items}
    198203      isLoading={loading}
  • siren-affiliates/trunk/frontend-source/src/service/screens/products/ProductViewScreen.tsx

    r3775642 r3788740  
    2727import { HelpTooltip } from '@service/components/help'
    2828import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview'
     29import { PlanUpgradeNotice } from '@service/components/plan-upgrade-notice'
    2930import { useTranslation } from '@service/i18n'
    3031import { collaboratorsApi } from '@service/api/collaborators'
    … …  
    4445import { usePropertyNames } from './usePropertyNames'
    4546import { formatDate } from '@service/utils/format-date'
     47import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    4648
    4749/** Rows on one page of the owner picker. */
    … …  
    6264 * product with one the merchant finds, and "Split off" turns one listing
    6365 * back into a product of its own.
     66 *
     67 * Where the plan doesn't include product ownership, the Owners card names
     68 * the plan that does instead of offering to link collaborators.
    6469 */
    6570export function ProductViewScreen() {
    … …  
    8186  const [unlinking, setUnlinking] = useState<ProductOwnerRef | null>(null)
    8287  const [loadError, setLoadError] = useState<string | null>(null)
    83   const { isWordPress } = usePlatform()
     88  const { isWordPress, planAllows } = usePlatform()
     89  // Choosing who owns a product is a plan feature. The product itself is not.
     90  const canOwn = planAllows('product-ownership')
    8491  const properties = usePropertyNames()
    8592
    … …  
    311318                <HelpTooltip topic="product-owners" side="right" />
    312319              </CardTitle>
    313               <Button size="sm" variant="outline" onClick={() => setPicking(true)} disabled={saving || room <= 0}>
    314                 <UserPlus className="h-4 w-4" aria-hidden="true" />
    315                 {translate('Link to collaborator')}
    316               </Button>
     320              {canOwn ? (
     321                <Button size="sm" variant="outline" onClick={() => setPicking(true)} disabled={saving || room <= 0}>
     322                  <UserPlus className="h-4 w-4" aria-hidden="true" />
     323                  {translate('Link to collaborator')}
     324                </Button>
     325              ) : null}
    317326            </div>
    318327          </CardHeader>
    319328          <CardContent>
    320             {product.owners.length === 0 ? (
     329            {!canOwn ? (
     330              <PlanUpgradeNotice feature={translate('product owners')} plan="essentials" />
     331            ) : product.owners.length === 0 ? (
    321332              <p className="text-sm text-muted-foreground">{translate('No owners')}</p>
    322333            ) : (
    … …  
    471482      setLoading(true)
    472483      try {
    473         const found = await collaboratorsApi.list({ search: params.search || undefined, page: params.page, perPage: params.perPage })
     484        // Collaborators only: not the trash, and not anyone only invited.
     485        const found = await collaboratorsApi.list({ search: params.search || undefined, page: params.page, perPage: params.perPage, status: 'active,pending,inactive,rejected' })
    474486        const candidates = found.items.map((collaborator) => ({
    475487          id: collaborator.id,
    476           name: collaborator.fullName || collaborator.nickname || collaborator.email,
     488          name: collaboratorDisplayName(collaborator),
    477489          email: collaborator.email,
    478490          status: collaborator.status,
  • siren-affiliates/trunk/frontend-source/src/service/screens/products/ProductsListScreen.tsx

    r3775642 r3788740  
    22import { useNavigate, useSearchParams } from 'react-router-dom'
    33import { toast } from 'sonner'
    4 import { Plus, Search } from 'lucide-react'
     4import { Plus, Search, Upload } from 'lucide-react'
    55import {
    66  Button,
    … …  
    1818import { ActivityDrawer } from '@service/components/ActivityDrawer'
    1919import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview'
     20import { RecordsEmptyState } from '@service/components/RecordsEmptyState'
     21import { usePlatform } from '@service/contexts/platform'
    2022import { useTranslation } from '@service/i18n'
     23import { Link } from '@service/components/Link'
    2124import { MAX_MERGE_PRODUCTS, productsApi, liveListings, type Product, type ProductList } from '@service/api/products'
    2225import { integrationName, knownIntegrations } from './integrationLabels'
    … …  
    2528import { MergeProductsDialog } from './MergeProductsDialog'
    2629import { usePropertyNames } from './usePropertyNames'
     30
     31/** The plan capability for choosing who owns a product. */
     32const PRODUCT_OWNERSHIP = 'product-ownership'
    2733
    2834/** Rows on one page of the list. */
    … …  
    5056 * merchant keeps. `propertyId` holds an embedded list to one store.
    5157 *
    52  * When no active integration provides products any more, a banner says the
    53  * products are kept from before, and their owners still earn.
     58 * Siren keeps one list of products for the whole organization, so the page
     59 * shows whichever integrations the org runs. With no products yet, it says
     60 * how they arrive. When no active integration provides products any more, a
     61 * banner says the products are kept from before, and their owners still earn.
     62 * Owners show only where the plan includes product ownership.
    5463 */
    5564export function ProductsListScreen({ propertyId, embedded = false }: { propertyId?: number; embedded?: boolean } = {}) {
    5665  const { translate } = useTranslation()
    5766  const navigate = useNavigate()
     67  const { planAllows } = usePlatform()
     68  const showsOwners = planAllows(PRODUCT_OWNERSHIP)
    5869  const [searchParams, setSearchParams] = useSearchParams()
     70  // The import runs as a recipe. A platform that says this person can't import hides it.
     71  const canImport = usePlatform().capabilities.recipeImport !== false
    5972
    6073  const property = propertyId ?? wholeNumber(searchParams.get('property'))
    … …  
    109122
    110123  const capability = data?.capability ?? null
     124  const displayedProducts = useMemo(() => {
     125    const products = data?.products ?? []
     126    const children = new Map<number, Product[]>()
     127    for (const product of products) {
     128      if (product.parentId == null) continue
     129      children.set(product.parentId, [...(children.get(product.parentId) ?? []), product])
     130    }
     131
     132    const ordered: Product[] = []
     133    const seen = new Set<number>()
     134    const add = (product: Product) => {
     135      if (seen.has(product.id)) return
     136      seen.add(product.id)
     137      ordered.push(product)
     138      for (const child of children.get(product.id) ?? []) add(child)
     139    }
     140    for (const product of products.filter((item) => item.parentId == null || !products.some((parent) => parent.id === item.parentId))) add(product)
     141    for (const product of products) add(product)
     142    return ordered
     143  }, [data?.products])
    111144
    112145  /** Changes the query string. A new filter or search goes back to page one. */
    … …  
    132165        header: translate('Product'),
    133166        cell: (product) => (
    134           <div className="flex min-w-0 max-w-xs items-center gap-2">
     167          <div className={`flex min-w-0 max-w-xs items-center gap-2 ${product.parentId != null ? 'pl-5' : ''}`}>
    135168            <span className="truncate font-medium">{product.name}</span>
     169            {product.parentId != null && <span className="text-xs text-muted-foreground">{translate('Variation')}</span>}
    136170            {product.openSuggestions > 0 && (
    137171              <span className="status-badge status-yellow shrink-0">
    … …  
    159193        },
    160194      },
    161       {
    162         id: 'owners',
    163         header: translate('Owners'),
    164         cell: (product) =>
    165           product.owners.length === 0 ? (
    166             <span className="text-sm text-muted-foreground">{translate('No owners')}</span>
    167           ) : (
    168             <span className="text-sm">{product.owners.map((owner) => owner.name).join(', ')}</span>
    169           ),
    170       },
     195      ...(showsOwners
     196        ? [
     197            {
     198              id: 'owners',
     199              header: translate('Owners'),
     200              cell: (product: Product) =>
     201                product.owners.length === 0 ? (
     202                  <span className="text-sm text-muted-foreground">{translate('No owners')}</span>
     203                ) : (
     204                  <span className="text-sm">{product.owners.map((owner) => owner.name).join(', ')}</span>
     205                ),
     206            },
     207          ]
     208        : []),
    171209    ],
    172     [properties, translate]
     210    [properties, showsOwners, translate]
    173211  )
     212
     213  const filtered = Boolean(appliedSearch || integration || matchesOnly || (property !== null && !embedded))
     214  // The server counts the org's products. Without its answer, an empty list
     215  // with no filters reads as no products at all.
     216  const noProducts = capability === null || !capability.hasRecords
    174217
    175218  const filterItems = [
    … …  
    214257        <div className="flex flex-wrap items-center gap-2">
    215258          {embedded ? null : <ActivityDrawer sourceType="product" contextLabel={translate('all products')} />}
     259          {!embedded && canImport && (
     260            <Button variant="outline" asChild>
     261              <Link to="/products/import">
     262                <Upload className="h-4 w-4" aria-hidden="true" />
     263                {translate('Import')}
     264              </Link>
     265            </Button>
     266          )}
    216267          <Button onClick={() => setAdding(true)}>
    217268            <Plus className="h-4 w-4" aria-hidden="true" />
    … …  
    316367        <DataTable
    317368          columns={columns}
    318           data={data?.products ?? []}
     369          data={displayedProducts}
     370        sampleKey="products"
    319371          selectable
    320372          selectedIds={selected}
    … …  
    322374          isLoading={loading}
    323375          emptyMessage={
    324             appliedSearch || integration || matchesOnly || (property !== null && !embedded)
    325               ? translate('No products match these filters.')
    326               : translate('No products yet. A product shows up here when a store saves it or sells it.')
     376            filtered ? (
     377              translate('No products match these filters.')
     378            ) : noProducts && !embedded ? (
     379              <RecordsEmptyState kind="product" />
     380            ) : soldNow ? (
     381              translate('No products are sold now. Clear Sold now to see every product.')
     382            ) : (
     383              translate('No products yet. A product shows up here when a store saves it or sells it.')
     384            )
    327385          }
    328386          getRowLabel={(product) => product.name}
  • siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramViewScreen.tsx

    r3775642 r3788740  
    4848import { linkedRecordName } from '@service/utils/linked-record'
    4949import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter'
     50import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    5051
    5152const incentiveTypeLabels: Record<string, string> = {
    … …  
    117118      const programId = parseInt(id)
    118119      fetchOne(programId)
    119       fetchConversions({ programId, perPage: 10, status: 'pending,approved,complete,rejected' })
     120      fetchConversions({ programId, perPage: 10, status: 'pending,approved,complete,rejected', orderBy: 'dateCreated', order: 'desc' })
    120121      // An engagement is active, complete or expired. A completed one led to a conversion.
    121       fetchEngagements({ programId, perPage: 10, status: 'active,complete,expired' })
     122      fetchEngagements({ programId, perPage: 10, status: 'active,complete,expired', orderBy: 'dateCreated', order: 'desc' })
    122123      fetchCollaborators({ programId, perPage: 10, status: 'active,pending,inactive,rejected' })
    123124    }
    … …  
    219220      cell: (collaborator) => (
    220221        <Link to={`/collaborators/${collaborator.id}/view`} className="text-primary hover:underline">
    221           {collaborator.fullName}
     222          {collaboratorDisplayName(collaborator)}
    222223        </Link>
    223224      ),
    … …  
    271272          </Button>
    272273        )}
    273         <div className="flex-1 min-w-[min(100%,14rem)]">
     274        <div className="flex-1 min-w-[min(100%,14rem)]" data-tour="program-heading">
    274275          <div className="flex flex-wrap items-center gap-3">
    275276            <h1 className="text-2xl font-semibold">{current.name}</h1>
    … …  
    280281        <div className="flex items-center gap-2">
    281282          <ActivityDrawer sourceType="program" sourceId={current.id} contextLabel={current.name} />
    282           <Button asChild>
     283          <Button asChild data-tour="program-edit">
    283284            <Link to={`/programs/${current.id}`}>
    284285              <Pencil className="h-4 w-4 mr-2" />
    … …  
    317318        />
    318319
    319         <Card>
     320        <Card data-tour="program-rewards">
    320321          <CardHeader>
    321322            <CardTitle>{translate('Configuration')}</CardTitle>
    … …  
    404405        </Card>
    405406
    406         <Card>
     407        <Card data-tour="program-stats">
    407408          <CardHeader>
    408409            <CardTitle>{translate('Statistics')}</CardTitle>
    … …  
    512513      {/* Collaborators Table */}
    513514      <div className="mt-6">
    514         <Card>
     515        <Card data-tour="program-collaborators">
    515516          <CardHeader className="flex flex-row items-center justify-between">
    516517            <div>
  • siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramsEditScreen.tsx

    r3775642 r3788740  
    7979import { useCategoryFilterSupport } from '@service/hooks/useCategoryFilterSupport'
    8080import { CategoryFilterNotice } from '@service/components/CategoryFilterNotice'
     81import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
    8182
    8283// The backend may return registry values as plain strings OR as {id, name} objects.
    … …  
    13511352        <form onSubmit={handleSubmit} className="flex-1 min-w-0 max-w-2xl space-y-6 min-h-0 pb-[50vh]">
    13521353        {/* Basic Information */}
    1353         <div className="space-y-4">
     1354        <div className="space-y-4" data-tour="program-form-basics">
    13541355          <FormField
    13551356            label={translate('Name')}
    … …  
    15831584                  currentColumns={
    15841585                    [
    1585                       { id: 'fullName', header: translate('Name'), cell: (c) => c.fullName },
     1586                      { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) },
    15861587                      { id: 'email', header: translate('Email'), cell: (c) => c.email },
    15871588                      { id: 'status', header: translate('Status'), cell: (c) => c.status },
    … …  
    15931594                  pendingAdditionColumns={
    15941595                    [
    1595                       { id: 'fullName', header: translate('Name'), cell: (c) => c.fullName },
     1596                      { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) },
    15961597                      { id: 'email', header: translate('Email'), cell: (c) => c.email },
    15971598                      { id: 'status', header: translate('Status'), cell: (c) => c.status },
    … …  
    16061607                  pickerColumns={
    16071608                    [
    1608                       { id: 'fullName', header: translate('Name'), cell: (c) => c.fullName },
     1609                      { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) },
    16091610                      { id: 'email', header: translate('Email'), cell: (c) => c.email },
    16101611                      { id: 'status', header: translate('Status'), cell: (c) => c.status },
    … …  
    16881689        <Card
    16891690          id="engagement-tracking"
     1691          data-tour="program-form-engagements"
    16901692          className={cn(
    16911693            'transition-all duration-300',
    … …  
    17731775        <Card
    17741776          id="attribution-model"
     1777          data-tour="program-form-attribution"
    17751778          className={cn(
    17761779            'transition-all duration-300',
    … …  
    18781881        <Card
    18791882          id="incentive-structure"
     1883          data-tour="program-form-rewards"
    18801884          className={cn(
    18811885            'transition-all duration-300',
    … …  
    20852089        />
    20862090
    2087         <div className="flex gap-2">
     2091        <div className="flex gap-2" data-tour="program-form-save">
    20882092          <Button
    20892093            type="submit"
  • siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramsListScreen.tsx

    r3775642 r3788740  
    2121import { ActivityDrawer } from '@service/components/ActivityDrawer'
    2222import { useTranslation } from '@service/i18n'
     23import { useTourSample } from '@service/contexts/tour-sample'
    2324import { DeleteConfirmDialog } from '@service/components/DeleteConfirmDialog'
    2425import { programsApi } from '@service/api/programs'
    … …  
    571572  const showColdStart =
    572573    hasLoaded && !isLoading && !error && items.length === 0 && !hasActiveListFilters
     574  // The product tour shows its example programs in the list instead.
     575  const tourRows = useTourSample<unknown[]>('programs')
     576  const showsColdStart = showColdStart && tourRows === null
     577
     578  // An org whose programs are all in the trash also lands on the cold start,
     579  // which hides the status filter. It still needs a way into the trash.
     580  const [hasTrashed, setHasTrashed] = useState(false)
     581  useEffect(() => {
     582    if (!showsColdStart) return
     583
     584    let cancelled = false
     585    programsApi
     586      .list({ status: 'deleted', perPage: 1, fields: ['id'] })
     587      .then((response) => {
     588        if (!cancelled) setHasTrashed(response.items.length > 0)
     589      })
     590      .catch(() => {
     591        if (!cancelled) setHasTrashed(false)
     592      })
     593
     594    return () => {
     595      cancelled = true
     596    }
     597  }, [showsColdStart])
    573598
    574599  return (
    … …  
    582607          <ActivityDrawer sourceType="program" contextLabel="all programs" />
    583608          {ProgramsListLinks && <ProgramsListLinks />}
    584           {supports.customCurrencies && currenciesPath ? (
    585             <Button variant="outline" onClick={() => navigate(currenciesPath)}>
    586               <Coins className="h-4 w-4 mr-2" />
    587               {translate('Manage Currencies')}
    588             </Button>
    589           ) : supports.customCurrencies ? (
     609          {/* A platform with its own Currencies screen lists it in its menu, so the list needs no button. */}
     610          {currenciesPath ? null : supports.customCurrencies ? (
    590611            <Button variant="outline" onClick={() => setShowCurrencies(true)}>
    591612              <Coins className="h-4 w-4 mr-2" />
    … …  
    601622            </Button>
    602623          )}
    603           <Button onClick={() => setShowSplash(true)}>
     624          <Button onClick={() => setShowSplash(true)} data-tour="add-program">
    604625            <Plus className="h-4 w-4" />
    605626            {translate('Add Program')}
    … …  
    616637      />
    617638
    618       {showColdStart ? (
     639      {showsColdStart ? (
    619640        <div className="animate-in fade-in duration-300">
    620641          <div className="mb-1.5 flex items-center gap-3">
    … …  
    634655            onBrowse={() => navigate('/recipes/browse')}
    635656          />
     657          {hasTrashed && (
     658            <p className="mt-6 text-sm text-muted-foreground" data-testid="programs-trash-link">
     659              {translate('Looking for programs you deleted?')}{' '}
     660              <button type="button" className="text-primary hover:underline" onClick={() => handleStatusChange('deleted')}>
     661                {translate('View trashed programs')}
     662              </button>
     663            </p>
     664          )}
    636665        </div>
    637666      ) : (
    … …  
    645674      )}
    646675
    647       <div className="flex gap-2 mb-4 flex-wrap">
     676      <div className="flex gap-2 mb-4 flex-wrap" data-tour="programs-filters">
    648677        <div className="relative flex-1 max-w-sm">
    649678          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
    … …  
    709738        columns={columns}
    710739        data={items}
     740        sampleKey="programs"
    711741        isLoading={isLoading}
    712742        emptyMessage={translate('No programs found.')}
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/CreateProgramChooser.tsx

    r3754739 r3788740  
    2626  const { translate } = useTranslation()
    2727  const { status, recipes, load } = useRecipeCatalogStore()
    28   const { isWordPress } = usePlatform()
     28  const { isWordPress, capabilities } = usePlatform()
     29  const canBrowseRecipes = capabilities.recipeExport === true
    2930
    3031  // Pull the catalog so we can show how many recipes are on offer; cheap + cached.
    3132  useEffect(() => {
    32     if (status === 'idle') void load({ isWordPress })
    33   }, [status, load, isWordPress])
     33    if (canBrowseRecipes && status === 'idle') void load({ isWordPress })
     34  }, [canBrowseRecipes, status, load, isWordPress])
    3435
    3536  const noun = kind === 'distributors' ? translate('distributor') : translate('program')
    … …  
    4445        onClick={onBlank}
    4546      />
    46       <ChooserCard
    47         icon={Library}
    48         title={translate('Browse ready-made recipes')}
    49         description={
    50           recipeCount > 0
    51             ? `${recipeCount} ${translate('proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.')}`
    52             : translate('Proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.')
    53         }
    54         cta={translate('Browse recipes')}
    55         onClick={onBrowse}
    56       />
     47      {canBrowseRecipes && (
     48        <ChooserCard
     49          icon={Library}
     50          title={translate('Browse ready-made recipes')}
     51          description={
     52            recipeCount > 0
     53              ? `${recipeCount} ${translate('proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.')}`
     54              : translate('Proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.')
     55          }
     56          cta={translate('Browse recipes')}
     57          onClick={onBrowse}
     58        />
     59      )}
    5760      <ChooserCard
    5861        icon={Bot}
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/ImportRecipeScreen.tsx

    r3754739 r3788740  
    1515import { useTranslation } from '@service/i18n'
    1616import { UploadView } from './UploadView'
     17import { CsvImport, type LoadedFile } from '../csv-import'
    1718import { SectionCard } from './SectionCard'
    1819
    … …  
    2223 * Entry points:
    2324 *   1. `?recipe=<base64-json>` URL param — Beacon / UseRecipeModal handoff.
    24  *      Auto-previews on mount, bypassing upload. Add `&apply=1` and the
    25  *      screen approves the preview on its own, so a "try it in the demo"
    26  *      link lands straight on the finished import with no click.
     25 *      Auto-previews on mount, bypassing upload. The preview always waits
     26 *      for the admin's click. Only a platform that runs a sandbox with no
     27 *      real organization behind it, such as the demo, passes
     28 *      `allowAutoApply`, and there `&apply=1` approves the preview on its
     29 *      own, so a "try it in the demo" link lands straight on the finished
     30 *      import. A link can never create programs in a live organization by
     31 *      itself.
    2732 *   2. No token — the user uploads a JSON file via UploadView.
     33 *   3. A CSV file dropped on UploadView runs the shared CSV import, which
     34 *      asks what the file holds, maps its columns and builds a recipe that
     35 *      goes through the same preview and apply.
    2836 *
    2937 * On approve, the screen dispatches the apply task and navigates to
    … …  
    3240 * users navigate away without losing the running import.
    3341 */
    34 export function ImportRecipeScreen({ payload: payloadProp }: { payload?: string | null }) {
     42export function ImportRecipeScreen({
     43  payload: payloadProp,
     44  allowAutoApply = false,
     45}: {
     46  payload?: string | null
     47  /** Let `&apply=1` approve without a click. Only for a sandbox with no live organization. */
     48  allowAutoApply?: boolean
     49}) {
    3550  const { translate } = useTranslation()
    3651  const navigate = useNavigate()
    3752  const search = typeof window !== 'undefined' ? new URLSearchParams(window.location.search) : null
    3853  const payload = payloadProp ?? search?.get('recipe') ?? null
    39   const autoApply = payload !== null && search?.get('apply') === '1'
     54  const autoApply = allowAutoApply && payload !== null && search?.get('apply') === '1'
    4055  const autoApplied = useRef(false)
     56  const [csvFile, setCsvFile] = useState<LoadedFile | null>(null)
    4157
    4258  const {
    … …  
    104120      </div>
    105121
    106       {step === 'idle' && !payload && <UploadView onRecipeLoaded={loadFromJson} />}
     122      {step === 'idle' && !payload && csvFile && <CsvImport key={csvFile.name + csvFile.text.length} initialFile={csvFile} onExit={() => setCsvFile(null)} />}
     123
     124      {step === 'idle' && !payload && !csvFile && <UploadView onRecipeLoaded={loadFromJson} onCsvLoaded={setCsvFile} />}
    107125
    108126      {step === 'previewing' && (
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeBrowserScreen.tsx

    r3754739 r3788740  
    3636 * on the left, grouped recipe cards on the right. Clicking a card opens the
    3737 * full-page recipe detail, which owns the apply flow.
     38 *
     39 * Another flow can host the same browser: with `onPick`, a card hands its
     40 * recipe back instead of opening the detail page, and `embedded` leaves out
     41 * the page heading and the link back to Programs. The onboarding wizard uses
     42 * both.
    3843 */
    39 export function RecipeBrowserScreen() {
     44export function RecipeBrowserScreen({
     45  onPick,
     46  embedded = false,
     47}: {
     48  /** Called with the recipe a card was clicked for, instead of opening its detail page. */
     49  onPick?: (recipe: CatalogRecipe) => void
     50  /** Leaves out the page heading and the link back to Programs, for use inside another screen. */
     51  embedded?: boolean
     52} = {}) {
    4053  const { translate } = useTranslation()
    4154  const navigate = useNavigate()
    … …  
    5972  } = store
    6073
    61   const { tier: installTier, isWordPress } = usePlatform()
     74  const { tier: installTier, isWordPress, capabilities } = usePlatform()
     75  const canBrowseRecipes = capabilities.recipeExport === true
    6276
    6377  useEffect(() => {
    64     if (status === 'idle') {
     78    if (canBrowseRecipes && status === 'idle') {
    6579      void load({ isWordPress })
    6680    }
    67   }, [status, load, isWordPress])
     81  }, [canBrowseRecipes, status, load, isWordPress])
    6882
    6983  // The store defaults to the top tier (SaaS includes everything); once the
    … …  
    116130  }
    117131
     132  if (!canBrowseRecipes) {
     133    return (
     134      <Card className="mx-auto max-w-md">
     135        <CardHeader>
     136          <CardTitle>{translate('Recipe access required')}</CardTitle>
     137        </CardHeader>
     138        <CardContent>
     139          <p className="text-sm text-muted-foreground">
     140            {translate('Ask an administrator or platform manager for access to browse recipes.')}
     141          </p>
     142        </CardContent>
     143      </Card>
     144    )
     145  }
     146
    118147  if (status === 'loading' || status === 'idle') {
    119148    return (
    … …  
    140169  }
    141170
     171  if (embedded && recipes.length === 0) {
     172    return (
     173      <Card className="mx-auto max-w-md">
     174        <CardHeader>
     175          <CardTitle>{translate('No recipes to show yet')}</CardTitle>
     176        </CardHeader>
     177        <CardContent className="space-y-4">
     178          <p className="text-sm text-muted-foreground">
     179            {translate('The recipe list came back empty. Anything you chose is kept.')}
     180          </p>
     181          <Button onClick={() => void load({ isWordPress })}>{translate('Try again')}</Button>
     182        </CardContent>
     183      </Card>
     184    )
     185  }
     186
    142187  return (
    143188    <div className="space-y-6">
    144       <div className="space-y-2">
    145         <Link
    146           to="/programs"
    147           className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
    148         >
    149           <ArrowLeft className="h-4 w-4" aria-hidden="true" />
    150           {translate('Back to Programs')}
    151         </Link>
    152         <h1 className="text-2xl font-semibold">{translate('Browse recipes')}</h1>
    153         <p className="text-sm text-muted-foreground">
    154           {translate('Pick a starting point and launch a fully-configured program in a few clicks.')}
    155         </p>
    156       </div>
     189      {!embedded && (
     190        <div className="space-y-2">
     191          <Link
     192            to="/programs"
     193            className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
     194          >
     195            <ArrowLeft className="h-4 w-4" aria-hidden="true" />
     196            {translate('Back to Programs')}
     197          </Link>
     198          <h1 className="text-2xl font-semibold">{translate('Browse recipes')}</h1>
     199          <p className="text-sm text-muted-foreground">
     200            {translate('Pick a starting point and launch a fully-configured program in a few clicks.')}
     201          </p>
     202        </div>
     203      )}
    157204
    158205      <div className="relative max-w-md">
    … …  
    224271        {/* RIGHT main */}
    225272        <div className="min-w-0 flex-1">
    226           {view.isNoResults ? (
     273          {view.isEmptyCatalog ? (
     274            <Card className="flex flex-col items-center gap-3 p-12 text-center">
     275              <p className="text-sm font-medium">{translate('No recipes are available')}</p>
     276              <p className="text-sm text-muted-foreground">
     277                {translate('Check again later for new recipes.')}
     278              </p>
     279            </Card>
     280          ) : view.isNoResults ? (
    227281            <Card className="flex flex-col items-center gap-3 p-12 text-center">
    228282              <p className="text-sm font-medium">{translate('No recipes match your filters')}</p>
    … …  
    247301                        key={recipe.id}
    248302                        recipe={recipe}
    249                         onClick={() => navigate(`/recipes/browse/${recipe.slug}`)}
     303                        onClick={() => (onPick ? onPick(recipe) : navigate(`/recipes/browse/${recipe.slug}`))}
    250304                      />
    251305                    ))}
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeConstructs.tsx

    r3775642 r3788740  
    44import { cn } from '@service/components/lib/utils'
    55import { useTranslation } from '@service/i18n'
    6 import { ProgramFlowDiagram } from '@service/components/help/ProgramFlowDiagram'
     6import { getCommissionText, ProgramFlowDiagram } from '@service/components/help/ProgramFlowDiagram'
    77import { ProgramGroupFlowDiagram } from '@service/components/help/ProgramGroupFlowDiagram'
    88import { parseRecipeConstructs, type RecipeConstruct } from './catalog-taxonomy'
    … …  
    1717
    1818/**
     19 * Writes a program's payout amounts. A currency the recipe brings with it is
     20 * not in the org's registry until the recipe is applied. Recipes create those
     21 * as whole-unit currencies, so the stored number is the number to show, beside
     22 * the recipe's own symbol.
     23 */
     24function useConstructAmount(construct: RecipeConstruct): (stored: number) => string {
     25  const { formatMoney, definitions } = useMoneyFormatter()
     26  const units = construct.kind === 'Program' ? construct.program.units : undefined
     27  const unitsLabel = construct.kind === 'Program' ? construct.program.unitsLabel : undefined
     28  const leads = construct.kind === 'Program' && construct.program.unitsLabelLeads
     29  const recipeOwned = Boolean(units && unitsLabel && !findCurrencyDefinition(units, definitions))
     30
     31  return (stored) => {
     32    if (!recipeOwned) return formatMoney(stored, units)
     33
     34    const amount = stored.toLocaleString('en-US')
     35    return leads ? `${unitsLabel}${amount}` : `${amount} ${unitsLabel}`
     36  }
     37}
     38
     39/**
    1940 * The expanded body of a construct drawer: the same Siren flow diagram the
    2041 * program / group view screens render for programs and groups, or a spec
    … …  
    2445function ConstructDetail({ construct }: { construct: RecipeConstruct }) {
    2546  const { translate } = useTranslation()
    26   const { formatMoney, definitions } = useMoneyFormatter()
     47  const formatAmount = useConstructAmount(construct)
    2748
    2849  if (construct.kind === 'Program') {
    29     const { units, unitsLabel } = construct.program
    30     // A currency the recipe brings with it is not in the org's registry until
    31     // the recipe is applied. Recipes create those as whole-unit currencies, so
    32     // the stored number is the number to show, beside the recipe's own symbol.
    33     const recipeOwned = Boolean(units && unitsLabel && !findCurrencyDefinition(units, definitions))
    34     const formatAmount = (stored: number) =>
    35       recipeOwned ? `${stored.toLocaleString('en-US')} ${unitsLabel}` : formatMoney(stored, units)
    36 
    3750    return (
    3851      <ProgramFlowDiagram
    … …  
    7790 * description, and the construct's flow diagram or spec summary.
    7891 */
    79 function ConstructDrawer({ construct }: { construct: RecipeConstruct }) {
     92function ConstructDrawer({ construct, badge, savedSettings = false }: { construct: RecipeConstruct; badge?: string; savedSettings?: boolean }) {
    8093  const { translate } = useTranslation()
    8194  const [open, setOpen] = useState(false)
     95  const formatAmount = useConstructAmount(construct)
    8296  const Icon = KIND_ICON[construct.kind]
    83   const summary = construct.roleNote || construct.description || ''
     97  // Saved settings may differ from the recipe's own words, so the summary
     98  // reads the saved reward, which stays in view while the drawer is closed.
     99  const savedReward =
     100    construct.kind === 'Program' && construct.program.incentiveType
     101      ? getCommissionText(construct.program.incentiveType, construct.program.commissionConfig, formatAmount, construct.program.conversionTypes)
     102      : ''
     103  const summary = savedSettings ? savedReward : construct.roleNote || construct.description || ''
    84104
    85105  return (
    … …  
    100120              {translate(construct.kind)}
    101121            </span>
     122            {badge && (
     123              <span className="rounded-full border border-primary/30 bg-primary/10 px-2 py-0.5 text-[0.65rem] font-medium text-primary">
     124                {translate(badge)}
     125              </span>
     126            )}
    102127          </span>
    103128          {summary && !open && (
    … …  
    122147          )}
    123148
    124           {construct.description && (
     149          {!savedSettings && construct.description && (
    125150            <p className="text-sm leading-relaxed text-muted-foreground">{translate(construct.description)}</p>
    126151          )}
    … …  
    137162 * drawer per program, group, and distributor the recipe creates. When `values`
    138163 * (the apply-panel edits) are passed, the previews update live to match.
     164 * `badges` adds a short label beside a construct's kind, keyed by its name,
     165 * such as the plan it needs.
    139166 */
    140167export function RecipeConstructs({
    141168  recipe,
    142169  values,
     170  badges,
     171  savedSettings = false,
    143172}: {
    144173  recipe: CatalogRecipe
    145174  values?: Record<string, string | number>
     175  badges?: Record<string, string>
     176  savedSettings?: boolean
    146177}) {
    147178  const constructs = parseRecipeConstructs(recipe, values)
    … …  
    151182    <div className="space-y-2.5">
    152183      {constructs.map((construct) => (
    153         <ConstructDrawer key={`${construct.kind}-${construct.name}`} construct={construct} />
     184        <ConstructDrawer
     185          key={`${construct.kind}-${construct.name}`}
     186          construct={construct}
     187          badge={badges?.[construct.name]}
     188          savedSettings={savedSettings}
     189        />
    154190      ))}
    155191    </div>
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeDetailScreen.tsx

    r3775642 r3788740  
    353353function useRecipeBySlug(slug: string | null | undefined) {
    354354  const { status, recipes, load, error } = useRecipeCatalogStore()
    355   const { isWordPress } = usePlatform()
     355  const { isWordPress, capabilities } = usePlatform()
     356  const canBrowseRecipes = capabilities.recipeExport === true
    356357  const retry = () => void load({ isWordPress })
    357358
    358359  useEffect(() => {
    359     if (slug && status === 'idle') {
     360    if (canBrowseRecipes && slug && status === 'idle') {
    360361      void load({ isWordPress })
    361362    }
    362   }, [slug, status, load, isWordPress])
     363  }, [canBrowseRecipes, slug, status, load, isWordPress])
    363364
    364365  const recipe = useMemo(
    … …  
    367368  )
    368369
    369   return { recipe, status, error, retry }
     370  return { recipe, status, error, retry, canBrowseRecipes }
    370371}
    371372
    … …  
    666667  const { translate } = useTranslation()
    667668  const { slug } = useParams<{ slug: string }>()
    668   const { recipe, status, error, retry } = useRecipeBySlug(slug)
     669  const { recipe, status, error, retry, canBrowseRecipes } = useRecipeBySlug(slug)
     670
     671  if (!canBrowseRecipes) {
     672    return (
     673      <Card className="mx-auto max-w-md">
     674        <CardHeader>
     675          <CardTitle>{translate('Recipe access required')}</CardTitle>
     676        </CardHeader>
     677        <CardContent>
     678          <p className="text-sm text-muted-foreground">
     679            {translate('Ask an administrator or platform manager for access to browse recipes.')}
     680          </p>
     681        </CardContent>
     682      </Card>
     683    )
     684  }
    669685
    670686  if (status === 'loading' || status === 'idle') {
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/UploadView.tsx

    r3590633 r3788740  
    1111} from '@service/components/ui'
    1212import { useTranslation } from '@service/i18n'
     13import { csvProblemMessage, parseCsv, type LoadedFile } from '../csv-import'
    1314
    1415function readFileAsText(file: File): Promise<string> {
    … …  
    2627 * forwards the decoded recipe to the store.
    2728 *
    28  * CSV support is planned as the first migration integration — the component is
    29  * shaped to grow a CSV branch once the column mapping is defined.
     29 * A CSV file goes to the shared CSV import instead: a file named .csv, or
     30 * one that isn't JSON but reads as CSV.
    3031 */
    3132export function UploadView({
    3233  onRecipeLoaded,
     34  onCsvLoaded,
    3335}: {
    3436  onRecipeLoaded: (recipe: RecipeData) => void
     37  /** A CSV file, read and parsed. Without it the view takes JSON only. */
     38  onCsvLoaded?: (file: LoadedFile) => void
    3539}) {
    3640  const { translate } = useTranslation()
    … …  
    5054    }
    5155
     56    const named = file.name.toLowerCase()
     57    const csvByName = /\.(csv|tsv|txt)$/.test(named)
     58    if (onCsvLoaded && csvByName) {
     59      loadCsv(file.name, text)
     60      return
     61    }
     62
    5263    let recipe: RecipeData
    5364    try {
    5465      recipe = JSON.parse(text) as RecipeData
    5566    } catch (err) {
     67      // Text that isn't JSON but reads as CSV goes to the CSV import.
     68      const asCsv = onCsvLoaded && !named.endsWith('.json') ? parseCsv(text) : null
     69      if (asCsv?.ok) {
     70        onCsvLoaded?.({ name: file.name, text, csv: asCsv.csv })
     71        return
     72      }
    5673      const detail = err instanceof Error ? err.message : translate('Unknown parse error.')
    5774      setParseError(translate(`That file is not valid JSON: ${detail}`))
    … …  
    6077
    6178    onRecipeLoaded(recipe)
     79  }
     80
     81  const loadCsv = (name: string, text: string) => {
     82    const parsed = parseCsv(text)
     83    if (!parsed.ok) {
     84      setParseError(translate(csvProblemMessage(parsed.problem, parsed.rowCount)))
     85      return
     86    }
     87    onCsvLoaded?.({ name, text, csv: parsed.csv })
    6288  }
    6389
    … …  
    119145          <div className="space-y-1">
    120146            <p className="text-sm font-medium">
    121               {translate('Drop a recipe JSON file here, or click to browse')}
    122             </p>
    123             <p className="text-xs text-muted-foreground">
    124               {translate('CSV import coming soon.')}
     147              {onCsvLoaded ? translate('Drop a recipe JSON or a CSV file here, or click to browse') : translate('Drop a recipe JSON file here, or click to browse')}
    125148            </p>
    126149          </div>
    … …  
    128151            ref={inputRef}
    129152            type="file"
    130             accept=".json,application/json"
     153            accept={onCsvLoaded ? '.json,application/json,.csv,text/csv,.tsv,.txt' : '.json,application/json'}
    131154            className="hidden"
    132155            onChange={handleChange}
    … …  
    155178          </Button>
    156179        </div>
     180
     181        {onCsvLoaded && (
     182          <p className="text-sm text-muted-foreground">
     183            {translate('A CSV file from a spreadsheet or another platform works too. Siren asks what it holds and helps you match its columns.')}
     184          </p>
     185        )}
    157186      </CardContent>
    158187    </Card>
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/UseRecipeModal.tsx

    r3775642 r3788740  
    455455}
    456456
    457 function FieldInput({
     457export function FieldInput({
    458458  field,
    459459  value,
  • siren-affiliates/trunk/frontend-source/src/service/screens/recipes/catalog-taxonomy.ts

    r3775642 r3788740  
    2323import { incentiveConfigAsNumbers } from '@core/utils/money'
    2424import { applyEnhancementPatch, type EnhancementKey } from '@service/recipes/enhancements'
     25import { rewriteDescribedValues } from '@service/recipes/describedValues'
    2526
    2627/**
    … …  
    313314
    314315  return entry[1]?.symbol?.trim() || units
     316}
     317
     318/** Whether the recipe writes its own currency's symbol before the amount. */
     319function recipeCurrencyLeads(units: string | undefined, currencies: Record<string, PayloadCurrency>): boolean {
     320  if (!units) return false
     321
     322  return Object.entries(currencies).some(([key, currency]) => (currency?.code ?? key) === units && currency?.symbolPosition === 'before')
    315323}
    316324
    … …  
    331339   */
    332340  unitsLabel?: string
     341  /** Whether `unitsLabel` goes before the amount, as a currency symbol such as $ does. */
     342  unitsLabelLeads?: boolean
    333343}
    334344
    … …  
    374384  units?: string
    375385}
    376 interface PayloadCurrency { code?: string; name?: string; symbol?: string }
     386interface PayloadCurrency { code?: string; name?: string; symbol?: string; symbolPosition?: string }
    377387interface PayloadGroup { name?: string; description?: string; sorter?: string; programs?: string[] }
    378388interface PayloadDistributor {
    … …  
    455465        units: p.units,
    456466        unitsLabel: recipeCurrencyLabel(p.units, recipeCurrencies),
     467        unitsLabelLeads: recipeCurrencyLeads(p.units, recipeCurrencies),
    457468      },
    458469    })
    … …  
    532543  }
    533544  cursor[keys[keys.length - 1]] = value
     545}
     546
     547/** Read the value at a dot path inside a plain object, or undefined. */
     548function getAtPath(source: Record<string, unknown>, path: string): unknown {
     549  let cursor: unknown = source
     550  for (const key of path.split('.')) {
     551    if (typeof cursor !== 'object' || cursor === null) return undefined
     552    cursor = (cursor as Record<string, unknown>)[key]
     553  }
     554  return cursor
     555}
     556
     557/** Hundredths per whole unit, the way Siren stores a fixed money amount. */
     558const MINOR_UNITS = 100
     559
     560/**
     561 * The field with the multiplier its catalog entry left out, if any.
     562 *
     563 * Siren stores a fixed money amount in hundredths, and a recipe payload holds
     564 * it that way: a $25 bounty is 2500. Some catalog fields offer that amount in
     565 * whole units (default 25, suffix "USD") without saying to multiply by 100,
     566 * so the typed 25 would be applied as 25 hundredths and pay $0.25. When a
     567 * number field is labelled with a currency code and the payload holds exactly
     568 * its default times 100, the field means whole units, and it gets that
     569 * multiplier. A field that already declares a multiplier keeps its own, so an
     570 * amount is never scaled twice.
     571 */
     572export function withStoredMultiplier<T extends CatalogCustomizableField | EnhancementField>(
     573  field: T,
     574  payload: Record<string, unknown>,
     575): T {
     576  if (field.multiplier !== undefined || field.type !== 'number') return field
     577  if (!/^[A-Z]{3}$/.test((field.suffix ?? '').trim())) return field
     578  const fallback = Number(field.default)
     579  if (!Number.isFinite(fallback) || fallback === 0) return field
     580  return getAtPath(payload, field.path) === fallback * MINOR_UNITS ? { ...field, multiplier: MINOR_UNITS } : field
    534581}
    535582
    … …  
    584631      continue
    585632    }
    586     setAtPath(payload, field.path, resolveFieldValue(field, raw))
    587   }
     633    setAtPath(payload, field.path, resolveFieldValue(withStoredMultiplier(field, payload), raw))
     634  }
     635
     636  // The descriptions collaborators read promise the values that apply.
     637  rewriteDescribedValues(payload, recipe.customizableFields ?? [], values)
    588638
    589639  return payload as unknown as RecipeData
    … …  
    617667    const raw = baseValues[field.path]
    618668    if (raw === undefined || raw === '') continue
    619     setAtPath(payload, field.path, resolveFieldValue(field, raw))
     669    setAtPath(payload, field.path, resolveFieldValue(withStoredMultiplier(field, payload), raw))
    620670  }
    621671
    … …  
    625675      const raw = addonValues[field.path]
    626676      if (raw === undefined || raw === '') continue
    627       setAtPath(payload, field.path, resolveFieldValue(field, raw))
     677      setAtPath(payload, field.path, resolveFieldValue(withStoredMultiplier(field, payload), raw))
    628678    }
    629679  }
    630680
     681  // The descriptions collaborators read promise the values that apply.
     682  rewriteDescribedValues(payload, recipe.customizableFields ?? [], baseValues)
     683  for (const addon of addons) rewriteDescribedValues(payload, addon.fields, addonValues)
     684
    631685  return payload as unknown as RecipeData
    632686}
  • siren-affiliates/trunk/frontend-source/src/service/screens/transactions/TransactionDetailScreen.tsx

    r3775642 r3788740  
    1 import { useEffect, useMemo } from 'react'
     1import { useEffect, useMemo, useState } from 'react'
    22import { useNavigate, useParams } from 'react-router-dom'
    33import { Link } from '@service/components/Link'
    … …  
    2424} from '@service/components/ui'
    2525import { ActivityDrawer } from '@service/components/ActivityDrawer'
     26import { propertiesApi, type Property } from '@service/api/properties'
     27import { isOrderSource, orderAdminUrl } from './order-link'
    2628
    2729const conversionStatusColors: Record<string, string> = {
    … …  
    4850  const navigate = useNavigate()
    4951  const { isWordPress } = usePlatform()
     52  const [properties, setProperties] = useState<Property[]>([])
    5053
    5154  const {
    … …  
    7174      const transactionId = parseInt(id)
    7275      fetchOne(transactionId)
    73       fetchConversions({ transactionId, perPage: 20 })
     76      fetchConversions({ transactionId, perPage: 20, orderBy: 'dateCreated', order: 'desc' })
    7477    }
    7578
    … …  
    7881    }
    7982  }, [id, fetchOne, clearCurrent, fetchConversions])
     83
     84  useEffect(() => {
     85    if (current?.sourcePropertyId) {
     86      void propertiesApi.list().then(setProperties).catch(() => setProperties([]))
     87    }
     88  }, [current?.sourcePropertyId])
    8089
    8190  const formatDate = (dateString: string) => {
    … …  
    163172    return Array.from(totals.entries())
    164173  }
    165   const subtotals = current.subtotal === undefined ? detailTotals(['line_item', 'product']) : [[current.currency || '', current.subtotal] as [string, number]]
     174  const subtotals = current.subtotal == null ? detailTotals(['line_item', 'product', 'subscription']) : [[current.currency || '', current.subtotal] as [string, number]]
    166175  const taxes = current.taxTotal === undefined ? detailTotals(['tax']) : [[current.currency || '', current.taxTotal] as [string, number]]
    167176  const shipping = current.shippingTotal === undefined ? detailTotals(['shipping']) : [[current.currency || '', current.shippingTotal] as [string, number]]
    168177  const discounts = current.discountTotal === undefined ? detailTotals(['discount'], true) : [[current.currency || '', current.discountTotal] as [string, number]]
     178  const adminUrl = orderAdminUrl(current, properties)
     179  const fees = current.feeTotal === undefined ? detailTotals(['fee']) : [[current.currency || '', current.feeTotal] as [string, number]]
    169180  // Refund lines carry negative values, so the refunded amount is their
    170181  // total turned positive.
    … …  
    220231                </div>
    221232              )}
    222               {current.sourceId && (
     233              {current.sourceId && (isOrderSource(current.source) ? (
     234                <div>
     235                  <dt className="text-sm font-medium text-muted-foreground">{translate('Order')}</dt>
     236                  <dd className="text-sm mt-1 font-mono">
     237                    {adminUrl
     238                      ? <a href={adminUrl} className="text-primary hover:underline">#{current.sourceId}</a>
     239                      : <>#{current.sourceId}</>}
     240                  </dd>
     241                </div>
     242              ) : (
    223243                <div>
    224244                  <dt className="text-sm font-medium text-muted-foreground">{translate('Source ID')}</dt>
    225245                  <dd className="text-sm mt-1 font-mono">{current.sourceId}</dd>
    226246                </div>
    227               )}
     247              ))}
    228248            </dl>
    229249          </CardContent>
    … …  
    280300                    </div>
    281301                  ))}
     302                  {fees.map(([currency, feeTotal]) => feeTotal > 0 && (
     303                    <div key={'fees-' + currency} className="flex justify-between text-sm">
     304                      <span className="text-muted-foreground">{translate('Fee')}</span>
     305                      <span>{formatAmount(feeTotal, currency)}</span>
     306                    </div>
     307                  ))}
    282308                  {taxes.map(([currency, taxTotal]) => taxTotal > 0 && (
    283309                    <div key={'taxes-' + currency} className="flex justify-between text-sm">
  • siren-affiliates/trunk/frontend-source/src/service/screens/transactions/TransactionsListScreen.tsx

    r3775642 r3788740  
    3333import { useTranslation } from '@service/i18n'
    3434import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter'
     35import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName'
     36import { propertiesApi, type Property } from '@service/api/properties'
     37import { isOrderSource, orderAdminUrl } from './order-link'
    3538
    3639type SortField = 'dateCreated' | 'status'
    3740type SortOrder = 'asc' | 'desc'
     41
     42/**
     43 * Siren records every sale a store reports, so most sales are credited to
     44 * nobody. The Credited filter shows only the sales a conversion credits to a
     45 * collaborator, or only the ones it doesn't.
     46 */
     47type CreditedFilter = 'all' | 'credited' | 'uncredited'
     48
     49const CREDITED_PARAM: Record<Exclude<CreditedFilter, 'all'>, string> = { credited: '1', uncredited: '0' }
     50
     51function creditedFromParam(value: string | null): CreditedFilter {
     52  if (value === '1') return 'credited'
     53  if (value === '0') return 'uncredited'
     54  return 'all'
     55}
     56
     57function creditedParam(filter: CreditedFilter): boolean | undefined {
     58  return filter === 'all' ? undefined : filter === 'credited'
     59}
    3860
    3961export function TransactionsListScreen() {
    … …  
    7496
    7597  const [statusFilter, setStatusFilter] = useState<string>(initialStatus)
     98  const [creditedFilter, setCreditedFilter] = useState<CreditedFilter>(creditedFromParam(searchParams.get('credited')))
    7699  const [localPerPage, setLocalPerPage] = useState(10)
    77100  const [sortField, setSortField] = useState<SortField>('dateCreated')
    … …  
    80103  const [showCreditDialog, setShowCreditDialog] = useState(false)
    81104  const [selectedCollaboratorId, setSelectedCollaboratorId] = useState<string>('')
     105  const [properties, setProperties] = useState<Property[]>([])
     106
     107  useEffect(() => {
     108    if (items.some((transaction) => transaction.sourcePropertyId)) {
     109      void propertiesApi.list().then(setProperties).catch(() => setProperties([]))
     110    }
     111  }, [items])
    82112
    83113  useEffect(() => {
    … …  
    92122  }, [searchParams, statusFilter])
    93123
     124  useEffect(() => {
     125    const credited = creditedFromParam(searchParams.get('credited'))
     126    if (credited !== creditedFilter) {
     127      setCreditedFilter(credited)
     128    }
     129  }, [searchParams, creditedFilter])
     130
    94131  // Clear selection when filters change
    95132  useEffect(() => {
    96133    setSelectedIds(new Set())
    97   }, [statusFilter])
     134  }, [statusFilter, creditedFilter])
    98135
    99136  // Fetch collaborators when credit dialog opens
    … …  
    111148      order: sortOrder,
    112149      status: statusFilter !== 'all' ? statusFilter : undefined,
     150      credited: creditedParam(creditedFilter),
    113151    })
    114   }, [fetchList, localPerPage, sortField, sortOrder, statusFilter])
     152  }, [fetchList, localPerPage, sortField, sortOrder, statusFilter, creditedFilter])
    115153
    116154  const buildParams = (overrides: Partial<{
    … …  
    124162    perPage: overrides.perPage ?? localPerPage,
    125163    status: (overrides.status ?? statusFilter) !== 'all' ? (overrides.status ?? statusFilter) : undefined,
     164    credited: creditedParam(creditedFilter),
    126165    orderBy: overrides.orderBy ?? sortField,
    127166    order: overrides.order ?? sortOrder,
    … …  
    134173    } else {
    135174      searchParams.delete('status')
     175    }
     176    setSearchParams(searchParams)
     177  }
     178
     179  const handleCreditedChange = (value: string) => {
     180    const filter = value as CreditedFilter
     181    setCreditedFilter(filter)
     182    if (filter !== 'all') {
     183      searchParams.set('credited', CREDITED_PARAM[filter])
     184    } else {
     185      searchParams.delete('credited')
    136186    }
    137187    setSearchParams(searchParams)
    … …  
    199249      id: 'source',
    200250      header: translate('Source'),
    201       cell: (transaction) =>
    202         transaction.source ? (
    203           <span className="text-sm">{sourceLabels[transaction.source] || transaction.source}</span>
     251      cell: (transaction) => {
     252        const adminUrl = orderAdminUrl(transaction, properties)
     253        return transaction.source ? (
     254          <span className="text-sm">
     255            {sourceLabels[transaction.source] || transaction.source}
     256            {transaction.sourceId && (
     257              <span className="block font-mono">
     258                {!isOrderSource(transaction.source)
     259                  ? transaction.sourceId
     260                  : adminUrl
     261                    ? <a href={adminUrl} className="text-primary hover:underline">#{transaction.sourceId}</a>
     262                    : <>#{transaction.sourceId}</>}
     263              </span>
     264            )}
     265          </span>
    204266        ) : (
    205267          <span className="text-muted-foreground">—</span>
    206         ),
     268        )
     269      },
    207270    },
    208271    {
    … …  
    210273      header: translate('Details'),
    211274      cell: (transaction) => {
    212         // Refund lines say what was given back, not what was bought.
    213         const details = (transaction.details ?? []).filter((detail) => detail.type !== 'refund')
     275        // What was bought. Totals lines and refunds are left out, and any
     276        // other line, such as a credit, still shows.
     277        const details = (transaction.details ?? []).filter((detail) => !['tax', 'discount', 'shipping', 'fee', 'refund'].includes(detail.type))
    214278        if (details.length === 0) {
    215279          return <span className="text-muted-foreground">—</span>
    … …  
    268332  ]
    269333
     334  const creditedLabels: Record<CreditedFilter, string> = {
     335    all: translate('All Sales'),
     336    credited: translate('Credited'),
     337    uncredited: translate('Not Credited'),
     338  }
     339
    270340  const filterItems = [
    271341    {
    … …  
    276346      onRemove: () => handleStatusChange('all'),
    277347    },
     348    {
     349      key: 'credited',
     350      label: 'Credited',
     351      value: creditedFilter,
     352      displayValue: creditedLabels[creditedFilter],
     353      onRemove: () => handleCreditedChange('all'),
     354    },
    278355  ]
    279356
    280357  const handleClearAllFilters = () => {
    281358    handleStatusChange('all')
     359    handleCreditedChange('all')
    282360  }
    283361
    … …  
    327405          </SelectContent>
    328406        </Select>
     407        <Select value={creditedFilter} onValueChange={handleCreditedChange}>
     408          <SelectTrigger aria-label={translate('Filter by credit')} className="w-[160px]">
     409            <SelectValue placeholder={translate('Credited')} />
     410          </SelectTrigger>
     411          <SelectContent>
     412            <SelectItem value="all">{creditedLabels.all}</SelectItem>
     413            <SelectItem value="credited">{creditedLabels.credited}</SelectItem>
     414            <SelectItem value="uncredited">{creditedLabels.uncredited}</SelectItem>
     415          </SelectContent>
     416        </Select>
    329417      </div>
    330418
    … …  
    339427        columns={columns}
    340428        data={items}
     429        sampleKey="transactions"
    341430        isLoading={isLoading}
    342431        emptyMessage={translate('No transactions found.')}
    … …  
    399488            <DialogTitle>{translate('Credit Collaborator')}</DialogTitle>
    400489            <DialogDescription>
    401               Select a collaborator to credit with the selected transactions.
     490              Select a collaborator to credit with the selected transactions. Each sale credited
     491              this way creates an engagement for the collaborator, which counts toward your usage.
    402492            </DialogDescription>
    403493          </DialogHeader>
    … …  
    412502                  {collaborators.map((collaborator) => (
    413503                    <SelectItem key={collaborator.id} value={collaborator.id.toString()}>
    414                       {collaborator.fullName || collaborator.email || `Collaborator #${collaborator.id}`}
     504                      {collaboratorDisplayName(collaborator)}
    415505                    </SelectItem>
    416506                  ))}
  • siren-affiliates/trunk/frontend-source/src/service/stores/collaborators.ts

    r3754739 r3788740  
    4444  bulkRestore: (ids: number[]) => Promise<void>
    4545  bulkSendSignupEmail: (ids: number[]) => Promise<void>
     46  resendInvitation: (id: number) => Promise<void>
     47  cancelInvitation: (id: number) => Promise<void>
    4648  clearCurrent: () => void
    4749  clearError: () => void
    … …  
    350352    }
    351353  },
     354
     355  resendInvitation: async (id) => {
     356    set({ isSubmitting: true, error: null })
     357    try {
     358      await collaboratorsApi.resendInvitation(id)
     359      set({ isSubmitting: false })
     360      toast.success('Invitation sent again')
     361      get().fetchList(get().lastListParams || { page: get().page, perPage: get().perPage })
     362    } catch (err) {
     363      const message = err instanceof Error && err.message ? err.message : 'The invitation could not be sent again.'
     364      set({ error: message, isSubmitting: false })
     365      toast.error(message)
     366    }
     367  },
     368
     369  cancelInvitation: async (id) => {
     370    set({ isSubmitting: true, error: null })
     371    try {
     372      await collaboratorsApi.cancelInvitation(id)
     373      set({ isSubmitting: false })
     374      toast.success('Invitation cancelled')
     375      get().fetchList(get().lastListParams || { page: get().page, perPage: get().perPage })
     376    } catch (err) {
     377      const message = err instanceof Error && err.message ? err.message : 'The invitation could not be cancelled.'
     378      set({ error: message, isSubmitting: false })
     379      toast.error(message)
     380    }
     381  },
    352382}))
    353383
  • siren-affiliates/trunk/frontend-source/src/service/stores/fulfillments.ts

    r3775642 r3788740  
    2727  fetchList: (params?: ListFulfillmentsParams) => Promise<void>
    2828  fetchOne: (id: number) => Promise<void>
     29  /**
     30   * Read the list again with its last params, and show the answer in place.
     31   * No spinner and no error page: a failed read leaves the rows as they are.
     32   */
     33  refreshList: () => Promise<void>
     34  /** The same for the open fulfillment. */
     35  refreshCurrent: (id: number) => Promise<void>
    2936  update: (id: number, input: Partial<Fulfillment>) => Promise<Fulfillment>
    3037  bulkProcess: (ids: number[]) => Promise<void>
    … …  
    5057const listRequests = createRequestSequence()
    5158
     59/** The same for the open fulfillment, so a slow refresh cannot undo a newer load. */
     60const detailRequests = createRequestSequence()
     61
    5262export const useFulfillmentsStore = create<FulfillmentsState>((set, get) => ({
    5363  // Initial state
    … …  
    8898
    8999  fetchOne: async (id) => {
     100    const request = detailRequests.begin()
    90101    set({ isLoading: true, error: null, current: null })
    91102    try {
    92103      const fulfillment = await fulfillmentsApi.get(id)
     104      if (!detailRequests.isCurrent(request)) return
    93105      set({ current: fulfillment, isLoading: false })
    94106    } catch (err) {
     107      if (!detailRequests.isCurrent(request)) return
    95108      set({
    96109        error: err instanceof Error ? err.message : 'Failed to fetch fulfillment',
    97110        isLoading: false,
    98111      })
     112    }
     113  },
     114
     115  refreshList: async () => {
     116    // A load in flight owns the list, and only its answer clears isLoading.
     117    if (get().isLoading) return
     118    const request = listRequests.begin()
     119    try {
     120      const response = await fulfillmentsApi.list(get().lastListParams || { page: get().page, perPage: get().perPage })
     121      if (!listRequests.isCurrent(request)) return
     122      set({
     123        items: response.items,
     124        total: response.total,
     125        page: response.page,
     126        perPage: response.perPage,
     127        totalPages: response.totalPages,
     128      })
     129    } catch {
     130      // The next refresh tries again.
     131    }
     132  },
     133
     134  refreshCurrent: async (id) => {
     135    // Nothing open means a load is in flight or the screen has closed.
     136    if (get().current?.id !== id) return
     137    const request = detailRequests.begin()
     138    try {
     139      const fulfillment = await fulfillmentsApi.get(id)
     140      if (!detailRequests.isCurrent(request) || get().current?.id !== id) return
     141      set({ current: fulfillment })
     142    } catch {
     143      // The next refresh tries again.
    99144    }
    100145  },
  • siren-affiliates/trunk/frontend-source/src/service/stores/inbound.ts

    r3775642 r3788740  
    3333  status: InboundConnectionStatus,
    3434): Partial<StatusMaps> {
     35  const map = mode === 'test' ? state.testConnections : state.connections
     36  const previous = map[sourceSlug]
     37  // Only a read carries what reached the connection and the store's address.
     38  // Starting setup or saving a key keeps the last ones read, until a
     39  // disconnect clears them.
     40  const merged: InboundConnectionStatus =
     41    previous && status.started !== false
     42      ? { deliveries: previous.deliveries, store: previous.store, ...status }
     43      : status
     44
    3545  return mode === 'test'
    36     ? { testConnections: { ...state.testConnections, [sourceSlug]: status } }
    37     : { connections: { ...state.connections, [sourceSlug]: status } }
     46    ? { testConnections: { ...state.testConnections, [sourceSlug]: merged } }
     47    : { connections: { ...state.connections, [sourceSlug]: merged } }
    3848}
    3949
  • siren-affiliates/trunk/frontend-source/src/service/stores/recipeCatalog.ts

    r3775642 r3788740  
    173173  resultCount: number
    174174  total: number
     175  isEmptyCatalog: boolean
    175176  isNoResults: boolean
    176177  /** Curated "Popular starting points" for the cold-start empty state. */
    … …  
    451452    resultCount: filtered.length,
    452453    total: recipes.length,
     454    isEmptyCatalog: recipes.length === 0,
    453455    isNoResults: recipes.length > 0 && filtered.length === 0,
    454456    popularFeatured,
  • siren-affiliates/trunk/frontend-source/src/vite-env.d.ts

    r3775642 r3788740  
    5959  readonly env: ImportMetaEnv
    6060}
     61
     62/**
     63 * True only in the sandbox bundle (`npm run build:sandbox`), false in every
     64 * other. Replaced at build time, so code behind `if (__SIREN_SANDBOX__)` is
     65 * left out of every other bundle entirely.
     66 */
     67declare const __SIREN_SANDBOX__: boolean
  • siren-affiliates/trunk/frontend-source/tsconfig.json

    r3590633 r3788740  
    99    /* Bundler mode */
    1010    "moduleResolution": "bundler",
     11    "resolveJsonModule": true,
    1112    "allowImportingTsExtensions": true,
    1213    "isolatedModules": true,
  • siren-affiliates/trunk/frontend-source/vite.config.ts

    r3775642 r3788740  
    299299export default defineConfig(({ mode, command }) => {
    300300  const isWordPress = mode === 'wordpress' || mode.startsWith('wordpress-')
    301   const isSaaS = mode === 'saas'
     301  // The sandbox edition is the SaaS bundle plus the sandbox screens. Every
     302  // other mode compiles __SIREN_SANDBOX__ to false, so those screens are left
     303  // out of the bundle entirely (see src/platform/saas/sandbox/).
     304  const isSandbox = mode === 'sandbox'
     305  const isSaaS = mode === 'saas' || isSandbox
    302306  const isDemo = mode === 'demo'
    303307  const isBuild = command === 'build'
    … …  
    312316  // Modes: 'lite', 'essentials', 'wordpress-lite', 'wordpress-essentials'
    313317  const tier = process.env.SIREN_TIER
    314     || mode.replace('wordpress-', '')
     318    || (isSandbox ? 'saas' : mode.replace('wordpress-', ''))
    315319    || 'essentials' // Default to essentials for dev mode (all features)
    316320
    … …  
    389393    define: {
    390394      ...featureDefines,
     395      __SIREN_SANDBOX__: JSON.stringify(isSandbox),
    391396    },
    392397    // Proxy API requests to PHP backend in SaaS dev mode
    … …  
    458463      },
    459464    } : isSaaS ? {
    460       outDir: 'dist/saas',
     465      outDir: isSandbox ? 'dist/sandbox' : 'dist/saas',
    461466      // Vendor code changes far less often than app code, so splitting it into
    462467      // its own long-cached chunks (with React kept whole to preserve a single
  • siren-affiliates/trunk/frontend/collaborator-coupons.js

    r3775642 r3788740  
    1 import{c as T,u as g,r as c,j as e,o as k,C as j,s as C,B as u,H as E,v as f,E as I,F as S,Z as z,T as H}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as y,i as L}from"./shared/collaborator-dashboard-CmODHn95.js";import{H as P}from"./shared/HelpTooltip-DsFyDQG4.js";import"./shared/registries-Ql2SZeKd.js";import{H as U}from"./shared/HelpDrawer-CQSl1exo.js";import{C as D}from"./shared/copy-j7vAIT70.js";import{G as F}from"./shared/gift-Bbpi-vg_.js";import{T as R}from"./shared/tag-DozXXg8T.js";import"./shared/react-zvEYxxW2.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-s6F8PPyM.js";/**
     1import{c as T,u as g,r as c,j as e,p as k,C as j,t as C,B as u,H as E,w as f,E as I,F as S,Z as z,T as H}from"./shared/wordpress-admin-D_eccjaB.js";import{u as y,i as L}from"./shared/collaborator-dashboard-o5ivsW6s.js";import{H as P}from"./shared/HelpTooltip-YN4U7Ym7.js";import"./shared/registries-CatPSk3G.js";import{H as U}from"./shared/HelpDrawer-BOa5Le1J.js";import{C as D,w as F}from"./shared/clipboard-Ch4rpUJU.js";import{G as R}from"./shared/gift-Bz0xaFMj.js";import{T as B}from"./shared/tag-C-fbb3UJ.js";import"./shared/react-Rq6nbqOn.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-1IfYWwRA.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const B=T("Percent",[["line",{x1:"19",x2:"5",y1:"5",y2:"19",key:"1x9vlm"}],["circle",{cx:"6.5",cy:"6.5",r:"2.5",key:"4mh3h7"}],["circle",{cx:"17.5",cy:"17.5",r:"2.5",key:"1mdrzq"}]]);function A({couponSourceAvailable:r=!0,isShareable:s}={}){const{collaboratorId:i,coupons:o,isLoadingCoupons:d,error:l,fetchCoupons:n}=y(),{translate:a}=g(),m=(s?o.filter(t=>s(t.code)):o).filter((t,b,w)=>w.findIndex(v=>v.code===t.code)===b),[p,x]=c.useState(null),N=t=>x(t);return c.useEffect(()=>{i&&n()},[i,n]),i?e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:[a("Coupons"),e.jsx(P,{topic:"collab-coupons",onLearnMore:N})]}),e.jsx("p",{className:"text-muted-foreground",children:a("Your coupon codes for sharing with customers.")})]}),l&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:l}),d?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(k,{})}):m.length===0?e.jsx(j,{children:e.jsx(C,{className:"py-8 text-center",children:r?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-muted-foreground",children:a("You don't have any coupon codes yet.")}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:a("Contact your program manager to get coupon codes assigned.")})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-muted-foreground",children:a("This organization does not use coupon codes.")}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:a("Share your referral link from the dashboard to earn credit for the people you send.")})]})})}):e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-3",children:m.map(t=>e.jsx(M,{coupon:t},t.code))}),e.jsx(U,{topic:p,open:!!p,onOpenChange:t=>!t&&x(null)})]}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("p",{className:"text-muted-foreground",children:a("Unable to load coupons. Please try again.")})})}function M({coupon:r}){const[s,i]=c.useState(!1),{translate:o}=g(),d=async()=>{try{await navigator.clipboard.writeText(r.code),i(!0),f.success(o("Coupon code copied!")),setTimeout(()=>i(!1),2e3)}catch{f.error(o("Failed to copy to clipboard"))}},l=()=>{const n=r.code.toUpperCase();return n.includes("SHIP")||n.includes("FREE")?e.jsx(F,{className:"h-5 w-5 text-purple-500"}):n.includes("%")||/\d+/.test(n)?e.jsx(B,{className:"h-5 w-5 text-green-500"}):e.jsx(R,{className:"h-5 w-5 text-blue-500"})};return e.jsxs(j,{className:"overflow-hidden",children:[e.jsx("div",{className:"bg-gradient-to-r from-primary/10 to-primary/5 px-4 py-3 border-b",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[l(),e.jsx("span",{className:"font-mono font-bold text-lg tracking-wide",children:r.code})]}),e.jsx(u,{variant:"ghost",size:"icon",onClick:d,"aria-label":o(s?"Copied":"Copy coupon code"),className:"h-8 w-8",children:s?e.jsx(E,{className:"h-4 w-4 text-green-500"}):e.jsx(D,{className:"h-4 w-4"})})]})}),e.jsxs(C,{className:"pt-4",children:[r.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-3",children:r.description}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{variant:"outline",size:"sm",onClick:d,className:"text-xs",children:o(s?"Copied!":"Copy Code")}),r.dateCreated&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:[o("Added")," ",new Date(r.dateCreated).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})]})]})]})]})}window.sirenConfig&&I({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function G(){const r=y(s=>s.initialize);return c.useEffect(()=>{const s=window.sirenConfig;L(s)&&r(s.collaboratorId,{trackingId:s.trackingId||"",urlReference:s.urlReference||"ref",baseUrl:s.baseUrl||""})},[r]),e.jsx("div",{className:"p-4",children:e.jsx(A,{})})}const h=document.getElementById("siren-collaborator-coupons");h&&S.createRoot(h).render(e.jsx(c.StrictMode,{children:e.jsxs(z,{children:[e.jsx(H,{position:"top-right",richColors:!0}),e.jsx(G,{})]})}));
     6 */const A=T("Percent",[["line",{x1:"19",x2:"5",y1:"5",y2:"19",key:"1x9vlm"}],["circle",{cx:"6.5",cy:"6.5",r:"2.5",key:"4mh3h7"}],["circle",{cx:"17.5",cy:"17.5",r:"2.5",key:"1mdrzq"}]]);function M({couponSourceAvailable:r=!0,isShareable:s}={}){const{collaboratorId:i,coupons:t,isLoadingCoupons:d,error:l,fetchCoupons:n}=y(),{translate:a}=g(),m=(s?t.filter(o=>s(o.code)):t).filter((o,b,w)=>w.findIndex(v=>v.code===o.code)===b),[p,x]=c.useState(null),N=o=>x(o);return c.useEffect(()=>{i&&n()},[i,n]),i?e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:[a("Coupons"),e.jsx(P,{topic:"collab-coupons",onLearnMore:N})]}),e.jsx("p",{className:"text-muted-foreground",children:a("Your coupon codes for sharing with customers.")})]}),l&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:l}),d?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(k,{})}):m.length===0?e.jsx(j,{children:e.jsx(C,{className:"py-8 text-center",children:r?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-muted-foreground",children:a("You don't have any coupon codes yet.")}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:a("Contact your program manager to get coupon codes assigned.")})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-muted-foreground",children:a("This organization does not use coupon codes.")}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:a("Share your referral link from the dashboard to earn credit for the people you send.")})]})})}):e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-3",children:m.map(o=>e.jsx(G,{coupon:o},o.code))}),e.jsx(U,{topic:p,open:!!p,onOpenChange:o=>!o&&x(null)})]}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("p",{className:"text-muted-foreground",children:a("Unable to load coupons. Please try again.")})})}function G({coupon:r}){const[s,i]=c.useState(!1),{translate:t}=g(),d=async()=>{try{await F(r.code),i(!0),f.success(t("Coupon code copied!")),setTimeout(()=>i(!1),2e3)}catch{f.error(t("Failed to copy to clipboard"))}},l=()=>{const n=r.code.toUpperCase();return n.includes("SHIP")||n.includes("FREE")?e.jsx(R,{className:"h-5 w-5 text-purple-500"}):n.includes("%")||/\d+/.test(n)?e.jsx(A,{className:"h-5 w-5 text-green-500"}):e.jsx(B,{className:"h-5 w-5 text-blue-500"})};return e.jsxs(j,{className:"overflow-hidden",children:[e.jsx("div",{className:"bg-gradient-to-r from-primary/10 to-primary/5 px-4 py-3 border-b",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[l(),e.jsx("span",{className:"font-mono font-bold text-lg tracking-wide",children:r.code})]}),e.jsx(u,{variant:"ghost",size:"icon",onClick:d,"aria-label":t(s?"Copied":"Copy coupon code"),className:"h-8 w-8",children:s?e.jsx(E,{className:"h-4 w-4 text-green-500"}):e.jsx(D,{className:"h-4 w-4"})})]})}),e.jsxs(C,{className:"pt-4",children:[r.description&&e.jsx("p",{className:"text-sm text-muted-foreground mb-3",children:r.description}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{variant:"outline",size:"sm",onClick:d,className:"text-xs",children:t(s?"Copied!":"Copy Code")}),r.dateCreated&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:[t("Added")," ",new Date(r.dateCreated).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})]})]})]})]})}window.sirenConfig&&I({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function W(){const r=y(s=>s.initialize);return c.useEffect(()=>{const s=window.sirenConfig;L(s)&&r(s.collaboratorId,{trackingId:s.trackingId||"",urlReference:s.urlReference||"ref",baseUrl:s.baseUrl||""})},[r]),e.jsx("div",{className:"p-4",children:e.jsx(M,{})})}const h=document.getElementById("siren-collaborator-coupons");h&&S.createRoot(h).render(e.jsx(c.StrictMode,{children:e.jsxs(z,{children:[e.jsx(H,{position:"top-right",richColors:!0}),e.jsx(W,{})]})}));
  • siren-affiliates/trunk/frontend/collaborator-dashboard.js

    r3775642 r3788740  
    1 import{c as x,u as g,r as d,t as q,j as e,C as U,p as E,q as H,x as D,s as R,v as w,I as T,B as M,H as z,z as O,o as V,E as F,F as G,Z as K,T as _}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as I,i as Z}from"./shared/collaborator-dashboard-CmODHn95.js";import{C as J}from"./shared/copy-j7vAIT70.js";import{H as Q}from"./shared/HelpTooltip-DsFyDQG4.js";import{H as X}from"./shared/HelpDrawer-CQSl1exo.js";import{u as S}from"./shared/usePortalMoney-BvA6Y-hX.js";import{i as ee,a as te}from"./shared/payout-waiting-k6RU_ZQa.js";import{P as se}from"./shared/CollaboratorProfileScreen-DiVRzawG.js";import{S as L}from"./shared/shopping-cart-BNnMkrGt.js";import{C as re,a as ae}from"./shared/clock-MPHmQLgH.js";import{T as ne}from"./shared/trending-up-B12dlnRi.js";import"./shared/registries-Ql2SZeKd.js";import"./shared/react-zvEYxxW2.js";import"./shared/markdown-renderer-s6F8PPyM.js";import"./shared/useMoneyFormatter-BaBJUw_5.js";import"./shared/triangle-alert-B1idIoet.js";import"./shared/unshipped-CGZcvpGp.js";/**
     1import{c as x,u as g,r as d,v as q,j as e,C as U,q as E,s as H,x as D,t as P,w as v,I as T,B as M,H as z,z as O,p as V,E as F,F as G,Z as K,T as _}from"./shared/wordpress-admin-D_eccjaB.js";import{u as I,i as Z}from"./shared/collaborator-dashboard-o5ivsW6s.js";import{w as J,C as Q}from"./shared/clipboard-Ch4rpUJU.js";import{H as X}from"./shared/HelpTooltip-YN4U7Ym7.js";import{H as ee}from"./shared/HelpDrawer-BOa5Le1J.js";import{u as S}from"./shared/usePortalMoney-l-aykMsd.js";import{i as te,a as se}from"./shared/payout-waiting-k6RU_ZQa.js";import{P as re}from"./shared/CollaboratorProfileScreen-BdTj_h9E.js";import{S as L}from"./shared/shopping-cart-wQHZa-fh.js";import{C as ae,a as ne}from"./shared/clock-3iWagaOq.js";import{T as oe}from"./shared/trending-up-Cg5-4LxH.js";import"./shared/registries-CatPSk3G.js";import"./shared/react-Rq6nbqOn.js";import"./shared/markdown-renderer-1IfYWwRA.js";import"./shared/useMoneyFormatter-B6sdhxKB.js";import"./shared/triangle-alert-BXQaBsm-.js";import"./shared/unshipped-CGZcvpGp.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const oe=x("ArrowDownRight",[["path",{d:"m7 7 10 10",key:"1fmybs"}],["path",{d:"M17 7v10H7",key:"6fjiku"}]]);/**
     6 */const ie=x("ArrowDownRight",[["path",{d:"m7 7 10 10",key:"1fmybs"}],["path",{d:"M17 7v10H7",key:"6fjiku"}]]);/**
    77 * @license lucide-react v0.469.0 - ISC
    88 *
    99 * This source code is licensed under the ISC license.
    1010 * See the LICENSE file in the root directory of this source tree.
    11  */const ie=x("ArrowUpRight",[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]]);/**
     11 */const le=x("ArrowUpRight",[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]]);/**
    1212 * @license lucide-react v0.469.0 - ISC
    1313 *
    1414 * This source code is licensed under the ISC license.
    1515 * See the LICENSE file in the root directory of this source tree.
    16  */const le=x("Coins",[["circle",{cx:"8",cy:"8",r:"6",key:"3yglwk"}],["path",{d:"M18.09 10.37A6 6 0 1 1 10.34 18",key:"t5s6rm"}],["path",{d:"M7 6h1v4",key:"1obek4"}],["path",{d:"m16.71 13.88.7.71-2.82 2.82",key:"1rbuyh"}]]);/**
     16 */const ce=x("Coins",[["circle",{cx:"8",cy:"8",r:"6",key:"3yglwk"}],["path",{d:"M18.09 10.37A6 6 0 1 1 10.34 18",key:"t5s6rm"}],["path",{d:"M7 6h1v4",key:"1obek4"}],["path",{d:"m16.71 13.88.7.71-2.82 2.82",key:"1rbuyh"}]]);/**
    1717 * @license lucide-react v0.469.0 - ISC
    1818 *
    1919 * This source code is licensed under the ISC license.
    2020 * See the LICENSE file in the root directory of this source tree.
    21  */const ce=x("DollarSign",[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]]);/**
     21 */const de=x("DollarSign",[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]]);/**
    2222 * @license lucide-react v0.469.0 - ISC
    2323 *
    2424 * This source code is licensed under the ISC license.
    2525 * See the LICENSE file in the root directory of this source tree.
    26  */const de=x("Link",[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]]);/**
     26 */const me=x("Link",[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]]);/**
    2727 * @license lucide-react v0.469.0 - ISC
    2828 *
    2929 * This source code is licensed under the ISC license.
    3030 * See the LICENSE file in the root directory of this source tree.
    31  */const me=x("Package",[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["path",{d:"m3.3 7 7.703 4.734a2 2 0 0 0 1.994 0L20.7 7",key:"yx3hmr"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]]);/**
     31 */const ue=x("Package",[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["path",{d:"m3.3 7 7.703 4.734a2 2 0 0 0 1.994 0L20.7 7",key:"yx3hmr"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]]);/**
    3232 * @license lucide-react v0.469.0 - ISC
    3333 *
    3434 * This source code is licensed under the ISC license.
    3535 * See the LICENSE file in the root directory of this source tree.
    36  */const B=x("Wallet",[["path",{d:"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1",key:"18etb6"}],["path",{d:"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4",key:"xoc0q4"}]]);function ue({collaboratorId:s}){const{translate:t}=g(),[a,r]=d.useState([]);return d.useEffect(()=>{let n=!1;return q.get(`/collaborators/${s}`,{fields:"products"}).then(c=>{n||r(c.products??[])}).catch(()=>{n||r([])}),()=>{n=!0}},[s]),a.length===0?null:e.jsxs(U,{children:[e.jsxs(E,{children:[e.jsxs(H,{className:"flex items-center gap-2",children:[e.jsx(me,{className:"h-4 w-4","aria-hidden":"true"}),t("Your products")]}),e.jsx(D,{children:t("You earn when these sell, through programs that reward product sales.")})]}),e.jsx(R,{children:e.jsx("ul",{className:"list-disc space-y-1 pl-5 text-sm",children:a.map(n=>e.jsx("li",{children:n.name},n.id))})})]})}function C(s,t){const a=s.trim();if(!a||!t.trackingId)return null;try{const r=new URL(/^https?:\/\//i.test(a)?a:"https://"+a);return r.searchParams.set(t.urlReference,t.trackingId),r.toString()}catch{return null}}function he({config:s}){const[t,a]=d.useState(s.baseUrl),[r,n]=d.useState(()=>C(s.baseUrl,s)??""),[c,m]=d.useState(!1),{translate:o}=g();d.useEffect(()=>{a(h=>h||s.baseUrl),n(h=>C(t||s.baseUrl,s)??h)},[s.baseUrl,s.trackingId,s.urlReference]);const u=d.useCallback(()=>{if(!t){w.error(o("Please enter a URL"));return}const h=C(t,s);if(!h){w.error(o("Please enter a valid URL"));return}n(h)},[t,s,o]),p=d.useCallback(async()=>{if(r)try{await navigator.clipboard.writeText(r),m(!0),w.success(o("Copied to clipboard!")),setTimeout(()=>m(!1),2e3)}catch{w.error(o("Failed to copy to clipboard"))}},[r,o]),v=d.useCallback(h=>{h.key==="Enter"&&u()},[u]);return e.jsxs(U,{children:[e.jsxs(E,{children:[e.jsxs(H,{className:"flex items-center gap-2",children:[e.jsx(de,{className:"h-5 w-5"}),o("Referral URL Generator")]}),e.jsx(D,{children:o("Enter any URL to create a referral link with your tracking code.")})]}),e.jsxs(R,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:o("Your referral code:")}),e.jsx("code",{className:"rounded bg-muted px-2 py-1 font-mono text-sm",children:s.trackingId})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"text",placeholder:o("Enter URL (e.g., https://example.com/product)"),value:t,onChange:h=>a(h.target.value),onKeyDown:v,className:"flex-1"}),e.jsx(M,{onClick:u,children:o("Generate")})]}),r&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:o("Your Referral Link:")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"text",value:r,readOnly:!0,className:"flex-1 font-mono text-sm"}),e.jsx(M,{variant:"outline",size:"icon",onClick:p,title:o("Copy to clipboard"),children:c?e.jsx(z,{className:"h-4 w-4 text-green-500"}):e.jsx(J,{className:"h-4 w-4"})})]})]})]})]})}const W=s=>`siren-portal-visited-${s}`;function pe(s){try{return window.localStorage.getItem(W(s))!==null}catch{return!1}}function xe(s,t){const a=d.useMemo(()=>pe(s),[s]);return d.useEffect(()=>{if(s!==null)try{window.localStorage.setItem(W(s),String(Date.now()))}catch{}},[s]),s!==null&&!a&&!t}function fe({payouts:s}){const{translate:t}=g(),{formatMoney:a}=S(),r=(s??[]).filter(ee);if(r.length===0)return null;const n=new Map;for(const u of r)n.set(u.currency,(n.get(u.currency)??0)+u.value);const c=Array.from(n,([u,p])=>a(p,u)).join(", "),m=te(r),o=m.length>1?`${m.slice(0,-1).join(", ")} ${t("and")} ${m[m.length-1]}`:m[0];return e.jsxs("div",{role:"status","data-testid":"payouts-waiting-banner",className:"flex flex-col gap-3 rounded-lg border border-amber-300 bg-amber-50 p-4 text-amber-900 sm:flex-row sm:items-center sm:justify-between dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(B,{className:"mt-0.5 h-5 w-5 shrink-0","aria-hidden":"true"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:t("%s is waiting for you").replace("%s",c)}),e.jsx("p",{className:"text-sm",children:t("Set up %s to receive it. Your payout is sent as soon as you finish.").replace("%s",o)})]})]}),e.jsx(M,{asChild:!0,size:"sm",children:e.jsx(O,{to:`profile#${se}`,children:t("Set up payouts")})})]})}function ye({balances:s}){const{translate:t}=g();if(s.length===0)return null;const a=s.filter(r=>r.redeemAt!==void 0);return a.length===0?e.jsxs("p",{className:"flex items-start gap-2 mt-3 text-sm text-muted-foreground","data-testid":"credit-redeem-hint",children:[e.jsx(L,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("span",{children:t("Sign in on this site when you shop, and your credit comes off your order at checkout.")})]}):e.jsx("ul",{className:"mt-3 space-y-1 text-sm text-muted-foreground","data-testid":"credit-redeem-hint",children:a.map(r=>{const n=r.redeemAt??[],c=n.map(o=>o.name).filter(o=>o!==""),m=c.length>0?ge(c,t("and")):t("your store");return e.jsxs("li",{className:"flex items-start gap-2","data-testid":`credit-redeem-hint-${r.currency}`,children:[e.jsx(L,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("span",{children:n.length>0?`${r.name}: ${t("spend it at checkout on")} ${m}. ${t("Sign in there with your account, and it comes off your order.")}`:`${r.name}: ${t("no store takes this credit at checkout yet.")}`})]},r.currency)})})}function ge(s,t){return s.length<=1?s[0]??"":`${s.slice(0,-1).join(", ")} ${t} ${s[s.length-1]}`}function y({label:s,amounts:t,icon:a,description:r,trend:n,helpTopic:c,onLearnMore:m}){const{translate:o}=g(),{formatMoney:u}=S();return e.jsx(U,{children:e.jsx(R,{className:"pt-6",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("p",{className:"text-sm font-medium text-muted-foreground",children:[s,c&&e.jsx(Q,{topic:c,onLearnMore:m})]}),t.length===0?e.jsx("p",{className:"text-2xl font-bold",children:"—"}):t.length===1?e.jsx("p",{className:"text-2xl font-bold",children:u(t[0].value,t[0].currency)}):e.jsx("div",{className:"space-y-0.5",children:t.map(p=>e.jsx("p",{className:"text-lg font-bold",children:u(p.value,p.currency)},p.currency))}),r&&e.jsx("p",{className:"text-xs text-muted-foreground",children:r}),n&&e.jsxs("div",{className:`flex items-center text-xs ${n.isPositive?"text-green-600":"text-red-600"}`,children:[n.isPositive?e.jsx(ie,{className:"h-3 w-3 mr-1"}):e.jsx(oe,{className:"h-3 w-3 mr-1"}),n.value,"% ",o("vs last month")]})]}),e.jsx("div",{className:"p-2 rounded-lg bg-muted",children:a})]})})})}function je(){const{formatMoney:s}=S(),{collaboratorId:t,referralConfig:a,profile:r,isLoadingProfile:n,balanceSummary:c,payouts:m,moneyTruncated:o,isLoadingReporting:u,error:p,fetchProfile:v,fetchDashboardSummary:h}=I(),{translate:i}=g(),Y=xe(t,c.length>0),[$,P]=d.useState(null),b=l=>P(l);if(d.useEffect(()=>{t&&(v(),h())},[t,v,h]),!t)return e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("p",{className:"text-muted-foreground",children:i("Unable to load dashboard. Please try again.")})});if(n&&!r||u&&c.length===0)return e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(V,{})});const f=c[0],N=(f==null?void 0:f.lastMonth)>0?Math.round((f.thisMonth-f.lastMonth)/f.lastMonth*100):null,j=l=>c.map(k=>({value:k[l],currency:k.currency,symbol:k.currency}));return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:[i(Y?"Welcome":"Welcome back"),r!=null&&r.fullName?`, ${r.fullName.split(" ")[0]}`:"","!"]}),e.jsx("p",{className:"text-muted-foreground",children:i("Here's how your referrals are performing.")}),((r==null?void 0:r.linkedCustomerCount)??0)>0&&e.jsx("p",{className:"mt-1 text-sm",children:(r==null?void 0:r.linkedCustomerCount)===1?i("1 customer credits you on every purchase."):`${r==null?void 0:r.linkedCustomerCount} ${i("customers credit you on every purchase.")}`})]}),e.jsx(fe,{payouts:m}),p&&e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:p}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-medium mb-3",children:i("Earnings")}),o&&e.jsx("p",{className:"mb-3 text-sm text-muted-foreground",children:i("You have more rewards than this page can add up. The totals below cover your most recent rewards only.")}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-5",children:[e.jsx(y,{label:i("Payable"),amounts:j("payable"),icon:e.jsx(ce,{className:"h-5 w-5"}),description:i("Approved, not paid yet"),helpTopic:"collab-available-balance",onLearnMore:b}),e.jsx(y,{label:i("Awaiting approval"),amounts:j("awaiting"),icon:e.jsx(re,{className:"h-5 w-5"}),description:i("Sales not approved yet"),helpTopic:"collab-pending-balance",onLearnMore:b}),e.jsx(y,{label:i("Paid"),amounts:j("paid"),icon:e.jsx(B,{className:"h-5 w-5"}),description:i("Paid out to you")}),e.jsx(y,{label:i("This Month"),amounts:j("thisMonth"),icon:e.jsx(ne,{className:"h-5 w-5"}),trend:N===null?void 0:{value:Math.abs(N),isPositive:N>=0},helpTopic:"collab-this-month",onLearnMore:b}),e.jsx(y,{label:i("Lifetime Earnings"),amounts:j("earned"),icon:e.jsx(ae,{className:"h-5 w-5"}),description:i("Payable plus paid"),helpTopic:"collab-lifetime-earnings",onLearnMore:b})]})]}),e.jsx(ue,{collaboratorId:t}),(r==null?void 0:r.creditBalances)&&r.creditBalances.length>0&&e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-medium mb-3",children:i("Credit Balances")}),e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:r.creditBalances.map(l=>e.jsx(y,{label:l.name,amounts:[{value:l.balance,currency:l.currency,symbol:l.symbol}],icon:e.jsx(le,{className:"h-5 w-5"}),description:l.onHold&&l.onHold>0?`${s(l.available??0,l.currency)} ${i("available")} · ${s(l.onHold,l.currency)} ${i("on hold")}`:s(l.balance,l.currency)},l.currency))}),e.jsx(ye,{balances:r.creditBalances})]}),a&&a.trackingId&&e.jsx(he,{config:a}),e.jsx(X,{topic:$,open:!!$,onOpenChange:l=>!l&&P(null)})]})}window.sirenConfig&&F({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function ve(){const s=I(t=>t.initialize);return d.useEffect(()=>{const t=window.sirenConfig;Z(t)&&t.trackingId&&s(t.collaboratorId,{trackingId:t.trackingId,urlReference:t.urlReference,baseUrl:t.baseUrl})},[s]),e.jsx("div",{className:"p-4",children:e.jsx(je,{})})}const A=document.getElementById("siren-collaborator-dashboard");A&&G.createRoot(A).render(e.jsx(d.StrictMode,{children:e.jsxs(K,{children:[e.jsx(_,{position:"top-right",richColors:!0}),e.jsx(ve,{})]})}));
     36 */const B=x("Wallet",[["path",{d:"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1",key:"18etb6"}],["path",{d:"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4",key:"xoc0q4"}]]);function he({collaboratorId:s}){const{translate:t}=g(),[a,r]=d.useState([]);return d.useEffect(()=>{let n=!1;return q.get(`/collaborators/${s}`,{fields:"products"}).then(c=>{n||r(c.products??[])}).catch(()=>{n||r([])}),()=>{n=!0}},[s]),a.length===0?null:e.jsxs(U,{children:[e.jsxs(E,{children:[e.jsxs(H,{className:"flex items-center gap-2",children:[e.jsx(ue,{className:"h-4 w-4","aria-hidden":"true"}),t("Your products")]}),e.jsx(D,{children:t("You earn when these sell, through programs that reward product sales.")})]}),e.jsx(P,{children:e.jsx("ul",{className:"list-disc space-y-1 pl-5 text-sm",children:a.map(n=>e.jsx("li",{children:n.name},n.id))})})]})}function C(s,t){const a=s.trim();if(!a||!t.trackingId)return null;try{const r=new URL(/^https?:\/\//i.test(a)?a:"https://"+a);return r.searchParams.set(t.urlReference,t.trackingId),r.toString()}catch{return null}}function pe({config:s}){const[t,a]=d.useState(s.baseUrl),[r,n]=d.useState(()=>C(s.baseUrl,s)??""),[c,m]=d.useState(!1),{translate:o}=g();d.useEffect(()=>{a(h=>h||s.baseUrl),n(h=>C(t||s.baseUrl,s)??h)},[s.baseUrl,s.trackingId,s.urlReference]);const u=d.useCallback(()=>{if(!t){v.error(o("Please enter a URL"));return}const h=C(t,s);if(!h){v.error(o("Please enter a valid URL"));return}n(h)},[t,s,o]),p=d.useCallback(async()=>{if(r)try{await J(r),m(!0),v.success(o("Copied to clipboard!")),setTimeout(()=>m(!1),2e3)}catch{v.error(o("Failed to copy to clipboard"))}},[r,o]),b=d.useCallback(h=>{h.key==="Enter"&&u()},[u]);return e.jsxs(U,{children:[e.jsxs(E,{children:[e.jsxs(H,{className:"flex items-center gap-2",children:[e.jsx(me,{className:"h-5 w-5"}),o("Referral URL Generator")]}),e.jsx(D,{children:o("Enter any URL to create a referral link with your tracking code.")})]}),e.jsxs(P,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:o("Your referral code:")}),e.jsx("code",{className:"rounded bg-muted px-2 py-1 font-mono text-sm",children:s.trackingId})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"text",placeholder:o("Enter URL (e.g., https://example.com/product)"),value:t,onChange:h=>a(h.target.value),onKeyDown:b,className:"flex-1"}),e.jsx(M,{onClick:u,children:o("Generate")})]}),r&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:o("Your Referral Link:")}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"text",value:r,readOnly:!0,className:"flex-1 font-mono text-sm"}),e.jsx(M,{variant:"outline",size:"icon",onClick:p,title:o("Copy to clipboard"),children:c?e.jsx(z,{className:"h-4 w-4 text-green-500"}):e.jsx(Q,{className:"h-4 w-4"})})]})]})]})]})}const W=s=>`siren-portal-visited-${s}`;function xe(s){try{return window.localStorage.getItem(W(s))!==null}catch{return!1}}function fe(s,t){const a=d.useMemo(()=>xe(s),[s]);return d.useEffect(()=>{if(s!==null)try{window.localStorage.setItem(W(s),String(Date.now()))}catch{}},[s]),s!==null&&!a&&!t}function ye({payouts:s}){const{translate:t}=g(),{formatMoney:a}=S(),r=(s??[]).filter(te);if(r.length===0)return null;const n=new Map;for(const u of r)n.set(u.currency,(n.get(u.currency)??0)+u.value);const c=Array.from(n,([u,p])=>a(p,u)).join(", "),m=se(r),o=m.length>1?`${m.slice(0,-1).join(", ")} ${t("and")} ${m[m.length-1]}`:m[0];return e.jsxs("div",{role:"status","data-testid":"payouts-waiting-banner",className:"flex flex-col gap-3 rounded-lg border border-amber-300 bg-amber-50 p-4 text-amber-900 sm:flex-row sm:items-center sm:justify-between dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(B,{className:"mt-0.5 h-5 w-5 shrink-0","aria-hidden":"true"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:t("%s is waiting for you").replace("%s",c)}),e.jsx("p",{className:"text-sm",children:t("Set up %s to receive it. Your payout is sent as soon as you finish.").replace("%s",o)})]})]}),e.jsx(M,{asChild:!0,size:"sm",children:e.jsx(O,{to:`profile#${re}`,children:t("Set up payouts")})})]})}function ge({balances:s}){const{translate:t}=g();if(s.length===0)return null;const a=s.filter(r=>r.redeemAt!==void 0);return a.length===0?e.jsxs("p",{className:"flex items-start gap-2 mt-3 text-sm text-muted-foreground","data-testid":"credit-redeem-hint",children:[e.jsx(L,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("span",{children:t("Sign in on this site when you shop, and your credit comes off your order at checkout.")})]}):e.jsx("ul",{className:"mt-3 space-y-1 text-sm text-muted-foreground","data-testid":"credit-redeem-hint",children:a.map(r=>{const n=r.redeemAt??[],c=n.map(o=>o.name).filter(o=>o!==""),m=c.length>0?je(c,t("and")):t("your store");return e.jsxs("li",{className:"flex items-start gap-2","data-testid":`credit-redeem-hint-${r.currency}`,children:[e.jsx(L,{className:"h-4 w-4 mt-0.5 flex-shrink-0"}),e.jsx("span",{children:n.length>0?`${r.name}: ${t("spend it at checkout on")} ${m}. ${t("Sign in there with your account, and it comes off your order.")}`:`${r.name}: ${t("no store takes this credit at checkout yet.")}`})]},r.currency)})})}function je(s,t){return s.length<=1?s[0]??"":`${s.slice(0,-1).join(", ")} ${t} ${s[s.length-1]}`}function y({label:s,amounts:t,icon:a,description:r,trend:n,helpTopic:c,onLearnMore:m}){const{translate:o}=g(),{formatMoney:u}=S();return e.jsx(U,{children:e.jsx(P,{className:"pt-6",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("p",{className:"text-sm font-medium text-muted-foreground",children:[s,c&&e.jsx(X,{topic:c,onLearnMore:m})]}),t.length===0?e.jsx("p",{className:"text-2xl font-bold",children:"—"}):t.length===1?e.jsx("p",{className:"text-2xl font-bold",children:u(t[0].value,t[0].currency)}):e.jsx("div",{className:"space-y-0.5",children:t.map(p=>e.jsx("p",{className:"text-lg font-bold",children:u(p.value,p.currency)},p.currency))}),r&&e.jsx("p",{className:"text-xs text-muted-foreground",children:r}),n&&e.jsxs("div",{className:`flex items-center text-xs ${n.isPositive?"text-green-600":"text-red-600"}`,children:[n.isPositive?e.jsx(le,{className:"h-3 w-3 mr-1"}):e.jsx(ie,{className:"h-3 w-3 mr-1"}),n.value,"% ",o("vs last month")]})]}),e.jsx("div",{className:"p-2 rounded-lg bg-muted",children:a})]})})})}function be(){const{formatMoney:s}=S(),{collaboratorId:t,referralConfig:a,profile:r,isLoadingProfile:n,balanceSummary:c,payouts:m,moneyTruncated:o,isLoadingReporting:u,error:p,fetchProfile:b,fetchDashboardSummary:h}=I(),{translate:i}=g(),Y=fe(t,c.length>0),[R,$]=d.useState(null),w=l=>$(l);if(d.useEffect(()=>{t&&(b(),h())},[t,b,h]),!t)return e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("p",{className:"text-muted-foreground",children:i("Unable to load dashboard. Please try again.")})});if(n&&!r||u&&c.length===0)return e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(V,{})});const f=c[0],N=(f==null?void 0:f.lastMonth)>0?Math.round((f.thisMonth-f.lastMonth)/f.lastMonth*100):null,j=l=>c.map(k=>({value:k[l],currency:k.currency,symbol:k.currency}));return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:[i(Y?"Welcome":"Welcome back"),r!=null&&r.fullName?`, ${r.fullName.split(" ")[0]}`:"","!"]}),e.jsx("p",{className:"text-muted-foreground",children:i("Here's how your referrals are performing.")}),((r==null?void 0:r.linkedCustomerCount)??0)>0&&e.jsx("p",{className:"mt-1 text-sm",children:(r==null?void 0:r.linkedCustomerCount)===1?i("1 customer credits you on every purchase."):`${r==null?void 0:r.linkedCustomerCount} ${i("customers credit you on every purchase.")}`})]}),e.jsx(ye,{payouts:m}),p&&e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:p}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-medium mb-3",children:i("Earnings")}),o&&e.jsx("p",{className:"mb-3 text-sm text-muted-foreground",children:i("You have more rewards than this page can add up. The totals below cover your most recent rewards only.")}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-5",children:[e.jsx(y,{label:i("Payable"),amounts:j("payable"),icon:e.jsx(de,{className:"h-5 w-5"}),description:i("Approved, not paid yet"),helpTopic:"collab-available-balance",onLearnMore:w}),e.jsx(y,{label:i("Awaiting approval"),amounts:j("awaiting"),icon:e.jsx(ae,{className:"h-5 w-5"}),description:i("Sales not approved yet"),helpTopic:"collab-pending-balance",onLearnMore:w}),e.jsx(y,{label:i("Paid"),amounts:j("paid"),icon:e.jsx(B,{className:"h-5 w-5"}),description:i("Paid out to you")}),e.jsx(y,{label:i("This Month"),amounts:j("thisMonth"),icon:e.jsx(oe,{className:"h-5 w-5"}),trend:N===null?void 0:{value:Math.abs(N),isPositive:N>=0},helpTopic:"collab-this-month",onLearnMore:w}),e.jsx(y,{label:i("Lifetime Earnings"),amounts:j("earned"),icon:e.jsx(ne,{className:"h-5 w-5"}),description:i("Payable plus paid"),helpTopic:"collab-lifetime-earnings",onLearnMore:w})]})]}),e.jsx(he,{collaboratorId:t}),(r==null?void 0:r.creditBalances)&&r.creditBalances.length>0&&e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-medium mb-3",children:i("Credit Balances")}),e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:r.creditBalances.map(l=>e.jsx(y,{label:l.name,amounts:[{value:l.balance,currency:l.currency,symbol:l.symbol}],icon:e.jsx(ce,{className:"h-5 w-5"}),description:l.onHold&&l.onHold>0?`${s(l.available??0,l.currency)} ${i("available")} · ${s(l.onHold,l.currency)} ${i("on hold")}`:s(l.balance,l.currency)},l.currency))}),e.jsx(ge,{balances:r.creditBalances})]}),a&&a.trackingId&&!a.inPersonOnly&&e.jsx(pe,{config:a}),(a==null?void 0:a.inPersonOnly)&&e.jsx("p",{className:"rounded-md border bg-muted/40 px-4 py-3 text-sm text-muted-foreground","data-testid":"in-person-only",children:i("This business sells in person, so there’s no link to share. Share your coupon code instead, and each sale with it counts for you.")}),e.jsx(ee,{topic:R,open:!!R,onOpenChange:l=>!l&&$(null)})]})}window.sirenConfig&&F({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function we(){const s=I(t=>t.initialize);return d.useEffect(()=>{const t=window.sirenConfig;Z(t)&&t.trackingId&&s(t.collaboratorId,{trackingId:t.trackingId,urlReference:t.urlReference,baseUrl:t.baseUrl})},[s]),e.jsx("div",{className:"p-4",children:e.jsx(be,{})})}const A=document.getElementById("siren-collaborator-dashboard");A&&G.createRoot(A).render(e.jsx(d.StrictMode,{children:e.jsxs(K,{children:[e.jsx(_,{position:"top-right",richColors:!0}),e.jsx(we,{})]})}));
  • siren-affiliates/trunk/frontend/collaborator-performance.js

    r3775642 r3788740  
    1 import{c as E,u as H,r as o,j as e,o as R,C as P,p as z,q as O,x as Y,S as L,d as M,e as I,f as V,g as m,s as k,B as F,E as G,F as W,Z,T as J}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as B,i as Q}from"./shared/collaborator-dashboard-CmODHn95.js";import{H as f,D as X}from"./shared/HelpTooltip-DsFyDQG4.js";import"./shared/registries-Ql2SZeKd.js";import{A as ee}from"./shared/AreaChart-58TrxGu7.js";import{H as se}from"./shared/HelpDrawer-CQSl1exo.js";import{L as te}from"./shared/link-2-CR4ULk7z.js";import{S as ae}from"./shared/shopping-cart-BNnMkrGt.js";import{T as re}from"./shared/tag-DozXXg8T.js";import{T as ne}from"./shared/trending-up-B12dlnRi.js";import"./shared/react-zvEYxxW2.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-s6F8PPyM.js";/**
     1import{c as E,u as H,r as o,j as e,p as R,C as P,q as z,s as O,x as Y,S as L,e as M,f as I,g as V,h as m,t as k,B as F,E as G,F as W,Z,T as J}from"./shared/wordpress-admin-D_eccjaB.js";import{u as B,i as Q}from"./shared/collaborator-dashboard-o5ivsW6s.js";import{H as f,D as X}from"./shared/HelpTooltip-YN4U7Ym7.js";import"./shared/registries-CatPSk3G.js";import{A as ee}from"./shared/AreaChart-CUGMAtch.js";import{H as se}from"./shared/HelpDrawer-BOa5Le1J.js";import{L as te}from"./shared/link-2-C4uE2qWf.js";import{S as ae}from"./shared/shopping-cart-wQHZa-fh.js";import{T as re}from"./shared/tag-C-fbb3UJ.js";import{T as ne}from"./shared/trending-up-Cg5-4LxH.js";import"./shared/react-Rq6nbqOn.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-1IfYWwRA.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
  • siren-affiliates/trunk/frontend/collaborator-profile.js

    r3775642 r3788740  
    1 import{E as t,F as s,j as o,r as n,Z as a,T as c}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as l,i as p}from"./shared/collaborator-dashboard-CmODHn95.js";import"./shared/HelpTooltip-DsFyDQG4.js";import"./shared/registries-Ql2SZeKd.js";import{C as f}from"./shared/CollaboratorProfileScreen-DiVRzawG.js";import"./shared/react-zvEYxxW2.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/HelpDrawer-CQSl1exo.js";import"./shared/markdown-renderer-s6F8PPyM.js";import"./shared/triangle-alert-B1idIoet.js";window.sirenConfig&&t({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function d(){const i=l(r=>r.initialize);return n.useEffect(()=>{const r=window.sirenConfig;p(r)&&i(r.collaboratorId,{trackingId:r.trackingId||"",urlReference:r.urlReference||"ref",baseUrl:r.baseUrl||""})},[i]),o.jsx("div",{className:"p-4",children:o.jsx(f,{})})}const e=document.getElementById("siren-collaborator-profile");e&&s.createRoot(e).render(o.jsx(n.StrictMode,{children:o.jsxs(a,{children:[o.jsx(c,{position:"top-right",richColors:!0}),o.jsx(d,{})]})}));
     1import{E as t,F as s,j as o,r as n,Z as a,T as c}from"./shared/wordpress-admin-D_eccjaB.js";import{u as l,i as p}from"./shared/collaborator-dashboard-o5ivsW6s.js";import"./shared/HelpTooltip-YN4U7Ym7.js";import"./shared/registries-CatPSk3G.js";import{C as f}from"./shared/CollaboratorProfileScreen-BdTj_h9E.js";import"./shared/react-Rq6nbqOn.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/HelpDrawer-BOa5Le1J.js";import"./shared/markdown-renderer-1IfYWwRA.js";import"./shared/triangle-alert-BXQaBsm-.js";window.sirenConfig&&t({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function d(){const i=l(r=>r.initialize);return n.useEffect(()=>{const r=window.sirenConfig;p(r)&&i(r.collaboratorId,{trackingId:r.trackingId||"",urlReference:r.urlReference||"ref",baseUrl:r.baseUrl||""})},[i]),o.jsx("div",{className:"p-4",children:o.jsx(f,{})})}const e=document.getElementById("siren-collaborator-profile");e&&s.createRoot(e).render(o.jsx(n.StrictMode,{children:o.jsxs(a,{children:[o.jsx(c,{position:"top-right",richColors:!0}),o.jsx(d,{})]})}));
  • siren-affiliates/trunk/frontend/collaborator-rewards.js

    r3775642 r3788740  
    1 import{u as Z,r as l,j as e,o as _,C as I,s as L,_ as ie,$ as ce,a0 as G,a1 as q,p as F,q as V,x as J,S as B,d as z,e as H,f as U,g as x,B as A,a2 as de,a3 as oe,E as me,F as ue,Z as xe,T as he}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as se,e as pe,a as je,p as ge,U as fe,r as ve,b as Ne,m as ye,c as Q,i as be}from"./shared/collaborator-dashboard-CmODHn95.js";import{H as R,D as ae}from"./shared/HelpTooltip-DsFyDQG4.js";import"./shared/registries-Ql2SZeKd.js";import{A as we}from"./shared/AreaChart-58TrxGu7.js";import{H as Ce}from"./shared/HelpDrawer-CQSl1exo.js";import{u as K}from"./shared/usePortalMoney-BvA6Y-hX.js";import"./shared/react-zvEYxxW2.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-s6F8PPyM.js";import"./shared/useMoneyFormatter-BaBJUw_5.js";const X=["#22c55e","#eab308","#a855f7","#0ea5e9","#ef4444"],Se=[{value:"this-month",label:"This month"},{value:"last-month",label:"Last month"},{value:"3",label:"Last 3 months"},{value:"6",label:"Last 6 months"},{value:"12",label:"Last 12 months"}];function Te(a,i){const o=ge(a,i);return{id:a.id,orderId:a.conversionId?`#${a.conversionId}`:`#${a.id}`,orderTotal:a.conversionAmount??a.value,orderCurrency:a.conversionAmount!=null?fe:Q(a),commission:a.value,currency:Q(a),statusKey:ye(a.status,o)??a.status,statusLabel:Ne(a.status,o),statusBadge:ve(a.status,o),date:a.dateCreated,programName:a.programName}}function Pe(a,i){const o={paid:"paid",unpaid:"pending",failed:"failed"},r=i.filter(c=>c.payoutId===a.id);return{id:a.id,amount:a.value,currency:a.currency,itemCount:r.length,status:o[a.status]??"pending",date:a.datePaid||a.dateCreated,items:r.map(c=>({id:c.id,description:c.conversionId?`Order #${c.conversionId}`:`Reward #${c.id}`,amount:c.value,date:c.dateCreated}))}}const te={pending:"Not paid yet",paid:"Paid",failed:"Failed"},ne={pending:"status-badge status-yellow",paid:"status-badge status-green",failed:"status-badge status-red"};function $(a){return new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}function Ie({data:a,isLoading:i,onLearnMore:o}){const{translate:r}=Z(),{formatMoney:c}=K(),[m,O]=l.useState("all"),[h,N]=l.useState("date"),[j,g]=l.useState("desc"),[u,y]=l.useState(1),[d,v]=l.useState(10),f=n=>{h===n?g(j==="asc"?"desc":"asc"):(N(n),g("desc")),y(1)},E=n=>{v(parseInt(n)),y(1)},b=l.useMemo(()=>{let n=[...a];return m!=="all"&&(n=n.filter(C=>C.statusKey===m)),h&&n.sort((C,M)=>{let S=0;switch(h){case"date":S=new Date(C.date).getTime()-new Date(M.date).getTime();break;case"orderTotal":S=C.orderTotal-M.orderTotal;break;case"commission":S=C.commission-M.commission;break;case"status":S=C.statusLabel.localeCompare(M.statusLabel);break}return j==="asc"?S:-S}),n},[a,m,h,j]),D=Math.ceil(b.length/d),P=b.slice((u-1)*d,u*d),w=[{id:"date",header:r("Date"),sortable:!0,cell:n=>e.jsx("span",{className:"text-sm text-muted-foreground",children:$(n.date)})},{id:"order",header:r("Order"),cell:n=>e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"font-mono text-sm",children:n.orderId}),n.programName&&e.jsx("span",{className:"block text-xs text-muted-foreground",children:n.programName})]})},{id:"orderTotal",header:r("Order Total"),sortable:!0,className:"text-right",cell:n=>e.jsx("span",{className:"text-sm",children:c(n.orderTotal,n.orderCurrency)})},{id:"commission",header:r("Your Commission"),sortable:!0,className:"text-right",headerAdornment:e.jsx(R,{topic:"collab-earnings-commission-amount",onLearnMore:o}),cell:n=>e.jsx("span",{className:"font-medium",children:c(n.commission,n.currency)})},{id:"status",header:r("Status"),sortable:!0,headerAdornment:e.jsx(R,{topic:"collab-earnings-status",onLearnMore:o}),cell:n=>e.jsx("span",{className:n.statusBadge,children:n.statusLabel})}];return e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(V,{children:["Commissions",e.jsx(R,{topic:"collab-earnings-commissions",onLearnMore:o})]}),e.jsx(J,{children:"Sales attributed to you and your commission earned"})]}),e.jsxs(B,{value:m,onValueChange:n=>{O(n),y(1)},children:[e.jsx(z,{"aria-label":r("Filter by status"),className:"w-[160px]",children:e.jsx(H,{placeholder:r("Status")})}),e.jsxs(U,{children:[e.jsx(x,{value:"all",children:"All Statuses"}),e.jsx(x,{value:"awaiting",children:"Awaiting approval"}),e.jsx(x,{value:"payable",children:"Payable"}),e.jsx(x,{value:"paid",children:"Paid"}),e.jsx(x,{value:"rejected",children:"Rejected"})]})]})]})}),e.jsxs(L,{children:[e.jsx(ae,{columns:w,data:P,isLoading:i,emptyMessage:r("No commissions found."),sortField:h??void 0,sortOrder:j,onSort:n=>f(n)}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",b.length===0?0:(u-1)*d+1," to"," ",Math.min(u*d,b.length)," of ",b.length," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Per page:"}),e.jsxs(B,{value:d.toString(),onValueChange:E,children:[e.jsx(z,{"aria-label":r("Rows per page"),className:"w-[80px] h-8",children:e.jsx(H,{})}),e.jsxs(U,{children:[e.jsx(x,{value:"10",children:"10"}),e.jsx(x,{value:"25",children:"25"}),e.jsx(x,{value:"50",children:"50"})]})]})]})]}),D>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(A,{variant:"outline",size:"sm",disabled:u===1,onClick:()=>y(u-1),children:"Previous"}),e.jsx(A,{variant:"outline",size:"sm",disabled:u===D,onClick:()=>y(u+1),children:"Next"})]})]})]})]})}function Le({data:a,isLoading:i,onLearnMore:o}){const{translate:r}=Z(),{formatMoney:c}=K(),[m,O]=l.useState(null),[h,N]=l.useState("date"),[j,g]=l.useState("desc"),[u,y]=l.useState("all"),[d,v]=l.useState(1),[f,E]=l.useState(10),b=t=>{O(m===t?null:t)},D=t=>{h===t?g(j==="asc"?"desc":"asc"):(N(t),g("desc")),v(1)},P=t=>{E(parseInt(t)),v(1)},w=l.useMemo(()=>{let t=[...a];return u!=="all"&&(t=t.filter(p=>p.status===u)),h&&t.sort((p,k)=>{let T=0;switch(h){case"date":T=new Date(p.date).getTime()-new Date(k.date).getTime();break;case"amount":T=p.amount-k.amount;break;case"itemCount":T=p.itemCount-k.itemCount;break;case"status":T=p.status.localeCompare(k.status);break}return j==="asc"?T:-T}),t},[a,u,h,j]),n=Math.ceil(w.length/f),C=w.slice((d-1)*f,d*f),M=[{id:"expand",header:()=>e.jsx("span",{className:"sr-only",children:r("Details")}),className:"w-8 px-2",cell:t=>t.items.length>0?e.jsx(A,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>b(t.id),"aria-expanded":m===t.id,"aria-label":r("What this payment included"),children:m===t.id?e.jsx(de,{className:"h-4 w-4"}):e.jsx(oe,{className:"h-4 w-4"})}):null},{id:"date",header:r("Date"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm",children:$(t.date)})},{id:"amount",header:r("Amount"),sortable:!0,className:"text-right",cell:t=>e.jsx("span",{className:"font-medium",children:c(t.amount,t.currency)})},{id:"itemCount",header:r("Items"),sortable:!0,className:"text-right",cell:t=>e.jsxs("span",{className:"text-sm text-muted-foreground",children:[t.itemCount," ",t.itemCount===1?"item":"items"]})},{id:"status",header:r("Status"),sortable:!0,cell:t=>e.jsx("span",{className:ne[t.status],children:te[t.status]})}],S=t=>m===t.id&&t.items.length>0?e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium mb-2 text-muted-foreground",children:"Included in this payment:"}),e.jsx("div",{className:"space-y-1",children:t.items.map(p=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 py-1 px-2 rounded hover:bg-muted/50",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4",children:[e.jsx("span",{className:"text-sm",children:p.description}),e.jsx("span",{className:"text-muted-foreground text-xs",children:$(p.date)})]}),e.jsx("span",{className:"font-medium",children:c(p.amount,t.currency)})]},p.id))})]}):null;return e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(V,{children:["Payment History",e.jsx(R,{topic:"collab-earnings-payments",onLearnMore:o})]}),e.jsx(J,{children:"Your payout history. Open a payment to see what it included."})]}),e.jsxs(B,{value:u,onValueChange:t=>{y(t),v(1)},children:[e.jsx(z,{"aria-label":r("Filter by status"),className:"w-[160px]",children:e.jsx(H,{placeholder:r("Status")})}),e.jsxs(U,{children:[e.jsx(x,{value:"all",children:"All Statuses"}),e.jsx(x,{value:"pending",children:"Not paid yet"}),e.jsx(x,{value:"paid",children:"Paid"}),e.jsx(x,{value:"failed",children:"Failed"})]})]})]})}),e.jsxs(L,{children:[e.jsx(ae,{columns:M,data:C,isLoading:i,emptyMessage:r("No payments found."),sortField:h??void 0,sortOrder:j,onSort:t=>D(t),renderExpanded:S}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",w.length===0?0:(d-1)*f+1," to"," ",Math.min(d*f,w.length)," of ",w.length," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Per page:"}),e.jsxs(B,{value:f.toString(),onValueChange:P,children:[e.jsx(z,{"aria-label":r("Rows per page"),className:"w-[80px] h-8",children:e.jsx(H,{})}),e.jsxs(U,{children:[e.jsx(x,{value:"10",children:"10"}),e.jsx(x,{value:"25",children:"25"}),e.jsx(x,{value:"50",children:"50"})]})]})]})]}),n>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(A,{variant:"outline",size:"sm",disabled:d===1,onClick:()=>v(d-1),children:"Previous"}),e.jsx(A,{variant:"outline",size:"sm",disabled:d===n,onClick:()=>v(d+1),children:"Next"})]})]})]})]})}function Y({amounts:a,colorClass:i}){const{formatMoney:o}=K();return e.jsx("div",{className:"space-y-1",children:a.map((r,c)=>e.jsx("div",{className:c===0?`text-2xl font-bold ${i||""}`:"text-sm text-muted-foreground",children:o(r.value,r.currency)},r.currency))})}function Me(){const{translate:a}=Z(),{formatMoney:i,formatCompactMoney:o,currencyName:r}=K(),{collaboratorId:c,balanceSummary:m,moneyTruncated:O,isLoadingReporting:h,rewards:N,isLoadingRewards:j,payouts:g,isLoadingPayouts:u,fetchDashboardSummary:y}=se(),[d,v]=l.useState("overview"),[f,E]=l.useState("6"),[b,D]=l.useState(null),P=s=>D(s);l.useEffect(()=>{c&&y()},[c,y]);const w=l.useMemo(()=>pe(N,g,f),[N,g,f]),n=m.map(s=>s.currency),C=n.map((s,re)=>({dataKey:s,name:r(s),color:X[re%X.length],formatValue:le=>o(le,s)})),M=m.map(s=>({value:s.payable,currency:s.currency})),S=m.map(s=>({value:s.awaiting,currency:s.currency})),t=m.map(s=>({value:s.paid,currency:s.currency})),p=m.map(s=>({value:s.earned,currency:s.currency})),k=l.useMemo(()=>je(g),[g]),T=l.useMemo(()=>N.map(s=>Te(s,k)),[N,k]),W=l.useMemo(()=>g.map(s=>Pe(s,N)),[g,N]);return h&&m.length===0?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(_,{})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Earnings",e.jsx(R,{topic:"collab-earnings",onLearnMore:P})]}),e.jsx("p",{className:"text-muted-foreground",children:"Track your commissions and payment history."})]}),O&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a("You have more rewards than this page can add up. The totals and tables below cover your most recent rewards only.")}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsxs("div",{className:"text-sm text-muted-foreground mb-2",children:["Payable",e.jsx(R,{topic:"collab-earnings-confirmed",onLearnMore:P})]}),e.jsx(Y,{amounts:M,colorClass:"text-green-600"}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"approved, not paid yet"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsxs("div",{className:"text-sm text-muted-foreground mb-2",children:["Awaiting approval",e.jsx(R,{topic:"collab-earnings-pending",onLearnMore:P})]}),e.jsx(Y,{amounts:S,colorClass:"text-yellow-600"}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"sales not approved yet"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground mb-2",children:"Paid"}),e.jsx(Y,{amounts:t}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"paid out to you"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground mb-2",children:"Lifetime Earnings"}),e.jsx(Y,{amounts:p}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"payable plus paid"})]})})]}),e.jsxs(ie,{value:d,onValueChange:s=>v(s),children:[e.jsxs(ce,{children:[e.jsx(G,{value:"overview",children:"Overview"}),e.jsx(G,{value:"commissions",children:"Commissions"}),e.jsx(G,{value:"payments",children:"Payments"})]}),e.jsxs(q,{value:"overview",className:"space-y-6 mt-4",children:[e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(V,{children:"Earnings Over Time"}),e.jsx(J,{children:"Payable and paid rewards by the date of the sale"})]}),e.jsxs(B,{value:f,onValueChange:E,children:[e.jsx(z,{className:"w-[160px]","aria-label":"Time range",children:e.jsx(H,{})}),e.jsx(U,{children:Se.map(s=>e.jsx(x,{value:s.value,children:s.label},s.value))})]})]})}),e.jsx(L,{children:w.length>0?e.jsx(we,{data:w,height:280,series:C,formatValue:s=>n.length===1?o(s,n[0]):"",showGrid:!0,showLegend:!0}):e.jsx("div",{className:"flex items-center justify-center h-[280px] text-muted-foreground",children:h?e.jsx(_,{}):a("No data available")})})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs(I,{children:[e.jsx(F,{children:e.jsx(V,{className:"text-base",children:"Recent Commissions"})}),e.jsxs(L,{children:[j?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(_,{})}):T.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No commissions yet."}):e.jsx("div",{className:"space-y-2",children:T.slice(0,5).map(s=>e.jsxs("div",{className:"flex items-center justify-between py-2 border-b last:border-0",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-mono text-sm",children:s.orderId}),e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:$(s.date)})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:i(s.commission,s.currency)}),e.jsx("span",{className:s.statusBadge+" text-xs",children:s.statusLabel})]})]},s.id))}),e.jsx(A,{variant:"link",className:"px-0 mt-2",onClick:()=>v("commissions"),children:"View all commissions →"})]})]}),e.jsxs(I,{children:[e.jsx(F,{children:e.jsx(V,{className:"text-base",children:"Recent Payments"})}),e.jsxs(L,{children:[u?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(_,{})}):W.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No payments yet."}):e.jsx("div",{className:"space-y-2",children:W.slice(0,5).map(s=>e.jsxs("div",{className:"flex items-center justify-between py-2 border-b last:border-0",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm",children:$(s.date)}),e.jsxs("span",{className:"text-xs text-muted-foreground ml-2",children:[s.itemCount," ",s.itemCount===1?"item":"items"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:i(s.amount,s.currency)}),e.jsx("span",{className:ne[s.status]+" text-xs",children:te[s.status]})]})]},s.id))}),e.jsx(A,{variant:"link",className:"px-0 mt-2",onClick:()=>v("payments"),children:"View payment history →"})]})]})]})]}),e.jsx(q,{value:"commissions",className:"mt-4",children:e.jsx(Ie,{data:T,isLoading:j,onLearnMore:P})}),e.jsx(q,{value:"payments",className:"mt-4",children:e.jsx(Le,{data:W,isLoading:u,onLearnMore:P})})]}),e.jsx(Ce,{topic:b,open:!!b,onOpenChange:s=>!s&&D(null)})]})}window.sirenConfig&&me({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function De(){const a=se(i=>i.initialize);return l.useEffect(()=>{const i=window.sirenConfig;be(i)&&a(i.collaboratorId,{trackingId:i.trackingId||"",urlReference:i.urlReference||"ref",baseUrl:i.baseUrl||""})},[a]),e.jsx("div",{className:"p-4",children:e.jsx(Me,{})})}const ee=document.getElementById("siren-collaborator-rewards");ee&&ue.createRoot(ee).render(e.jsx(l.StrictMode,{children:e.jsxs(xe,{children:[e.jsx(he,{position:"top-right",richColors:!0}),e.jsx(De,{})]})}));
     1import{u as Z,r as l,j as e,p as _,C as I,t as L,_ as ie,$ as ce,a0 as G,a1 as q,q as F,s as V,x as J,S as B,e as z,f as H,g as U,h as x,B as A,a2 as de,a3 as oe,E as me,F as ue,Z as xe,T as he}from"./shared/wordpress-admin-D_eccjaB.js";import{u as se,e as pe,a as je,p as ge,U as fe,r as ve,b as Ne,m as ye,c as Q,i as be}from"./shared/collaborator-dashboard-o5ivsW6s.js";import{H as R,D as ae}from"./shared/HelpTooltip-YN4U7Ym7.js";import"./shared/registries-CatPSk3G.js";import{A as we}from"./shared/AreaChart-CUGMAtch.js";import{H as Ce}from"./shared/HelpDrawer-BOa5Le1J.js";import{u as K}from"./shared/usePortalMoney-l-aykMsd.js";import"./shared/react-Rq6nbqOn.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/markdown-renderer-1IfYWwRA.js";import"./shared/useMoneyFormatter-B6sdhxKB.js";const X=["#22c55e","#eab308","#a855f7","#0ea5e9","#ef4444"],Se=[{value:"this-month",label:"This month"},{value:"last-month",label:"Last month"},{value:"3",label:"Last 3 months"},{value:"6",label:"Last 6 months"},{value:"12",label:"Last 12 months"}];function Te(a,i){const o=ge(a,i);return{id:a.id,orderId:a.conversionId?`#${a.conversionId}`:`#${a.id}`,orderTotal:a.conversionAmount??a.value,orderCurrency:a.conversionAmount!=null?fe:Q(a),commission:a.value,currency:Q(a),statusKey:ye(a.status,o)??a.status,statusLabel:Ne(a.status,o),statusBadge:ve(a.status,o),date:a.dateCreated,programName:a.programName}}function Pe(a,i){const o={paid:"paid",unpaid:"pending",failed:"failed"},r=i.filter(c=>c.payoutId===a.id);return{id:a.id,amount:a.value,currency:a.currency,itemCount:r.length,status:o[a.status]??"pending",date:a.datePaid||a.dateCreated,items:r.map(c=>({id:c.id,description:c.conversionId?`Order #${c.conversionId}`:`Reward #${c.id}`,amount:c.value,date:c.dateCreated}))}}const te={pending:"Not paid yet",paid:"Paid",failed:"Failed"},ne={pending:"status-badge status-yellow",paid:"status-badge status-green",failed:"status-badge status-red"};function $(a){return new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}function Ie({data:a,isLoading:i,onLearnMore:o}){const{translate:r}=Z(),{formatMoney:c}=K(),[m,O]=l.useState("all"),[h,N]=l.useState("date"),[j,g]=l.useState("desc"),[u,y]=l.useState(1),[d,v]=l.useState(10),f=n=>{h===n?g(j==="asc"?"desc":"asc"):(N(n),g("desc")),y(1)},E=n=>{v(parseInt(n)),y(1)},b=l.useMemo(()=>{let n=[...a];return m!=="all"&&(n=n.filter(C=>C.statusKey===m)),h&&n.sort((C,M)=>{let S=0;switch(h){case"date":S=new Date(C.date).getTime()-new Date(M.date).getTime();break;case"orderTotal":S=C.orderTotal-M.orderTotal;break;case"commission":S=C.commission-M.commission;break;case"status":S=C.statusLabel.localeCompare(M.statusLabel);break}return j==="asc"?S:-S}),n},[a,m,h,j]),D=Math.ceil(b.length/d),P=b.slice((u-1)*d,u*d),w=[{id:"date",header:r("Date"),sortable:!0,cell:n=>e.jsx("span",{className:"text-sm text-muted-foreground",children:$(n.date)})},{id:"order",header:r("Order"),cell:n=>e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"font-mono text-sm",children:n.orderId}),n.programName&&e.jsx("span",{className:"block text-xs text-muted-foreground",children:n.programName})]})},{id:"orderTotal",header:r("Order Total"),sortable:!0,className:"text-right",cell:n=>e.jsx("span",{className:"text-sm",children:c(n.orderTotal,n.orderCurrency)})},{id:"commission",header:r("Your Commission"),sortable:!0,className:"text-right",headerAdornment:e.jsx(R,{topic:"collab-earnings-commission-amount",onLearnMore:o}),cell:n=>e.jsx("span",{className:"font-medium",children:c(n.commission,n.currency)})},{id:"status",header:r("Status"),sortable:!0,headerAdornment:e.jsx(R,{topic:"collab-earnings-status",onLearnMore:o}),cell:n=>e.jsx("span",{className:n.statusBadge,children:n.statusLabel})}];return e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(V,{children:["Commissions",e.jsx(R,{topic:"collab-earnings-commissions",onLearnMore:o})]}),e.jsx(J,{children:"Sales attributed to you and your commission earned"})]}),e.jsxs(B,{value:m,onValueChange:n=>{O(n),y(1)},children:[e.jsx(z,{"aria-label":r("Filter by status"),className:"w-[160px]",children:e.jsx(H,{placeholder:r("Status")})}),e.jsxs(U,{children:[e.jsx(x,{value:"all",children:"All Statuses"}),e.jsx(x,{value:"awaiting",children:"Awaiting approval"}),e.jsx(x,{value:"payable",children:"Payable"}),e.jsx(x,{value:"paid",children:"Paid"}),e.jsx(x,{value:"rejected",children:"Rejected"})]})]})]})}),e.jsxs(L,{children:[e.jsx(ae,{columns:w,data:P,isLoading:i,emptyMessage:r("No commissions found."),sortField:h??void 0,sortOrder:j,onSort:n=>f(n)}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",b.length===0?0:(u-1)*d+1," to"," ",Math.min(u*d,b.length)," of ",b.length," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Per page:"}),e.jsxs(B,{value:d.toString(),onValueChange:E,children:[e.jsx(z,{"aria-label":r("Rows per page"),className:"w-[80px] h-8",children:e.jsx(H,{})}),e.jsxs(U,{children:[e.jsx(x,{value:"10",children:"10"}),e.jsx(x,{value:"25",children:"25"}),e.jsx(x,{value:"50",children:"50"})]})]})]})]}),D>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(A,{variant:"outline",size:"sm",disabled:u===1,onClick:()=>y(u-1),children:"Previous"}),e.jsx(A,{variant:"outline",size:"sm",disabled:u===D,onClick:()=>y(u+1),children:"Next"})]})]})]})]})}function Le({data:a,isLoading:i,onLearnMore:o}){const{translate:r}=Z(),{formatMoney:c}=K(),[m,O]=l.useState(null),[h,N]=l.useState("date"),[j,g]=l.useState("desc"),[u,y]=l.useState("all"),[d,v]=l.useState(1),[f,E]=l.useState(10),b=t=>{O(m===t?null:t)},D=t=>{h===t?g(j==="asc"?"desc":"asc"):(N(t),g("desc")),v(1)},P=t=>{E(parseInt(t)),v(1)},w=l.useMemo(()=>{let t=[...a];return u!=="all"&&(t=t.filter(p=>p.status===u)),h&&t.sort((p,k)=>{let T=0;switch(h){case"date":T=new Date(p.date).getTime()-new Date(k.date).getTime();break;case"amount":T=p.amount-k.amount;break;case"itemCount":T=p.itemCount-k.itemCount;break;case"status":T=p.status.localeCompare(k.status);break}return j==="asc"?T:-T}),t},[a,u,h,j]),n=Math.ceil(w.length/f),C=w.slice((d-1)*f,d*f),M=[{id:"expand",header:()=>e.jsx("span",{className:"sr-only",children:r("Details")}),className:"w-8 px-2",cell:t=>t.items.length>0?e.jsx(A,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>b(t.id),"aria-expanded":m===t.id,"aria-label":r("What this payment included"),children:m===t.id?e.jsx(de,{className:"h-4 w-4"}):e.jsx(oe,{className:"h-4 w-4"})}):null},{id:"date",header:r("Date"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm",children:$(t.date)})},{id:"amount",header:r("Amount"),sortable:!0,className:"text-right",cell:t=>e.jsx("span",{className:"font-medium",children:c(t.amount,t.currency)})},{id:"itemCount",header:r("Items"),sortable:!0,className:"text-right",cell:t=>e.jsxs("span",{className:"text-sm text-muted-foreground",children:[t.itemCount," ",t.itemCount===1?"item":"items"]})},{id:"status",header:r("Status"),sortable:!0,cell:t=>e.jsx("span",{className:ne[t.status],children:te[t.status]})}],S=t=>m===t.id&&t.items.length>0?e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium mb-2 text-muted-foreground",children:"Included in this payment:"}),e.jsx("div",{className:"space-y-1",children:t.items.map(p=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 py-1 px-2 rounded hover:bg-muted/50",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4",children:[e.jsx("span",{className:"text-sm",children:p.description}),e.jsx("span",{className:"text-muted-foreground text-xs",children:$(p.date)})]}),e.jsx("span",{className:"font-medium",children:c(p.amount,t.currency)})]},p.id))})]}):null;return e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(V,{children:["Payment History",e.jsx(R,{topic:"collab-earnings-payments",onLearnMore:o})]}),e.jsx(J,{children:"Your payout history. Open a payment to see what it included."})]}),e.jsxs(B,{value:u,onValueChange:t=>{y(t),v(1)},children:[e.jsx(z,{"aria-label":r("Filter by status"),className:"w-[160px]",children:e.jsx(H,{placeholder:r("Status")})}),e.jsxs(U,{children:[e.jsx(x,{value:"all",children:"All Statuses"}),e.jsx(x,{value:"pending",children:"Not paid yet"}),e.jsx(x,{value:"paid",children:"Paid"}),e.jsx(x,{value:"failed",children:"Failed"})]})]})]})}),e.jsxs(L,{children:[e.jsx(ae,{columns:M,data:C,isLoading:i,emptyMessage:r("No payments found."),sortField:h??void 0,sortOrder:j,onSort:t=>D(t),renderExpanded:S}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",w.length===0?0:(d-1)*f+1," to"," ",Math.min(d*f,w.length)," of ",w.length," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Per page:"}),e.jsxs(B,{value:f.toString(),onValueChange:P,children:[e.jsx(z,{"aria-label":r("Rows per page"),className:"w-[80px] h-8",children:e.jsx(H,{})}),e.jsxs(U,{children:[e.jsx(x,{value:"10",children:"10"}),e.jsx(x,{value:"25",children:"25"}),e.jsx(x,{value:"50",children:"50"})]})]})]})]}),n>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(A,{variant:"outline",size:"sm",disabled:d===1,onClick:()=>v(d-1),children:"Previous"}),e.jsx(A,{variant:"outline",size:"sm",disabled:d===n,onClick:()=>v(d+1),children:"Next"})]})]})]})]})}function Y({amounts:a,colorClass:i}){const{formatMoney:o}=K();return e.jsx("div",{className:"space-y-1",children:a.map((r,c)=>e.jsx("div",{className:c===0?`text-2xl font-bold ${i||""}`:"text-sm text-muted-foreground",children:o(r.value,r.currency)},r.currency))})}function Me(){const{translate:a}=Z(),{formatMoney:i,formatCompactMoney:o,currencyName:r}=K(),{collaboratorId:c,balanceSummary:m,moneyTruncated:O,isLoadingReporting:h,rewards:N,isLoadingRewards:j,payouts:g,isLoadingPayouts:u,fetchDashboardSummary:y}=se(),[d,v]=l.useState("overview"),[f,E]=l.useState("6"),[b,D]=l.useState(null),P=s=>D(s);l.useEffect(()=>{c&&y()},[c,y]);const w=l.useMemo(()=>pe(N,g,f),[N,g,f]),n=m.map(s=>s.currency),C=n.map((s,re)=>({dataKey:s,name:r(s),color:X[re%X.length],formatValue:le=>o(le,s)})),M=m.map(s=>({value:s.payable,currency:s.currency})),S=m.map(s=>({value:s.awaiting,currency:s.currency})),t=m.map(s=>({value:s.paid,currency:s.currency})),p=m.map(s=>({value:s.earned,currency:s.currency})),k=l.useMemo(()=>je(g),[g]),T=l.useMemo(()=>N.map(s=>Te(s,k)),[N,k]),W=l.useMemo(()=>g.map(s=>Pe(s,N)),[g,N]);return h&&m.length===0?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(_,{})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Earnings",e.jsx(R,{topic:"collab-earnings",onLearnMore:P})]}),e.jsx("p",{className:"text-muted-foreground",children:"Track your commissions and payment history."})]}),O&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a("You have more rewards than this page can add up. The totals and tables below cover your most recent rewards only.")}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsxs("div",{className:"text-sm text-muted-foreground mb-2",children:["Payable",e.jsx(R,{topic:"collab-earnings-confirmed",onLearnMore:P})]}),e.jsx(Y,{amounts:M,colorClass:"text-green-600"}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"approved, not paid yet"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsxs("div",{className:"text-sm text-muted-foreground mb-2",children:["Awaiting approval",e.jsx(R,{topic:"collab-earnings-pending",onLearnMore:P})]}),e.jsx(Y,{amounts:S,colorClass:"text-yellow-600"}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"sales not approved yet"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground mb-2",children:"Paid"}),e.jsx(Y,{amounts:t}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"paid out to you"})]})}),e.jsx(I,{children:e.jsxs(L,{className:"pt-6",children:[e.jsx("div",{className:"text-sm text-muted-foreground mb-2",children:"Lifetime Earnings"}),e.jsx(Y,{amounts:p}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"payable plus paid"})]})})]}),e.jsxs(ie,{value:d,onValueChange:s=>v(s),children:[e.jsxs(ce,{children:[e.jsx(G,{value:"overview",children:"Overview"}),e.jsx(G,{value:"commissions",children:"Commissions"}),e.jsx(G,{value:"payments",children:"Payments"})]}),e.jsxs(q,{value:"overview",className:"space-y-6 mt-4",children:[e.jsxs(I,{children:[e.jsx(F,{children:e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(V,{children:"Earnings Over Time"}),e.jsx(J,{children:"Payable and paid rewards by the date of the sale"})]}),e.jsxs(B,{value:f,onValueChange:E,children:[e.jsx(z,{className:"w-[160px]","aria-label":"Time range",children:e.jsx(H,{})}),e.jsx(U,{children:Se.map(s=>e.jsx(x,{value:s.value,children:s.label},s.value))})]})]})}),e.jsx(L,{children:w.length>0?e.jsx(we,{data:w,height:280,series:C,formatValue:s=>n.length===1?o(s,n[0]):"",showGrid:!0,showLegend:!0}):e.jsx("div",{className:"flex items-center justify-center h-[280px] text-muted-foreground",children:h?e.jsx(_,{}):a("No data available")})})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs(I,{children:[e.jsx(F,{children:e.jsx(V,{className:"text-base",children:"Recent Commissions"})}),e.jsxs(L,{children:[j?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(_,{})}):T.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No commissions yet."}):e.jsx("div",{className:"space-y-2",children:T.slice(0,5).map(s=>e.jsxs("div",{className:"flex items-center justify-between py-2 border-b last:border-0",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-mono text-sm",children:s.orderId}),e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:$(s.date)})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:i(s.commission,s.currency)}),e.jsx("span",{className:s.statusBadge+" text-xs",children:s.statusLabel})]})]},s.id))}),e.jsx(A,{variant:"link",className:"px-0 mt-2",onClick:()=>v("commissions"),children:"View all commissions →"})]})]}),e.jsxs(I,{children:[e.jsx(F,{children:e.jsx(V,{className:"text-base",children:"Recent Payments"})}),e.jsxs(L,{children:[u?e.jsx("div",{className:"flex items-center justify-center py-4",children:e.jsx(_,{})}):W.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No payments yet."}):e.jsx("div",{className:"space-y-2",children:W.slice(0,5).map(s=>e.jsxs("div",{className:"flex items-center justify-between py-2 border-b last:border-0",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm",children:$(s.date)}),e.jsxs("span",{className:"text-xs text-muted-foreground ml-2",children:[s.itemCount," ",s.itemCount===1?"item":"items"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:i(s.amount,s.currency)}),e.jsx("span",{className:ne[s.status]+" text-xs",children:te[s.status]})]})]},s.id))}),e.jsx(A,{variant:"link",className:"px-0 mt-2",onClick:()=>v("payments"),children:"View payment history →"})]})]})]})]}),e.jsx(q,{value:"commissions",className:"mt-4",children:e.jsx(Ie,{data:T,isLoading:j,onLearnMore:P})}),e.jsx(q,{value:"payments",className:"mt-4",children:e.jsx(Le,{data:W,isLoading:u,onLearnMore:P})})]}),e.jsx(Ce,{topic:b,open:!!b,onOpenChange:s=>!s&&D(null)})]})}window.sirenConfig&&me({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});function De(){const a=se(i=>i.initialize);return l.useEffect(()=>{const i=window.sirenConfig;be(i)&&a(i.collaboratorId,{trackingId:i.trackingId||"",urlReference:i.urlReference||"ref",baseUrl:i.baseUrl||""})},[a]),e.jsx("div",{className:"p-4",children:e.jsx(Me,{})})}const ee=document.getElementById("siren-collaborator-rewards");ee&&ue.createRoot(ee).render(e.jsx(l.StrictMode,{children:e.jsxs(xe,{children:[e.jsx(he,{position:"top-right",richColors:!0}),e.jsx(De,{})]})}));
  • siren-affiliates/trunk/frontend/collaborators.js

    r3775642 r3788740  
    1 import{c as ft,u as ee,a as Xe,b as _t,r as l,j as e,L as B,B as j,I as fe,S as ie,d as ne,e as de,f as ce,g as T,D as $e,h as Ee,i as Fe,k as Te,l as Oe,m as Be,n as jt,o as ze,C as H,p as _,q as K,s as J,t as E,v as X,X as bt,w as vt,x as xe,y as Kt,z as Jt,A as Xt,E as Yt,F as Qt,T as Zt,R as es,G as ge}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as Ye,g as ot,v as ts,r as it,p as ss}from"./shared/validation-f7jbdrjp.js";import{u as yt,a as Ct,D as as,b as nt,p as rs,P as dt,S as ls}from"./shared/useStagedMembership-C1sNy_D6.js";import{u as os}from"./shared/unshipped-CGZcvpGp.js";import{c as St}from"./shared/react-zvEYxxW2.js";import{F as is,H as je,a as ns,B as ds,D as Ke,P as cs}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as Nt}from"./shared/ActivityDrawer-iYDgZTH3.js";import{c as Je}from"./shared/collaborators-BvingK76.js";import{u as us}from"./shared/useListRequest-CKMUCtxK.js";import{P as wt}from"./shared/plus-xgV5QLEC.js";import{S as ms,W as hs}from"./shared/WordPressRouter-ifxiIFvs.js";import{F as we}from"./shared/form-field-Dbux2jvw.js";import{u as ps}from"./shared/conversions-HMIw6T3R.js";import{u as gs}from"./shared/obligations-1RIdX1q5.js";import{u as xs}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{p as fs,B as js}from"./shared/properties-Cx8gxvGK.js";import{C as kt}from"./shared/confirm-dialog-DM12emMj.js";import{u as bs}from"./shared/IntegrationPreview-BM-XjKI4.js";import{l as Pt,a as vs,s as ys,S as Cs,U as Ss,b as Ns,c as ws}from"./shared/CouponDialogs-Ci2bD_jZ.js";import{A as ks}from"./shared/arrow-left-W0B3m2vw.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/registries-Ql2SZeKd.js";/**
     1import{c as At,u as V,j as e,B as x,a as He,b as We,d as ds,r as l,L as F,I as ue,S as oe,e as ne,f as ie,g as de,h as R,D as me,i as he,k as pe,l as xe,m as ge,n as fe,o as Lt,p as Ye,C as Y,q as K,s as J,t as X,v as E,w as U,X as $t,x as ce,y as rt,z as cs,A as us,E as ms,F as hs,T as ps,R as xs,G as le}from"./shared/wordpress-admin-D_eccjaB.js";import{u as ot,g as ft,v as gs,r as jt,p as fs}from"./shared/validation-D6cKTXRt.js";import{u as Et,a as Rt,D as js,b as bt,P as vt,S as bs}from"./shared/useStagedMembership-pDKVh3Wd.js";import{u as vs}from"./shared/unshipped-CGZcvpGp.js";import{c as Tt}from"./shared/react-Rq6nbqOn.js";import{F as ys,H as De,a as Cs,B as Ns,D as lt,P as Ft,T as ws}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as Ot}from"./shared/ActivityDrawer-BZxDAdLe.js";import{c as je,a as qe}from"./shared/collaboratorDisplayName-DvmzsaZc.js";import{u as Ss}from"./shared/useListRequest-BAYNcD8F.js";import{U as ks}from"./shared/upload-ZoYz9lGb.js";import{P as nt}from"./shared/plus-8fF9_2v-.js";import{S as Is,W as Ps}from"./shared/WordPressRouter-CAYzko7X.js";import{p as Ds,i as As,s as yt,C as Ls}from"./shared/CsvImport-Dumku5_r.js";import{F as ze}from"./shared/form-field-CrfWqu5t.js";import{u as $s}from"./shared/conversions-D67NHe2F.js";import{u as Es}from"./shared/obligations-tU6cfrpO.js";import{u as Rs}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{p as Ts}from"./shared/properties-ByxWotcN.js";import{C as zt}from"./shared/confirm-dialog-BdfYPOfc.js";import{u as Fs}from"./shared/IntegrationPreview-VmIfRPju.js";import{l as Bt,a as Os,s as zs,S as Bs,U as Ms,b as Gs,c as Us}from"./shared/CouponDialogs-BS2YEuir.js";import{B as Vs}from"./shared/BulkPickerModal-DpL-mI_R.js";import{A as Mt}from"./shared/arrow-left-XvsxLAWy.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/collaborator-groups-BP0hAJf8.js";import"./shared/triangle-alert-BXQaBsm-.js";import"./shared/conversion.schema-BXGiWhtb.js";import"./shared/clipboard-Ch4rpUJU.js";import"./shared/registries-CatPSk3G.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const Ps=ft("Globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/**
     6 */const _s=At("Globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/**
    77 * @license lucide-react v0.469.0 - ISC
    88 *
    99 * This source code is licensed under the ISC license.
    1010 * See the LICENSE file in the root directory of this source tree.
    11  */const Is=ft("Shuffle",[["path",{d:"m18 14 4 4-4 4",key:"10pe0f"}],["path",{d:"m18 2 4 4-4 4",key:"pucp1d"}],["path",{d:"M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22",key:"1ailkh"}],["path",{d:"M2 6h1.972a4 4 0 0 1 3.6 2.2",key:"km57vx"}],["path",{d:"M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45",key:"os18l9"}]]),Z=os("Distributors"),Ds=St(()=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,hasLoaded:!1,isSubmitting:!1,error:null,current:null,fetchList:async()=>{},fetchOne:async()=>{},create:Z.create,update:Z.update,delete:Z.delete,bulkActivate:Z.bulkActivate,bulkDeactivate:Z.bulkDeactivate,bulkDelete:Z.bulkDelete,bulkPermanentDelete:Z.bulkPermanentDelete,bulkRestore:Z.bulkRestore,clearCurrent:()=>{},clearError:()=>{}})),ct={distributors:!1,customerOwnership:!1},As={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red",deleted:"status-badge status-red"};function ut(){var lt;const{translate:t}=ee(),s={active:t("Active"),pending:t("Pending"),inactive:t("Inactive"),rejected:t("Rejected"),deleted:t("Trashed")},h=Xe(),[u,p]=_t(),{items:f,total:m,page:n,perPage:R,totalPages:P,isLoading:k,isSubmitting:r,error:y,fetchList:N,delete:I,bulkActivate:b,bulkDeactivate:c,bulkAddToProgram:g,bulkRemoveFromProgram:w,bulkAddToGroup:F,bulkRemoveFromGroup:o,bulkAddToDistributor:C,bulkRemoveFromDistributor:O,bulkDelete:te,bulkPermanentDelete:se,bulkRestore:Ge,bulkSendSignupEmail:Ue,update:Ve}=Ye(),{items:ue,fetchList:ae}=yt(),{items:Y,fetchList:ke}=Ct(),{items:Q,fetchList:me}=Ds(),he=u.get("status")||"all",M=u.get("programId")||"",q=u.get("distributorId")||"",[re,Pe]=l.useState(""),[le,be]=l.useState(""),[$,W]=l.useState(he),[z,pe]=l.useState(M),[G,U]=l.useState(q),[d,oe]=l.useState(null),[Ie,De]=l.useState(10),[i,x]=l.useState("fullName"),[S,ve]=l.useState("asc"),[v,L]=l.useState(new Set),D=$==="deleted",[ye,Ce]=l.useState(null),[Ae,Qe]=l.useState(""),[Se,qe]=l.useState(null),[Le,Ze]=l.useState(""),[Ne,We]=l.useState(null),[Re,et]=l.useState("");l.useEffect(()=>{ae({perPage:100,status:"active,inactive,pending,draft",fields:["id","name","status","collaboratorGroupId"]})},[ae,ke,me]),l.useEffect(()=>{const a=u.get("status"),A=u.get("programId");a&&a!==$&&W(a),A&&A!==z&&pe(A);const V=u.get("distributorId");V&&V!==G&&U(V)},[u,$,z,G]),l.useEffect(()=>{L(new Set)},[$]);const tt=us(N,{perPage:Ie,search:le,orderBy:i,order:S,status:$==="all"?"active,pending,inactive,rejected":$,programId:z?parseInt(z):void 0,distributorId:G?parseInt(G):void 0}),st=()=>{if(re.trim()===le.trim()){tt.refetch();return}be(re)},at=a=>tt.setPage(a),It=a=>De(parseInt(a)),He=a=>{W(a),a!=="all"?u.set("status",a):u.delete("status"),p(u)},Dt=a=>{const A=i===a&&S==="asc"?"desc":"asc";x(a),ve(A)},At=(a,A)=>{var V;return{email:a.email,fullName:a.fullName,nickname:a.nickname,status:A,programIds:(V=a.programs)==null?void 0:V.map(Ht=>Ht.id),distributorIds:a.distributorId?[a.distributorId]:void 0}},Lt=async(a,A)=>{await Ve(a.id,At(a,A))},Rt=async()=>{if(d){if(d.status==="deleted"||D){await se([d.id]);return}await I(d.id)}},rt=f.filter(a=>v.has(a.id)).map(a=>a.fullName||a.email),$t=a=>{h(`/collaborators/${a.id}/edit`)},Et=async()=>{await b(Array.from(v)),L(new Set)},Ft=async()=>{await c(Array.from(v)),L(new Set)},Tt=async()=>{await te(Array.from(v)),L(new Set)},Ot=async()=>{await Ge(Array.from(v)),L(new Set)},Bt=async()=>{try{await Ue(Array.from(v)),L(new Set)}catch{}},Mt=async()=>{await se(Array.from(v)),L(new Set)},zt=async()=>{if(!Ae)return;const a=parseInt(Ae);ye==="add"?await g(Array.from(v),a):ye==="remove"&&await w(Array.from(v),a),L(new Set),Ce(null),Qe("")},Gt=async()=>{if(!Le)return;const a=parseInt(Le);Se==="add"?await F(Array.from(v),a):Se==="remove"&&await o(Array.from(v),a),L(new Set),qe(null),Ze("")},Ut=async()=>{if(!Re)return;const a=parseInt(Re);Ne==="add"?await C(Array.from(v),a):Ne==="remove"&&await O(Array.from(v),a),L(new Set),We(null),et("")},Vt=[{id:"fullName",header:t("Name"),sortable:!0,cell:a=>a.fullName},{id:"id",header:t("ID"),cell:a=>a.id},{id:"referralCode",header:t("Referral Code"),cell:a=>a.referralCode||e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"email",header:t("Email"),sortable:!0,cell:a=>a.email},{id:"programs",header:t("Programs"),cell:a=>{var A;return e.jsx("div",{className:"flex flex-wrap gap-1",children:((A=a.programs)==null?void 0:A.map(V=>e.jsx(B,{to:`/programs/${V.id}/view`,className:"text-primary hover:underline text-sm",children:V.name},V.id)))||"-"})}},{id:"unfulfilledObligationCount",header:t("Unpaid"),cell:a=>e.jsx(B,{to:`/obligations?collaboratorId=${a.id}&status=approved`,className:"text-primary hover:underline",children:a.unfulfilledObligationCount??0})},{id:"fulfilledObligationCount",header:t("Paid"),cell:a=>e.jsx(B,{to:`/obligations?collaboratorId=${a.id}&status=complete`,className:"text-primary hover:underline",children:a.fulfilledObligationCount??0})},{id:"engagementsCount",header:t("Engagements"),cell:a=>a.engagementsCount??0},{id:"status",header:t("Status"),sortable:!0,cell:a=>e.jsx(is,{filterKey:"status",filterValue:a.status,children:e.jsx("span",{className:As[a.status],children:s[a.status]})})},...D?[{id:"actions",header:t("Actions"),cell:a=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",onClick:()=>Lt(a,"inactive"),children:t("Restore")}),e.jsx(j,{variant:"destructive",size:"sm",onClick:()=>oe(a),children:t("Delete Permanently")})]})}]:[]],qt=D?[{label:t("Restore (Inactive)"),onClick:Ot},{label:t("Delete Permanently"),onClick:Mt,variant:"destructive",confirmMessage:`Permanently delete ${v.size} collaborator(s)? This action cannot be undone.`,confirmItems:rt}]:[{label:t("Activate"),onClick:Et},{label:t("Deactivate"),onClick:Ft},{label:t("Send Signup Email"),onClick:Bt},{label:t("Add to Program"),onClick:()=>Ce("add")},{label:t("Remove from Program"),onClick:()=>Ce("remove")},{label:t("Delete"),onClick:Tt,variant:"destructive",confirmMessage:`Delete ${v.size} collaborator(s)? You can undo from Trash.`,confirmItems:rt}],Wt=[{key:"status",label:"Status",value:$,displayValue:s[$]||$,onRemove:()=>He("all")},...z?[{key:"programId",label:"Program",value:z,displayValue:`#${z}`,onRemove:()=>{pe(""),u.delete("programId"),p(u)}}]:[],...G?[{key:"distributorId",label:"Distributor",value:G,displayValue:((lt=Q.find(a=>a.id===parseInt(G)))==null?void 0:lt.name)??`#${G}`,onRemove:()=>{U(""),u.delete("distributorId"),p(u)}}]:[]];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[t("Collaborators"),e.jsx(je,{topic:"what-is-collaborator",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Nt,{sourceType:"collaborator",contextLabel:"all collaborators"}),e.jsx(j,{asChild:!0,children:e.jsxs(B,{to:"/collaborators/new",children:[e.jsx(wt,{className:"h-4 w-4"}),t("Add Collaborator")]})})]})]}),e.jsx(ns,{filters:Wt}),y&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:y}),e.jsxs("div",{className:"flex gap-2 mb-4",children:[e.jsxs("div",{className:"relative flex-1 max-w-sm",children:[e.jsx(ms,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(fe,{placeholder:t("Search collaborators..."),value:re,onChange:a=>Pe(a.target.value),onKeyDown:a=>a.key==="Enter"&&st(),className:"pl-9"})]}),e.jsxs(ie,{value:$,onValueChange:He,children:[e.jsx(ne,{"aria-label":t("Filter by status"),className:"w-[150px]",children:e.jsx(de,{placeholder:t("Status")})}),e.jsxs(ce,{children:[e.jsx(T,{value:"all",children:t("All Statuses")}),e.jsx(T,{value:"active",children:t("Active")}),e.jsx(T,{value:"pending",children:t("Pending")}),e.jsx(T,{value:"inactive",children:t("Inactive")}),e.jsx(T,{value:"rejected",children:t("Rejected")}),e.jsx(T,{value:"deleted",children:t("Trashed")})]})]}),e.jsx(j,{variant:"secondary",onClick:st,children:t("Search")})]}),!D&&f.some(a=>a.status==="pending")&&e.jsx("p",{className:"mb-4 rounded-md border bg-muted/40 px-3 py-2 text-sm text-muted-foreground","data-testid":"pending-collaborators-hint",children:t("Pending collaborators are not credited for visits or sales yet. Select them and choose Activate to start crediting them.")}),e.jsx(ds,{selectedCount:v.size,actions:qt,onClear:()=>L(new Set),isProcessing:r}),e.jsx(Ke,{columns:Vt,data:f,isLoading:k,emptyMessage:t("No collaborators found."),selectable:!0,selectedIds:v,onSelectionChange:L,getRowHref:a=>`/collaborators/${a.id}/view`,onEdit:D?void 0:$t,onDelete:D?void 0:a=>oe(a),sortField:i,sortOrder:S,onSort:Dt}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",m===0?0:(n-1)*R+1," to ",Math.min(n*R,m)," of"," ",m," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(ie,{value:Ie.toString(),onValueChange:It,children:[e.jsx(ne,{"aria-label":t("Rows per page"),className:"w-[80px] h-8",children:e.jsx(de,{})}),e.jsxs(ce,{children:[e.jsx(T,{value:"10",children:"10"}),e.jsx(T,{value:"25",children:"25"}),e.jsx(T,{value:"50",children:"50"}),e.jsx(T,{value:"100",children:"100"})]})]})]})]}),P>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",disabled:n===1,onClick:()=>at(n-1),children:t("Previous")}),e.jsx(j,{variant:"outline",size:"sm",disabled:n===P,onClick:()=>at(n+1),children:t("Next")})]}),e.jsx(j,{variant:"link",className:"text-sm",onClick:()=>He(D?"all":"deleted"),children:t(D?"Back to active collaborators":"Trash")})]}),e.jsx(as,{open:d!==null,onClose:()=>oe(null),noun:t("collaborator"),name:(d==null?void 0:d.fullName)||(d==null?void 0:d.email)||"",permanent:D,title:t(D?"Delete Collaborator Permanently":"Delete Collaborator"),onConfirm:Rt,loadBlockers:d?()=>Je.deletionBlockers(d.id):void 0}),e.jsx($e,{open:ye!==null,onOpenChange:()=>Ce(null),children:e.jsxs(Ee,{children:[e.jsxs(Fe,{children:[e.jsx(Te,{children:ye==="add"?"Add to Program":"Remove from Program"}),e.jsx(Oe,{children:ye==="add"?`Select a program to add ${v.size} collaborator(s) to.`:`Select a program to remove ${v.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:e.jsxs(ie,{value:Ae,onValueChange:Qe,children:[e.jsx(ne,{"aria-label":t("Select a program"),children:e.jsx(de,{placeholder:t("Select a program")})}),e.jsx(ce,{children:ue.map(a=>{const A=!!a.collaboratorGroupId;return e.jsxs(T,{value:a.id.toString(),disabled:A,children:[e.jsx("span",{className:A?"line-through opacity-60":"",children:a.name}),A&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:t("uses a collaborator group")})]},a.id)})})]})}),e.jsxs(Be,{children:[e.jsx(j,{variant:"outline",onClick:()=>Ce(null),children:t("Cancel")}),e.jsx(j,{onClick:zt,disabled:!Ae||r,children:r?"Processing...":"Confirm"})]})]})}),e.jsx($e,{open:Se!==null,onOpenChange:()=>qe(null),children:e.jsxs(Ee,{children:[e.jsxs(Fe,{children:[e.jsx(Te,{children:Se==="add"?"Add to Collaborator Group":"Remove from Collaborator Group"}),e.jsx(Oe,{children:Se==="add"?`Select a group to add ${v.size} collaborator(s) to.`:`Select a group to remove ${v.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:Y.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:t("No collaborator groups exist yet.")}):e.jsxs(ie,{value:Le,onValueChange:Ze,children:[e.jsx(ne,{"aria-label":t("Select a group"),children:e.jsx(de,{placeholder:t("Select a group")})}),e.jsx(ce,{children:Y.map(a=>e.jsx(T,{value:a.id.toString(),children:a.name},a.id))})]})}),e.jsxs(Be,{children:[e.jsx(j,{variant:"outline",onClick:()=>qe(null),children:t("Cancel")}),e.jsx(j,{onClick:Gt,disabled:!Le||r,children:r?"Processing...":"Confirm"})]})]})}),e.jsx($e,{open:Ne!==null,onOpenChange:()=>We(null),children:e.jsxs(Ee,{children:[e.jsxs(Fe,{children:[e.jsx(Te,{children:Ne==="add"?"Add to Distributor":"Remove from Distributor"}),e.jsx(Oe,{children:Ne==="add"?`Select a distributor to add ${v.size} collaborator(s) to.`:`Select a distributor to remove ${v.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:Q.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:t("No distributors exist yet.")}):e.jsxs(ie,{value:Re,onValueChange:et,children:[e.jsx(ne,{"aria-label":t("Select a distributor"),children:e.jsx(de,{placeholder:t("Select a distributor")})}),e.jsx(ce,{children:Q.map(a=>{const A=!!a.collaboratorGroupId;return e.jsxs(T,{value:a.id.toString(),disabled:A,children:[e.jsx("span",{className:A?"line-through opacity-60":"",children:a.name}),A&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:t("uses a collaborator group")})]},a.id)})})]})}),e.jsxs(Be,{children:[e.jsx(j,{variant:"outline",onClick:()=>We(null),children:t("Cancel")}),e.jsx(j,{onClick:Ut,disabled:!Re||r,children:r?"Processing...":"Confirm"})]})]})})]})}function mt(){const{translate:s}=ee(),h={active:s("Active"),pending:s("Pending"),inactive:s("Inactive"),rejected:s("Rejected"),deleted:s("Trashed")},u=Object.entries(h).filter(([i])=>i!=="deleted"),{id:p}=jt(),f=Xe(),m=!p,{current:n,isLoading:R,isSubmitting:P,error:k,fetchOne:r,create:y,update:N,clearCurrent:I,clearError:b}=Ye(),{items:c,total:g,page:w,perPage:F,totalPages:o,isLoading:C,fetchList:O}=yt(),{items:te,total:se,page:Ge,perPage:Ue,totalPages:Ve,isLoading:ue,fetchList:ae}=Ct(),[Y,ke]=l.useState([]),[Q,me]=l.useState(new Map),he=l.useRef(new Set),[M,q]=l.useState({email:"",fullName:"",nickname:"",status:"active",trackingId:"",distributorIds:[]}),[re,Pe]=l.useState([]),[le,be]=l.useState(!1),$=nt({getCandidateStagingId:i=>i.id}),W=nt({getCandidateStagingId:i=>i.id}),z=async()=>{be(!0);try{const i=await Je.generateReferralCode();U("trackingId",i.code)}catch{}finally{be(!1)}},pe=[{field:"fullName",validate:it("Full name is required")},{field:"email",validate:it("Email is required")},{field:"email",validate:ss(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Please enter a valid email address")}];l.useEffect(()=>(b(),O({perPage:10,status:"active,inactive,pending,draft"}),p?r(parseInt(p)):(I(),q({email:"",fullName:"",nickname:"",status:"active",trackingId:"",distributorIds:[]}),Je.generateReferralCode().then(i=>{q(x=>({...x,trackingId:i.code}))}).catch(()=>{})),()=>{I()}),[p,r,I,b,O,ae,!1]),l.useEffect(()=>{var i;n&&q({email:n.email,fullName:n.fullName,nickname:n.nickname||"",status:n.status,trackingId:n.referralCode||"",distributorIds:((i=n.distributors)==null?void 0:i.map(x=>x.id))||[]})},[n]);const G=async i=>{i.preventDefault();const x=ts(M,pe);if(Pe(x.errors),!x.valid)return;const S=new Set(((n==null?void 0:n.programs)??[]).map(D=>D.id)),ve=[...Array.from(S).filter(D=>!$.pendingRemovalIds.has(D)),...$.pendingAdditions.map(D=>D.id)],v=new Set((n==null?void 0:n.groupIds)??[]);[...Array.from(v).filter(D=>!W.pendingRemovalIds.has(D)),...W.pendingAdditions.map(D=>D.id)];const L={...M,programIds:ve};try{m?await y(L):await N(parseInt(p),L),$.reset(),W.reset(),f("/collaborators")}catch{}},U=(i,x)=>{q(S=>({...S,[i]:x}))},d=n==null?void 0:n.programs;l.useEffect(()=>{if(C)return;const i=new Set(c.map(S=>S.id)),x=(d??[]).filter(S=>!i.has(S.id)&&!he.current.has(S.id)).slice(0,25);x.length!==0&&(x.forEach(S=>he.current.add(S.id)),Promise.all(x.map(S=>rs.get(S.id).catch(()=>null))).then(S=>{me(ve=>{const v=new Map(ve);return S.forEach(L=>{L&&v.set(L.id,L)}),v})}))},[d,c,C]);const oe=l.useMemo(()=>{const i=new Map([...Q,...c.map(x=>[x.id,x])]);return(d??[]).map(x=>{const S=i.get(x.id);return S||{id:x.id,name:x.name??`${s("Program")} #${x.id}`,description:"",status:"",incentiveType:"",incentiveResolverType:"",units:""}})},[d,c,Q,s]);l.useMemo(()=>{const i=new Map(te.map(x=>[x.id,x]));return((n==null?void 0:n.groupIds)??[]).map(x=>{const S=i.get(x);return S||{id:x,name:`${s("Group")} #${x}`,description:"",structure:"flat"}})},[n==null?void 0:n.groupIds,te,s]);const Ie=[{id:"name",header:s("Name"),cell:i=>i.name},{id:"description",header:s("Description"),cell:i=>i.description||"—"},{id:"status",header:s("Status"),cell:i=>i.status?e.jsx(dt,{status:i.status}):"—"}];s("Name"),s("Description"),s("Structure");const De=[{id:"name",header:s("Name"),cell:i=>i.name},{id:"description",header:s("Description"),cell:i=>i.description||"—"},{id:"status",header:s("Status"),cell:i=>i.status?e.jsx(dt,{status:i.status}):"—"}];return s("Name"),s("Description"),R&&!m?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ze,{})}):e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:s(m?"New Collaborator":"Edit Collaborator")}),k&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:k}),e.jsxs("form",{onSubmit:G,className:"space-y-6",children:[e.jsxs(H,{children:[e.jsx(_,{children:e.jsx(K,{children:s("Basic Information")})}),e.jsxs(J,{className:"space-y-4",children:[e.jsx(we,{label:"Full Name",htmlFor:"fullName",required:!0,error:ot(re,"fullName"),children:e.jsx(fe,{id:"fullName",value:M.fullName,onChange:i=>U("fullName",i.target.value),placeholder:s("e.g., John Smith")})}),e.jsx(we,{label:"Email",htmlFor:"email",required:!0,error:ot(re,"email"),children:e.jsx(fe,{id:"email",type:"email",value:M.email,onChange:i=>U("email",i.target.value),placeholder:s("e.g., john@example.com")})}),e.jsx(we,{label:"Nickname",htmlFor:"nickname",description:"Optional display name or alias",children:e.jsx(fe,{id:"nickname",value:M.nickname||"",onChange:i=>U("nickname",i.target.value),placeholder:s("e.g., Johnny")})}),e.jsx(we,{label:e.jsxs("span",{children:["Referral Code",e.jsx(je,{topic:"referral-code",side:"right"})]}),htmlFor:"trackingId",description:"Used in tracking URLs: yoursite.com/?ref=CODE",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(fe,{id:"trackingId",value:M.trackingId||"",onChange:i=>U("trackingId",i.target.value),placeholder:s("e.g., johnsmith"),className:"font-mono flex-1"}),e.jsx(j,{type:"button",variant:"outline",size:"icon",onClick:z,disabled:le,title:s("Generate random code"),children:e.jsx(Is,{className:`h-4 w-4 ${le?"animate-spin":""}`})})]})}),e.jsx(we,{label:e.jsxs("span",{children:["Status",e.jsx(je,{topic:"collaborator-status",side:"right"})]}),htmlFor:"status",description:M.status==="pending"?s("A pending collaborator is not credited for visits or sales yet. Choose Active to start crediting them now, or activate them later from the Collaborators list."):void 0,children:e.jsxs(ie,{value:M.status,onValueChange:i=>U("status",i),children:[e.jsx(ne,{id:"status",children:e.jsx(de,{})}),e.jsx(ce,{children:u.map(([i,x])=>e.jsx(T,{value:i,children:x},i))})]})})]})]}),e.jsx(ls,{title:s("Programs"),description:s("Programs this collaborator is enrolled in"),helpTopic:"what-is-program",currentItems:oe,currentColumns:Ie,emptyCurrentMessage:s("No programs assigned yet."),getCurrentStagingId:i=>i.id,staged:$,pendingAdditionColumns:De,getCandidateStagingId:i=>i.id,pickerTitle:s("Add Programs"),pickerDescription:s("Select programs to enroll this collaborator in."),pickerCandidates:c,pickerColumns:De,pickerIsLoading:C,pickerPagination:{page:w,perPage:F,total:g,totalPages:o},onPickerParamsChange:({search:i,page:x,perPage:S})=>O({page:x,perPage:S,search:i,status:"active,inactive,pending,draft"}),onOpenPicker:()=>O({page:1,perPage:10,status:"active,inactive,pending,draft"}),addButtonLabel:s("Add Programs")}),!1,!1,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{type:"submit",disabled:P,children:P?"Saving...":s(m?"Create":"Update")}),e.jsx(j,{type:"button",variant:"outline",onClick:()=>f("/collaborators"),children:s("Cancel")})]})]})]})}const ht=["id","status","displayLabel","lastTriggered","customerCollaborators"],pt={list:t=>E.get("/opportunities",{collaboratorId:t==null?void 0:t.collaboratorId,status:t==null?void 0:t.status,offset:(t==null?void 0:t.offset)??0,number:(t==null?void 0:t.number)??50,fields:((t==null?void 0:t.fields)??ht).join(",")}),get:t=>E.get(`/opportunities/${t}`,{fields:ht.join(",")}),update:(t,s)=>E.put(`/opportunities/${t}`,s)},Ls=St((t,s)=>({ownedByCollaborator:[],isLoading:!1,error:null,fetchOwnedByCollaborator:async h=>{t({isLoading:!0,error:null});try{const u=await pt.list({collaboratorId:h});t({ownedByCollaborator:u.items,isLoading:!1})}catch(u){t({error:u instanceof Error?u.message:"Failed to load owned customers",isLoading:!1})}},removeOwner:async(h,u,p=!1)=>{const f=s().ownedByCollaborator.find(n=>n.id===h),m=((f==null?void 0:f.customerCollaborators)??[]).map(n=>n.id).filter(n=>n!==u);try{await pt.update(h,{customerCollaborators:m,...p?{cascadeRejectOnUnbind:[u]}:{}}),t({ownedByCollaborator:s().ownedByCollaborator.filter(n=>n.id!==h)})}catch(n){t({error:n instanceof Error?n.message:"Failed to remove owner"})}},clear:()=>t({ownedByCollaborator:[],error:null})}));function Rs({collaboratorId:t}){var F;const{translate:s}=ee(),h={signup:s("Signed up there"),migration:s("Came with its migration"),dashboard:s("Linked here")},[u,p]=l.useState(null),[f,m]=l.useState([]),[n,R]=l.useState(""),[P,k]=l.useState(!1),[r,y]=l.useState(null),N=l.useCallback(async()=>{try{const[o,C]=await Promise.all([E.get(`/collaborators/${t}/stores`),fs.list()]);p(o.stores??[]),m(C)}catch{p(null)}},[t]);l.useEffect(()=>{N()},[N]);const I=l.useCallback(async()=>{k(!0);try{await E.post(`/collaborators/${t}/merge/resend`),X.success(s("Siren emailed a new confirmation link."))}catch(o){X.error(o instanceof Error?o.message:s("Failed to send the email."))}finally{k(!1)}},[t,s]),b=l.useCallback(async(o,C)=>{k(!0);try{C?await E.put(`/collaborators/${t}/stores/${o}`):await E.delete(`/collaborators/${t}/stores/${o}`),R(""),await N()}catch(O){X.error(O instanceof Error?O.message:s("Failed to change the collaborator’s properties."))}finally{k(!1)}},[t,N,s]);if(u===null)return null;const c=r===null?"":((F=f.find(o=>o.id===r))==null?void 0:F.name)??`#${r}`,g=o=>{var C;return((C=f.find(O=>O.id===o))==null?void 0:C.name)??s("Property #%d").replace("%d",String(o))},w=f.filter(o=>!u.some(C=>C.propertyId===o.id));return e.jsxs(H,{"data-testid":"collaborator-properties",children:[e.jsx(_,{children:e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(Ps,{className:"h-4 w-4","aria-hidden":"true"}),s("Properties"),e.jsx(je,{topic:"collaborator-properties",side:"right"})]})}),e.jsxs(J,{className:"space-y-3",children:[u.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No property works with this collaborator.")}):e.jsx("ul",{className:"space-y-2",children:u.map(o=>e.jsxs("li",{className:"flex items-center justify-between gap-2 text-sm",children:[e.jsxs("span",{className:"min-w-0 break-words",children:[e.jsx(B,{to:`/properties/${o.propertyId}`,className:"text-primary hover:underline",children:g(o.propertyId)}),e.jsx("span",{className:"block text-xs text-muted-foreground",children:h[o.source]??o.source}),o.mergeInto?e.jsxs("span",{className:"block text-xs text-muted-foreground","data-testid":`pending-merge-${o.propertyId}`,children:[s("Waiting for %s to confirm this record joins collaborator %d.").replace("%s",o.email||s("the person")).replace("%d",String(o.mergeInto))," ",e.jsx(j,{variant:"link",size:"sm",className:"h-auto p-0",disabled:P,onClick:I,children:s("Resend email")})]}):null]}),e.jsx(j,{variant:"ghost",size:"icon",disabled:P,onClick:()=>y(o.propertyId),"aria-label":s("Remove from %s").replace("%s",g(o.propertyId)),children:e.jsx(bt,{className:"h-4 w-4"})})]},o.propertyId))}),w.length>0?e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(ie,{value:n,onValueChange:R,children:[e.jsx(ne,{className:"flex-1","aria-label":s("Property to add"),children:e.jsx(de,{placeholder:s("Add to a property")})}),e.jsx(ce,{children:w.map(o=>e.jsx(T,{value:String(o.id),children:o.name},o.id))})]}),e.jsx(j,{variant:"outline",disabled:P||n==="",onClick:()=>b(Number(n),!0),children:s("Add")})]}):null]}),e.jsx(kt,{open:r!==null,onOpenChange:o=>!o&&y(null),title:s("Remove from %s?").replace("%s",c),description:s("%s stops working with this collaborator. You can add it back later.").replace("%s",c),confirmLabel:s("Remove"),busyLabel:s("Removing..."),onConfirm:()=>r!==null?b(r,!1):void 0})]})}function $s({collaboratorId:t,name:s}){const{translate:h}=ee(),{isWordPress:u}=vt(),p=bs("coupon"),[f,m]=l.useState(null),[n,R]=l.useState([]),[P,k]=l.useState(!1),[r,y]=l.useState(null),[N,I]=l.useState(0),[b,c]=l.useState(!1),g=l.useCallback(async()=>{try{m((await Pt({holderId:t,perPage:100})).items),c(!1)}catch{m([]),c(!0)}},[t]);l.useEffect(()=>{p!==void 0&&g()},[p,g,N]),l.useEffect(()=>{if(p===void 0||u)return;let o=!1;return vs().then(C=>{o||R(C)}).catch(()=>{o||R([])}),()=>{o=!0}},[p,u]);const w=l.useMemo(()=>ys(n),[n]),F=()=>{k(!1),y(null),I(o=>o+1)};return p===void 0||!p.available&&(f===null||f.length===0)?null:e.jsxs(H,{"data-testid":"collaborator-coupon-codes",children:[e.jsxs(_,{className:"flex flex-row flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs(K,{className:"flex items-center",children:[h("Coupon codes"),e.jsx(je,{topic:"coupon-codes",side:"right"})]}),e.jsx(xe,{children:h("Codes that credit this collaborator")})]}),p.available?e.jsx(j,{size:"sm",variant:"outline",onClick:()=>k(!0),children:h("Link a coupon")}):null]}),e.jsx(J,{children:f===null?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(ze,{size:32,label:""})}):b?e.jsx("p",{className:"text-sm text-destructive",role:"alert",children:h("The coupon codes could not be loaded.")}):f.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:h("{name} has no coupon codes. Link a coupon to credit {name} for sales that use it.").replace(/\{name\}/g,s)}):e.jsx("ul",{className:"divide-y","aria-label":h("Coupon codes"),children:f.map(o=>e.jsxs("li",{className:"flex items-start justify-between gap-2 py-2",children:[e.jsxs("div",{className:"min-w-0 space-y-1",children:[e.jsx("div",{className:"font-mono text-sm font-medium",children:o.code}),e.jsx(Cs,{identities:o.identities,names:w,singleStore:u}),e.jsx("div",{className:"text-xs text-muted-foreground",children:h("{count} uses").replace("{count}",String(o.uses.count))})]}),o.currency===null?e.jsx(j,{size:"sm",variant:"outline",onClick:()=>y(o),children:h("Unlink")}):null]},o.id))})}),P?e.jsx(Es,{collaboratorId:t,name:s,names:w,singleStore:u,onClose:()=>k(!1),onLinked:F}):null,r?e.jsx(Ss,{coupon:r,onClose:()=>y(null),onSaved:F}):null]})}function Es({collaboratorId:t,name:s,names:h,singleStore:u,onClose:p,onLinked:f}){var F;const{translate:m}=ee(),[n,R]=l.useState(""),[P,k]=l.useState([]),[r,y]=l.useState(null),[N,I]=l.useState(!1),[b,c]=l.useState(!0);l.useEffect(()=>{let o=!1;const C=n.trim();c(!0);const O=window.setTimeout(()=>{Pt(C===""?{linked:!1,perPage:10}:{search:C,perPage:10}).then(te=>{o||k(te.items.filter(se=>se.currency===null&&se.holderId!==t))}).catch(()=>{o||k([])}).finally(()=>{o||c(!1)})},250);return()=>{o=!0,window.clearTimeout(O)}},[n,t]);const g=async o=>{I(!0);try{await ws(o.id,t),X.success(m("{code} now credits {collaborator}.").replace("{code}",o.code).replace("{collaborator}",s)),f()}catch(C){X.error(C instanceof Error&&C.message?C.message:m("Could not link the coupon code."))}finally{I(!1)}},w=o=>{o.holderId!==null?y(o):g(o)};return e.jsx($e,{open:!0,onOpenChange:o=>!o&&p(),children:e.jsxs(Ee,{className:"max-h-[90vh] overflow-y-auto",children:[e.jsxs(Fe,{children:[e.jsx(Te,{children:m("Link a coupon to {collaborator}").replace("{collaborator}",s)}),e.jsx(Oe,{children:m("Sales that use the code will credit {collaborator}.").replace("{collaborator}",s)})]}),r?e.jsx("p",{className:"rounded-md border bg-muted/40 px-3 py-2 text-sm","data-testid":"coupon-move-warning",children:m("{code} is currently linked to {holder}. Link it to {collaborator} instead?").replace("{code}",r.code).replace("{holder}",((F=r.holder)==null?void 0:F.name)??m("another collaborator")).replace("{collaborator}",s)}):e.jsxs("div",{className:"space-y-2",children:[e.jsx(Kt,{htmlFor:"link-coupon-search",children:m("Find a coupon code")}),e.jsx(fe,{id:"link-coupon-search",value:n,onChange:o=>R(o.target.value),placeholder:m("Search codes")}),e.jsx("ul",{className:"max-h-60 divide-y overflow-y-auto rounded-md border","aria-label":m("Coupon codes found"),children:P.length===0?e.jsx("li",{className:"px-3 py-2 text-sm text-muted-foreground",children:m(b?"Searching...":"No coupon codes found.")}):P.map(o=>e.jsx("li",{children:e.jsxs("button",{type:"button",disabled:N,onClick:()=>w(o),className:"flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm hover:bg-muted",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block font-mono font-medium",children:o.code}),e.jsx("span",{className:"block truncate text-xs text-muted-foreground",children:o.identities.map(C=>Ns(C,h,m,u)).join(", ")})]}),e.jsx("span",{className:"shrink-0 text-xs text-muted-foreground",children:o.holder?m("Currently linked to {holder}").replace("{holder}",o.holder.name):m("Link")})]})},o.id))})]}),e.jsx(Be,{children:r?e.jsxs(e.Fragment,{children:[e.jsx(j,{variant:"outline",onClick:()=>y(null),disabled:N,children:m("Back")}),e.jsx(j,{onClick:()=>void g(r),disabled:N,children:m("Link to {collaborator}").replace("{collaborator}",s)})]}):e.jsx(j,{variant:"outline",onClick:p,children:m("Cancel")})})]})})}const Fs=10,Me={list:(t={})=>{var s;return E.get("/products",{search:((s=t.search)==null?void 0:s.trim())||void 0,propertyId:t.propertyId,integration:t.integration||void 0,ownerId:t.ownerId,sold:t.sold?1:void 0,hasMatches:t.hasMatches?1:void 0,page:t.page??1,perPage:t.perPage??25})},get:t=>E.get(`/products/${t}`).then(s=>s.product),rename:(t,s)=>E.patch(`/products/${t}`,{name:s}).then(h=>h.product),setOwners:(t,s)=>E.put(`/products/${t}/owners`,{owners:s}).then(h=>h.product),add:t=>E.post("/products",t).then(s=>s.product),matches:t=>E.get(`/products/${t}/matches`).then(s=>s.matches),dismissMatch:(t,s)=>E.post(`/products/${t}/matches/${s}/dismiss`,{}).then(h=>h.matches),previewMerge:(t,s)=>E.post("/products/merge/preview",{survivorId:t,productIds:s}),merge:t=>E.post("/products/merge",t).then(s=>s.product),splitListing:(t,s)=>E.post(`/products/${t}/listings/${s}/split`,{}).then(h=>h.product)};function Ts(t){return t.listings.filter(s=>!s.removed)}const Os={wc:"WooCommerce",edd:"Easy Digital Downloads",nc:"North Commerce",llms:"LifterLMS",ld:"LearnDash",gf:"Gravity Forms",shopify:"Shopify",stripe:"Stripe",stripe_test:"Stripe test mode"};function Bs(t){return Os[t]??t}const _e=10;function Ms({collaboratorId:t}){const{translate:s}=ee(),[h,u]=l.useState([]),[p,f]=l.useState(!0),[m,n]=l.useState(!1),[R,P]=l.useState(0),[k,r]=l.useState(!1),[y,N]=l.useState(null);l.useEffect(()=>{let c=!1;return f(!0),Me.list({ownerId:t,perPage:100}).then(g=>{c||(u(g.products),r(!1))}).catch(()=>{c||(u([]),r(!0))}).finally(()=>{c||f(!1)}),()=>{c=!0}},[t,R]);const I=async c=>{try{await Me.setOwners(c.id,c.owners.filter(g=>g.id!==t).map(g=>g.id)),X.success(s("Unlinked %s.").replace("%s",c.name)),P(g=>g+1)}catch(g){X.error(g instanceof Error?g.message:s("The product could not be changed."))}},b=async c=>{n(!1);for(const g of c)try{await Me.setOwners(g.id,[...g.owners.map(w=>w.id),t])}catch(w){X.error(w instanceof Error?`${g.name}: ${w.message}`:s("The product could not be changed."))}P(g=>g+1)};return e.jsxs(H,{children:[e.jsx(_,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(K,{className:"flex items-center",children:[s("Products"),e.jsx(je,{topic:"product-owners",side:"right"})]}),e.jsxs(j,{size:"sm",variant:"outline",onClick:()=>n(!0),children:[e.jsx(wt,{className:"h-4 w-4","aria-hidden":"true"}),s("Link to a product")]})]})}),e.jsx(J,{children:p?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(ze,{size:32,label:""})}):k?e.jsx("p",{className:"text-sm text-destructive",role:"alert",children:s("The products could not be loaded.")}):h.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("This collaborator owns no products.")}):e.jsx("ul",{className:"space-y-2",children:h.map(c=>e.jsxs("li",{className:"flex items-center justify-between gap-2 text-sm",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx(Jt,{to:`/products/${c.id}`,className:"font-medium text-primary hover:underline",children:c.name}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:Ts(c).map(g=>Bs(g.integration)).filter((g,w,F)=>F.indexOf(g)===w).join(", ")||s("Not sold anywhere now")})]}),e.jsxs(j,{size:"sm",variant:"outline",onClick:()=>N(c),"aria-label":`${s("Unlink")} ${c.name}`,children:[e.jsx(bt,{className:"h-4 w-4","aria-hidden":"true"}),s("Unlink")]})]},c.id))})}),e.jsx(kt,{open:y!==null,onOpenChange:c=>!c&&N(null),title:s("Unlink product"),description:s("This collaborator stops earning from %s on every store that sells it.").replace("%s",(y==null?void 0:y.name)??""),confirmLabel:s("Unlink"),busyLabel:s("Unlinking..."),onConfirm:()=>y?I(y):void 0}),e.jsx(zs,{open:m,excluded:new Set(h.map(c=>c.id)),onClose:()=>n(!1),onPick:b})]})}function zs({open:t,excluded:s,onClose:h,onPick:u}){const{translate:p}=ee(),[f,m]=l.useState([]),[n,R]=l.useState(0),[P,k]=l.useState(1),[r,y]=l.useState(!1),N=l.useCallback(async b=>{y(!0);try{const c=await Me.list({search:b.search,page:b.page,perPage:b.perPage});m(c.products),R(c.total),k(b.page)}catch(c){X.error(c instanceof Error?c.message:p("The products could not be loaded."))}finally{y(!1)}},[p]);l.useEffect(()=>{t&&N({search:"",page:1,perPage:_e})},[t,N]);const I=[{id:"name",header:p("Product"),cell:b=>b.name},{id:"owners",header:p("Owners"),cell:b=>`${b.owners.length} / ${Fs}`}];return e.jsx(js,{open:t,onOpenChange:b=>!b&&h(),title:p("Link to a product"),description:p("This collaborator earns from the products you pick, on every store that sells them."),excludedIds:s,items:f,isLoading:r,total:n,page:P,perPage:_e,totalPages:Math.max(1,Math.ceil(n/_e)),onParamsChange:N,columns:I,onAdd:b=>u(f.filter(c=>b.includes(c.id)))})}const Gs={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red",deleted:"status-badge status-red"},Us={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},Vs={approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"};function gt(){const{translate:t}=ee(),{formatMoney:s,formatShownMoney:h,definitionFor:u}=xs(),p={active:t("Active"),pending:t("Pending"),inactive:t("Inactive"),rejected:t("Rejected"),deleted:t("Trashed")},{id:f}=jt(),m=Xe(),{isWordPress:n,extensions:R,planAllows:P}=vt(),k=R.collaboratorApplications,{current:r,isLoading:y,error:N,fetchOne:I,clearCurrent:b}=Ye(),[c,g]=l.useState(!1),[w,F]=l.useState(""),[o,C]=l.useState(""),[O,te]=l.useState(""),[se,Ge]=l.useState(!1),[Ue,Ve]=l.useState(void 0),ue=w?u(w):void 0,ae=Number(o),Y=ue&&o!==""&&Number.isFinite(ae)?Xt(ae,ue):0;ue?Y>0?`${t("Adds")} ${s(Y,w)}.`:Y<0?`${t("Deducts")} ${s(-Y,w)}.`:`${t("Type the amount as the balance shows it. 5 means")} ${h(5,w)}.`:t("Choose a currency first.");const{items:ke,isLoading:Q,fetchList:me}=ps(),{items:he,isLoading:M,fetchList:q}=gs(),{ownedByCollaborator:re,isLoading:Pe,fetchOwnedByCollaborator:le,removeOwner:be,clear:$}=Ls();l.useEffect(()=>{if(f){const d=parseInt(f);I(d),me({collaboratorId:d,perPage:10,status:"pending,approved,complete,rejected"}),q({collaboratorId:d,perPage:10,status:"approved,complete,rejected"})}return()=>{b(),$()}},[f,I,b,me,q,le,$]);const W=d=>d?new Date(d).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",z=(d,oe)=>s(d,oe),pe=[{id:"id",header:t("ID"),cell:d=>e.jsxs(B,{to:`/conversions/${d.id}`,className:"font-mono text-primary hover:underline",children:["#",d.id]})},{id:"type",header:t("Type"),cell:d=>e.jsx("span",{className:"capitalize",children:d.type})},{id:"amount",header:t("Amount"),cell:d=>z(d.amount,d.obligationAwardType)},{id:"status",header:t("Status"),cell:d=>e.jsx("span",{className:Us[d.status],children:d.status})},{id:"date",header:t("Date"),cell:d=>W(d.dateCreated)}],G=[{id:"id",header:t("ID"),cell:d=>e.jsxs(B,{to:`/obligations/${d.id}`,className:"font-mono text-primary hover:underline",children:["#",d.id]})},{id:"value",header:t("Value"),cell:d=>z(d.value,d.awardType)},{id:"status",header:t("Status"),cell:d=>e.jsx("span",{className:Vs[d.status],children:d.status})},{id:"date",header:t("Date"),cell:d=>W(d.dateCreated)}];if(y)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ze,{label:t("Loading collaborator...")})});if(N)return e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:N});if(!r)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx("p",{className:"text-muted-foreground",children:t("Collaborator not found.")})});const U="Programs";return r.distributors&&r.distributors.length>0?r.distributors:r.distributorId&&(r.distributorId,r.distributorName),r.groups&&r.groups.length>0?r.groups:(r.groupIds??[]).map(d=>({id:d})),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!n&&e.jsx(j,{variant:"ghost",size:"icon",onClick:()=>m("/collaborators"),"aria-label":t("Back"),children:e.jsx(ks,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:r.fullName}),e.jsx("span",{className:Gs[r.status],children:p[r.status]})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:r.email})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Nt,{sourceType:"collaborator",sourceId:r.id,contextLabel:r.fullName}),e.jsx(j,{asChild:!0,children:e.jsxs(B,{to:`/collaborators/${r.id}/edit`,children:[e.jsx(cs,{className:"h-4 w-4 mr-2"}),t("Edit Collaborator")]})})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2 lg:grid-cols-3",children:[k&&e.jsx(k,{collaboratorId:r.id,status:r.status,name:r.fullName||r.email,onChanged:()=>I(r.id)}),!n&&e.jsx(Rs,{collaboratorId:r.id}),e.jsx($s,{collaboratorId:r.id,name:r.fullName||r.email}),!n&&e.jsx(Ms,{collaboratorId:r.id}),e.jsxs(H,{children:[e.jsxs(_,{children:[e.jsx(K,{children:t("Profile")}),e.jsx(xe,{children:t("Collaborator information")})]}),e.jsxs(J,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Full Name")}),e.jsx("dd",{className:"font-medium",children:r.fullName})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Email")}),e.jsx("dd",{className:"font-medium",children:r.email})]}),r.nickname&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Nickname")}),e.jsx("dd",{className:"font-medium",children:r.nickname})]}),r.referralCode&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Tracking ID")}),e.jsx("dd",{className:"font-medium font-mono",children:r.referralCode})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("ID")}),e.jsx("dd",{className:"font-medium",children:r.id})]})]})]}),e.jsxs(H,{children:[e.jsxs(_,{children:[e.jsx(K,{children:t("Rewards Statistics")}),e.jsx(xe,{children:t("Obligation and payout summary")})]}),e.jsxs(J,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Unfulfilled Rewards")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(B,{to:`/obligations?collaboratorId=${r.id}&status=approved`,className:"text-primary hover:underline",children:[r.unfulfilledObligationCount??0," approved"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Fulfilled Rewards")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(B,{to:`/obligations?collaboratorId=${r.id}&status=complete`,className:"text-primary hover:underline",children:[r.fulfilledObligationCount??0," completed"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Total Engagements")}),e.jsx("dd",{className:"font-medium",children:e.jsx(B,{to:`/engagements?collaboratorId=${r.id}`,className:"text-primary hover:underline",children:r.engagementsCount??0})})]})]})]}),!1,!1,e.jsxs(H,{children:[e.jsxs(_,{children:[e.jsx(K,{children:U}),e.jsx(xe,{children:"Enrolled programs"})]}),e.jsxs(J,{children:[r.programs&&r.programs.length>0?e.jsx("ul",{className:"space-y-2",children:r.programs.map(d=>e.jsx("li",{children:e.jsx(B,{to:`/programs/${d.id}/view`,className:"text-primary hover:underline",children:d.name})},d.id))}):e.jsx("p",{className:"text-muted-foreground text-sm",children:t("Not enrolled in any programs")}),ct.distributors]})]}),!1,!1,!1,ct.customerOwnership]}),e.jsx("div",{className:"mt-8",children:e.jsxs(H,{children:[e.jsxs(_,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(K,{children:t("Recent Conversions")}),e.jsx(xe,{children:t("Latest conversions from this collaborator")})]}),e.jsx(j,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(B,{to:`/conversions?collaboratorId=${r.id}`,children:t("View All")})})]}),e.jsx(J,{children:e.jsx(Ke,{columns:pe,data:ke,isLoading:Q,emptyMessage:t("No conversions yet.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(H,{children:[e.jsxs(_,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(K,{children:t("Rewards")}),e.jsx(xe,{children:t("Reward obligations for this collaborator")})]}),e.jsx(j,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(B,{to:`/obligations?collaboratorId=${r.id}`,children:t("View All")})})]}),e.jsx(J,{children:e.jsx(Ke,{columns:G,data:he,isLoading:M,emptyMessage:t("No rewards yet.")})})]})})]})}window.sirenConfig&&Yt({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const xt=document.getElementById("siren-collaborators");xt&&Qt.createRoot(xt).render(e.jsx(l.StrictMode,{children:e.jsxs(hs,{defaultRoute:"/collaborators",children:[e.jsx(Zt,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(es,{children:[e.jsx(ge,{path:"/collaborators",element:e.jsx(ut,{})}),e.jsx(ge,{path:"/collaborators/new",element:e.jsx(mt,{})}),e.jsx(ge,{path:"/collaborators/:id",element:e.jsx(gt,{})}),e.jsx(ge,{path:"/collaborators/:id/view",element:e.jsx(gt,{})}),e.jsx(ge,{path:"/collaborators/:id/edit",element:e.jsx(mt,{})}),e.jsx(ge,{index:!0,element:e.jsx(ut,{})})]})})]})}));
     11 */const qs=At("Shuffle",[["path",{d:"m18 14 4 4-4 4",key:"10pe0f"}],["path",{d:"m18 2 4 4-4 4",key:"pucp1d"}],["path",{d:"M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22",key:"1ailkh"}],["path",{d:"M2 6h1.972a4 4 0 0 1 3.6 2.2",key:"km57vx"}],["path",{d:"M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45",key:"os18l9"}]]),se=vs("Distributors"),Hs=Tt(()=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,hasLoaded:!1,isSubmitting:!1,error:null,current:null,fetchList:async()=>{},fetchOne:async()=>{},create:se.create,update:se.update,delete:se.delete,bulkActivate:se.bulkActivate,bulkDeactivate:se.bulkDeactivate,bulkDelete:se.bulkDelete,bulkPermanentDelete:se.bulkPermanentDelete,bulkRestore:se.bulkRestore,clearCurrent:()=>{},clearError:()=>{}}));function Ws({collaborator:t,onResend:s,onCancel:n,disabled:j=!1}){const{translate:g}=V(),i=Ys(t,g);return e.jsxs("div",{className:"mt-1 flex flex-col gap-1","data-testid":`invitation-${t.id}`,children:[i&&e.jsx("span",{className:"text-xs text-muted-foreground",children:i}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{type:"button",variant:"outline",size:"sm",className:"h-7 px-2 text-xs",disabled:j,onClick:()=>s(t),children:g("Resend")}),e.jsx(x,{type:"button",variant:"ghost",size:"sm",className:"h-7 px-2 text-xs text-destructive hover:text-destructive",disabled:j,onClick:()=>n(t),children:g("Cancel invitation")})]})]})}function Ys(t,s){const n=t.invitation;if(!n)return null;switch(n.state){case"held":return s("Waiting for your email confirmation");case"sending":return s("Sending");case"expired":return s("Invitation expired");case"failed":return s("Invitation not delivered");case"sent":return n.sentAt?`${s("Sent")} ${Ks(n.sentAt)}`:s("Sent");default:return null}}function Ks(t){const s=new Date(t);return Number.isNaN(s.getTime())?"":s.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}const Js={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red",deleted:"status-badge status-red",invited:"status-badge status-blue"};function Ct(){var gt;const{translate:t}=V(),{extensions:s,capabilities:n}=He(),j=s.collaboratorsListLinks,g=s.collaboratorsListNotice,i=s.collaboratorStatusExtra,f=n.recipeImport!==!1,c={active:t("Active"),pending:t("Pending"),inactive:t("Inactive"),rejected:t("Rejected"),deleted:t("Trashed"),invited:t("Invited")},L=We(),[b,S]=ds(),{items:r,total:N,page:y,perPage:k,totalPages:I,isLoading:u,isSubmitting:m,error:w,fetchList:$,delete:o,bulkActivate:h,bulkDeactivate:A,bulkAddToProgram:_,bulkRemoveFromProgram:be,bulkAddToGroup:Ke,bulkRemoveFromGroup:Je,bulkAddToDistributor:Xe,bulkRemoveFromDistributor:ve,bulkDelete:ye,bulkPermanentDelete:ee,bulkRestore:Be,bulkSendSignupEmail:Ce,resendInvitation:Ne,cancelInvitation:we,update:z}=ot(),{items:Z,fetchList:Se}=Et(),{items:Ae,fetchList:ke}=Rt(),{items:ae,fetchList:Q}=Hs(),te=b.get("status")||"all",Ie=b.get("programId")||"",Le=b.get("distributorId")||"",[re,q]=l.useState(""),[p,$e]=l.useState(""),[B,Ee]=l.useState(te),[d,v]=l.useState(Ie),[C,Pe]=l.useState(Le),[O,H]=l.useState(null),[T,Me]=l.useState(null),[it,Gt]=l.useState(10),[Ze,Ut]=l.useState("fullName"),[Qe,Vt]=l.useState("asc"),[P,M]=l.useState(new Set),G=B==="deleted",[Re,Te]=l.useState(null),[Ge,dt]=l.useState(""),[Fe,et]=l.useState(null),[Ue,ct]=l.useState(""),[Oe,tt]=l.useState(null),[Ve,ut]=l.useState("");l.useEffect(()=>{Se({perPage:100,status:"active,inactive,pending,draft",fields:["id","name","status","collaboratorGroupId"]})},[Se,ke,Q]),l.useEffect(()=>{const a=b.get("status"),D=b.get("programId");a&&a!==B&&Ee(a),D&&D!==d&&v(D);const W=b.get("distributorId");W&&W!==C&&Pe(W)},[b,B,d,C]),l.useEffect(()=>{M(new Set)},[B]);const mt=Ss($,{perPage:it,search:p,orderBy:Ze,order:Qe,status:B==="all"?"active,pending,inactive,rejected,invited":B,programId:d?parseInt(d):void 0,distributorId:C?parseInt(C):void 0}),ht=()=>{if(re.trim()===p.trim()){mt.refetch();return}$e(re)},pt=a=>mt.setPage(a),_t=a=>Gt(parseInt(a)),st=a=>{Ee(a),a!=="all"?b.set("status",a):b.delete("status"),S(b)},qt=a=>{const D=Ze===a&&Qe==="asc"?"desc":"asc";Ut(a),Vt(D)},Ht=(a,D)=>{var W;return{email:a.email,fullName:a.fullName,nickname:a.nickname,status:D,programIds:(W=a.programs)==null?void 0:W.map(is=>is.id),distributorIds:a.distributorId?[a.distributorId]:void 0}},Wt=async(a,D)=>{await z(a.id,Ht(a,D))},Yt=async()=>{if(O){if(O.status==="deleted"||G){await ee([O.id]);return}await o(O.id)}},xt=r.filter(a=>P.has(a.id)).map(a=>je(a)),Kt=a=>{L(`/collaborators/${a.id}/edit`)},Jt=async()=>{await h(Array.from(P)),M(new Set)},Xt=async()=>{await A(Array.from(P)),M(new Set)},Zt=async()=>{await ye(Array.from(P)),M(new Set)},Qt=async()=>{await Be(Array.from(P)),M(new Set)},es=async()=>{try{await Ce(Array.from(P)),M(new Set)}catch{}},ts=async()=>{await ee(Array.from(P)),M(new Set)},ss=async()=>{if(!Ge)return;const a=parseInt(Ge);Re==="add"?await _(Array.from(P),a):Re==="remove"&&await be(Array.from(P),a),M(new Set),Te(null),dt("")},as=async()=>{if(!Ue)return;const a=parseInt(Ue);Fe==="add"?await Ke(Array.from(P),a):Fe==="remove"&&await Je(Array.from(P),a),M(new Set),et(null),ct("")},rs=async()=>{if(!Ve)return;const a=parseInt(Ve);Oe==="add"?await Xe(Array.from(P),a):Oe==="remove"&&await ve(Array.from(P),a),M(new Set),tt(null),ut("")},ls=[{id:"fullName",header:t("Name"),sortable:!0,cell:a=>je(a)},{id:"id",header:t("ID"),cell:a=>a.id},{id:"referralCode",header:t("Referral Code"),cell:a=>a.referralCode||e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"email",header:t("Email"),sortable:!0,cell:a=>a.email},{id:"programs",header:t("Programs"),cell:a=>{var D;return e.jsx("div",{className:"flex flex-wrap gap-1","data-tour":"collaborator-programs",children:((D=a.programs)==null?void 0:D.map(W=>e.jsx(F,{to:`/programs/${W.id}/view`,className:"text-primary hover:underline text-sm",children:W.name},W.id)))||"-"})}},{id:"unfulfilledObligationCount",header:t("Unpaid"),cell:a=>e.jsx(F,{to:`/obligations?collaboratorId=${a.id}&status=approved`,className:"text-primary hover:underline",children:a.unfulfilledObligationCount??0})},{id:"fulfilledObligationCount",header:t("Paid"),cell:a=>e.jsx(F,{to:`/obligations?collaboratorId=${a.id}&status=complete`,className:"text-primary hover:underline",children:a.fulfilledObligationCount??0})},{id:"engagementsCount",header:t("Engagements"),cell:a=>a.engagementsCount??0},{id:"status",header:t("Status"),sortable:!0,cell:a=>e.jsxs(e.Fragment,{children:[e.jsx(ys,{filterKey:"status",filterValue:a.status,children:e.jsx("span",{className:Js[a.status],children:c[a.status]})}),a.status==="invited"&&e.jsx(Ws,{collaborator:a,disabled:m,onResend:D=>Ne(D.id),onCancel:Me}),i&&!G&&e.jsx(i,{collaboratorId:a.id})]})},...G?[{id:"actions",header:t("Actions"),cell:a=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{variant:"outline",size:"sm",onClick:()=>Wt(a,"inactive"),children:t("Restore")}),e.jsx(x,{variant:"destructive",size:"sm",onClick:()=>H(a),children:t("Delete Permanently")})]})}]:[]],os=G?[{label:t("Restore (Inactive)"),onClick:Qt},{label:t("Delete Permanently"),onClick:ts,variant:"destructive",confirmMessage:`Permanently delete ${P.size} collaborator(s)? This action cannot be undone.`,confirmItems:xt}]:[{label:t("Activate"),onClick:Jt},{label:t("Deactivate"),onClick:Xt},{label:t("Send Signup Email"),onClick:es},{label:t("Add to Program"),onClick:()=>Te("add")},{label:t("Remove from Program"),onClick:()=>Te("remove")},{label:t("Delete"),onClick:Zt,variant:"destructive",confirmMessage:`Delete ${P.size} collaborator(s)? You can undo from Trash.`,confirmItems:xt}],ns=[{key:"status",label:"Status",value:B,displayValue:c[B]||B,onRemove:()=>st("all")},...d?[{key:"programId",label:"Program",value:d,displayValue:`#${d}`,onRemove:()=>{v(""),b.delete("programId"),S(b)}}]:[],...C?[{key:"distributorId",label:"Distributor",value:C,displayValue:((gt=ae.find(a=>a.id===parseInt(C)))==null?void 0:gt.name)??`#${C}`,onRemove:()=>{Pe(""),b.delete("distributorId"),S(b)}}]:[]];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[t("Collaborators"),e.jsx(De,{topic:"what-is-collaborator",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Ot,{sourceType:"collaborator",contextLabel:"all collaborators"}),j&&e.jsx(j,{}),f&&e.jsx(x,{variant:"outline",asChild:!0,"data-tour":"import-collaborators",children:e.jsxs(F,{to:"/collaborators/import",children:[e.jsx(ks,{className:"h-4 w-4"}),t("Import")]})}),e.jsx(x,{asChild:!0,"data-tour":"add-collaborator",children:e.jsxs(F,{to:"/collaborators/new",children:[e.jsx(nt,{className:"h-4 w-4"}),t("Add Collaborator")]})})]})]}),e.jsx(Cs,{filters:ns}),w&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:w}),e.jsxs("div",{className:"flex gap-2 mb-4","data-tour":"collaborators-filters",children:[e.jsxs("div",{className:"relative flex-1 max-w-sm",children:[e.jsx(Is,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(ue,{placeholder:t("Search collaborators..."),value:re,onChange:a=>q(a.target.value),onKeyDown:a=>a.key==="Enter"&&ht(),className:"pl-9"})]}),e.jsxs(oe,{value:B,onValueChange:st,children:[e.jsx(ne,{"aria-label":t("Filter by status"),className:"w-[150px]",children:e.jsx(ie,{placeholder:t("Status")})}),e.jsxs(de,{children:[e.jsx(R,{value:"all",children:t("All Statuses")}),e.jsx(R,{value:"active",children:t("Active")}),e.jsx(R,{value:"pending",children:t("Pending")}),e.jsx(R,{value:"inactive",children:t("Inactive")}),e.jsx(R,{value:"rejected",children:t("Rejected")}),e.jsx(R,{value:"invited",children:t("Invited")}),e.jsx(R,{value:"deleted",children:t("Trashed")})]})]}),e.jsx(x,{variant:"secondary",onClick:ht,children:t("Search")})]}),!G&&r.some(a=>a.status==="pending")&&e.jsx("p",{className:"mb-4 rounded-md border bg-muted/40 px-3 py-2 text-sm text-muted-foreground","data-testid":"pending-collaborators-hint",children:t("Pending collaborators are not credited for visits or sales yet. Select them and choose Activate to start crediting them.")}),g&&!G&&e.jsx(g,{}),e.jsx(Ns,{selectedCount:P.size,actions:os,onClear:()=>M(new Set),isProcessing:m}),e.jsx(lt,{columns:ls,data:r,sampleKey:"collaborators",isLoading:u,emptyMessage:t("No collaborators found."),selectable:!0,selectedIds:P,onSelectionChange:M,getRowHref:a=>`/collaborators/${a.id}/view`,onEdit:G?void 0:Kt,onDelete:G?void 0:a=>H(a),sortField:Ze,sortOrder:Qe,onSort:qt}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",N===0?0:(y-1)*k+1," to ",Math.min(y*k,N)," of"," ",N," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(oe,{value:it.toString(),onValueChange:_t,children:[e.jsx(ne,{"aria-label":t("Rows per page"),className:"w-[80px] h-8",children:e.jsx(ie,{})}),e.jsxs(de,{children:[e.jsx(R,{value:"10",children:"10"}),e.jsx(R,{value:"25",children:"25"}),e.jsx(R,{value:"50",children:"50"}),e.jsx(R,{value:"100",children:"100"})]})]})]})]}),I>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{variant:"outline",size:"sm",disabled:y===1,onClick:()=>pt(y-1),children:t("Previous")}),e.jsx(x,{variant:"outline",size:"sm",disabled:y===I,onClick:()=>pt(y+1),children:t("Next")})]}),e.jsx(x,{variant:"link",className:"text-sm",onClick:()=>st(G?"all":"deleted"),children:t(G?"Back to active collaborators":"Trash")})]}),e.jsx(js,{open:O!==null,onClose:()=>H(null),noun:t("collaborator"),name:O?je(O):"",permanent:G,title:t(G?"Delete Collaborator Permanently":"Delete Collaborator"),onConfirm:Yt,loadBlockers:O?()=>qe.deletionBlockers(O.id):void 0}),e.jsx(me,{open:T!==null,onOpenChange:a=>!a&&Me(null),children:e.jsxs(he,{children:[e.jsxs(pe,{children:[e.jsx(xe,{children:t("Cancel this invitation?")}),e.jsx(ge,{children:T?`${T.email} ${t("comes off the list, and the link in their email stops working. You can invite them again later.")}`:""})]}),e.jsxs(fe,{children:[e.jsx(x,{variant:"outline",onClick:()=>Me(null),children:t("Keep it")}),e.jsx(x,{variant:"destructive",disabled:m,onClick:async()=>{T&&await we(T.id),Me(null)},children:t("Cancel invitation")})]})]})}),e.jsx(me,{open:Re!==null,onOpenChange:()=>Te(null),children:e.jsxs(he,{children:[e.jsxs(pe,{children:[e.jsx(xe,{children:Re==="add"?"Add to Program":"Remove from Program"}),e.jsx(ge,{children:Re==="add"?`Select a program to add ${P.size} collaborator(s) to.`:`Select a program to remove ${P.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:e.jsxs(oe,{value:Ge,onValueChange:dt,children:[e.jsx(ne,{"aria-label":t("Select a program"),children:e.jsx(ie,{placeholder:t("Select a program")})}),e.jsx(de,{children:Z.map(a=>{const D=!!a.collaboratorGroupId;return e.jsxs(R,{value:a.id.toString(),disabled:D,children:[e.jsx("span",{className:D?"line-through opacity-60":"",children:a.name}),D&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:t("uses a collaborator group")})]},a.id)})})]})}),e.jsxs(fe,{children:[e.jsx(x,{variant:"outline",onClick:()=>Te(null),children:t("Cancel")}),e.jsx(x,{onClick:ss,disabled:!Ge||m,children:m?"Processing...":"Confirm"})]})]})}),e.jsx(me,{open:Fe!==null,onOpenChange:()=>et(null),children:e.jsxs(he,{children:[e.jsxs(pe,{children:[e.jsx(xe,{children:Fe==="add"?"Add to Collaborator Group":"Remove from Collaborator Group"}),e.jsx(ge,{children:Fe==="add"?`Select a group to add ${P.size} collaborator(s) to.`:`Select a group to remove ${P.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:Ae.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:t("No collaborator groups exist yet.")}):e.jsxs(oe,{value:Ue,onValueChange:ct,children:[e.jsx(ne,{"aria-label":t("Select a group"),children:e.jsx(ie,{placeholder:t("Select a group")})}),e.jsx(de,{children:Ae.map(a=>e.jsx(R,{value:a.id.toString(),children:a.name},a.id))})]})}),e.jsxs(fe,{children:[e.jsx(x,{variant:"outline",onClick:()=>et(null),children:t("Cancel")}),e.jsx(x,{onClick:as,disabled:!Ue||m,children:m?"Processing...":"Confirm"})]})]})}),e.jsx(me,{open:Oe!==null,onOpenChange:()=>tt(null),children:e.jsxs(he,{children:[e.jsxs(pe,{children:[e.jsx(xe,{children:Oe==="add"?"Add to Distributor":"Remove from Distributor"}),e.jsx(ge,{children:Oe==="add"?`Select a distributor to add ${P.size} collaborator(s) to.`:`Select a distributor to remove ${P.size} collaborator(s) from.`})]}),e.jsx("div",{className:"py-4",children:ae.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:t("No distributors exist yet.")}):e.jsxs(oe,{value:Ve,onValueChange:ut,children:[e.jsx(ne,{"aria-label":t("Select a distributor"),children:e.jsx(ie,{placeholder:t("Select a distributor")})}),e.jsx(de,{children:ae.map(a=>{const D=!!a.collaboratorGroupId;return e.jsxs(R,{value:a.id.toString(),disabled:D,children:[e.jsx("span",{className:D?"line-through opacity-60":"",children:a.name}),D&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:t("uses a collaborator group")})]},a.id)})})]})}),e.jsxs(fe,{children:[e.jsx(x,{variant:"outline",onClick:()=>tt(null),children:t("Cancel")}),e.jsx(x,{onClick:rs,disabled:!Ve||m,children:m?"Processing...":"Confirm"})]})]})})]})}function Nt(){const{translate:s}=V(),n={active:s("Active"),pending:s("Pending"),inactive:s("Inactive"),rejected:s("Rejected"),deleted:s("Trashed"),invited:s("Invited")},j=Object.entries(n).filter(([d])=>d!=="deleted"&&d!=="invited"),{id:g}=Lt(),i=We(),f=!g,{current:c,isLoading:L,isSubmitting:b,error:S,fetchOne:r,create:N,update:y,clearCurrent:k,clearError:I}=ot(),{items:u,total:m,page:w,perPage:$,totalPages:o,isLoading:h,fetchList:A}=Et(),{items:_,total:be,page:Ke,perPage:Je,totalPages:Xe,isLoading:ve,fetchList:ye}=Rt(),[ee,Be]=l.useState([]),[Ce,Ne]=l.useState(new Map),we=l.useRef(new Set),[z,Z]=l.useState({email:"",fullName:"",nickname:"",status:"active",trackingId:"",distributorIds:[]}),[Se,Ae]=l.useState([]),[ke,ae]=l.useState(!1),Q=bt({getCandidateStagingId:d=>d.id}),te=bt({getCandidateStagingId:d=>d.id}),Ie=async()=>{ae(!0);try{const d=await qe.generateReferralCode();q("trackingId",d.code)}catch{}finally{ae(!1)}},Le=[{field:"fullName",validate:jt("Full name is required")},{field:"email",validate:jt("Email is required")},{field:"email",validate:fs(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,"Please enter a valid email address")}];l.useEffect(()=>(I(),A({perPage:10,status:"active,inactive,pending,draft"}),g?r(parseInt(g)):(k(),Z({email:"",fullName:"",nickname:"",status:"active",trackingId:"",distributorIds:[]}),qe.generateReferralCode().then(d=>{Z(v=>({...v,trackingId:d.code}))}).catch(()=>{})),()=>{k()}),[g,r,k,I,A,ye,!1]),l.useEffect(()=>{var d;c&&Z({email:c.email,fullName:c.fullName,nickname:c.nickname||"",status:c.status,trackingId:c.referralCode||"",distributorIds:((d=c.distributors)==null?void 0:d.map(v=>v.id))||[]})},[c]);const re=async d=>{d.preventDefault();const v=gs(z,Le);if(Ae(v.errors),!v.valid)return;const C=new Set(((c==null?void 0:c.programs)??[]).map(T=>T.id)),Pe=[...Array.from(C).filter(T=>!Q.pendingRemovalIds.has(T)),...Q.pendingAdditions.map(T=>T.id)],O=new Set((c==null?void 0:c.groupIds)??[]);[...Array.from(O).filter(T=>!te.pendingRemovalIds.has(T)),...te.pendingAdditions.map(T=>T.id)];const H={...z,programIds:Pe};try{f?await N(H):await y(parseInt(g),H),Q.reset(),te.reset(),i("/collaborators")}catch{}},q=(d,v)=>{Z(C=>({...C,[d]:v}))},p=c==null?void 0:c.programs;l.useEffect(()=>{if(h)return;const d=new Set(u.map(C=>C.id)),v=(p??[]).filter(C=>!d.has(C.id)&&!we.current.has(C.id)).slice(0,25);v.length!==0&&(v.forEach(C=>we.current.add(C.id)),Promise.all(v.map(C=>Ds.get(C.id).catch(()=>null))).then(C=>{Ne(Pe=>{const O=new Map(Pe);return C.forEach(H=>{H&&O.set(H.id,H)}),O})}))},[p,u,h]);const $e=l.useMemo(()=>{const d=new Map([...Ce,...u.map(v=>[v.id,v])]);return(p??[]).map(v=>{const C=d.get(v.id);return C||{id:v.id,name:v.name??`${s("Program")} #${v.id}`,description:"",status:"",incentiveType:"",incentiveResolverType:"",units:""}})},[p,u,Ce,s]);l.useMemo(()=>{const d=new Map(_.map(v=>[v.id,v]));return((c==null?void 0:c.groupIds)??[]).map(v=>{const C=d.get(v);return C||{id:v,name:`${s("Group")} #${v}`,description:"",structure:"flat"}})},[c==null?void 0:c.groupIds,_,s]);const B=[{id:"name",header:s("Name"),cell:d=>d.name},{id:"description",header:s("Description"),cell:d=>d.description||"—"},{id:"status",header:s("Status"),cell:d=>d.status?e.jsx(vt,{status:d.status}):"—"}];s("Name"),s("Description"),s("Structure");const Ee=[{id:"name",header:s("Name"),cell:d=>d.name},{id:"description",header:s("Description"),cell:d=>d.description||"—"},{id:"status",header:s("Status"),cell:d=>d.status?e.jsx(vt,{status:d.status}):"—"}];return s("Name"),s("Description"),L&&!f?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ye,{})}):e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:s(f?"New Collaborator":"Edit Collaborator")}),S&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:S}),e.jsxs("form",{onSubmit:re,className:"space-y-6",children:[e.jsxs(Y,{children:[e.jsx(K,{children:e.jsx(J,{children:s("Basic Information")})}),e.jsxs(X,{className:"space-y-4",children:[e.jsx(ze,{label:"Full Name",htmlFor:"fullName",required:!0,error:ft(Se,"fullName"),children:e.jsx(ue,{id:"fullName",value:z.fullName,onChange:d=>q("fullName",d.target.value),placeholder:s("e.g., John Smith")})}),e.jsx(ze,{label:"Email",htmlFor:"email",required:!0,error:ft(Se,"email"),children:e.jsx(ue,{id:"email",type:"email",value:z.email,onChange:d=>q("email",d.target.value),placeholder:s("e.g., john@example.com")})}),e.jsx(ze,{label:"Nickname",htmlFor:"nickname",description:"Optional display name or alias",children:e.jsx(ue,{id:"nickname",value:z.nickname||"",onChange:d=>q("nickname",d.target.value),placeholder:s("e.g., Johnny")})}),e.jsx(ze,{label:e.jsxs("span",{children:["Referral Code",e.jsx(De,{topic:"referral-code",side:"right"})]}),htmlFor:"trackingId",description:"Used in tracking URLs: yoursite.com/?ref=CODE",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ue,{id:"trackingId",value:z.trackingId||"",onChange:d=>q("trackingId",d.target.value),placeholder:s("e.g., johnsmith"),className:"font-mono flex-1"}),e.jsx(x,{type:"button",variant:"outline",size:"icon",onClick:Ie,disabled:ke,title:s("Generate random code"),children:e.jsx(qs,{className:`h-4 w-4 ${ke?"animate-spin":""}`})})]})}),e.jsx(ze,{label:e.jsxs("span",{children:["Status",e.jsx(De,{topic:"collaborator-status",side:"right"})]}),htmlFor:"status",description:z.status==="pending"?s("A pending collaborator is not credited for visits or sales yet. Choose Active to start crediting them now, or activate them later from the Collaborators list."):void 0,children:z.status==="invited"?e.jsx("p",{id:"status",className:"text-sm text-muted-foreground","data-testid":"invited-status",children:s("Invited. They become a collaborator when they accept the invitation.")}):e.jsxs(oe,{value:z.status,onValueChange:d=>q("status",d),children:[e.jsx(ne,{id:"status",children:e.jsx(ie,{})}),e.jsx(de,{children:j.map(([d,v])=>e.jsx(R,{value:d,children:v},d))})]})})]})]}),e.jsx(bs,{title:s("Programs"),description:s("Programs this collaborator is enrolled in"),helpTopic:"what-is-program",currentItems:$e,currentColumns:B,emptyCurrentMessage:s("No programs assigned yet."),getCurrentStagingId:d=>d.id,staged:Q,pendingAdditionColumns:Ee,getCandidateStagingId:d=>d.id,pickerTitle:s("Add Programs"),pickerDescription:s("Select programs to enroll this collaborator in."),pickerCandidates:u,pickerColumns:Ee,pickerIsLoading:h,pickerPagination:{page:w,perPage:$,total:m,totalPages:o},onPickerParamsChange:({search:d,page:v,perPage:C})=>A({page:v,perPage:C,search:d,status:"active,inactive,pending,draft"}),onOpenPicker:()=>A({page:1,perPage:10,status:"active,inactive,pending,draft"}),addButtonLabel:s("Add Programs")}),!1,!1,e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{type:"submit",disabled:b,children:b?"Saving...":s(f?"Create":"Update")}),e.jsx(x,{type:"button",variant:"outline",onClick:()=>i("/collaborators"),children:s("Cancel")})]})]})]})}const wt=["id","status","displayLabel","lastTriggered","customerCollaborators"],St={list:t=>E.get("/opportunities",{collaboratorId:t==null?void 0:t.collaboratorId,status:t==null?void 0:t.status,offset:(t==null?void 0:t.offset)??0,number:(t==null?void 0:t.number)??50,fields:((t==null?void 0:t.fields)??wt).join(",")}),get:t=>E.get(`/opportunities/${t}`,{fields:wt.join(",")}),update:(t,s)=>E.put(`/opportunities/${t}`,s)},Xs=Tt((t,s)=>({ownedByCollaborator:[],isLoading:!1,error:null,fetchOwnedByCollaborator:async n=>{t({isLoading:!0,error:null});try{const j=await St.list({collaboratorId:n});t({ownedByCollaborator:j.items,isLoading:!1})}catch(j){t({error:j instanceof Error?j.message:"Failed to load owned customers",isLoading:!1})}},removeOwner:async(n,j,g=!1)=>{const i=s().ownedByCollaborator.find(c=>c.id===n),f=((i==null?void 0:i.customerCollaborators)??[]).map(c=>c.id).filter(c=>c!==j);try{await St.update(n,{customerCollaborators:f,...g?{cascadeRejectOnUnbind:[j]}:{}}),t({ownedByCollaborator:s().ownedByCollaborator.filter(c=>c.id!==n)})}catch(c){t({error:c instanceof Error?c.message:"Failed to remove owner"})}},clear:()=>t({ownedByCollaborator:[],error:null})}));function Zs({collaboratorId:t}){var $;const{translate:s}=V(),n={signup:s("Signed up there"),migration:s("Came with its migration"),dashboard:s("Linked here")},[j,g]=l.useState(null),[i,f]=l.useState([]),[c,L]=l.useState(""),[b,S]=l.useState(!1),[r,N]=l.useState(null),y=l.useCallback(async()=>{try{const[o,h]=await Promise.all([E.get(`/collaborators/${t}/stores`),Ts.list()]);g(o.stores??[]),f(h)}catch{g(null)}},[t]);l.useEffect(()=>{y()},[y]);const k=l.useCallback(async()=>{S(!0);try{await E.post(`/collaborators/${t}/merge/resend`),U.success(s("Siren emailed a new confirmation link."))}catch(o){U.error(o instanceof Error?o.message:s("Failed to send the email."))}finally{S(!1)}},[t,s]),I=l.useCallback(async(o,h)=>{S(!0);try{h?await E.put(`/collaborators/${t}/stores/${o}`):await E.delete(`/collaborators/${t}/stores/${o}`),L(""),await y()}catch(A){U.error(A instanceof Error?A.message:s("Failed to change the collaborator’s properties."))}finally{S(!1)}},[t,y,s]);if(j===null)return null;const u=r===null?"":(($=i.find(o=>o.id===r))==null?void 0:$.name)??`#${r}`,m=o=>{var h;return((h=i.find(A=>A.id===o))==null?void 0:h.name)??s("Property #%d").replace("%d",String(o))},w=i.filter(o=>!j.some(h=>h.propertyId===o.id));return e.jsxs(Y,{"data-testid":"collaborator-properties",children:[e.jsx(K,{children:e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(_s,{className:"h-4 w-4","aria-hidden":"true"}),s("Properties"),e.jsx(De,{topic:"collaborator-properties",side:"right"})]})}),e.jsxs(X,{className:"space-y-3",children:[j.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No property works with this collaborator.")}):e.jsx("ul",{className:"space-y-2",children:j.map(o=>e.jsxs("li",{className:"flex items-center justify-between gap-2 text-sm",children:[e.jsxs("span",{className:"min-w-0 break-words",children:[e.jsx(F,{to:`/properties/${o.propertyId}`,className:"text-primary hover:underline",children:m(o.propertyId)}),e.jsx("span",{className:"block text-xs text-muted-foreground",children:n[o.source]??o.source}),o.mergeInto?e.jsxs("span",{className:"block text-xs text-muted-foreground","data-testid":`pending-merge-${o.propertyId}`,children:[s("Waiting for %s to confirm this record joins collaborator %d.").replace("%s",o.email||s("the person")).replace("%d",String(o.mergeInto))," ",e.jsx(x,{variant:"link",size:"sm",className:"h-auto p-0",disabled:b,onClick:k,children:s("Resend email")})]}):null]}),e.jsx(x,{variant:"ghost",size:"icon",disabled:b,onClick:()=>N(o.propertyId),"aria-label":s("Remove from %s").replace("%s",m(o.propertyId)),children:e.jsx($t,{className:"h-4 w-4"})})]},o.propertyId))}),w.length>0?e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(oe,{value:c,onValueChange:L,children:[e.jsx(ne,{className:"flex-1","aria-label":s("Property to add"),children:e.jsx(ie,{placeholder:s("Add to a property")})}),e.jsx(de,{children:w.map(o=>e.jsx(R,{value:String(o.id),children:o.name},o.id))})]}),e.jsx(x,{variant:"outline",disabled:b||c==="",onClick:()=>I(Number(c),!0),children:s("Add")})]}):null]}),e.jsx(zt,{open:r!==null,onOpenChange:o=>!o&&N(null),title:s("Remove from %s?").replace("%s",u),description:s("%s stops working with this collaborator. You can add it back later.").replace("%s",u),confirmLabel:s("Remove"),busyLabel:s("Removing..."),onConfirm:()=>r!==null?I(r,!1):void 0})]})}function Qs({collaboratorId:t,name:s}){const{translate:n}=V(),{isWordPress:j}=He(),g=Fs("coupon"),[i,f]=l.useState(null),[c,L]=l.useState([]),[b,S]=l.useState(!1),[r,N]=l.useState(null),[y,k]=l.useState(0),[I,u]=l.useState(!1),m=l.useCallback(async()=>{try{const o=[];let h=1;for(;;){const A=await Bt({holderId:t,page:h,perPage:100});if(o.push(...A.items),A.items.length<A.perPage||o.length>=A.total)break;h+=1}f(o),u(!1)}catch{f([]),u(!0)}},[t]);l.useEffect(()=>{g!==void 0&&m()},[g,m,y]),l.useEffect(()=>{if(g===void 0||j)return;let o=!1;return Os().then(h=>{o||L(h)}).catch(()=>{o||L([])}),()=>{o=!0}},[g,j]);const w=l.useMemo(()=>zs(c),[c]),$=()=>{S(!1),N(null),k(o=>o+1)};return g===void 0||!g.available&&(i===null||i.length===0)?null:e.jsxs(Y,{"data-testid":"collaborator-coupon-codes","data-tour":"collaborator-coupons",children:[e.jsxs(K,{className:"flex flex-row flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs(J,{className:"flex items-center",children:[n("Coupon codes"),e.jsx(De,{topic:"coupon-codes",side:"right"})]}),e.jsx(ce,{children:n("Codes that credit this collaborator")})]}),g.available?e.jsx(x,{size:"sm",variant:"outline",onClick:()=>S(!0),children:n("Link a coupon")}):null]}),e.jsx(X,{children:i===null?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(Ye,{size:32,label:""})}):I?e.jsx("p",{className:"text-sm text-destructive",role:"alert",children:n("The coupon codes could not be loaded.")}):i.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:n("{name} has no coupon codes. Link a coupon to credit {name} for sales that use it.").replace(/\{name\}/g,s)}):e.jsx("ul",{className:"divide-y","aria-label":n("Coupon codes"),children:i.map(o=>e.jsxs("li",{className:"flex items-start justify-between gap-2 py-2",children:[e.jsxs("div",{className:"min-w-0 space-y-1",children:[e.jsx("div",{className:"font-mono text-sm font-medium",children:o.code}),e.jsx(Bs,{identities:o.identities,names:w,singleStore:j}),e.jsx("div",{className:"text-xs text-muted-foreground",children:n("{count} uses").replace("{count}",String(o.uses.count))})]}),o.currency===null?e.jsx(x,{size:"sm",variant:"outline",onClick:()=>N(o),children:n("Unlink")}):null]},o.id))})}),b?e.jsx(ea,{collaboratorId:t,name:s,names:w,singleStore:j,onClose:()=>S(!1),onLinked:$}):null,r?e.jsx(Ms,{coupon:r,onClose:()=>N(null),onSaved:$}):null]})}function ea({collaboratorId:t,name:s,names:n,singleStore:j,onClose:g,onLinked:i}){var $;const{translate:f}=V(),[c,L]=l.useState(""),[b,S]=l.useState([]),[r,N]=l.useState(null),[y,k]=l.useState(!1),[I,u]=l.useState(!0);l.useEffect(()=>{let o=!1;const h=c.trim();u(!0);const A=window.setTimeout(()=>{Bt(h===""?{linked:!1,perPage:10}:{search:h,perPage:10}).then(_=>{o||S(_.items.filter(be=>be.currency===null&&be.holderId!==t))}).catch(()=>{o||S([])}).finally(()=>{o||u(!1)})},250);return()=>{o=!0,window.clearTimeout(A)}},[c,t]);const m=async o=>{k(!0);try{await Us(o.id,t),U.success(f("{code} now credits {collaborator}.").replace("{code}",o.code).replace("{collaborator}",s)),i()}catch(h){U.error(h instanceof Error&&h.message?h.message:f("Could not link the coupon code."))}finally{k(!1)}},w=o=>{o.holderId!==null?N(o):m(o)};return e.jsx(me,{open:!0,onOpenChange:o=>!o&&g(),children:e.jsxs(he,{className:"max-h-[90vh] overflow-y-auto",children:[e.jsxs(pe,{children:[e.jsx(xe,{children:f("Link a coupon to {collaborator}").replace("{collaborator}",s)}),e.jsx(ge,{children:f("Sales that use the code will credit {collaborator}.").replace("{collaborator}",s)})]}),r?e.jsx("p",{className:"rounded-md border bg-muted/40 px-3 py-2 text-sm","data-testid":"coupon-move-warning",children:f("{code} is currently linked to {holder}. Link it to {collaborator} instead?").replace("{code}",r.code).replace("{holder}",(($=r.holder)==null?void 0:$.name)??f("another collaborator")).replace("{collaborator}",s)}):e.jsxs("div",{className:"space-y-2",children:[e.jsx(rt,{htmlFor:"link-coupon-search",children:f("Find a coupon code")}),e.jsx(ue,{id:"link-coupon-search",value:c,onChange:o=>L(o.target.value),placeholder:f("Search codes")}),e.jsx("ul",{className:"max-h-60 divide-y overflow-y-auto rounded-md border","aria-label":f("Coupon codes found"),children:b.length===0?e.jsx("li",{className:"px-3 py-2 text-sm text-muted-foreground",children:f(I?"Searching...":"No coupon codes found.")}):b.map(o=>e.jsx("li",{children:e.jsxs("button",{type:"button",disabled:y,onClick:()=>w(o),className:"flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm hover:bg-muted",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block font-mono font-medium",children:o.code}),e.jsx("span",{className:"block truncate text-xs text-muted-foreground",children:o.identities.map(h=>Gs(h,n,f,j)).join(", ")})]}),e.jsx("span",{className:"shrink-0 text-xs text-muted-foreground",children:o.holder?f("Currently linked to {holder}").replace("{holder}",o.holder.name):f("Link")})]})},o.id))})]}),e.jsx(fe,{children:r?e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"outline",onClick:()=>N(null),disabled:y,children:f("Back")}),e.jsx(x,{onClick:()=>void m(r),disabled:y,children:f("Link to {collaborator}").replace("{collaborator}",s)})]}):e.jsx(x,{variant:"outline",onClick:g,children:f("Cancel")})})]})})}const kt=10,_e={list:(t={})=>{var s;return E.get("/products",{search:((s=t.search)==null?void 0:s.trim())||void 0,propertyId:t.propertyId,integration:t.integration||void 0,ownerId:t.ownerId,sold:t.sold?1:void 0,hasMatches:t.hasMatches?1:void 0,page:t.page??1,perPage:t.perPage??25})},get:t=>E.get(`/products/${t}`).then(s=>s.product),rename:(t,s)=>E.patch(`/products/${t}`,{name:s}).then(n=>n.product),setOwners:(t,s)=>E.put(`/products/${t}/owners`,{owners:s}).then(n=>n.product),add:t=>E.post("/products",t).then(s=>s.product),matches:t=>E.get(`/products/${t}/matches`).then(s=>s.matches),dismissMatch:(t,s)=>E.post(`/products/${t}/matches/${s}/dismiss`,{}).then(n=>n.matches),previewMerge:(t,s)=>E.post("/products/merge/preview",{survivorId:t,productIds:s}),merge:t=>E.post("/products/merge",t).then(s=>s.product),splitListing:(t,s)=>E.post(`/products/${t}/listings/${s}/split`,{}).then(n=>n.product)};function ta(t){return t.listings.filter(s=>!s.removed)}const at=10;function sa({collaboratorId:t}){const{translate:s}=V(),[n,j]=l.useState([]),[g,i]=l.useState(!0),[f,c]=l.useState(!1),[L,b]=l.useState(0),[S,r]=l.useState(!1),[N,y]=l.useState(null);l.useEffect(()=>{let u=!1;return i(!0),_e.list({ownerId:t,perPage:100}).then(m=>{u||(j(m.products),r(!1))}).catch(()=>{u||(j([]),r(!0))}).finally(()=>{u||i(!1)}),()=>{u=!0}},[t,L]);const k=async u=>{try{await _e.setOwners(u.id,u.owners.filter(m=>m.id!==t).map(m=>m.id)),U.success(s("Unlinked %s.").replace("%s",u.name)),b(m=>m+1)}catch(m){U.error(m instanceof Error?m.message:s("The product could not be changed."))}},I=async u=>{c(!1);for(const m of u)try{await _e.setOwners(m.id,[...m.owners.map(w=>w.id),t])}catch(w){U.error(w instanceof Error?`${m.name}: ${w.message}`:s("The product could not be changed."))}b(m=>m+1)};return e.jsxs(Y,{children:[e.jsx(K,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(J,{className:"flex items-center",children:[s("Products"),e.jsx(De,{topic:"product-owners",side:"right"})]}),e.jsxs(x,{size:"sm",variant:"outline",onClick:()=>c(!0),children:[e.jsx(nt,{className:"h-4 w-4","aria-hidden":"true"}),s("Link to a product")]})]})}),e.jsx(X,{children:g?e.jsx("div",{className:"flex justify-center py-4",children:e.jsx(Ye,{size:32,label:""})}):S?e.jsx("p",{className:"text-sm text-destructive",role:"alert",children:s("The products could not be loaded.")}):n.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("This collaborator owns no products.")}):e.jsx("ul",{className:"space-y-2",children:n.map(u=>e.jsxs("li",{className:"flex items-center justify-between gap-2 text-sm",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx(cs,{to:`/products/${u.id}`,className:"font-medium text-primary hover:underline",children:u.name}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:ta(u).map(m=>As(m.integration)).filter((m,w,$)=>$.indexOf(m)===w).join(", ")||s("Not sold anywhere now")})]}),e.jsxs(x,{size:"sm",variant:"outline",onClick:()=>y(u),"aria-label":`${s("Unlink")} ${u.name}`,children:[e.jsx($t,{className:"h-4 w-4","aria-hidden":"true"}),s("Unlink")]})]},u.id))})}),e.jsx(zt,{open:N!==null,onOpenChange:u=>!u&&y(null),title:s("Unlink product"),description:s("This collaborator stops earning from %s on every store that sells it.").replace("%s",(N==null?void 0:N.name)??""),confirmLabel:s("Unlink"),busyLabel:s("Unlinking..."),onConfirm:()=>N?k(N):void 0}),e.jsx(aa,{open:f,excluded:new Set(n.map(u=>u.id)),onClose:()=>c(!1),onPick:I})]})}function aa({open:t,excluded:s,onClose:n,onPick:j}){const{translate:g}=V(),[i,f]=l.useState([]),[c,L]=l.useState(0),[b,S]=l.useState(1),[r,N]=l.useState(!1),y=l.useCallback(async u=>{N(!0);try{const m=await _e.list({search:u.search,page:u.page,perPage:u.perPage});f(m.products),L(m.total),S(u.page)}catch(m){U.error(m instanceof Error?m.message:g("The products could not be loaded."))}finally{N(!1)}},[g]);l.useEffect(()=>{t&&y({search:"",page:1,perPage:at})},[t,y]);const k=[{id:"name",header:g("Product"),cell:u=>u.name},{id:"owners",header:g("Owners"),cell:u=>`${u.owners.length} / ${kt}`}],I=new Set(s);return i.forEach(u=>{u.owners.length>=kt&&I.add(u.id)}),e.jsx(Vs,{open:t,onOpenChange:u=>!u&&n(),title:g("Link to a product"),description:g("This collaborator earns from the products you pick, on every store that sells them."),excludedIds:I,items:i,isLoading:r,total:c,page:b,perPage:at,totalPages:Math.max(1,Math.ceil(c/at)),onParamsChange:y,columns:k,onAdd:u=>j(i.filter(m=>u.includes(m.id)))})}const ra=64,It=1e3;function la(t){let s=t.trim().replace(/([a-z0-9])(?=[A-Z])/g,"$1 ");return s=s.normalize("NFD").replace(new RegExp("\\p{M}+","gu"),"").replace(/ß/g,"ss"),s=s.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,""),s===""?null:(/^[a-z]/.test(s)||(s=`field_${s}`),s=s.slice(0,ra).replace(/_+$/,""),/^[a-z][a-z0-9_]{0,63}$/.test(s)?s:null)}function oa({collaboratorId:t,fields:s}){const{translate:n}=V(),[j,g]=l.useState(s),[i,f]=l.useState(null),[c,L]=l.useState(""),[b,S]=l.useState(""),[r,N]=l.useState(!1),y=Object.keys(j).sort(),k=(i==null?void 0:i.mode)==="add"?la(c):null,I=(i==null?void 0:i.mode)==="add"?k:(i==null?void 0:i.key)??null,u=(i==null?void 0:i.mode)==="add"&&k!==null&&k in j,m=h=>{f(h),L(""),S(h.mode==="edit"?j[h.key]??"":"")},w=()=>{r||f(null)},$=async(h,A)=>{N(!0);try{g(await qe.updateFields(t,h)),U.success(A),f(null)}catch(_){U.error(_ instanceof Error?_.message:n("The custom field could not be saved."))}finally{N(!1)}},o=async h=>{h.preventDefault(),!(I===null||b.trim()==="")&&await $({[I]:b},n("Custom field saved"))};return e.jsxs(Y,{children:[e.jsx(K,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx(J,{children:n("Custom fields")}),e.jsx(ce,{children:n("Extra details you keep about this collaborator")})]}),e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>m({mode:"add"}),children:[e.jsx(nt,{className:"h-3.5 w-3.5 mr-1"}),n("Add field")]})]})}),e.jsx(X,{children:y.length>0?e.jsx("ul",{className:"space-y-3",children:y.map(h=>e.jsxs("li",{className:"flex items-start justify-between gap-2",children:[e.jsxs("dl",{className:"min-w-0 flex-1",children:[e.jsx("dt",{className:"text-sm text-muted-foreground font-mono break-all",children:h}),e.jsx("dd",{className:"font-medium break-words whitespace-pre-wrap",children:j[h]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(x,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":n("Edit %s").replace("%s",h),onClick:()=>m({mode:"edit",key:h}),children:e.jsx(Ft,{className:"h-4 w-4"})}),e.jsx(x,{variant:"ghost",size:"icon",className:"h-8 w-8","aria-label":n("Remove %s").replace("%s",h),onClick:()=>m({mode:"remove",key:h}),children:e.jsx(ws,{className:"h-4 w-4"})})]})]},h))}):e.jsx("p",{className:"text-muted-foreground text-sm",children:n("No custom fields yet.")})}),e.jsx(me,{open:i!==null&&i.mode!=="remove",onOpenChange:h=>{h||w()},children:e.jsx(he,{className:"sm:max-w-md",children:e.jsxs("form",{onSubmit:o,className:"space-y-4",children:[e.jsxs(pe,{children:[e.jsx(xe,{children:(i==null?void 0:i.mode)==="edit"?n("Edit custom field"):n("Add custom field")}),e.jsx(ge,{children:(i==null?void 0:i.mode)==="edit"?e.jsx("span",{className:"font-mono break-all",children:i.key}):n("Keep any detail about this collaborator, such as the ID they had in another system.")})]}),(i==null?void 0:i.mode)==="add"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(rt,{htmlFor:"custom-field-name",children:n("Name")}),e.jsx(ue,{id:"custom-field-name",value:c,onChange:h=>L(h.target.value),placeholder:n("Shirt size"),autoFocus:!0}),e.jsx("p",{className:"text-xs text-muted-foreground","aria-live":"polite",children:c.trim()===""?n("Letters, digits and spaces work best."):k===null?n("Use at least one letter or digit."):e.jsxs(e.Fragment,{children:[n("Saved as")," ",e.jsx("span",{className:"font-mono break-all",children:k}),".",u&&` ${n("This replaces the value it has now.")}`]})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(rt,{htmlFor:"custom-field-value",children:n("Value")}),e.jsx("textarea",{id:"custom-field-value",value:b,onChange:h=>S(h.target.value),maxLength:It,rows:3,autoFocus:(i==null?void 0:i.mode)==="edit",className:"flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:`${b.length} / ${It}`})]}),e.jsxs(fe,{className:"gap-2",children:[e.jsx(x,{type:"button",variant:"outline",onClick:w,disabled:r,children:n("Cancel")}),e.jsx(x,{type:"submit",disabled:r||I===null||b.trim()==="",children:n(r?"Saving...":"Save")})]})]})})}),e.jsx(me,{open:(i==null?void 0:i.mode)==="remove",onOpenChange:h=>{h||w()},children:e.jsxs(he,{className:"sm:max-w-md",children:[e.jsxs(pe,{children:[e.jsx(xe,{children:n("Remove custom field?")}),e.jsx(ge,{children:(i==null?void 0:i.mode)==="remove"?n("%s is removed from this collaborator.").replace("%s",i.key):null})]}),e.jsxs(fe,{className:"gap-2",children:[e.jsx(x,{variant:"outline",onClick:w,disabled:r,children:n("Cancel")}),e.jsx(x,{variant:"destructive",disabled:r,onClick:()=>(i==null?void 0:i.mode)==="remove"&&void $({[i.key]:""},n("Custom field removed")),children:n(r?"Removing...":"Remove")})]})]})})]})}const na={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red",deleted:"status-badge status-red",invited:"status-badge status-blue"},ia={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},da={approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"};function Pt(){const{translate:t}=V(),{formatMoney:s,formatShownMoney:n,definitionFor:j}=Rs(),g={active:t("Active"),pending:t("Pending"),inactive:t("Inactive"),rejected:t("Rejected"),deleted:t("Trashed"),invited:t("Invited")},{id:i}=Lt(),f=We(),{isWordPress:c,extensions:L,planAllows:b}=He(),S=L.collaboratorApplications,{current:r,isLoading:N,error:y,fetchOne:k,clearCurrent:I}=ot(),[u,m]=l.useState(!1),[w,$]=l.useState(""),[o,h]=l.useState(""),[A,_]=l.useState(""),[be,Ke]=l.useState(!1),[Je,Xe]=l.useState(void 0),ve=w?j(w):void 0,ye=Number(o),ee=ve&&o!==""&&Number.isFinite(ye)?us(ye,ve):0;ve?ee>0?`${t("Adds")} ${s(ee,w)}.`:ee<0?`${t("Deducts")} ${s(-ee,w)}.`:`${t("Type the amount as the balance shows it. 5 means")} ${n(5,w)}.`:t("Choose a currency first.");const{items:Be,isLoading:Ce,fetchList:Ne}=$s(),{items:we,isLoading:z,fetchList:Z}=Es(),{ownedByCollaborator:Se,isLoading:Ae,fetchOwnedByCollaborator:ke,removeOwner:ae,clear:Q}=Xs();l.useEffect(()=>{if(i){const p=parseInt(i);k(p),Ne({collaboratorId:p,perPage:10,status:"pending,approved,complete,rejected",orderBy:"dateCreated",order:"desc"}),Z({collaboratorId:p,perPage:10,status:"approved,complete,rejected",orderBy:"dateCreated",order:"desc"})}return()=>{I(),Q()}},[i,k,I,Ne,Z,ke,Q]);const te=p=>p?new Date(p).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",Ie=(p,$e)=>s(p,$e),Le=[{id:"id",header:t("ID"),cell:p=>e.jsxs(F,{to:`/conversions/${p.id}`,className:"font-mono text-primary hover:underline",children:["#",p.id]})},{id:"type",header:t("Type"),cell:p=>e.jsx("span",{className:"capitalize",children:p.type})},{id:"amount",header:t("Amount"),cell:p=>Ie(p.amount,p.obligationAwardType)},{id:"status",header:t("Status"),cell:p=>e.jsx("span",{className:ia[p.status],children:p.status})},{id:"date",header:t("Date"),cell:p=>te(p.dateCreated)}],re=[{id:"id",header:t("ID"),cell:p=>e.jsxs(F,{to:`/obligations/${p.id}`,className:"font-mono text-primary hover:underline",children:["#",p.id]})},{id:"value",header:t("Value"),cell:p=>Ie(p.value,p.awardType)},{id:"status",header:t("Status"),cell:p=>e.jsx("span",{className:da[p.status],children:p.status})},{id:"date",header:t("Date"),cell:p=>te(p.dateCreated)}];if(N)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ye,{label:t("Loading collaborator...")})});if(y)return e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:y});if(!r)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx("p",{className:"text-muted-foreground",children:t("Collaborator not found.")})});const q="Programs";return r.distributors&&r.distributors.length>0?r.distributors:r.distributorId&&(r.distributorId,r.distributorName),r.groups&&r.groups.length>0?r.groups:(r.groupIds??[]).map(p=>({id:p})),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!c&&e.jsx(x,{variant:"ghost",size:"icon",onClick:()=>f("/collaborators"),"aria-label":t("Back"),children:e.jsx(Mt,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]","data-tour":"collaborator-heading",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:je(r)}),e.jsx("span",{className:na[r.status],children:g[r.status]})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:r.email})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ot,{sourceType:"collaborator",sourceId:r.id,contextLabel:je(r)}),e.jsx(x,{asChild:!0,children:e.jsxs(F,{to:`/collaborators/${r.id}/edit`,children:[e.jsx(Ft,{className:"h-4 w-4 mr-2"}),t("Edit Collaborator")]})})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2 lg:grid-cols-3",children:[S&&e.jsx(S,{collaboratorId:r.id,status:r.status,name:je(r),onChanged:()=>k(r.id)}),!c&&e.jsx(Zs,{collaboratorId:r.id}),e.jsx(Qs,{collaboratorId:r.id,name:je(r)}),!c&&e.jsx(sa,{collaboratorId:r.id}),e.jsxs(Y,{"data-tour":"collaborator-profile",children:[e.jsxs(K,{children:[e.jsx(J,{children:t("Profile")}),e.jsx(ce,{children:t("Collaborator information")})]}),e.jsxs(X,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Full Name")}),e.jsx("dd",{className:"font-medium",children:r.fullName})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Email")}),e.jsx("dd",{className:"font-medium",children:r.email})]}),r.nickname&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Nickname")}),e.jsx("dd",{className:"font-medium",children:r.nickname})]}),r.referralCode&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Tracking ID")}),e.jsx("dd",{className:"font-medium font-mono",children:r.referralCode})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("ID")}),e.jsx("dd",{className:"font-medium",children:r.id})]})]})]}),r.fields!==null&&e.jsx(oa,{collaboratorId:r.id,fields:r.fields??{}},r.id),e.jsxs(Y,{"data-tour":"collaborator-rewards",children:[e.jsxs(K,{children:[e.jsx(J,{children:t("Rewards Statistics")}),e.jsx(ce,{children:t("Obligation and payout summary")})]}),e.jsxs(X,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Unfulfilled Rewards")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(F,{to:`/obligations?collaboratorId=${r.id}&status=approved`,className:"text-primary hover:underline",children:[r.unfulfilledObligationCount??0," approved"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Fulfilled Rewards")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(F,{to:`/obligations?collaboratorId=${r.id}&status=complete`,className:"text-primary hover:underline",children:[r.fulfilledObligationCount??0," completed"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:t("Total Engagements")}),e.jsx("dd",{className:"font-medium",children:e.jsx(F,{to:`/engagements?collaboratorId=${r.id}`,className:"text-primary hover:underline",children:r.engagementsCount??0})})]})]})]}),!1,!1,e.jsxs(Y,{"data-tour":"collaborator-enrolled-programs",children:[e.jsxs(K,{children:[e.jsx(J,{children:q}),e.jsx(ce,{children:"Enrolled programs"})]}),e.jsxs(X,{children:[r.programs&&r.programs.length>0?e.jsx("ul",{className:"space-y-2",children:r.programs.map(p=>e.jsx("li",{children:e.jsx(F,{to:`/programs/${p.id}/view`,className:"text-primary hover:underline",children:p.name})},p.id))}):e.jsx("p",{className:"text-muted-foreground text-sm",children:t("Not enrolled in any programs")}),yt.distributors]})]}),!1,!1,!1,yt.customerOwnership]}),e.jsx("div",{className:"mt-8",children:e.jsxs(Y,{children:[e.jsxs(K,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(J,{children:t("Recent Conversions")}),e.jsx(ce,{children:t("Latest conversions from this collaborator")})]}),e.jsx(x,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(F,{to:`/conversions?collaboratorId=${r.id}`,children:t("View All")})})]}),e.jsx(X,{children:e.jsx(lt,{columns:Le,data:Be,isLoading:Ce,emptyMessage:t("No conversions yet.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(Y,{children:[e.jsxs(K,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(J,{children:t("Rewards")}),e.jsx(ce,{children:t("Reward obligations for this collaborator")})]}),e.jsx(x,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(F,{to:`/obligations?collaboratorId=${r.id}`,children:t("View All")})})]}),e.jsx(X,{children:e.jsx(lt,{columns:re,data:we,isLoading:z,emptyMessage:t("No rewards yet.")})})]})})]})}function ca({presetProgramIds:t,...s}){const n=l.useMemo(()=>t?{programIds:t}:void 0,[t]);return e.jsx(Ls,{type:"collaborators",presetChoices:n,...s})}function ua(){const{translate:t}=V(),s=We(),{isWordPress:n}=He();return e.jsxs("div",{className:"max-w-4xl",children:[e.jsxs("div",{className:"mb-6 flex flex-wrap items-center gap-x-4 gap-y-2",children:[!n&&e.jsx(x,{variant:"ghost",size:"icon",onClick:()=>s("/collaborators"),"aria-label":t("Back"),children:e.jsx(Mt,{className:"h-4 w-4"})}),e.jsx("h1",{className:"text-2xl font-semibold",children:t("Import collaborators")})]}),e.jsx(ca,{})]})}window.sirenConfig&&ms({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Dt=document.getElementById("siren-collaborators");Dt&&hs.createRoot(Dt).render(e.jsx(l.StrictMode,{children:e.jsxs(Ps,{defaultRoute:"/collaborators",children:[e.jsx(ps,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(xs,{children:[e.jsx(le,{path:"/collaborators",element:e.jsx(Ct,{})}),e.jsx(le,{path:"/collaborators/new",element:e.jsx(Nt,{})}),e.jsx(le,{path:"/collaborators/import",element:e.jsx(ua,{})}),e.jsx(le,{path:"/collaborators/:id",element:e.jsx(Pt,{})}),e.jsx(le,{path:"/collaborators/:id/view",element:e.jsx(Pt,{})}),e.jsx(le,{path:"/collaborators/:id/edit",element:e.jsx(Nt,{})}),e.jsx(le,{index:!0,element:e.jsx(Ct,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/conversions.js

    r3775642 r3788740  
    1 import{u as ue,b as Le,r as i,j as e,L as w,B as m,S as X,d as Z,e as J,f as Q,g as o,n as Fe,a as Be,w as ze,o as Ve,H as $e,X as Ee,C as v,p as b,q as y,s as N,x as A,v as le,E as Me,F as Oe,T as He,R as Ue,G as _}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as xe,c as We}from"./shared/conversions-HMIw6T3R.js";import{F as ee,H as Ke,a as qe,B as Ye,D as he}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as pe}from"./shared/ActivityDrawer-iYDgZTH3.js";import{T as Ge}from"./shared/TestSaleBadge-DCBR_ipH.js";import{u as Xe}from"./shared/useListRequest-CKMUCtxK.js";import{u as Ze}from"./shared/registries-Ql2SZeKd.js";import{l as ie,h as de}from"./shared/linked-record-D4sO5j3k.js";import{u as Je}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{h as Qe}from"./shared/obligation-hold-JyNfYYW_.js";import{A as _e}from"./shared/arrow-left-W0B3m2vw.js";import{W as es}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/react-zvEYxxW2.js";import"./shared/unshipped-CGZcvpGp.js";const ss={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},oe={sale:"Sale",lead:"Lead",renewal:"Renewal"};function ce(){const{translate:s}=ue(),D={pending:s("Pending"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},[r,u]=Le(),{items:L,total:S,page:c,perPage:F,totalPages:B,isLoading:t,isSubmitting:O,error:C,fetchList:I,bulkApprove:z,bulkReject:g,bulkMarkPending:V,bulkDelete:$,bulkPermanentDelete:k,bulkRestore:f}=xe(),E=r.get("status")||"all",T=r.get("type")||"all",H=r.get("transactionId")||"",p=r.get("collaboratorId")||"",n=r.get("programId")||"",[l,se]=i.useState(E),[x,te]=i.useState(T),[j,U]=i.useState(H),[ae,je]=i.useState(10),[W,ge]=i.useState("dateCreated"),[K,fe]=i.useState("desc"),[d,h]=i.useState(new Set),[q,ne]=i.useState(null),R=l==="deleted";i.useEffect(()=>{const a=r.get("status"),P=r.get("type"),G=r.get("transactionId");a&&a!==l&&se(a),P&&P!==x&&te(P),G&&G!==j&&U(G)},[r,l,x,j]),i.useEffect(()=>{h(new Set)},[l,x,j,p,n]);const ve=Xe(I,{perPage:ae,orderBy:W,order:K,status:l==="all"?"pending,approved,complete,rejected":l,type:x!=="all"?x:void 0,transactionId:j?parseInt(j):void 0,collaboratorId:p?parseInt(p):void 0,programId:n?parseInt(n):void 0}),re=a=>ve.setPage(a),be=a=>je(parseInt(a)),M=a=>{se(a),a!=="all"?r.set("status",a):r.delete("status"),u(r)},Y=a=>{te(a),a!=="all"?r.set("type",a):r.delete("type"),u(r)},ye=a=>{const P=W===a&&K==="asc"?"desc":"asc";ge(a),fe(P)},Ne=async()=>{await z(Array.from(d)),h(new Set)},we=async()=>{await g(Array.from(d)),h(new Set)},Se=async()=>{await V(Array.from(d)),h(new Set)},Ce=async()=>{ne(Array.from(d)),await $(Array.from(d)),h(new Set)},Ie=async()=>{d.size&&(await f(Array.from(d)),h(new Set))},ke=async()=>{d.size&&(await k(Array.from(d)),h(new Set))},Te=a=>new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),Re=[{id:"id",header:s("ID"),cell:a=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",a.id]}),a.isTest&&e.jsx(Ge,{})]})},{id:"obligationId",header:s("Obligation"),cell:a=>a.obligationId?e.jsxs(w,{to:`/obligations/${a.obligationId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",a.obligationId]}):"-"},{id:"transactionId",header:s("Transaction"),cell:a=>a.transactionId!=null?e.jsx(ee,{filterKey:"transactionId",filterValue:a.transactionId.toString(),children:e.jsxs("span",{className:"font-mono text-sm",children:["#",a.transactionId]})}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"type",header:s("Type"),sortable:!0,cell:a=>e.jsx(ee,{filterKey:"type",filterValue:a.type,children:oe[a.type]})},{id:"status",header:s("Status"),sortable:!0,cell:a=>e.jsx(ee,{filterKey:"status",filterValue:a.status,children:e.jsx("span",{className:ss[a.status],children:D[a.status]})})},{id:"dateCreated",header:s("Date"),sortable:!0,cell:a=>e.jsx("span",{className:"text-sm text-muted-foreground",children:Te(a.dateCreated)})},...R?[{id:"actions",header:s("Actions"),cell:a=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(m,{variant:"outline",size:"sm",onClick:()=>f([a.id]),children:s("Restore")}),e.jsx(m,{variant:"destructive",size:"sm",onClick:()=>k([a.id]),children:s("Delete Permanently")})]})}]:[]],Pe=R?[{label:s("Restore (Pending)"),onClick:Ie},{label:s("Delete Permanently"),onClick:ke,variant:"destructive",confirmMessage:`Permanently delete ${d.size} conversion(s)? This action cannot be undone.`,confirmItems:Array.from(d).map(a=>`Conversion #${a}`)}]:[{label:s("Approve"),onClick:Ne},{label:s("Reject"),onClick:we},{label:s("Mark as Pending"),onClick:Se},{label:s("Delete"),onClick:Ce,variant:"destructive",confirmMessage:`Delete ${d.size} conversion(s)? You can undo from Trash.`}],Ae=[{key:"status",label:"Status",value:l,displayValue:D[l]||l,onRemove:()=>M("all")},{key:"type",label:"Type",value:x,displayValue:oe[x]||x,onRemove:()=>Y("all")},...j?[{key:"transactionId",label:"Transaction",value:j,displayValue:`#${j}`,onRemove:()=>{U(""),r.delete("transactionId"),u(r)}}]:[],...p?[{key:"collaboratorId",label:"Collaborator",value:p,displayValue:`#${p}`,onRemove:()=>{r.delete("collaboratorId"),u(r)}}]:[],...n?[{key:"programId",label:"Program",value:n,displayValue:`#${n}`,onRemove:()=>{r.delete("programId"),u(r)}}]:[]],De=()=>{M("all"),Y("all"),U(""),r.delete("transactionId"),r.delete("collaboratorId"),r.delete("programId"),u(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Conversions"),e.jsx(Ke,{topic:"what-is-conversion",side:"right"})]}),e.jsx(pe,{sourceType:"conversion",contextLabel:"all conversions"})]}),e.jsx(qe,{filters:Ae,onClearAll:De}),C&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:C}),e.jsxs("div",{className:"flex gap-2 mb-4 flex-wrap",children:[e.jsxs(X,{value:l,onValueChange:M,children:[e.jsx(Z,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(J,{placeholder:s("Status")})}),e.jsxs(Q,{children:[e.jsx(o,{value:"all",children:s("All Statuses")}),e.jsx(o,{value:"pending",children:s("Pending")}),e.jsx(o,{value:"approved",children:s("Approved")}),e.jsx(o,{value:"complete",children:s("Complete")}),e.jsx(o,{value:"rejected",children:s("Rejected")}),e.jsx(o,{value:"deleted",children:s("Trashed")})]})]}),e.jsxs(X,{value:x,onValueChange:Y,children:[e.jsx(Z,{"aria-label":s("Filter by type"),className:"w-[120px]",children:e.jsx(J,{placeholder:s("Type")})}),e.jsxs(Q,{children:[e.jsx(o,{value:"all",children:s("All Types")}),e.jsx(o,{value:"sale",children:s("Sale")}),e.jsx(o,{value:"lead",children:s("Lead")}),e.jsx(o,{value:"renewal",children:s("Renewal")})]})]})]}),e.jsx(Ye,{selectedCount:d.size,actions:Pe,onClear:()=>h(new Set),isProcessing:O}),q&&q.length>0&&!R&&e.jsxs("div",{className:"mb-4 flex items-center justify-between rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm",children:[e.jsxs("div",{className:"text-amber-900",children:[e.jsx("span",{className:"font-medium",children:s("Conversions deleted.")})," You can undo this action."]}),e.jsx(m,{variant:"outline",size:"sm",onClick:async()=>{await f(q),ne(null)},children:s("Undo")})]}),e.jsx(he,{columns:Re,data:L,isLoading:t,emptyMessage:s("No conversions found."),selectable:!0,selectedIds:d,onSelectionChange:h,getRowHref:a=>`/conversions/${a.id}`,sortField:W,sortOrder:K,onSort:ye}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",S===0?0:(c-1)*F+1," to ",Math.min(c*F,S)," of"," ",S," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(X,{value:ae.toString(),onValueChange:be,children:[e.jsx(Z,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(J,{})}),e.jsxs(Q,{children:[e.jsx(o,{value:"10",children:"10"}),e.jsx(o,{value:"25",children:"25"}),e.jsx(o,{value:"50",children:"50"}),e.jsx(o,{value:"100",children:"100"})]})]})]})]}),B>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(m,{variant:"outline",size:"sm",disabled:c===1,onClick:()=>re(c-1),children:s("Previous")}),e.jsx(m,{variant:"outline",size:"sm",disabled:c===B,onClick:()=>re(c+1),children:s("Next")})]}),e.jsx(m,{variant:"link",className:"text-sm",onClick:()=>M(R?"all":"deleted"),children:s(R?"Back to active conversions":"Trash")})]})]})}const ts={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},as={sale:"Sale",lead:"Lead",renewal:"Renewal"},ns={draft:"status-badge status-gray",pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"};function rs(){const{translate:s}=ue(),{formatMoney:D}=Je(),r={pending:s("Pending"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},{transactionSources:u,fetchTransactionSources:L}=Ze(),S=i.useMemo(()=>Object.fromEntries(u.map(n=>[n.id,n.name])),[u]),{id:c}=Fe(),F=Be(),{isWordPress:B}=ze(),{current:t,isLoading:O,error:C,fetchOne:I,clearCurrent:z}=xe();i.useEffect(()=>{L()},[L]);const[g,V]=i.useState(null),$=async n=>{if(c){V(n);try{await We.bulk(n,[parseInt(c)]),le.success(s(n==="approve"?"Conversion approved":"Conversion rejected")),await I(parseInt(c))}catch(l){le.error(l instanceof Error?l.message:s("Failed to update conversion"))}finally{V(null)}}};i.useEffect(()=>(c&&I(parseInt(c)),()=>{z()}),[c,I,z]);const k=n=>new Date(n).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"}),f=(n,l)=>D(n,l);if(O)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ve,{})});if(C)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:C})});const E=(t==null?void 0:t.obligationId)??(t==null?void 0:t.draftObligationId),T=!!(t!=null&&t.obligationHoldReason),H=E?[{id:E,value:(t==null?void 0:t.obligationValue)??(t==null?void 0:t.amount)??void 0,status:t!=null&&t.obligationId?(t==null?void 0:t.obligationStatus)??void 0:"draft",awardType:(t==null?void 0:t.obligationAwardType)??void 0}]:[],p=[{id:"id",header:s("ID"),cell:n=>e.jsxs(w,{to:`/obligations/${n.id}`,className:"font-mono text-primary hover:underline",children:["#",n.id]})},{id:"value",header:s("Value"),cell:n=>e.jsx("span",{className:"font-medium",children:f(n.value,n.awardType)})},{id:"status",header:s("Status"),cell:n=>n.status?e.jsx("span",{className:T&&n.status==="draft"?"status-badge status-yellow":ns[n.status]||"",children:n.status==="draft"?s(T?"Held for review":"Awaiting conversion approval"):n.status.charAt(0).toUpperCase()+n.status.slice(1)}):"—"}];return t?e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!B&&e.jsx(m,{variant:"ghost",size:"icon",onClick:()=>F("/conversions"),"aria-label":s("Back"),children:e.jsx(_e,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Conversion #",t.id]}),e.jsxs("p",{className:"text-muted-foreground",children:["Created ",k(t.dateCreated)]})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:ts[t.status],children:r[t.status]}),t.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsxs(m,{size:"sm",onClick:()=>$("approve"),disabled:g!==null,children:[e.jsx($e,{className:"h-4 w-4 mr-1"}),s(g==="approve"?"Approving...":"Approve")]}),e.jsxs(m,{variant:"outline",size:"sm",onClick:()=>$("reject"),disabled:g!==null,children:[e.jsx(Ee,{className:"h-4 w-4 mr-1"}),s(g==="reject"?"Rejecting...":"Reject")]})]}),e.jsx(pe,{sourceType:"conversion",sourceId:t.id,contextLabel:`conversion #${t.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[T&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",role:"status",children:[e.jsx("p",{className:"font-medium",children:s("Reward held for review")}),e.jsx("p",{className:"mt-1",children:s(Qe(t.obligationHoldReason))})]}),e.jsxs(v,{children:[e.jsx(b,{children:e.jsx(y,{children:s("Conversion Details")})}),e.jsx(N,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Type")}),e.jsx("dd",{className:"text-sm mt-1",children:as[t.type]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:r[t.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created Date")}),e.jsx("dd",{className:"text-sm mt-1",children:k(t.dateCreated)})]})]})})]}),e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Collaborator")}),e.jsx(A,{children:s("Who earned this conversion")})]}),e.jsx(N,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{children:e.jsx("p",{className:"font-medium",children:ie(t.collaboratorName,"collaborator",s)})}),t.collaboratorId&&de(t.collaboratorName)&&e.jsx(m,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(w,{to:`/collaborators/${t.collaboratorId}/view`,children:s("View Profile")})})]})})]}),t.programId&&e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Program")}),e.jsx(A,{children:s("The program this conversion counts toward")})]}),e.jsx(N,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"font-medium",children:ie(t.programName,"program",s)}),de(t.programName)&&e.jsx(m,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(w,{to:`/programs/${t.programId}/view`,children:s("View Program")})})]})})]}),e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Transaction")}),e.jsx(A,{children:s("The commerce event that triggered this conversion")})]}),e.jsx(N,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction ID")}),e.jsx("dd",{children:t.transactionId!=null?e.jsxs(w,{to:`/transactions/${t.transactionId}`,className:"text-primary hover:underline font-mono",children:["#",t.transactionId]}):e.jsx("span",{className:"text-muted-foreground font-mono",children:"—"})})]}),t.transactionTotal!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction Total")}),e.jsx("dd",{className:"font-medium",children:f(t.transactionTotal)})]}),t.transactionSource&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Source")}),e.jsx("dd",{children:S[t.transactionSource]||t.transactionSource})]}),t.transactionSourceId&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Source Order ID")}),e.jsx("dd",{className:"font-mono",children:t.transactionSourceId})]}),t.transactionStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction Status")}),e.jsx("dd",{className:"capitalize",children:t.transactionStatus})]})]})})]}),e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Engagement")}),e.jsx(A,{children:s("How the collaborator was attributed")})]}),e.jsx(N,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Engagement ID")}),e.jsx("dd",{children:e.jsxs(w,{to:`/engagements/${t.engagementId}`,className:"text-primary hover:underline font-mono",children:["#",t.engagementId]})})]}),t.engagementType&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Engagement Type")}),e.jsx("dd",{className:"capitalize",children:t.engagementType.replace(/([A-Z])/g," $1").trim()})]}),t.engagementScore!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Score")}),e.jsx("dd",{children:t.engagementScore})]}),t.engagementStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"capitalize",children:t.engagementStatus})]})]})})]}),e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Obligations")}),e.jsx(A,{children:s("Reward obligations created from this conversion")})]}),e.jsx(N,{children:e.jsx(he,{columns:p,data:H,emptyMessage:s("No obligations for this conversion.")})})]})]})]}):e.jsx("div",{className:"max-w-2xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Conversion not found.")})})}window.sirenConfig&&Me({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const me=document.getElementById("siren-conversions");me&&Oe.createRoot(me).render(e.jsx(i.StrictMode,{children:e.jsxs(es,{defaultRoute:"/conversions",children:[e.jsx(He,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Ue,{children:[e.jsx(_,{path:"/conversions",element:e.jsx(ce,{})}),e.jsx(_,{path:"/conversions/:id",element:e.jsx(rs,{})}),e.jsx(_,{index:!0,element:e.jsx(ce,{})})]})})]})}));
     1import{u as xe,d as Fe,r as i,j as e,L as w,B as m,S as X,e as Z,f as J,g as Q,h as c,o as ze,b as Be,a as Ve,p as $e,H as Ee,X as Me,C as v,q as b,s as y,t as N,x as A,w as le,E as Oe,F as He,T as Ue,R as Ke,G as _}from"./shared/wordpress-admin-D_eccjaB.js";import{u as he,c as We}from"./shared/conversions-D67NHe2F.js";import{F as ee,H as qe,a as Ye,B as Ge,D as pe}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as je}from"./shared/ActivityDrawer-BZxDAdLe.js";import{T as Xe}from"./shared/TestSaleBadge--DG3xZwg.js";import{u as Ze}from"./shared/useListRequest-BAYNcD8F.js";import{u as Je}from"./shared/registries-CatPSk3G.js";import{l as ie,h as oe}from"./shared/linked-record-D4sO5j3k.js";import{u as Qe}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{h as _e}from"./shared/obligation-hold-JyNfYYW_.js";import{A as es}from"./shared/arrow-left-XvsxLAWy.js";import{W as ss}from"./shared/WordPressRouter-CAYzko7X.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/conversion.schema-BXGiWhtb.js";import"./shared/react-Rq6nbqOn.js";import"./shared/unshipped-CGZcvpGp.js";const de=s=>s==="approved"?"complete":s,ts={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},ce={sale:"Sale",lead:"Lead",renewal:"Renewal"};function me(){const{translate:s}=xe(),D={pending:s("Pending"),approved:s("Approved"),complete:s("Approved"),rejected:s("Rejected"),deleted:s("Trashed")},[r,u]=Fe(),{items:L,total:S,page:d,perPage:F,totalPages:z,isLoading:t,isSubmitting:O,error:C,fetchList:I,bulkApprove:B,bulkReject:g,bulkMarkPending:V,bulkDelete:$,bulkPermanentDelete:k,bulkRestore:f}=he(),E=de(r.get("status")||"all"),T=r.get("type")||"all",H=r.get("transactionId")||"",p=r.get("collaboratorId")||"",n=r.get("programId")||"",[l,se]=i.useState(E),[x,te]=i.useState(T),[j,U]=i.useState(H),[ae,ge]=i.useState(10),[K,fe]=i.useState("dateCreated"),[W,ve]=i.useState("desc"),[o,h]=i.useState(new Set),[q,ne]=i.useState(null),R=l==="deleted";i.useEffect(()=>{const a=de(r.get("status")||""),P=r.get("type"),G=r.get("transactionId");a&&a!==l&&se(a),P&&P!==x&&te(P),G&&G!==j&&U(G)},[r,l,x,j]),i.useEffect(()=>{h(new Set)},[l,x,j,p,n]);const be=Ze(I,{perPage:ae,orderBy:K,order:W,status:l==="all"?"pending,approved,complete,rejected":l,type:x!=="all"?x:void 0,transactionId:j?parseInt(j):void 0,collaboratorId:p?parseInt(p):void 0,programId:n?parseInt(n):void 0}),re=a=>be.setPage(a),ye=a=>ge(parseInt(a)),M=a=>{se(a),a!=="all"?r.set("status",a):r.delete("status"),u(r)},Y=a=>{te(a),a!=="all"?r.set("type",a):r.delete("type"),u(r)},Ne=a=>{const P=K===a&&W==="asc"?"desc":"asc";fe(a),ve(P)},we=async()=>{await B(Array.from(o)),h(new Set)},Se=async()=>{await g(Array.from(o)),h(new Set)},Ce=async()=>{await V(Array.from(o)),h(new Set)},Ie=async()=>{ne(Array.from(o)),await $(Array.from(o)),h(new Set)},ke=async()=>{o.size&&(await f(Array.from(o)),h(new Set))},Te=async()=>{o.size&&(await k(Array.from(o)),h(new Set))},Re=a=>new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),Pe=[{id:"id",header:s("ID"),cell:a=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",a.id]}),a.isTest&&e.jsx(Xe,{})]})},{id:"obligationId",header:s("Obligation"),cell:a=>a.obligationId?e.jsxs(w,{to:`/obligations/${a.obligationId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",a.obligationId]}):"-"},{id:"transactionId",header:s("Transaction"),cell:a=>a.transactionId!=null?e.jsx(ee,{filterKey:"transactionId",filterValue:a.transactionId.toString(),children:e.jsxs("span",{className:"font-mono text-sm",children:["#",a.transactionId]})}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"type",header:s("Type"),sortable:!0,cell:a=>e.jsx(ee,{filterKey:"type",filterValue:a.type,children:ce[a.type]})},{id:"status",header:s("Status"),sortable:!0,cell:a=>e.jsx(ee,{filterKey:"status",filterValue:a.status,children:e.jsx("span",{className:ts[a.status],children:D[a.status]})})},{id:"dateCreated",header:s("Date"),sortable:!0,cell:a=>e.jsx("span",{className:"text-sm text-muted-foreground",children:Re(a.dateCreated)})},...R?[{id:"actions",header:s("Actions"),cell:a=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(m,{variant:"outline",size:"sm",onClick:()=>f([a.id]),children:s("Restore")}),e.jsx(m,{variant:"destructive",size:"sm",onClick:()=>k([a.id]),children:s("Delete Permanently")})]})}]:[]],Ae=R?[{label:s("Restore (Pending)"),onClick:ke},{label:s("Delete Permanently"),onClick:Te,variant:"destructive",confirmMessage:`Permanently delete ${o.size} conversion(s)? This action cannot be undone.`,confirmItems:Array.from(o).map(a=>`Conversion #${a}`)}]:[{label:s("Approve"),onClick:we},{label:s("Reject"),onClick:Se},{label:s("Mark as Pending"),onClick:Ce},{label:s("Delete"),onClick:Ie,variant:"destructive",confirmMessage:`Delete ${o.size} conversion(s)? You can undo from Trash.`}],De=[{key:"status",label:"Status",value:l,displayValue:D[l]||l,onRemove:()=>M("all")},{key:"type",label:"Type",value:x,displayValue:ce[x]||x,onRemove:()=>Y("all")},...j?[{key:"transactionId",label:"Transaction",value:j,displayValue:`#${j}`,onRemove:()=>{U(""),r.delete("transactionId"),u(r)}}]:[],...p?[{key:"collaboratorId",label:"Collaborator",value:p,displayValue:`#${p}`,onRemove:()=>{r.delete("collaboratorId"),u(r)}}]:[],...n?[{key:"programId",label:"Program",value:n,displayValue:`#${n}`,onRemove:()=>{r.delete("programId"),u(r)}}]:[]],Le=()=>{M("all"),Y("all"),U(""),r.delete("transactionId"),r.delete("collaboratorId"),r.delete("programId"),u(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Conversions"),e.jsx(qe,{topic:"what-is-conversion",side:"right"})]}),e.jsx(je,{sourceType:"conversion",contextLabel:"all conversions"})]}),e.jsx(Ye,{filters:De,onClearAll:Le}),C&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:C}),e.jsxs("div",{className:"flex gap-2 mb-4 flex-wrap","data-tour":"conversions-filters",children:[e.jsxs(X,{value:l,onValueChange:M,children:[e.jsx(Z,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(J,{placeholder:s("Status")})}),e.jsxs(Q,{children:[e.jsx(c,{value:"all",children:s("All Statuses")}),e.jsx(c,{value:"pending",children:s("Pending")}),e.jsx(c,{value:"complete",children:s("Approved")}),e.jsx(c,{value:"rejected",children:s("Rejected")}),e.jsx(c,{value:"deleted",children:s("Trashed")})]})]}),e.jsxs(X,{value:x,onValueChange:Y,children:[e.jsx(Z,{"aria-label":s("Filter by type"),className:"w-[120px]",children:e.jsx(J,{placeholder:s("Type")})}),e.jsxs(Q,{children:[e.jsx(c,{value:"all",children:s("All Types")}),e.jsx(c,{value:"sale",children:s("Sale")}),e.jsx(c,{value:"lead",children:s("Lead")}),e.jsx(c,{value:"renewal",children:s("Renewal")})]})]})]}),e.jsx(Ge,{selectedCount:o.size,actions:Ae,onClear:()=>h(new Set),isProcessing:O}),q&&q.length>0&&!R&&e.jsxs("div",{className:"mb-4 flex items-center justify-between rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm",children:[e.jsxs("div",{className:"text-amber-900",children:[e.jsx("span",{className:"font-medium",children:s("Conversions deleted.")})," You can undo this action."]}),e.jsx(m,{variant:"outline",size:"sm",onClick:async()=>{await f(q),ne(null)},children:s("Undo")})]}),e.jsx(pe,{columns:Pe,data:L,sampleKey:"conversions",isLoading:t,emptyMessage:s("No conversions found."),selectable:!0,selectedIds:o,onSelectionChange:h,getRowHref:a=>`/conversions/${a.id}`,sortField:K,sortOrder:W,onSort:Ne}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",S===0?0:(d-1)*F+1," to ",Math.min(d*F,S)," of"," ",S," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(X,{value:ae.toString(),onValueChange:ye,children:[e.jsx(Z,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(J,{})}),e.jsxs(Q,{children:[e.jsx(c,{value:"10",children:"10"}),e.jsx(c,{value:"25",children:"25"}),e.jsx(c,{value:"50",children:"50"}),e.jsx(c,{value:"100",children:"100"})]})]})]})]}),z>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(m,{variant:"outline",size:"sm",disabled:d===1,onClick:()=>re(d-1),children:s("Previous")}),e.jsx(m,{variant:"outline",size:"sm",disabled:d===z,onClick:()=>re(d+1),children:s("Next")})]}),e.jsx(m,{variant:"link",className:"text-sm",onClick:()=>M(R?"all":"deleted"),children:s(R?"Back to active conversions":"Trash")})]})]})}const as={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},ns={sale:"Sale",lead:"Lead",renewal:"Renewal"},rs={draft:"status-badge status-gray",pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"};function ls(){const{translate:s}=xe(),{formatMoney:D}=Qe(),r={pending:s("Pending"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},{transactionSources:u,fetchTransactionSources:L}=Je(),S=i.useMemo(()=>Object.fromEntries(u.map(n=>[n.id,n.name])),[u]),{id:d}=ze(),F=Be(),{isWordPress:z}=Ve(),{current:t,isLoading:O,error:C,fetchOne:I,clearCurrent:B}=he();i.useEffect(()=>{L()},[L]);const[g,V]=i.useState(null),$=async n=>{if(d){V(n);try{await We.bulk(n,[parseInt(d)]),le.success(s(n==="approve"?"Conversion approved":"Conversion rejected")),await I(parseInt(d))}catch(l){le.error(l instanceof Error?l.message:s("Failed to update conversion"))}finally{V(null)}}};i.useEffect(()=>(d&&I(parseInt(d)),()=>{B()}),[d,I,B]);const k=n=>new Date(n).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"}),f=(n,l)=>D(n,l);if(O)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx($e,{})});if(C)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:C})});const E=(t==null?void 0:t.obligationId)??(t==null?void 0:t.draftObligationId),T=!!(t!=null&&t.obligationHoldReason),H=E?[{id:E,value:(t==null?void 0:t.obligationValue)??(t==null?void 0:t.amount)??void 0,status:t!=null&&t.obligationId?(t==null?void 0:t.obligationStatus)??void 0:"draft",awardType:(t==null?void 0:t.obligationAwardType)??void 0}]:[],p=[{id:"id",header:s("ID"),cell:n=>e.jsxs(w,{to:`/obligations/${n.id}`,className:"font-mono text-primary hover:underline",children:["#",n.id]})},{id:"value",header:s("Value"),cell:n=>e.jsx("span",{className:"font-medium",children:f(n.value,n.awardType)})},{id:"status",header:s("Status"),cell:n=>n.status?e.jsx("span",{className:T&&n.status==="draft"?"status-badge status-yellow":rs[n.status]||"",children:n.status==="draft"?s(T?"Held for review":"Awaiting conversion approval"):n.status.charAt(0).toUpperCase()+n.status.slice(1)}):"—"}];return t?e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!z&&e.jsx(m,{variant:"ghost",size:"icon",onClick:()=>F("/conversions"),"aria-label":s("Back"),children:e.jsx(es,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Conversion #",t.id]}),e.jsxs("p",{className:"text-muted-foreground",children:["Created ",k(t.dateCreated)]})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:as[t.status],"data-tour":"conversion-status",children:r[t.status]}),t.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsxs(m,{size:"sm",onClick:()=>$("approve"),disabled:g!==null,"data-tour":"conversion-approve",children:[e.jsx(Ee,{className:"h-4 w-4 mr-1"}),s(g==="approve"?"Approving...":"Approve")]}),e.jsxs(m,{variant:"outline",size:"sm",onClick:()=>$("reject"),disabled:g!==null,children:[e.jsx(Me,{className:"h-4 w-4 mr-1"}),s(g==="reject"?"Rejecting...":"Reject")]})]}),e.jsx(je,{sourceType:"conversion",sourceId:t.id,contextLabel:`conversion #${t.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[T&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",role:"status",children:[e.jsx("p",{className:"font-medium",children:s("Reward held for review")}),e.jsx("p",{className:"mt-1",children:s(_e(t.obligationHoldReason))})]}),e.jsxs(v,{children:[e.jsx(b,{children:e.jsx(y,{children:s("Conversion Details")})}),e.jsx(N,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Type")}),e.jsx("dd",{className:"text-sm mt-1",children:ns[t.type]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:r[t.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created Date")}),e.jsx("dd",{className:"text-sm mt-1",children:k(t.dateCreated)})]})]})})]}),e.jsxs(v,{"data-tour":"conversion-collaborator",children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Collaborator")}),e.jsx(A,{children:s("Who earned this conversion")})]}),e.jsx(N,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{children:e.jsx("p",{className:"font-medium",children:ie(t.collaboratorName,"collaborator",s)})}),t.collaboratorId&&oe(t.collaboratorName)&&e.jsx(m,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(w,{to:`/collaborators/${t.collaboratorId}/view`,children:s("View Profile")})})]})})]}),t.programId&&e.jsxs(v,{children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Program")}),e.jsx(A,{children:s("The program this conversion counts toward")})]}),e.jsx(N,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"font-medium",children:ie(t.programName,"program",s)}),oe(t.programName)&&e.jsx(m,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(w,{to:`/programs/${t.programId}/view`,children:s("View Program")})})]})})]}),e.jsxs(v,{"data-tour":"conversion-transaction",children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Transaction")}),e.jsx(A,{children:s("The commerce event that triggered this conversion")})]}),e.jsx(N,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction ID")}),e.jsx("dd",{children:t.transactionId!=null?e.jsxs(w,{to:`/transactions/${t.transactionId}`,className:"text-primary hover:underline font-mono",children:["#",t.transactionId]}):e.jsx("span",{className:"text-muted-foreground font-mono",children:"—"})})]}),t.transactionTotal!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction Total")}),e.jsx("dd",{className:"font-medium",children:f(t.transactionTotal)})]}),t.transactionSource&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Source")}),e.jsx("dd",{children:S[t.transactionSource]||t.transactionSource})]}),t.transactionSourceId&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Source Order ID")}),e.jsx("dd",{className:"font-mono",children:t.transactionSourceId})]}),t.transactionStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Transaction Status")}),e.jsx("dd",{className:"capitalize",children:t.transactionStatus})]})]})})]}),e.jsxs(v,{"data-tour":"conversion-attribution",children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Engagement")}),e.jsx(A,{children:s("How the collaborator was attributed")})]}),e.jsx(N,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Engagement ID")}),e.jsx("dd",{children:e.jsxs(w,{to:`/engagements/${t.engagementId}`,className:"text-primary hover:underline font-mono",children:["#",t.engagementId]})})]}),t.engagementType&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Engagement Type")}),e.jsx("dd",{className:"capitalize",children:t.engagementType.replace(/([A-Z])/g," $1").trim()})]}),t.engagementScore!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Score")}),e.jsx("dd",{children:t.engagementScore})]}),t.engagementStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"capitalize",children:t.engagementStatus})]})]})})]}),e.jsxs(v,{"data-tour":"conversion-rewards",children:[e.jsxs(b,{children:[e.jsx(y,{children:s("Obligations")}),e.jsx(A,{children:s("Reward obligations created from this conversion")})]}),e.jsx(N,{children:e.jsx(pe,{columns:p,data:H,emptyMessage:s("No obligations for this conversion.")})})]})]})]}):e.jsx("div",{className:"max-w-2xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Conversion not found.")})})}window.sirenConfig&&Oe({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const ue=document.getElementById("siren-conversions");ue&&He.createRoot(ue).render(e.jsx(i.StrictMode,{children:e.jsxs(ss,{defaultRoute:"/conversions",children:[e.jsx(Ue,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Ke,{children:[e.jsx(_,{path:"/conversions",element:e.jsx(me,{})}),e.jsx(_,{path:"/conversions/:id",element:e.jsx(ls,{})}),e.jsx(_,{index:!0,element:e.jsx(me,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/coupon-codes.js

    r3775642 r3788740  
    1 import{c as Ae,u as Ie,w as De,b as Me,r as i,v as O,j as e,B as P,L as oe,af as Ee,ag as Fe,ah as Te,ai as y,aj as Be,I as Ue,S as R,d as L,e as A,f as I,g,M as re,y as ne,E as Ve,F as Oe,T as ze,R as We,G as ae}from"./shared/wordpress-admin-DNnGQGoM.js";import{H as K,a as Ge,B as He,D as $e}from"./shared/HelpTooltip-DsFyDQG4.js";import{L as Ke}from"./shared/ListPager-DKO5XR7M.js";import{A as le}from"./shared/ActivityDrawer-iYDgZTH3.js";import{u as _e,p as qe,I as Je}from"./shared/IntegrationPreview-BM-XjKI4.js";import{a as Qe,l as Xe,s as Ye,b as ie,S as Ze,i as es,L as ss,U as ts,M as os,C as rs,R as ns,A as as,d as ls}from"./shared/CouponDialogs-Ci2bD_jZ.js";import{P as is}from"./shared/plus-xgV5QLEC.js";import{S as cs,W as ds}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/collaborators-BvingK76.js";import"./shared/form-field-Dbux2jvw.js";/**
     1import{c as Le,u as Ae,a as Ie,d as De,r as i,w as O,j as e,B as R,L as Me,af as Ee,ag as Fe,ah as Te,ai as y,aj as Be,I as Ue,S as P,e as L,f as A,g as I,h as p,M as oe,y as re,E as Ve,F as Oe,T as ze,R as We,G as ne}from"./shared/wordpress-admin-D_eccjaB.js";import{H as G,a as He,B as Ke,D as $e}from"./shared/HelpTooltip-YN4U7Ym7.js";import{R as Ge,L as _e}from"./shared/RecordsEmptyState-jrCUXFqo.js";import{A as ae}from"./shared/ActivityDrawer-BZxDAdLe.js";import{u as qe,p as Je,I as Qe}from"./shared/IntegrationPreview-VmIfRPju.js";import{a as Xe,l as Ye,s as Ze,b as le,S as es,i as ss,L as ts,U as os,M as rs,C as ns,R as as,A as ls,d as is}from"./shared/CouponDialogs-BS2YEuir.js";import{P as cs}from"./shared/plus-8fF9_2v-.js";import{S as ds,W as us}from"./shared/WordPressRouter-CAYzko7X.js";import"./shared/collaboratorDisplayName-DvmzsaZc.js";import"./shared/upload-ZoYz9lGb.js";import"./shared/form-field-CrfWqu5t.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const us=Ae("Ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]),S="all",hs=[10,25,50,100];function ms(d){return d&&/^\d+$/.test(d)?Number(d):void 0}function xs(d){if(!d)return"";const x=new Date(d);return Number.isNaN(x.getTime())?"":x.toLocaleDateString()}function ce({propertyId:d,embedded:x=!1}={}){var te;const{translate:t}=Ie(),{isWordPress:k}=De(),u=_e("coupon"),m=k,[h,D]=Me(),l=d??ms(h.get("property")),c=h.get("integration")||void 0,C=h.get("linked"),z=C==="yes"?!0:C==="no"?!1:void 0,M=h.get("kind")==="credit"?"credit":"attribution",E=h.get("removed")==="1",F=h.get("matches")==="1",[f,xe]=i.useState(null),[j,_]=i.useState([]),[q,J]=i.useState(!0),[pe,Q]=i.useState(!1),[X,ge]=i.useState(h.get("search")??""),[W,fe]=i.useState(h.get("search")??""),[G,T]=i.useState(1),[B,je]=i.useState(25),[H,U]=i.useState(new Set),[r,a]=i.useState(null),[ve,Y]=i.useState(0);i.useEffect(()=>{let s=!1;return Qe().then(o=>{s||_(o)}).catch(()=>{s||_([])}),()=>{s=!0}},[]),i.useEffect(()=>{let s=!1;return J(!0),Xe({propertyId:l,integration:c,search:W,linked:z,kind:M,includeRemoved:E,suggested:F,page:G,perPage:B}).then(o=>{s||(xe(o),Q(!1))}).catch(o=>{s||(Q(!0),O.error(o instanceof Error?o.message:t("The coupon codes could not be loaded.")))}).finally(()=>{s||J(!1)}),()=>{s=!0}},[l,c,W,z,M,E,F,G,B,ve,t]);const b=i.useMemo(()=>Ye(j),[j]),w=i.useMemo(()=>(f==null?void 0:f.items)??[],[f]),p=M==="credit",Z=i.useMemo(()=>{const s=new Map;for(const o of j)if(!(l!==void 0&&o.id!==l))for(const n of o.integrations)(!s.has(n.slug)||!n.preview)&&s.set(n.slug,qe(n.label,n.preview,t));for(const o of w)for(const n of o.identities)n.integration!==""&&!s.has(n.integration)&&s.set(n.integration,n.integrationLabel);return c&&!s.has(c)&&s.set(c,c),[...s.entries()].map(([o,n])=>({slug:o,label:n}))},[j,w,l,c,t]),N=i.useCallback(()=>{a(null),U(new Set),Y(s=>s+1)},[]),v=(s,o)=>{const n=new URLSearchParams(h);o===null||o===S?n.delete(s):n.set(s,o),s==="property"&&n.delete("integration"),T(1),U(new Set),D(n)},ee=()=>{T(1),fe(X.trim())},be=async s=>{try{await ls(s),O.success(t("Siren won't suggest these again.")),Y(o=>o+1)}catch(o){O.error(o instanceof Error?o.message:t("Could not dismiss the suggestion."))}},ye=[{id:"code",header:t("Code"),cell:s=>e.jsxs("div",{className:"max-w-[16rem] space-y-1",children:[e.jsx("button",{type:"button",className:"block max-w-full truncate text-left font-mono text-sm font-medium hover:underline",onClick:()=>a({kind:"stores",coupon:s}),children:s.code}),e.jsx("div",{className:"text-xs text-muted-foreground sm:hidden",children:s.identities.map(o=>ie(o,b,t,m)).join(", ")}),p?null:s.suggestions.slice(0,1).map(o=>{const n=o.stores.map(V=>ie(V,b,t,m)).join(", ");return e.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-xs","data-testid":"coupon-suggestion",children:[e.jsx("span",{className:"text-muted-foreground",children:t(n?"Possible match: {code} at {stores}":"Possible match: {code}").replace("{code}",o.code).replace("{stores}",n)}),e.jsx(P,{size:"sm",variant:"link",className:"h-auto p-0 text-xs","aria-label":t("Merge {code} with {other}").replace("{code}",s.code).replace("{other}",o.code),onClick:()=>{const V=w.find(Le=>Le.id===o.couponId);a({kind:"merge",coupons:V?[s,V]:[s]})},children:t("Merge")}),e.jsx(P,{size:"sm",variant:"link",className:"h-auto p-0 text-xs","aria-label":t("{code} and {other} are not the same").replace("{code}",s.code).replace("{other}",o.code),onClick:()=>void be(o.id),children:t("Not the same")})]},o.id)})]})},{id:"stores",header:t("Stores"),headerAdornment:e.jsx(K,{topic:"coupon-code-stores",side:"top"}),className:"hidden sm:table-cell",cell:s=>e.jsx(Ze,{identities:s.identities,names:b,singleStore:m})},{id:"collaborator",header:t("Linked collaborator"),cell:s=>p?e.jsxs("span",{className:"inline-flex items-center text-sm",children:[s.holder?t("Credit for {collaborator}").replace("{collaborator}",s.holder.name):t("Shared credit code"),e.jsx(K,{topic:"coupon-code-credit",side:"right"})]}):s.holder?e.jsxs(oe,{to:`/collaborators/${s.holder.id}/view`,className:"text-sm text-primary hover:underline",children:[s.holder.name,s.holder.status!=="active"&&s.holder.status!==""?e.jsxs("span",{className:"ml-1 text-xs text-muted-foreground",children:["(",s.holder.status==="deleted"?t("trashed"):s.holder.status,")"]}):null]}):e.jsx("span",{className:"text-sm text-muted-foreground",children:s.holderId===null?t("Not linked"):t("Collaborator no longer exists")})},{id:"uses",header:t("Uses"),className:"hidden md:table-cell",cell:s=>e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{children:s.uses.count}),s.uses.lastUsedAt?e.jsx("div",{className:"text-xs text-muted-foreground",children:t("Last {date}").replace("{date}",xs(s.uses.lastUsedAt))}):null]})},{id:"actions",header:()=>e.jsx("span",{className:"sr-only",children:t("Actions")}),className:"w-[1px]",cell:s=>e.jsxs(Ee,{children:[e.jsx(Fe,{asChild:!0,children:e.jsx(P,{size:"sm",variant:"ghost","aria-label":t("Actions for {code}").replace("{code}",s.code),children:e.jsx(us,{className:"h-4 w-4","aria-hidden":"true"})})}),e.jsxs(Te,{align:"end",children:[!p&&s.holderId===null?e.jsx(y,{onSelect:()=>a({kind:"link",coupon:s}),children:t("Link to collaborator")}):null,!p&&s.holderId!==null?e.jsxs(e.Fragment,{children:[e.jsx(y,{onSelect:()=>a({kind:"link",coupon:s}),children:t("Change collaborator")}),e.jsx(y,{onSelect:()=>a({kind:"unlink",coupon:s}),children:t("Unlink")})]}):null,p?null:e.jsx(y,{onSelect:()=>a({kind:"merge",coupons:[s]}),children:t("Merge with…")}),e.jsx(y,{onSelect:()=>a({kind:"stores",coupon:s}),children:t("Stores")}),e.jsx(y,{onSelect:()=>a({kind:"activity",coupon:s}),children:t("Activity")}),es(s)?e.jsxs(e.Fragment,{children:[e.jsx(Be,{}),e.jsx(y,{onSelect:()=>a({kind:"remove",coupon:s}),className:"text-destructive",children:t("Remove")})]}):null]})]})}],Se=[...d===void 0&&l!==void 0?[{key:"property",label:t("Property"),value:String(l),displayValue:b.get(l)??`#${l}`,onRemove:()=>v("property",null)}]:[],...c?[{key:"integration",label:t("Integration"),value:c,displayValue:((te=Z.find(s=>s.slug===c))==null?void 0:te.label)??c,onRemove:()=>v("integration",null)}]:[]],ke=l!==void 0||c!==void 0||W!==""||z!==void 0||E||F,we=(f==null?void 0:f.total)??w.length,se=w.filter(s=>H.has(s.id)),Ne=u!==void 0&&!u.shown,Ce=u!==void 0&&!u.available&&u.hasRecords,$=l!==void 0?j.find(s=>s.id===l):void 0,Pe=$!==void 0&&$.integrations.length>0&&$.integrations.every(s=>s.slug==="shopify"),Re=!p&&j.some(s=>s.integrations.length>0);return Ne&&!x?e.jsxs("div",{className:"space-y-4",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:t("Coupon codes")}),e.jsxs("div",{className:"rounded-md border p-6 text-sm text-muted-foreground","data-testid":"coupon-codes-unavailable",children:[e.jsx("p",{children:t("No active integration provides coupons. Turn on a store integration that has coupons to manage them here.")}),k?null:e.jsx("p",{className:"mt-2",children:e.jsx(oe,{to:"/settings/integrations",className:"text-primary hover:underline",children:t("Go to integrations")})})]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsx("div",{className:"max-w-3xl",children:x?null:e.jsxs("h1",{className:"flex items-center text-2xl font-semibold",children:[t("Coupon codes"),e.jsx(K,{topic:"coupon-codes",side:"right"})]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[x?null:e.jsx(le,{sourceType:"coupon",contextLabel:t("all coupon codes")}),Re?e.jsxs(P,{onClick:()=>a({kind:"add"}),children:[e.jsx(is,{className:"h-4 w-4","aria-hidden":"true"}),t("Add code")]}):null]})]}),e.jsx(Je,{}),Ce?e.jsx("p",{className:"rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:bg-amber-950 dark:text-amber-100",role:"status","data-testid":"coupon-codes-orphaned",children:t("No active integration provides coupons. These coupons are kept from before, and still credit their collaborators if a store sends their codes.")}):null,Pe?e.jsx("p",{className:"text-sm text-muted-foreground","data-testid":"coupon-codes-shopify-note",children:t("Shopify sends Siren a code the first time a shopper uses it. To link a code before then, add it yourself.")}):null,e.jsx(Ge,{filters:Se}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"relative min-w-[12rem] flex-1 sm:max-w-sm",children:[e.jsx(cs,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx(Ue,{value:X,onChange:s=>ge(s.target.value),onKeyDown:s=>s.key==="Enter"&&ee(),placeholder:t("Search codes or collaborators"),"aria-label":t("Search coupon codes"),className:"pl-9"})]}),d===void 0&&!m?e.jsxs(R,{value:l===void 0?S:String(l),onValueChange:s=>v("property",s),children:[e.jsx(L,{"aria-label":t("Filter by Property"),className:"w-[11rem]",children:e.jsx(A,{placeholder:t("Property")})}),e.jsxs(I,{children:[e.jsx(g,{value:S,children:t("All Properties")}),j.map(s=>e.jsx(g,{value:String(s.id),children:s.name},s.id))]})]}):null,e.jsxs(R,{value:c??S,onValueChange:s=>v("integration",s),children:[e.jsx(L,{"aria-label":t("Filter by integration"),className:"w-[11rem]",children:e.jsx(A,{placeholder:t("Integration")})}),e.jsxs(I,{children:[e.jsx(g,{value:S,children:t("All integrations")}),Z.map(s=>e.jsx(g,{value:s.slug,children:s.label},s.slug))]})]}),p?null:e.jsxs(R,{value:C==="yes"||C==="no"?C:S,onValueChange:s=>v("linked",s),children:[e.jsx(L,{"aria-label":t("Filter by link"),className:"w-[9rem]",children:e.jsx(A,{placeholder:t("Linked")})}),e.jsxs(I,{children:[e.jsx(g,{value:S,children:t("Linked or not")}),e.jsx(g,{value:"yes",children:t("Linked")}),e.jsx(g,{value:"no",children:t("Not linked")})]})]}),e.jsxs(R,{value:M,onValueChange:s=>v("kind",s==="credit"?"credit":null),children:[e.jsx(L,{"aria-label":t("Kind of code"),className:"w-[10rem]",children:e.jsx(A,{})}),e.jsxs(I,{children:[e.jsx(g,{value:"attribution",children:t("Attribution codes")}),e.jsx(g,{value:"credit",children:t("Store credit codes")})]})]}),e.jsx(P,{variant:"secondary",onClick:ee,children:t("Search")})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[p?null:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(re,{id:"coupon-matches",checked:F,onCheckedChange:s=>v("matches",s===!0?"1":null)}),e.jsx(ne,{htmlFor:"coupon-matches",className:"text-sm font-normal",children:t("Possible matches only")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(re,{id:"coupon-removed",checked:E,onCheckedChange:s=>v("removed",s===!0?"1":null)}),e.jsx(ne,{htmlFor:"coupon-removed",className:"text-sm font-normal",children:t("Show coupons removed from every store")})]})]}),p?null:e.jsx(He,{selectedCount:H.size,onClear:()=>U(new Set),actions:[{label:t("Merge"),onClick:()=>{if(se.length<2){O.error(t("Select at least two coupon codes to merge."));return}a({kind:"merge",coupons:se})}}]}),pe&&!f?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:t("The coupon codes could not be loaded.")}):e.jsx($e,{columns:ye,data:w,isLoading:q,selectable:!p,selectedIds:H,onSelectionChange:U,emptyMessage:t(ke?"No coupon codes match these filters.":x?"No coupon codes from this Property yet.":"No coupon codes yet. Coupon codes appear here when your store saves one or a shopper uses one."),getRowLabel:s=>s.code}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(R,{value:String(B),onValueChange:s=>{T(1),je(Number(s))},children:[e.jsx(L,{"aria-label":t("Rows per page"),className:"h-8 w-[80px]",children:e.jsx(A,{})}),e.jsx(I,{children:hs.map(s=>e.jsx(g,{value:String(s),children:s},s))})]})]})}),e.jsx(Ke,{page:G,perPage:B,total:we,onPageChange:T,disabled:q}),(r==null?void 0:r.kind)==="link"?e.jsx(ss,{coupon:r.coupon,names:b,singleStore:m,onClose:()=>a(null),onSaved:N}):null,(r==null?void 0:r.kind)==="unlink"?e.jsx(ts,{coupon:r.coupon,onClose:()=>a(null),onSaved:N}):null,(r==null?void 0:r.kind)==="merge"?e.jsx(os,{coupons:r.coupons,names:b,singleStore:m,onClose:()=>a(null),onMerged:N}):null,(r==null?void 0:r.kind)==="stores"?e.jsx(rs,{coupon:r.coupon,names:b,singleStore:m,onClose:()=>a(null),onSplit:N}):null,(r==null?void 0:r.kind)==="remove"?e.jsx(ns,{coupon:r.coupon,onClose:()=>a(null),onRemoved:N}):null,(r==null?void 0:r.kind)==="add"?e.jsx(as,{stores:j,singleStore:m,propertyId:l,onClose:()=>a(null),onAdded:N}):null,(r==null?void 0:r.kind)==="activity"?e.jsx(le,{sourceType:"coupon",sourceId:r.coupon.id,contextLabel:r.coupon.code,open:!0,onOpenChange:s=>!s&&a(null)}):null]})}function ps(d){if(!d||typeof d!="object"||Array.isArray(d))return{};const x={};for(const[t,k]of Object.entries(d)){if(!k||typeof k!="object")continue;const u=k,m=l=>Array.isArray(l)?l.map(Number).filter(c=>Number.isInteger(c)&&c>=0):[],h=u.available===!0,D=u.hasRecords===!0;x[t]={kind:t,feature:typeof u.feature=="string"?u.feature:"",available:h,shown:u.shown===!0||h||D,hasRecords:D,propertyIds:m(u.propertyIds),propertyIdsWithRecords:m(u.propertyIdsWithRecords)}}return x}window.sirenConfig&&Ve({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});var ue,he,me;const gs={...((ue=window.sirenConfig)==null?void 0:ue.capabilities)??{},records:ps((me=(he=window.sirenConfig)==null?void 0:he.capabilities)==null?void 0:me.records)},de=document.getElementById("siren-coupon-codes");de&&Oe.createRoot(de).render(e.jsx(i.StrictMode,{children:e.jsxs(ds,{defaultRoute:"/coupon-codes",capabilities:gs,children:[e.jsx(ze,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(We,{children:[e.jsx(ae,{path:"/coupon-codes",element:e.jsx(ce,{})}),e.jsx(ae,{index:!0,element:e.jsx(ce,{})})]})})]})}));
     6 */const hs=Le("Ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]),S="all",ms=[10,25,50,100];function xs(d){return d&&/^\d+$/.test(d)?Number(d):void 0}function ps(d){if(!d)return"";const g=new Date(d);return Number.isNaN(g.getTime())?"":g.toLocaleDateString()}function ie({propertyId:d,embedded:g=!1}={}){var te;const{translate:t}=Ae(),{isWordPress:C}=Ie(),u=qe("coupon"),m=C,[h,D]=De(),l=d??xs(h.get("property")),c=h.get("integration")||void 0,N=h.get("linked"),z=N==="yes"?!0:N==="no"?!1:void 0,M=h.get("kind")==="credit"?"credit":"attribution",E=h.get("removed")==="1",F=h.get("matches")==="1",[f,me]=i.useState(null),[j,_]=i.useState([]),[q,J]=i.useState(!0),[xe,Q]=i.useState(!1),[X,pe]=i.useState(h.get("search")??""),[W,ge]=i.useState(h.get("search")??""),[H,T]=i.useState(1),[B,fe]=i.useState(25),[K,U]=i.useState(new Set),[r,a]=i.useState(null),[je,Y]=i.useState(0);i.useEffect(()=>{let s=!1;return Xe().then(o=>{s||_(o)}).catch(()=>{s||_([])}),()=>{s=!0}},[]),i.useEffect(()=>{let s=!1;return J(!0),Ye({propertyId:l,integration:c,search:W,linked:z,kind:M,includeRemoved:E,suggested:F,page:H,perPage:B}).then(o=>{s||(me(o),Q(!1))}).catch(o=>{s||(Q(!0),O.error(o instanceof Error?o.message:t("The coupon codes could not be loaded.")))}).finally(()=>{s||J(!1)}),()=>{s=!0}},[l,c,W,z,M,E,F,H,B,je,t]);const b=i.useMemo(()=>Ze(j),[j]),k=i.useMemo(()=>(f==null?void 0:f.items)??[],[f]),x=M==="credit",Z=i.useMemo(()=>{const s=new Map;for(const o of j)if(!(l!==void 0&&o.id!==l))for(const n of o.integrations)(!s.has(n.slug)||!n.preview)&&s.set(n.slug,Je(n.label,n.preview,t));for(const o of k)for(const n of o.identities)n.integration!==""&&!s.has(n.integration)&&s.set(n.integration,n.integrationLabel);return c&&!s.has(c)&&s.set(c,c),[...s.entries()].map(([o,n])=>({slug:o,label:n}))},[j,k,l,c,t]),w=i.useCallback(()=>{a(null),U(new Set),Y(s=>s+1)},[]),v=(s,o)=>{const n=new URLSearchParams(h);o===null||o===S?n.delete(s):n.set(s,o),s==="property"&&n.delete("integration"),T(1),U(new Set),D(n)},ee=()=>{T(1),ge(X.trim())},ve=async s=>{try{await is(s),O.success(t("Siren won't suggest these again.")),Y(o=>o+1)}catch(o){O.error(o instanceof Error?o.message:t("Could not dismiss the suggestion."))}},be=[{id:"code",header:t("Code"),cell:s=>e.jsxs("div",{className:"max-w-[16rem] space-y-1",children:[e.jsx("button",{type:"button",className:"block max-w-full truncate text-left font-mono text-sm font-medium hover:underline",onClick:()=>a({kind:"stores",coupon:s}),children:s.code}),e.jsx("div",{className:"text-xs text-muted-foreground sm:hidden",children:s.identities.map(o=>le(o,b,t,m)).join(", ")}),x?null:s.suggestions.slice(0,1).map(o=>{const n=o.stores.map(V=>le(V,b,t,m)).join(", ");return e.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-xs","data-testid":"coupon-suggestion",children:[e.jsx("span",{className:"text-muted-foreground",children:t(n?"Possible match: {code} at {stores}":"Possible match: {code}").replace("{code}",o.code).replace("{stores}",n)}),e.jsx(R,{size:"sm",variant:"link",className:"h-auto p-0 text-xs","aria-label":t("Merge {code} with {other}").replace("{code}",s.code).replace("{other}",o.code),onClick:()=>{const V=k.find(Pe=>Pe.id===o.couponId);a({kind:"merge",coupons:V?[s,V]:[s]})},children:t("Merge")}),e.jsx(R,{size:"sm",variant:"link",className:"h-auto p-0 text-xs","aria-label":t("{code} and {other} are not the same").replace("{code}",s.code).replace("{other}",o.code),onClick:()=>void ve(o.id),children:t("Not the same")})]},o.id)})]})},{id:"stores",header:t("Stores"),headerAdornment:e.jsx(G,{topic:"coupon-code-stores",side:"top"}),className:"hidden sm:table-cell",cell:s=>e.jsx(es,{identities:s.identities,names:b,singleStore:m})},{id:"collaborator",header:t("Linked collaborator"),cell:s=>x?e.jsxs("span",{className:"inline-flex items-center text-sm",children:[s.holder?t("Credit for {collaborator}").replace("{collaborator}",s.holder.name):t("Shared credit code"),e.jsx(G,{topic:"coupon-code-credit",side:"right"})]}):s.holder?e.jsxs(Me,{to:`/collaborators/${s.holder.id}/view`,className:"text-sm text-primary hover:underline",children:[s.holder.name,s.holder.status!=="active"&&s.holder.status!==""?e.jsxs("span",{className:"ml-1 text-xs text-muted-foreground",children:["(",s.holder.status==="deleted"?t("trashed"):s.holder.status,")"]}):null]}):e.jsx("span",{className:"text-sm text-muted-foreground",children:s.holderId===null?t("Not linked"):t("Collaborator no longer exists")})},{id:"uses",header:t("Uses"),className:"hidden md:table-cell",cell:s=>e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{children:s.uses.count}),s.uses.lastUsedAt?e.jsx("div",{className:"text-xs text-muted-foreground",children:t("Last {date}").replace("{date}",ps(s.uses.lastUsedAt))}):null]})},{id:"actions",header:()=>e.jsx("span",{className:"sr-only",children:t("Actions")}),className:"w-[1px]",cell:s=>e.jsxs(Ee,{children:[e.jsx(Fe,{asChild:!0,children:e.jsx(R,{size:"sm",variant:"ghost","aria-label":t("Actions for {code}").replace("{code}",s.code),children:e.jsx(hs,{className:"h-4 w-4","aria-hidden":"true"})})}),e.jsxs(Te,{align:"end",children:[!x&&s.holderId===null?e.jsx(y,{onSelect:()=>a({kind:"link",coupon:s}),children:t("Link to collaborator")}):null,!x&&s.holderId!==null?e.jsxs(e.Fragment,{children:[e.jsx(y,{onSelect:()=>a({kind:"link",coupon:s}),children:t("Change collaborator")}),e.jsx(y,{onSelect:()=>a({kind:"unlink",coupon:s}),children:t("Unlink")})]}):null,x?null:e.jsx(y,{onSelect:()=>a({kind:"merge",coupons:[s]}),children:t("Merge with…")}),e.jsx(y,{onSelect:()=>a({kind:"stores",coupon:s}),children:t("Stores")}),e.jsx(y,{onSelect:()=>a({kind:"activity",coupon:s}),children:t("Activity")}),ss(s)?e.jsxs(e.Fragment,{children:[e.jsx(Be,{}),e.jsx(y,{onSelect:()=>a({kind:"remove",coupon:s}),className:"text-destructive",children:t("Remove")})]}):null]})]})}],ye=[...d===void 0&&l!==void 0?[{key:"property",label:t("Property"),value:String(l),displayValue:b.get(l)??`#${l}`,onRemove:()=>v("property",null)}]:[],...c?[{key:"integration",label:t("Integration"),value:c,displayValue:((te=Z.find(s=>s.slug===c))==null?void 0:te.label)??c,onRemove:()=>v("integration",null)}]:[]],Se=l!==void 0||c!==void 0||W!==""||z!==void 0||E||F,ke=(f==null?void 0:f.total)??k.length,se=k.filter(s=>K.has(s.id)),we=u===void 0||!u.hasRecords,Ce=u!==void 0&&!u.available&&u.hasRecords,$=l!==void 0?j.find(s=>s.id===l):void 0,Ne=$!==void 0&&$.integrations.length>0&&$.integrations.every(s=>s.slug==="shopify"),Re=!x&&j.some(s=>s.integrations.length>0);return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsx("div",{className:"max-w-3xl",children:g?null:e.jsxs("h1",{className:"flex items-center text-2xl font-semibold",children:[t("Coupon codes"),e.jsx(G,{topic:"coupon-codes",side:"right"})]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[g?null:e.jsx(ae,{sourceType:"coupon",contextLabel:t("all coupon codes")}),Re?e.jsxs(R,{onClick:()=>a({kind:"add"}),children:[e.jsx(cs,{className:"h-4 w-4","aria-hidden":"true"}),t("Add code")]}):null]})]}),e.jsx(Qe,{}),Ce?e.jsx("p",{className:"rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:bg-amber-950 dark:text-amber-100",role:"status","data-testid":"coupon-codes-orphaned",children:t("No active integration provides coupons. These coupons are kept from before, and still credit their collaborators if a store sends their codes.")}):null,Ne?e.jsx("p",{className:"text-sm text-muted-foreground","data-testid":"coupon-codes-shopify-note",children:t("Shopify sends Siren a code the first time a shopper uses it. To link a code before then, add it yourself.")}):null,e.jsx(He,{filters:ye}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"relative min-w-[12rem] flex-1 sm:max-w-sm",children:[e.jsx(ds,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx(Ue,{value:X,onChange:s=>pe(s.target.value),onKeyDown:s=>s.key==="Enter"&&ee(),placeholder:t("Search codes or collaborators"),"aria-label":t("Search coupon codes"),className:"pl-9"})]}),d===void 0&&!m?e.jsxs(P,{value:l===void 0?S:String(l),onValueChange:s=>v("property",s),children:[e.jsx(L,{"aria-label":t("Filter by Property"),className:"w-[11rem]",children:e.jsx(A,{placeholder:t("Property")})}),e.jsxs(I,{children:[e.jsx(p,{value:S,children:t("All Properties")}),j.map(s=>e.jsx(p,{value:String(s.id),children:s.name},s.id))]})]}):null,e.jsxs(P,{value:c??S,onValueChange:s=>v("integration",s),children:[e.jsx(L,{"aria-label":t("Filter by integration"),className:"w-[11rem]",children:e.jsx(A,{placeholder:t("Integration")})}),e.jsxs(I,{children:[e.jsx(p,{value:S,children:t("All integrations")}),Z.map(s=>e.jsx(p,{value:s.slug,children:s.label},s.slug))]})]}),x?null:e.jsxs(P,{value:N==="yes"||N==="no"?N:S,onValueChange:s=>v("linked",s),children:[e.jsx(L,{"aria-label":t("Filter by link"),className:"w-[9rem]",children:e.jsx(A,{placeholder:t("Linked")})}),e.jsxs(I,{children:[e.jsx(p,{value:S,children:t("Linked or not")}),e.jsx(p,{value:"yes",children:t("Linked")}),e.jsx(p,{value:"no",children:t("Not linked")})]})]}),e.jsxs(P,{value:M,onValueChange:s=>v("kind",s==="credit"?"credit":null),children:[e.jsx(L,{"aria-label":t("Kind of code"),className:"w-[10rem]",children:e.jsx(A,{})}),e.jsxs(I,{children:[e.jsx(p,{value:"attribution",children:t("Attribution codes")}),e.jsx(p,{value:"credit",children:t("Store credit codes")})]})]}),e.jsx(R,{variant:"secondary",onClick:ee,children:t("Search")})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[x?null:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(oe,{id:"coupon-matches",checked:F,onCheckedChange:s=>v("matches",s===!0?"1":null)}),e.jsx(re,{htmlFor:"coupon-matches",className:"text-sm font-normal",children:t("Possible matches only")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(oe,{id:"coupon-removed",checked:E,onCheckedChange:s=>v("removed",s===!0?"1":null)}),e.jsx(re,{htmlFor:"coupon-removed",className:"text-sm font-normal",children:t("Show coupons removed from every store")})]})]}),x?null:e.jsx(Ke,{selectedCount:K.size,onClear:()=>U(new Set),actions:[{label:t("Merge"),onClick:()=>{if(se.length<2){O.error(t("Select at least two coupon codes to merge."));return}a({kind:"merge",coupons:se})}}]}),xe&&!f?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:t("The coupon codes could not be loaded.")}):e.jsx($e,{columns:be,data:k,sampleKey:"couponCodes",isLoading:q,selectable:!x,selectedIds:K,onSelectionChange:U,emptyMessage:Se?t("No coupon codes match these filters."):g?t("No coupon codes from this Property yet."):we&&!x?e.jsx(Ge,{kind:"coupon"}):t("No coupon codes yet. Coupon codes appear here when your store saves one or a shopper uses one."),getRowLabel:s=>s.code}),e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-2",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(P,{value:String(B),onValueChange:s=>{T(1),fe(Number(s))},children:[e.jsx(L,{"aria-label":t("Rows per page"),className:"h-8 w-[80px]",children:e.jsx(A,{})}),e.jsx(I,{children:ms.map(s=>e.jsx(p,{value:String(s),children:s},s))})]})]})}),e.jsx(_e,{page:H,perPage:B,total:ke,onPageChange:T,disabled:q}),(r==null?void 0:r.kind)==="link"?e.jsx(ts,{coupon:r.coupon,names:b,singleStore:m,onClose:()=>a(null),onSaved:w}):null,(r==null?void 0:r.kind)==="unlink"?e.jsx(os,{coupon:r.coupon,onClose:()=>a(null),onSaved:w}):null,(r==null?void 0:r.kind)==="merge"?e.jsx(rs,{coupons:r.coupons,names:b,singleStore:m,onClose:()=>a(null),onMerged:w}):null,(r==null?void 0:r.kind)==="stores"?e.jsx(ns,{coupon:r.coupon,names:b,singleStore:m,onClose:()=>a(null),onSplit:w}):null,(r==null?void 0:r.kind)==="remove"?e.jsx(as,{coupon:r.coupon,onClose:()=>a(null),onRemoved:w}):null,(r==null?void 0:r.kind)==="add"?e.jsx(ls,{stores:j,singleStore:m,propertyId:l,onClose:()=>a(null),onAdded:w}):null,(r==null?void 0:r.kind)==="activity"?e.jsx(ae,{sourceType:"coupon",sourceId:r.coupon.id,contextLabel:r.coupon.code,open:!0,onOpenChange:s=>!s&&a(null)}):null]})}function gs(d){if(!d||typeof d!="object"||Array.isArray(d))return{};const g={};for(const[t,C]of Object.entries(d)){if(!C||typeof C!="object")continue;const u=C,m=l=>Array.isArray(l)?l.map(Number).filter(c=>Number.isInteger(c)&&c>=0):[],h=u.available===!0,D=u.hasRecords===!0;g[t]={kind:t,feature:typeof u.feature=="string"?u.feature:"",available:h,shown:u.shown===!0||h||D,hasRecords:D,propertyIds:m(u.propertyIds),propertyIdsWithRecords:m(u.propertyIdsWithRecords)}}return g}window.sirenConfig&&Ve({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});var de,ue,he;const fs={...((de=window.sirenConfig)==null?void 0:de.capabilities)??{},records:gs((he=(ue=window.sirenConfig)==null?void 0:ue.capabilities)==null?void 0:he.records)},ce=document.getElementById("siren-coupon-codes");ce&&Oe.createRoot(ce).render(e.jsx(i.StrictMode,{children:e.jsxs(us,{defaultRoute:"/coupon-codes",capabilities:fs,children:[e.jsx(ze,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(We,{children:[e.jsx(ne,{path:"/coupon-codes",element:e.jsx(ie,{})}),e.jsx(ne,{index:!0,element:e.jsx(ie,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/customers.js

    r3775642 r3788740  
    1 import{c as Ie,t as E,w as Me,r as l,u as W,j as e,D as he,h as xe,i as ge,k as fe,l as pe,J as Ve,K as He,y as me,M as Pe,m as je,B as N,v as I,I as $e,a as Ee,b as Ke,L as ae,S as le,d as ie,e as oe,f as ce,g as U,n as Ge,o as qe,C as ee,p as se,q as te,s as re,E as _e,F as Je,T as Qe,R as Xe,G as de}from"./shared/wordpress-admin-DNnGQGoM.js";import{H as D,a as Ye,B as Ze,D as es}from"./shared/HelpTooltip-DsFyDQG4.js";import{L as ss}from"./shared/ListPager-DKO5XR7M.js";import{u as Te,I as De}from"./shared/IntegrationPreview-BM-XjKI4.js";import{A as Re}from"./shared/ActivityDrawer-iYDgZTH3.js";import{p as ts,B as rs}from"./shared/properties-Cx8gxvGK.js";import{c as Ae}from"./shared/collaborators-BvingK76.js";import{S as Oe,W as as}from"./shared/WordPressRouter-ifxiIFvs.js";import{C as ve}from"./shared/confirm-dialog-DM12emMj.js";import{p as ns}from"./shared/plan-upgrade-notice-D9kRnx4x.js";import{t as ls,a as is}from"./shared/transaction-status-DFlw8wS1.js";import{A as os}from"./shared/arrow-left-W0B3m2vw.js";import"./shared/unshipped-CGZcvpGp.js";/**
     1import{c as Ie,v as E,a as Me,r as l,u as z,j as e,D as he,i as xe,k as ge,l as fe,m as pe,J as Ke,K as He,y as me,M as Pe,n as je,B as v,w as I,I as $e,b as Ee,d as Ge,L as ae,S as le,e as ie,f as oe,g as ce,h as W,o as qe,p as _e,C as ee,q as se,s as te,t as re,E as Je,F as Qe,T as Xe,R as Ye,G as de}from"./shared/wordpress-admin-D_eccjaB.js";import{H as R,a as Ze,B as es,D as ss}from"./shared/HelpTooltip-YN4U7Ym7.js";import{R as ts,L as rs}from"./shared/RecordsEmptyState-jrCUXFqo.js";import{u as Te,I as Re}from"./shared/IntegrationPreview-VmIfRPju.js";import{A as De}from"./shared/ActivityDrawer-BZxDAdLe.js";import{p as as}from"./shared/properties-ByxWotcN.js";import{a as Ae,c as Oe}from"./shared/collaboratorDisplayName-DvmzsaZc.js";import{S as Be,W as ns}from"./shared/WordPressRouter-CAYzko7X.js";import{C as ke}from"./shared/confirm-dialog-BdfYPOfc.js";import{p as ls}from"./shared/plan-upgrade-notice-D9kRnx4x.js";import{t as is,a as os}from"./shared/transaction-status-DFlw8wS1.js";import{B as cs}from"./shared/BulkPickerModal-DpL-mI_R.js";import{A as ds}from"./shared/arrow-left-XvsxLAWy.js";import"./shared/upload-ZoYz9lGb.js";import"./shared/unshipped-CGZcvpGp.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const cs=Ie("Merge",[["path",{d:"m8 6 4-4 4 4",key:"ybng9g"}],["path",{d:"M12 2v10.3a4 4 0 0 1-1.172 2.872L4 22",key:"1hyw0i"}],["path",{d:"m20 22-5-5",key:"1m27yz"}]]);/**
     6 */const ms=Ie("Merge",[["path",{d:"m8 6 4-4 4 4",key:"ybng9g"}],["path",{d:"M12 2v10.3a4 4 0 0 1-1.172 2.872L4 22",key:"1hyw0i"}],["path",{d:"m20 22-5-5",key:"1m27yz"}]]);/**
    77 * @license lucide-react v0.469.0 - ISC
    88 *
    99 * This source code is licensed under the ISC license.
    1010 * See the LICENSE file in the root directory of this source tree.
    11  */const ds=Ie("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),Ne="collaboratorIds",M={list:(s={})=>{var t;return E.get("/customers",{search:((t=s.search)==null?void 0:t.trim())||void 0,propertyId:s.propertyId,integration:s.integration||void 0,linked:s.linked===void 0?void 0:s.linked?"1":"0",collaboratorId:s.collaboratorId,matches:s.matches?"1":void 0,page:s.page??1,perPage:s.perPage??25})},get:s=>E.get(`/customers/${s}`),suggestions:s=>E.get("/customers/suggestions",{customerId:s}).then(t=>t.data),dismissSuggestion:s=>E.post(`/customers/suggestions/${s}/dismiss`),previewMerge:(s,t)=>E.post("/customers/merge",{survivorId:s,customerIds:t,preview:!0}).then(g=>g.conflicts),merge:(s,t,g)=>E.post("/customers/merge",{survivorId:s,customerIds:t,...g?{collaboratorIds:g}:{}}),split:(s,t)=>E.post(`/customers/${s}/identities/${t}/split`),link:(s,t)=>E.post(`/customers/${s}/collaborators`,{collaboratorId:t}),unlink:(s,t)=>E.delete(`/customers/${s}/collaborators/${t}`),crossStoreMatching:()=>E.get("/customers/matching/cross-store"),setCrossStoreMatching:s=>E.put("/customers/matching/cross-store",{confirmed:s})};function F(s){return s.name??s.label}const G={wordpress:"WordPress account",wc:"WooCommerce",woocommerce:"WooCommerce",edd:"Easy Digital Downloads",stripe:"Stripe",shopify:"Shopify",llms:"LifterLMS",learndash:"LearnDash",nc:"North Commerce"};function ne(s){return G[s]??s}function ms(){return[["wordpress",G.wordpress],["wc",G.wc],["edd",G.edd],["stripe",G.stripe],["shopify",G.shopify]]}function X(s){return s.guest?`${ne(s.integration)} guest`:`${ne(s.integration)} #${s.platformId??""}`}function Be(){const{isWordPress:s}=Me(),[t,g]=l.useState([]);l.useEffect(()=>{if(s)return;let a=!1;return ts.list().then(d=>{a||g(d.map(o=>({id:o.id,name:o.name||o.siteUrl||`#${o.id}`})))}).catch(()=>{a||g([])}),()=>{a=!0}},[s]);const m=l.useCallback(a=>{var d;return((d=t.find(o=>o.id===a))==null?void 0:d.name)??null},[t]);return l.useMemo(()=>({list:t,nameOf:m}),[t,m])}function be(s){const[t,g]=l.useState({}),m=[...new Set(s)].sort((a,d)=>a-d).join(",");return l.useEffect(()=>{const a=m===""?[]:m.split(",").map(Number).filter(o=>!(o in t));if(a.length===0)return;let d=!1;return Promise.all(a.map(o=>Ae.get(o).then(u=>[o,u.fullName||u.email||`#${o}`]).catch(()=>[o,`#${o}`]))).then(o=>{d||g(u=>({...u,...Object.fromEntries(o)}))}),()=>{d=!0}},[m]),l.useCallback(a=>t[a]??`#${a}`,[t])}function Fe(){const{translate:s}=W(),t=Te("customer");return!t||t.available||!t.hasRecords?null:e.jsx("div",{role:"status",className:"mb-4 rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",children:s("No active integration provides customers. These customers are kept from before, and their links still credit collaborators. Turn on a store integration that records customers to add new ones.")})}function us(){const{translate:s}=W();return e.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:s("No active integration provides customers. Turn on a store integration that records customers to manage them here.")})}function ye({customers:s,defaultSurvivorId:t,onClose:g,onMerged:m}){var V;const{translate:a}=W(),[d,o]=l.useState(t??((V=s[0])==null?void 0:V.id)??0),[u,b]=l.useState(null),[f,w]=l.useState(null),[k,v]=l.useState([]),[p,h]=l.useState(!1),$=be(s.flatMap(i=>i.collaboratorIds)),R=s.filter(i=>i.id!==d).map(i=>i.id),j=R.join(","),C=u==null?void 0:u.find(i=>i.key===Ne);l.useEffect(()=>{let i=!1;return b(null),w(null),M.previewMerge(d,j===""?[]:j.split(",").map(Number)).then(P=>{if(i)return;b(P);const L=P.find(T=>T.key===Ne);v(L&&L.options.length>0?[L.options[0]]:[])}).catch(P=>{i||w(P instanceof Error?P.message:a("These customers can’t be merged."))}),()=>{i=!0}},[d,j,a]);const O=async()=>{h(!0);try{const i=await M.merge(d,R,C?k:void 0);I.success(a("Customers merged.")),m(i.customer)}catch(i){I.error(i instanceof Error?i.message:a("The customers could not be merged."))}finally{h(!1)}},q=u!==null&&f===null&&(!C||k.length>0);return e.jsx(he,{open:!0,onOpenChange:i=>!i&&g(),children:e.jsxs(xe,{className:"max-h-[90vh] overflow-y-auto sm:max-w-2xl",children:[e.jsxs(ge,{children:[e.jsxs(fe,{className:"flex items-center",children:[a("Merge customers"),e.jsx(D,{topic:"customer-merge",side:"right"})]}),e.jsx(pe,{children:a("Choose the customer to keep. Everything below moves to it, and each visit stays its own.")})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:a("Customer to keep")}),e.jsx(Ve,{value:String(d),onValueChange:i=>o(Number(i)),"aria-label":a("Customer to keep"),children:s.map(i=>e.jsxs("label",{htmlFor:`merge-survivor-${i.id}`,className:"flex cursor-pointer gap-3 rounded-md border p-3",children:[e.jsx(He,{id:`merge-survivor-${i.id}`,value:String(i.id),className:"mt-1"}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsxs("span",{className:"block font-medium",children:[F(i)," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",i.label,")"]}),d===i.id&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:a("Kept")})]}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:i.identities.map(X).join(", ")||a("No identities")}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:i.collaboratorIds.length===0?a("Not linked"):`${a("Linked to")} ${i.collaboratorIds.map($).join(", ")}`})]})]},i.id))})]}),f&&e.jsx("p",{className:"rounded-md bg-destructive/10 p-3 text-sm text-destructive",children:f}),C&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(me,{className:"flex items-center",children:[a("Which collaborators stay linked?"),e.jsx(D,{topic:"customer-links",side:"right"})]}),C.options.map(i=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Pe,{id:`merge-keep-link-${i}`,checked:k.includes(i),onCheckedChange:P=>v(L=>P===!0?[...L,i]:L.filter(T=>T!==i))}),e.jsx(me,{htmlFor:`merge-keep-link-${i}`,className:"text-sm font-normal",children:$(i)})]},i)),k.length>1&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a("Each collaborator you keep earns from every later purchase.")}),k.length===0&&e.jsx("p",{className:"text-sm text-destructive",children:a("Keep at least one collaborator.")})]}),e.jsxs(je,{children:[e.jsx(N,{variant:"outline",onClick:g,children:a("Cancel")}),e.jsx(N,{onClick:O,disabled:!q||p,children:a(p?"Merging…":"Merge")})]})]})})}function We({customer:s,onClose:t,onMerged:g}){const{translate:m}=W(),[a,d]=l.useState(""),[o,u]=l.useState(null),[b,f]=l.useState(!1),[w,k]=l.useState(null),v=async()=>{if(a.trim()!==""){f(!0);try{const p=await M.list({search:a,perPage:10});u(p.customers.filter(h=>h.id!==s.id))}catch{u([])}finally{f(!1)}}};return w?e.jsx(ye,{customers:[s,w],defaultSurvivorId:s.id,onClose:t,onMerged:g}):e.jsx(he,{open:!0,onOpenChange:p=>!p&&t(),children:e.jsxs(xe,{className:"sm:max-w-lg",children:[e.jsxs(ge,{children:[e.jsx(fe,{children:m("Merge with…")}),e.jsx(pe,{children:m("Find the other customer by their customer number, a store ID or their exact email.")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(Oe,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx($e,{className:"pl-9","aria-label":m("Find a customer"),value:a,onChange:p=>d(p.target.value),onKeyDown:p=>p.key==="Enter"&&v()})]}),e.jsx(N,{variant:"secondary",onClick:v,disabled:b,children:m("Find")})]}),o!==null&&e.jsxs("ul",{className:"max-h-64 space-y-2 overflow-y-auto",children:[o.length===0&&e.jsx("li",{className:"text-sm text-muted-foreground",children:m("No other customer matches.")}),o.map(p=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:"w-full rounded-md border p-3 text-left hover:bg-muted",onClick:()=>k(p),children:[e.jsxs("span",{className:"block font-medium",children:[F(p)," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",p.label,")"]})]}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:p.identities.map(X).join(", ")})]})},p.id))]}),e.jsx(je,{children:e.jsx(N,{variant:"outline",onClick:t,children:m("Cancel")})})]})})}function hs(){const{translate:s}=W(),[t,g]=l.useState(null),[m,a]=l.useState(!1),[d,o]=l.useState(!1);if(l.useEffect(()=>{let b=!1;return M.crossStoreMatching().then(f=>{b||g(f.confirmed)}).catch(()=>{b||g(null)}),()=>{b=!0}},[]),t===null)return null;const u=async b=>{a(!0);try{const f=await M.setCrossStoreMatching(b);g(f.confirmed),I.success(f.confirmed?s("Siren will look for matches across your stores."):s("Matching across stores is off."))}catch(f){I.error(f instanceof Error?f.message:s("The setting could not be saved."))}finally{a(!1)}};return e.jsxs("div",{className:"mb-4 flex flex-col gap-2 rounded-md border p-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("span",{className:"flex items-center text-sm",children:[s(t?"Customers are matched across your stores.":"Customers are matched within each store only."),e.jsx(D,{topic:"customer-cross-store",side:"right"})]}),e.jsx(N,{size:"sm",variant:"outline",disabled:m,onClick:()=>t?u(!1):o(!0),children:s(t?"Match within each store only":"My stores are one business")}),e.jsx(he,{open:d,onOpenChange:o,children:e.jsxs(xe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:s("Match customers across stores?")}),e.jsx(pe,{children:s("Confirm that your stores are one business and that their privacy notices say customer records may be linked across them. Siren then suggests matches by email across your stores. Nothing merges until you choose.")})]}),e.jsxs(je,{children:[e.jsx(N,{variant:"outline",onClick:()=>o(!1),children:s("Cancel")}),e.jsx(N,{disabled:m,onClick:async()=>{await u(!0),o(!1)},children:s("Confirm")})]})]})})]})}function ue(s){if(s==null||s==="")return"—";const t=new Date(s);return Number.isNaN(t.getTime())?"—":t.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}const ke=25,z="all";function we(s){return s!==null&&/^[0-9]+$/.test(s)?Number(s):null}function Se({canConfirmCrossStore:s=!1}={}){const{translate:t}=W(),g=Ee(),m=Te("customer"),[a,d]=Ke(),o=we(a.get("property")),u=a.get("integration")??"",b=a.get("linked"),f=a.get("matches")==="1",w=a.get("search")??"",k=we(a.get("page"))??1,[v,p]=l.useState(w),[h,$]=l.useState(null),[R,j]=l.useState([]),[C,O]=l.useState(!0),[q,V]=l.useState(!1),[i,P]=l.useState(0),[L,T]=l.useState(new Set),[A,H]=l.useState(null),[Y,_]=l.useState(null),B=Be(),J=be(((h==null?void 0:h.customers)??[]).flatMap(r=>r.collaboratorIds)),y=m!==void 0&&!m.shown;l.useEffect(()=>{if(y)return;let r=!1;return O(!0),Promise.all([M.list({search:w,propertyId:o??void 0,integration:u||void 0,linked:b==="1"?!0:b==="0"?!1:void 0,matches:f,page:k,perPage:ke}),M.suggestions().catch(()=>[])]).then(([c,K])=>{r||($(c),j(K),V(!1))}).catch(c=>{r||(V(!0),I.error(c instanceof Error?c.message:t("The customers could not be loaded.")))}).finally(()=>{r||O(!1)}),()=>{r=!0}},[y,w,o,u,b,f,k,i,t]);const S=l.useCallback(r=>{const c=new URLSearchParams(a);for(const[K,Z]of Object.entries(r))Z===null||Z===""||Z===z?c.delete(K):c.set(K,Z);"page"in r||c.delete("page"),d(c)},[a,d]),Q=r=>{H(null),_(null),T(new Set),P(c=>c+1),g(`/customers/${r.id}`)},n=async r=>{try{await M.dismissSuggestion(r.id),j(c=>c.filter(K=>K.id!==r.id))}catch(c){I.error(c instanceof Error?c.message:t("The suggestion could not be dismissed."))}},x=l.useMemo(()=>[{id:"customer",header:t("Customer"),cell:r=>e.jsxs("div",{className:"flex min-w-0 max-w-xs flex-col",children:[e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:F(r)}),r.openSuggestions>0&&e.jsx("span",{className:"status-badge status-yellow shrink-0",children:t("Possible match")})]}),r.name!==null&&e.jsx("span",{className:"text-xs text-muted-foreground",children:r.label})]})},{id:"identities",header:t("Identities"),headerAdornment:e.jsx(D,{topic:"customer-identities"}),cell:r=>e.jsx("div",{className:"flex flex-wrap gap-1",children:r.identities.filter(c=>!c.deleted).map(c=>e.jsxs("span",{className:"rounded-md border px-1.5 py-0.5 text-xs",children:[X(c),B.nameOf(c.propertyId)?` · ${B.nameOf(c.propertyId)}`:""]},c.id))})},{id:"linked",header:t("Linked collaborator"),cell:r=>r.collaboratorIds.length===0?e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Not linked")}):e.jsx("span",{className:"flex flex-wrap gap-x-2 text-sm",children:r.collaboratorIds.map(c=>e.jsx(ae,{to:`/collaborators/${c}/view`,className:"text-primary hover:underline",children:J(c)},c))})},{id:"lastSeen",header:t("Last seen"),cell:r=>e.jsx("span",{className:"text-sm text-muted-foreground",children:ue(r.lastSeenAt)})},{id:"actions",header:()=>e.jsx("span",{className:"sr-only",children:t("Actions")}),cell:r=>e.jsx(N,{variant:"ghost",size:"sm",onClick:c=>{c.stopPropagation(),_(r)},children:t("Merge with…")})}],[J,B,t]);if(y)return e.jsxs("div",{children:[e.jsx("h1",{className:"mb-2 text-2xl font-semibold",children:t("Customers")}),e.jsx(us,{})]});const Ue=[{key:"property",label:t("Store"),value:o!==null?String(o):"",displayValue:o!==null?B.nameOf(o)??`#${o}`:"",onRemove:()=>S({property:null})},{key:"integration",label:t("Integration"),value:u,displayValue:u?ne(u):"",onRemove:()=>S({integration:null})},{key:"linked",label:t("Linked"),value:b??"",displayValue:t(b==="1"?"Linked":"Not linked"),onRemove:()=>S({linked:null})},{key:"matches",label:t("Possible matches"),value:f?"1":"",displayValue:t("Only"),onRemove:()=>S({matches:null})}],ze=((h==null?void 0:h.customers)??[]).filter(r=>L.has(r.id));return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("h1",{className:"flex items-center text-2xl font-semibold",children:[t("Customers"),e.jsx(D,{topic:"customers",side:"right"})]}),e.jsx(Re,{sourceType:"customer",contextLabel:t("all customers")})]}),e.jsx(Fe,{}),e.jsx(De,{className:"mb-4"}),s&&e.jsx(hs,{}),R.length>0&&e.jsxs("section",{className:"mb-4 rounded-md border p-3","aria-labelledby":"customer-suggestions",children:[e.jsxs("h2",{id:"customer-suggestions",className:"mb-2 flex items-center text-sm font-semibold",children:[t("Possible matches"),e.jsx(D,{topic:"customer-suggestions",side:"right"})]}),e.jsx("ul",{className:"space-y-2",children:R.slice(0,10).map(r=>e.jsxs("li",{className:"flex flex-col gap-2 rounded-md bg-muted/40 p-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("span",{className:"text-sm",children:r.customers.map(c=>`${F(c)} (${c.label})`).join(t(" and "))}),e.jsxs("span",{className:"flex gap-2",children:[e.jsx(N,{size:"sm",onClick:()=>H({customers:r.customers,survivorId:r.customers[0].id}),children:t("Merge")}),e.jsx(N,{size:"sm",variant:"outline",onClick:()=>n(r),children:t("Not the same")})]})]},r.id))})]}),e.jsx(Ye,{filters:Ue}),e.jsxs("div",{className:"mb-4 flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center",children:[e.jsxs("div",{className:"relative flex-1 sm:max-w-sm",children:[e.jsx(Oe,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx($e,{placeholder:t("Customer number, store ID or exact email"),"aria-label":t("Search customers"),value:v,onChange:r=>p(r.target.value),onKeyDown:r=>r.key==="Enter"&&S({search:v.trim()}),className:"pl-9"})]}),B.list.length>0&&e.jsxs(le,{value:o!==null?String(o):z,onValueChange:r=>S({property:r}),children:[e.jsx(ie,{"aria-label":t("Filter by store"),className:"w-full sm:w-[200px]",children:e.jsx(oe,{placeholder:t("Store")})}),e.jsxs(ce,{children:[e.jsx(U,{value:z,children:t("All stores")}),B.list.map(r=>e.jsx(U,{value:String(r.id),children:r.name},r.id))]})]}),e.jsxs(le,{value:u||z,onValueChange:r=>S({integration:r}),children:[e.jsx(ie,{"aria-label":t("Filter by integration"),className:"w-full sm:w-[200px]",children:e.jsx(oe,{placeholder:t("Integration")})}),e.jsxs(ce,{children:[e.jsx(U,{value:z,children:t("All integrations")}),ms().map(([r,c])=>e.jsx(U,{value:r,children:c},r))]})]}),e.jsxs(le,{value:b??z,onValueChange:r=>S({linked:r}),children:[e.jsx(ie,{"aria-label":t("Filter by link"),className:"w-full sm:w-[160px]",children:e.jsx(oe,{placeholder:t("Linked")})}),e.jsxs(ce,{children:[e.jsx(U,{value:z,children:t("Linked or not")}),e.jsx(U,{value:"1",children:t("Linked")}),e.jsx(U,{value:"0",children:t("Not linked")})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Pe,{id:"customer-matches",checked:f,onCheckedChange:r=>S({matches:r===!0?"1":null})}),e.jsx(me,{htmlFor:"customer-matches",className:"text-sm font-normal",children:t("Has a possible match")})]}),e.jsx(N,{variant:"secondary",onClick:()=>S({search:v.trim()}),children:t("Search")})]}),e.jsx(Ze,{selectedCount:L.size,onClear:()=>T(new Set),actions:L.size>=2?[{label:t("Merge"),onClick:()=>H({customers:ze})}]:[]}),q&&!h?e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:t("The customers could not be loaded.")}):e.jsx(es,{columns:x,data:(h==null?void 0:h.customers)??[],isLoading:C,selectable:!0,selectedIds:L,onSelectionChange:T,emptyMessage:t(w||u||b||f||o!==null?"No customers match these filters.":"No customers yet. Customers appear here when they buy, sign in after a referral, or are linked to a collaborator."),getRowLabel:r=>F(r),getRowHref:r=>`/customers/${r.id}`,onEdit:r=>g(`/customers/${r.id}`)}),e.jsx(ss,{page:k,perPage:ke,total:(h==null?void 0:h.total)??0,onPageChange:r=>S({page:String(r)}),disabled:C}),A&&A.customers.length>=2&&e.jsx(ye,{customers:A.customers,defaultSurvivorId:A.survivorId,onClose:()=>H(null),onMerged:Q}),Y&&e.jsx(We,{customer:Y,onClose:()=>_(null),onMerged:Q})]})}function xs({open:s,linkedIds:t,onClose:g,onLink:m}){const{translate:a}=W(),[d,o]=l.useState({search:"",page:1,perPage:10}),[u,b]=l.useState([]),[f,w]=l.useState(0),[k,v]=l.useState(!1),[p,h]=l.useState(!1);l.useEffect(()=>{if(!s)return;let j=!1;return v(!0),Ae.list({search:d.search||void 0,page:d.page,perPage:d.perPage}).then(C=>{j||(b(C.items),w(C.total))}).catch(()=>{j||b([])}).finally(()=>{j||v(!1)}),()=>{j=!0}},[s,d]);const $=[{id:"name",header:a("Collaborator"),cell:j=>j.fullName||j.email},{id:"email",header:a("Email"),cell:j=>j.email}],R=l.useCallback(async j=>{h(!0);try{await m(j)}finally{h(!1)}},[m]);return e.jsx(rs,{open:s,onOpenChange:j=>!j&&g(),title:a("Link to collaborator"),description:a("The collaborators you pick earn from every later purchase this customer makes."),excludedIds:new Set(t),items:u,isLoading:k,total:f,page:d.page,perPage:d.perPage,totalPages:Math.max(1,Math.ceil(f/d.perPage)),onParamsChange:o,columns:$,onAdd:R,addButtonLabel:a("Link"),isSubmitting:p})}function gs(){const{translate:s}=W(),t=Ee(),{id:g}=Ge(),m=Number(g),[a,d]=l.useState(null),[o,u]=l.useState(null),[b,f]=l.useState(0),[w,k]=l.useState(!1),[v,p]=l.useState(null),[h,$]=l.useState(null),[R,j]=l.useState(!1),[C,O]=l.useState(null),{isWordPress:q,planAllows:V}=Me(),i=!1,P=!1,L=Be(),T=be((a==null?void 0:a.customer.collaboratorIds)??[]);l.useEffect(()=>{let n=!1;return M.get(m).then(x=>{if(!n){if(x.customer.mergedIntoId){t(`/customers/${x.customer.mergedIntoId}`,{replace:!0});return}d(x),u(null)}}).catch(x=>{n||u(x instanceof Error?x.message:s("The customer could not be loaded."))}),()=>{n=!0}},[m,b,t,s]);const A=l.useCallback(()=>f(n=>n+1),[]),H=async n=>{try{for(const x of n)await M.link(m,x);I.success(s("Linked.")),k(!1),A()}catch(x){I.error(x instanceof Error?x.message:s("The customer could not be linked."))}},Y=async n=>{try{await M.unlink(m,n),I.success(s("Unlinked.")),A()}catch(x){I.error(x instanceof Error?x.message:s("The customer could not be unlinked."))}finally{p(null)}},_=async n=>{try{const x=await M.split(m,n.id);I.success(s("Split off into a new customer.")),$(null),t(`/customers/${x.split.id}`)}catch(x){I.error(x instanceof Error?x.message:s("The identity could not be split off.")),$(null)}},B=async n=>{try{await M.dismissSuggestion(n),A()}catch(x){I.error(x instanceof Error?x.message:s("The suggestion could not be dismissed."))}},J=n=>{j(!1),O(null),n.id===m?A():t(`/customers/${n.id}`)};if(o)return e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:o});if(!a)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(qe,{label:s("Loading customer...")})});const{customer:y,suggestions:S,sales:Q}=a;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!q&&e.jsx(N,{variant:"ghost",size:"icon",onClick:()=>t("/customers"),"aria-label":s("Back"),children:e.jsx(os,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:F(y)}),y.name!==null&&e.jsx("p",{className:"text-muted-foreground mt-1",children:y.label})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Re,{sourceType:"customer",sourceId:y.id,contextLabel:F(y)}),e.jsxs(N,{variant:"outline",onClick:()=>j(!0),children:[e.jsx(cs,{className:"h-4 w-4","aria-hidden":"true"}),s("Merge with…")]})]})]}),e.jsx(Fe,{}),e.jsx(De,{className:"mb-4"}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2 [&>*]:min-w-0",children:[e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(te,{className:"flex items-center",children:[s("Identities"),e.jsx(D,{topic:"customer-identities",side:"right"})]})}),e.jsx(re,{children:y.identities.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No store has named this customer yet.")}):e.jsx("ul",{className:"divide-y",children:y.identities.map(n=>e.jsxs("li",{className:"flex flex-col gap-2 py-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsxs("span",{className:"block text-sm font-medium",children:[X(n),n.deleted&&e.jsx("span",{className:"status-badge status-gray ml-2",children:s("Deleted at the store")})]}),e.jsx("span",{className:"block text-xs text-muted-foreground",children:[n.name,L.nameOf(n.propertyId),n.hasEmail?s("Email on file as a keyed hash"):null,n.lastSeenAt?`${s("Last seen")} ${ue(n.lastSeenAt)}`:null].filter(Boolean).join(" · ")})]}),y.identities.length>1&&e.jsx(N,{size:"sm",variant:"outline",onClick:()=>$(n),children:s("Split off")})]},n.id))})})]}),(i||P||y.collaboratorIds.length>0)&&e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(te,{className:"flex items-center",children:[s("Linked collaborators"),e.jsx(D,{topic:"customer-links",side:"right"})]}),i&&e.jsxs(N,{size:"sm",variant:"outline",onClick:()=>k(!0),children:[e.jsx(ds,{className:"h-4 w-4","aria-hidden":"true"}),y.collaboratorIds.length===0?s("Link to collaborator"):s("Link another")]})]})}),e.jsxs(re,{className:"space-y-3",children:[y.collaboratorIds.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("Not linked. A linked collaborator earns from every later purchase.")}):e.jsx("ul",{className:"divide-y",children:y.collaboratorIds.map(n=>e.jsxs("li",{className:"flex items-center justify-between py-2",children:[e.jsx(ae,{to:`/collaborators/${n}/view`,className:"text-primary hover:underline",children:T(n)}),i&&e.jsx(N,{size:"sm",variant:"outline",onClick:()=>p(n),children:s("Unlink")})]},n))}),P&&e.jsx(ns.PlanUpgradeNotice,{feature:s("lifetime customer links"),plan:"plus"})]})]}),S.length>0&&e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(te,{className:"flex items-center",children:[s("Possible matches"),e.jsx(D,{topic:"customer-suggestions",side:"right"})]})}),e.jsx(re,{children:e.jsx("ul",{className:"divide-y",children:S.map(n=>e.jsxs("li",{className:"flex flex-col gap-2 py-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs(ae,{to:`/customers/${n.customer.id}`,className:"text-sm text-primary hover:underline",children:[F(n.customer)," (",n.customer.label,") ·"," ",n.customer.identities.map(x=>ne(x.integration)).join(", ")]}),e.jsxs("span",{className:"flex gap-2",children:[e.jsx(N,{size:"sm",onClick:()=>O(n.customer),children:s("Merge")}),e.jsx(N,{size:"sm",variant:"outline",onClick:()=>B(n.id),children:s("Not the same")})]})]},n.id))})})]}),e.jsxs(ee,{children:[e.jsx(se,{children:e.jsx(te,{children:s("Sales")})}),e.jsx(re,{children:Q.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No sales credited from this customer’s visits yet.")}):e.jsx("ul",{className:"divide-y",children:Q.map(n=>e.jsxs("li",{className:"flex items-center justify-between py-2 text-sm",children:[e.jsxs(ae,{to:`/transactions/${n.id}`,className:"text-primary hover:underline",children:[s("Transaction")," #",n.id]}),e.jsxs("span",{className:"flex items-center gap-2 text-muted-foreground",children:[ue(n.date),e.jsx("span",{className:ls[n.status]??"status-badge status-gray",children:s(is[n.status]??n.status)})]})]},n.id))})})]})]}),e.jsx(xs,{open:w,linkedIds:y.collaboratorIds,onClose:()=>k(!1),onLink:H}),e.jsx(ve,{open:v!==null,onOpenChange:n=>!n&&p(null),title:s("Unlink this customer?"),description:v!==null?`${T(v)} ${s("won’t earn from this customer’s future purchases. Rewards already earned stay.")}`:"",confirmLabel:s("Unlink"),busyLabel:s("Unlinking..."),onConfirm:()=>v!==null?Y(v):void 0}),e.jsx(ve,{open:h!==null,onOpenChange:n=>!n&&$(null),title:e.jsxs("span",{className:"flex items-center",children:[s("Split off this identity?"),e.jsx(D,{topic:"customer-split",side:"right"})]}),description:h?`${X(h)} ${s("becomes a new customer with the visits and sales that came through it, and no collaborator linked.")}`:"",confirmLabel:s("Split off"),busyLabel:s("Splitting..."),destructive:!1,onConfirm:()=>h?_(h):void 0}),R&&e.jsx(We,{customer:y,onClose:()=>j(!1),onMerged:J}),C&&e.jsx(ye,{customers:[y,C],defaultSurvivorId:y.id,onClose:()=>O(null),onMerged:J})]})}window.sirenConfig&&_e({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ce=document.getElementById("siren-customers");var Le;Ce&&Je.createRoot(Ce).render(e.jsx(l.StrictMode,{children:e.jsxs(as,{defaultRoute:"/customers",capabilities:(Le=window.sirenConfig)==null?void 0:Le.capabilities,children:[e.jsx(Qe,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Xe,{children:[e.jsx(de,{path:"/customers",element:e.jsx(Se,{})}),e.jsx(de,{path:"/customers/:id",element:e.jsx(gs,{})}),e.jsx(de,{index:!0,element:e.jsx(Se,{})})]})})]})}));
     11 */const us=Ie("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),ve="collaboratorIds",M={list:(s={})=>{var t;return E.get("/customers",{search:((t=s.search)==null?void 0:t.trim())||void 0,propertyId:s.propertyId,integration:s.integration||void 0,linked:s.linked===void 0?void 0:s.linked?"1":"0",collaboratorId:s.collaboratorId,matches:s.matches?"1":void 0,page:s.page??1,perPage:s.perPage??25})},get:s=>E.get(`/customers/${s}`),suggestions:s=>E.get("/customers/suggestions",{customerId:s}).then(t=>t.data),dismissSuggestion:s=>E.post(`/customers/suggestions/${s}/dismiss`),previewMerge:(s,t)=>E.post("/customers/merge",{survivorId:s,customerIds:t,preview:!0}).then(g=>g.conflicts),merge:(s,t,g)=>E.post("/customers/merge",{survivorId:s,customerIds:t,...g?{collaboratorIds:g}:{}}),split:(s,t)=>E.post(`/customers/${s}/identities/${t}/split`),link:(s,t)=>E.post(`/customers/${s}/collaborators`,{collaboratorId:t}),unlink:(s,t)=>E.delete(`/customers/${s}/collaborators/${t}`),crossStoreMatching:()=>E.get("/customers/matching/cross-store"),setCrossStoreMatching:s=>E.put("/customers/matching/cross-store",{confirmed:s})};function F(s){return s.name??s.label}const G={wordpress:"WordPress account",wc:"WooCommerce",woocommerce:"WooCommerce",edd:"Easy Digital Downloads",stripe:"Stripe",shopify:"Shopify",llms:"LifterLMS",learndash:"LearnDash",nc:"North Commerce"};function ne(s){return G[s]??s}function hs(){return[["wordpress",G.wordpress],["wc",G.wc],["edd",G.edd],["stripe",G.stripe],["shopify",G.shopify]]}function X(s){return s.guest?`${ne(s.integration)} guest`:`${ne(s.integration)} #${s.platformId??""}`}function Fe(){const{isWordPress:s}=Me(),[t,g]=l.useState([]);l.useEffect(()=>{if(s)return;let a=!1;return as.list().then(d=>{a||g(d.map(o=>({id:o.id,name:o.name||o.siteUrl||`#${o.id}`})))}).catch(()=>{a||g([])}),()=>{a=!0}},[s]);const m=l.useCallback(a=>{var d;return((d=t.find(o=>o.id===a))==null?void 0:d.name)??null},[t]);return l.useMemo(()=>({list:t,nameOf:m}),[t,m])}function be(s){const[t,g]=l.useState({}),m=[...new Set(s)].sort((a,d)=>a-d).join(",");return l.useEffect(()=>{const a=m===""?[]:m.split(",").map(Number).filter(o=>!(o in t));if(a.length===0)return;let d=!1;return Promise.all(a.map(o=>Ae.get(o).then(u=>[o,Oe(u)]).catch(()=>[o,`#${o}`]))).then(o=>{d||g(u=>({...u,...Object.fromEntries(o)}))}),()=>{d=!0}},[m]),l.useCallback(a=>t[a]??`#${a}`,[t])}function We(){const{translate:s}=z(),t=Te("customer");return!t||t.available||!t.hasRecords?null:e.jsx("div",{role:"status",className:"mb-4 rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",children:s("No active integration provides customers. These customers are kept from before, and their links still credit collaborators. Turn on a store integration that records customers to add new ones.")})}function ye({customers:s,defaultSurvivorId:t,onClose:g,onMerged:m}){var V;const{translate:a}=z(),[d,o]=l.useState(t??((V=s[0])==null?void 0:V.id)??0),[u,j]=l.useState(null),[f,w]=l.useState(null),[N,y]=l.useState([]),[p,h]=l.useState(!1),$=be(s.flatMap(i=>i.collaboratorIds)),D=s.filter(i=>i.id!==d).map(i=>i.id),b=D.join(","),C=u==null?void 0:u.find(i=>i.key===ve);l.useEffect(()=>{let i=!1;return j(null),w(null),M.previewMerge(d,b===""?[]:b.split(",").map(Number)).then(P=>{if(i)return;j(P);const L=P.find(T=>T.key===ve);y(L&&L.options.length>0?[L.options[0]]:[])}).catch(P=>{i||w(P instanceof Error?P.message:a("These customers can’t be merged."))}),()=>{i=!0}},[d,b,a]);const O=async()=>{h(!0);try{const i=await M.merge(d,D,C?N:void 0);I.success(a("Customers merged.")),m(i.customer)}catch(i){I.error(i instanceof Error?i.message:a("The customers could not be merged."))}finally{h(!1)}},q=u!==null&&f===null&&(!C||N.length>0);return e.jsx(he,{open:!0,onOpenChange:i=>!i&&g(),children:e.jsxs(xe,{className:"max-h-[90vh] overflow-y-auto sm:max-w-2xl",children:[e.jsxs(ge,{children:[e.jsxs(fe,{className:"flex items-center",children:[a("Merge customers"),e.jsx(R,{topic:"customer-merge",side:"right"})]}),e.jsx(pe,{children:a("Choose the customer to keep. Everything below moves to it, and each visit stays its own.")})]}),e.jsxs("fieldset",{className:"space-y-2",children:[e.jsx("legend",{className:"sr-only",children:a("Customer to keep")}),e.jsx(Ke,{value:String(d),onValueChange:i=>o(Number(i)),"aria-label":a("Customer to keep"),children:s.map(i=>e.jsxs("label",{htmlFor:`merge-survivor-${i.id}`,className:"flex cursor-pointer gap-3 rounded-md border p-3",children:[e.jsx(He,{id:`merge-survivor-${i.id}`,value:String(i.id),className:"mt-1"}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsxs("span",{className:"block font-medium",children:[F(i)," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",i.label,")"]}),d===i.id&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground",children:a("Kept")})]}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:i.identities.map(X).join(", ")||a("No identities")}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:i.collaboratorIds.length===0?a("Not linked"):`${a("Linked to")} ${i.collaboratorIds.map($).join(", ")}`})]})]},i.id))})]}),f&&e.jsx("p",{className:"rounded-md bg-destructive/10 p-3 text-sm text-destructive",children:f}),C&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(me,{className:"flex items-center",children:[a("Which collaborators stay linked?"),e.jsx(R,{topic:"customer-links",side:"right"})]}),C.options.map(i=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Pe,{id:`merge-keep-link-${i}`,checked:N.includes(i),onCheckedChange:P=>y(L=>P===!0?[...L,i]:L.filter(T=>T!==i))}),e.jsx(me,{htmlFor:`merge-keep-link-${i}`,className:"text-sm font-normal",children:$(i)})]},i)),N.length>1&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a("Each collaborator you keep earns from every later purchase.")}),N.length===0&&e.jsx("p",{className:"text-sm text-destructive",children:a("Keep at least one collaborator.")})]}),e.jsxs(je,{children:[e.jsx(v,{variant:"outline",onClick:g,children:a("Cancel")}),e.jsx(v,{onClick:O,disabled:!q||p,children:a(p?"Merging…":"Merge")})]})]})})}function Ue({customer:s,onClose:t,onMerged:g}){const{translate:m}=z(),[a,d]=l.useState(""),[o,u]=l.useState(null),[j,f]=l.useState(!1),[w,N]=l.useState(null),y=async()=>{if(a.trim()!==""){f(!0);try{const p=await M.list({search:a,perPage:10});u(p.customers.filter(h=>h.id!==s.id))}catch{u([])}finally{f(!1)}}};return w?e.jsx(ye,{customers:[s,w],defaultSurvivorId:s.id,onClose:t,onMerged:g}):e.jsx(he,{open:!0,onOpenChange:p=>!p&&t(),children:e.jsxs(xe,{className:"sm:max-w-lg",children:[e.jsxs(ge,{children:[e.jsx(fe,{children:m("Merge with…")}),e.jsx(pe,{children:m("Find the other customer by their customer number, a store ID or their exact email.")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(Be,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx($e,{className:"pl-9","aria-label":m("Find a customer"),value:a,onChange:p=>d(p.target.value),onKeyDown:p=>p.key==="Enter"&&y()})]}),e.jsx(v,{variant:"secondary",onClick:y,disabled:j,children:m("Find")})]}),o!==null&&e.jsxs("ul",{className:"max-h-64 space-y-2 overflow-y-auto",children:[o.length===0&&e.jsx("li",{className:"text-sm text-muted-foreground",children:m("No other customer matches.")}),o.map(p=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:"w-full rounded-md border p-3 text-left hover:bg-muted",onClick:()=>N(p),children:[e.jsxs("span",{className:"block font-medium",children:[F(p)," ",e.jsxs("span",{className:"text-muted-foreground",children:["(",p.label,")"]})]}),e.jsx("span",{className:"block text-sm text-muted-foreground",children:p.identities.map(X).join(", ")})]})},p.id))]}),e.jsx(je,{children:e.jsx(v,{variant:"outline",onClick:t,children:m("Cancel")})})]})})}function xs(){const{translate:s}=z(),[t,g]=l.useState(null),[m,a]=l.useState(!1),[d,o]=l.useState(!1);if(l.useEffect(()=>{let j=!1;return M.crossStoreMatching().then(f=>{j||g(f.confirmed)}).catch(()=>{j||g(null)}),()=>{j=!0}},[]),t===null)return null;const u=async j=>{a(!0);try{const f=await M.setCrossStoreMatching(j);g(f.confirmed),I.success(f.confirmed?s("Siren will look for matches across your stores."):s("Matching across stores is off."))}catch(f){I.error(f instanceof Error?f.message:s("The setting could not be saved."))}finally{a(!1)}};return e.jsxs("div",{className:"mb-4 flex flex-col gap-2 rounded-md border p-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("span",{className:"flex items-center text-sm",children:[s(t?"Customers are matched across your stores.":"Customers are matched within each store only."),e.jsx(R,{topic:"customer-cross-store",side:"right"})]}),e.jsx(v,{size:"sm",variant:"outline",disabled:m,onClick:()=>t?u(!1):o(!0),children:s(t?"Match within each store only":"My stores are one business")}),e.jsx(he,{open:d,onOpenChange:o,children:e.jsxs(xe,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:s("Match customers across stores?")}),e.jsx(pe,{children:s("Confirm that your stores are one business and that their privacy notices say customer records may be linked across them. Siren then suggests matches by email across your stores. Nothing merges until you choose.")})]}),e.jsxs(je,{children:[e.jsx(v,{variant:"outline",onClick:()=>o(!1),children:s("Cancel")}),e.jsx(v,{disabled:m,onClick:async()=>{await u(!0),o(!1)},children:s("Confirm")})]})]})})]})}function ue(s){if(s==null||s==="")return"—";const t=new Date(s);return Number.isNaN(t.getTime())?"—":t.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}const Ne=25,U="all";function we(s){return s!==null&&/^[0-9]+$/.test(s)?Number(s):null}function Se({canConfirmCrossStore:s=!1}={}){const{translate:t}=z(),g=Ee(),m=Te("customer"),[a,d]=Ge(),o=we(a.get("property")),u=a.get("integration")??"",j=a.get("linked"),f=a.get("matches")==="1",w=a.get("search")??"",N=we(a.get("page"))??1,[y,p]=l.useState(w),[h,$]=l.useState(null),[D,b]=l.useState([]),[C,O]=l.useState(!0),[q,V]=l.useState(!1),[i,P]=l.useState(0),[L,T]=l.useState(new Set),[A,K]=l.useState(null),[Y,_]=l.useState(null),B=Fe(),J=be(((h==null?void 0:h.customers)??[]).flatMap(r=>r.collaboratorIds)),k=m===void 0||!m.hasRecords;l.useEffect(()=>{let r=!1;return O(!0),Promise.all([M.list({search:w,propertyId:o??void 0,integration:u||void 0,linked:j==="1"?!0:j==="0"?!1:void 0,matches:f,page:N,perPage:Ne}),M.suggestions().catch(()=>[])]).then(([c,H])=>{r||($(c),b(H),V(!1))}).catch(c=>{r||(V(!0),I.error(c instanceof Error?c.message:t("The customers could not be loaded.")))}).finally(()=>{r||O(!1)}),()=>{r=!0}},[w,o,u,j,f,N,i,t]);const S=l.useCallback(r=>{const c=new URLSearchParams(a);for(const[H,Z]of Object.entries(r))Z===null||Z===""||Z===U?c.delete(H):c.set(H,Z);"page"in r||c.delete("page"),d(c)},[a,d]),Q=r=>{K(null),_(null),T(new Set),P(c=>c+1),g(`/customers/${r.id}`)},n=async r=>{try{await M.dismissSuggestion(r.id),b(c=>c.filter(H=>H.id!==r.id))}catch(c){I.error(c instanceof Error?c.message:t("The suggestion could not be dismissed."))}},x=l.useMemo(()=>[{id:"customer",header:t("Customer"),cell:r=>e.jsxs("div",{className:"flex min-w-0 max-w-xs flex-col",children:[e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium",children:F(r)}),r.openSuggestions>0&&e.jsx("span",{className:"status-badge status-yellow shrink-0",children:t("Possible match")})]}),r.name!==null&&e.jsx("span",{className:"text-xs text-muted-foreground",children:r.label})]})},{id:"identities",header:t("Identities"),headerAdornment:e.jsx(R,{topic:"customer-identities"}),cell:r=>e.jsx("div",{className:"flex flex-wrap gap-1",children:r.identities.filter(c=>!c.deleted).map(c=>e.jsxs("span",{className:"rounded-md border px-1.5 py-0.5 text-xs",children:[X(c),B.nameOf(c.propertyId)?` · ${B.nameOf(c.propertyId)}`:""]},c.id))})},{id:"linked",header:t("Linked collaborator"),cell:r=>r.collaboratorIds.length===0?e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Not linked")}):e.jsx("span",{className:"flex flex-wrap gap-x-2 text-sm",children:r.collaboratorIds.map(c=>e.jsx(ae,{to:`/collaborators/${c}/view`,className:"text-primary hover:underline",children:J(c)},c))})},{id:"lastSeen",header:t("Last seen"),cell:r=>e.jsx("span",{className:"text-sm text-muted-foreground",children:ue(r.lastSeenAt)})},{id:"actions",header:()=>e.jsx("span",{className:"sr-only",children:t("Actions")}),cell:r=>e.jsx(v,{variant:"ghost",size:"sm",onClick:c=>{c.stopPropagation(),_(r)},children:t("Merge with…")})}],[J,B,t]),ze=[{key:"property",label:t("Store"),value:o!==null?String(o):"",displayValue:o!==null?B.nameOf(o)??`#${o}`:"",onRemove:()=>S({property:null})},{key:"integration",label:t("Integration"),value:u,displayValue:u?ne(u):"",onRemove:()=>S({integration:null})},{key:"linked",label:t("Linked"),value:j??"",displayValue:t(j==="1"?"Linked":"Not linked"),onRemove:()=>S({linked:null})},{key:"matches",label:t("Possible matches"),value:f?"1":"",displayValue:t("Only"),onRemove:()=>S({matches:null})}],Ve=((h==null?void 0:h.customers)??[]).filter(r=>L.has(r.id));return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("h1",{className:"flex items-center text-2xl font-semibold",children:[t("Customers"),e.jsx(R,{topic:"customers",side:"right"})]}),e.jsx(De,{sourceType:"customer",contextLabel:t("all customers")})]}),e.jsx(We,{}),e.jsx(Re,{className:"mb-4"}),s&&e.jsx(xs,{}),D.length>0&&e.jsxs("section",{className:"mb-4 rounded-md border p-3","aria-labelledby":"customer-suggestions",children:[e.jsxs("h2",{id:"customer-suggestions",className:"mb-2 flex items-center text-sm font-semibold",children:[t("Possible matches"),e.jsx(R,{topic:"customer-suggestions",side:"right"})]}),e.jsx("ul",{className:"space-y-2",children:D.slice(0,10).map(r=>e.jsxs("li",{className:"flex flex-col gap-2 rounded-md bg-muted/40 p-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("span",{className:"text-sm",children:r.customers.map(c=>`${F(c)} (${c.label})`).join(t(" and "))}),e.jsxs("span",{className:"flex gap-2",children:[e.jsx(v,{size:"sm",onClick:()=>K({customers:r.customers,survivorId:r.customers[0].id}),children:t("Merge")}),e.jsx(v,{size:"sm",variant:"outline",onClick:()=>n(r),children:t("Not the same")})]})]},r.id))})]}),e.jsx(Ze,{filters:ze}),e.jsxs("div",{className:"mb-4 flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center",children:[e.jsxs("div",{className:"relative flex-1 sm:max-w-sm",children:[e.jsx(Be,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground","aria-hidden":"true"}),e.jsx($e,{placeholder:t("Customer number, store ID or exact email"),"aria-label":t("Search customers"),value:y,onChange:r=>p(r.target.value),onKeyDown:r=>r.key==="Enter"&&S({search:y.trim()}),className:"pl-9"})]}),B.list.length>0&&e.jsxs(le,{value:o!==null?String(o):U,onValueChange:r=>S({property:r}),children:[e.jsx(ie,{"aria-label":t("Filter by store"),className:"w-full sm:w-[200px]",children:e.jsx(oe,{placeholder:t("Store")})}),e.jsxs(ce,{children:[e.jsx(W,{value:U,children:t("All stores")}),B.list.map(r=>e.jsx(W,{value:String(r.id),children:r.name},r.id))]})]}),e.jsxs(le,{value:u||U,onValueChange:r=>S({integration:r}),children:[e.jsx(ie,{"aria-label":t("Filter by integration"),className:"w-full sm:w-[200px]",children:e.jsx(oe,{placeholder:t("Integration")})}),e.jsxs(ce,{children:[e.jsx(W,{value:U,children:t("All integrations")}),hs().map(([r,c])=>e.jsx(W,{value:r,children:c},r))]})]}),e.jsxs(le,{value:j??U,onValueChange:r=>S({linked:r}),children:[e.jsx(ie,{"aria-label":t("Filter by link"),className:"w-full sm:w-[160px]",children:e.jsx(oe,{placeholder:t("Linked")})}),e.jsxs(ce,{children:[e.jsx(W,{value:U,children:t("Linked or not")}),e.jsx(W,{value:"1",children:t("Linked")}),e.jsx(W,{value:"0",children:t("Not linked")})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Pe,{id:"customer-matches",checked:f,onCheckedChange:r=>S({matches:r===!0?"1":null})}),e.jsx(me,{htmlFor:"customer-matches",className:"text-sm font-normal",children:t("Has a possible match")})]}),e.jsx(v,{variant:"secondary",onClick:()=>S({search:y.trim()}),children:t("Search")})]}),e.jsx(es,{selectedCount:L.size,onClear:()=>T(new Set),actions:L.size>=2?[{label:t("Merge"),onClick:()=>K({customers:Ve})}]:[]}),q&&!h?e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:t("The customers could not be loaded.")}):e.jsx(ss,{columns:x,data:(h==null?void 0:h.customers)??[],sampleKey:"customers",isLoading:C,selectable:!0,selectedIds:L,onSelectionChange:T,emptyMessage:w||u||j||f||o!==null?t("No customers match these filters."):k?e.jsx(ts,{kind:"customer"}):t("No customers yet. Customers appear here when they buy, sign in after a referral, or are linked to a collaborator."),getRowLabel:r=>F(r),getRowHref:r=>`/customers/${r.id}`,onEdit:r=>g(`/customers/${r.id}`)}),e.jsx(rs,{page:N,perPage:Ne,total:(h==null?void 0:h.total)??0,onPageChange:r=>S({page:String(r)}),disabled:C}),A&&A.customers.length>=2&&e.jsx(ye,{customers:A.customers,defaultSurvivorId:A.survivorId,onClose:()=>K(null),onMerged:Q}),Y&&e.jsx(Ue,{customer:Y,onClose:()=>_(null),onMerged:Q})]})}function gs({open:s,linkedIds:t,onClose:g,onLink:m}){const{translate:a}=z(),[d,o]=l.useState({search:"",page:1,perPage:10}),[u,j]=l.useState([]),[f,w]=l.useState(0),[N,y]=l.useState(!1),[p,h]=l.useState(!1);l.useEffect(()=>{if(!s)return;let b=!1;return y(!0),Ae.list({search:d.search||void 0,page:d.page,perPage:d.perPage,status:"active,pending,inactive,rejected"}).then(C=>{b||(j(C.items),w(C.total))}).catch(()=>{b||j([])}).finally(()=>{b||y(!1)}),()=>{b=!0}},[s,d]);const $=[{id:"name",header:a("Collaborator"),cell:b=>Oe(b)},{id:"email",header:a("Email"),cell:b=>b.email}],D=l.useCallback(async b=>{h(!0);try{await m(b)}finally{h(!1)}},[m]);return e.jsx(cs,{open:s,onOpenChange:b=>!b&&g(),title:a("Link to collaborator"),description:a("The collaborators you pick earn from every later purchase this customer makes."),excludedIds:new Set(t),items:u,isLoading:N,total:f,page:d.page,perPage:d.perPage,totalPages:Math.max(1,Math.ceil(f/d.perPage)),onParamsChange:o,columns:$,onAdd:D,addButtonLabel:a("Link"),isSubmitting:p})}function fs(){const{translate:s}=z(),t=Ee(),{id:g}=qe(),m=Number(g),[a,d]=l.useState(null),[o,u]=l.useState(null),[j,f]=l.useState(0),[w,N]=l.useState(!1),[y,p]=l.useState(null),[h,$]=l.useState(null),[D,b]=l.useState(!1),[C,O]=l.useState(null),{isWordPress:q,planAllows:V}=Me(),i=!1,P=!1,L=Fe(),T=be((a==null?void 0:a.customer.collaboratorIds)??[]);l.useEffect(()=>{let n=!1;return M.get(m).then(x=>{if(!n){if(x.customer.mergedIntoId){t(`/customers/${x.customer.mergedIntoId}`,{replace:!0});return}d(x),u(null)}}).catch(x=>{n||u(x instanceof Error?x.message:s("The customer could not be loaded."))}),()=>{n=!0}},[m,j,t,s]);const A=l.useCallback(()=>f(n=>n+1),[]),K=async n=>{try{for(const x of n)await M.link(m,x);I.success(s("Linked.")),N(!1),A()}catch(x){I.error(x instanceof Error?x.message:s("The customer could not be linked."))}},Y=async n=>{try{await M.unlink(m,n),I.success(s("Unlinked.")),A()}catch(x){I.error(x instanceof Error?x.message:s("The customer could not be unlinked."))}finally{p(null)}},_=async n=>{try{const x=await M.split(m,n.id);I.success(s("Split off into a new customer.")),$(null),t(`/customers/${x.split.id}`)}catch(x){I.error(x instanceof Error?x.message:s("The identity could not be split off.")),$(null)}},B=async n=>{try{await M.dismissSuggestion(n),A()}catch(x){I.error(x instanceof Error?x.message:s("The suggestion could not be dismissed."))}},J=n=>{b(!1),O(null),n.id===m?A():t(`/customers/${n.id}`)};if(o)return e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:o});if(!a)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(_e,{label:s("Loading customer...")})});const{customer:k,suggestions:S,sales:Q}=a;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!q&&e.jsx(v,{variant:"ghost",size:"icon",onClick:()=>t("/customers"),"aria-label":s("Back"),children:e.jsx(ds,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:F(k)}),k.name!==null&&e.jsx("p",{className:"text-muted-foreground mt-1",children:k.label})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(De,{sourceType:"customer",sourceId:k.id,contextLabel:F(k)}),e.jsxs(v,{variant:"outline",onClick:()=>b(!0),children:[e.jsx(ms,{className:"h-4 w-4","aria-hidden":"true"}),s("Merge with…")]})]})]}),e.jsx(We,{}),e.jsx(Re,{className:"mb-4"}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2 [&>*]:min-w-0",children:[e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(te,{className:"flex items-center",children:[s("Identities"),e.jsx(R,{topic:"customer-identities",side:"right"})]})}),e.jsx(re,{children:k.identities.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No store has named this customer yet.")}):e.jsx("ul",{className:"divide-y",children:k.identities.map(n=>e.jsxs("li",{className:"flex flex-col gap-2 py-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("span",{className:"min-w-0",children:[e.jsxs("span",{className:"block text-sm font-medium",children:[X(n),n.deleted&&e.jsx("span",{className:"status-badge status-gray ml-2",children:s("Deleted at the store")})]}),e.jsx("span",{className:"block text-xs text-muted-foreground",children:[n.name,L.nameOf(n.propertyId),n.hasEmail?s("Email on file as a keyed hash"):null,n.lastSeenAt?`${s("Last seen")} ${ue(n.lastSeenAt)}`:null].filter(Boolean).join(" · ")})]}),k.identities.length>1&&e.jsx(v,{size:"sm",variant:"outline",onClick:()=>$(n),children:s("Split off")})]},n.id))})})]}),(i||P||k.collaboratorIds.length>0)&&e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(te,{className:"flex items-center",children:[s("Linked collaborators"),e.jsx(R,{topic:"customer-links",side:"right"})]}),i&&e.jsxs(v,{size:"sm",variant:"outline",onClick:()=>N(!0),children:[e.jsx(us,{className:"h-4 w-4","aria-hidden":"true"}),k.collaboratorIds.length===0?s("Link to collaborator"):s("Link another")]})]})}),e.jsxs(re,{className:"space-y-3",children:[k.collaboratorIds.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("Not linked. A linked collaborator earns from every later purchase.")}):e.jsx("ul",{className:"divide-y",children:k.collaboratorIds.map(n=>e.jsxs("li",{className:"flex items-center justify-between py-2",children:[e.jsx(ae,{to:`/collaborators/${n}/view`,className:"text-primary hover:underline",children:T(n)}),i&&e.jsx(v,{size:"sm",variant:"outline",onClick:()=>p(n),children:s("Unlink")})]},n))}),P&&e.jsx(ls.PlanUpgradeNotice,{feature:s("lifetime customer links"),plan:"plus"})]})]}),S.length>0&&e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(te,{className:"flex items-center",children:[s("Possible matches"),e.jsx(R,{topic:"customer-suggestions",side:"right"})]})}),e.jsx(re,{children:e.jsx("ul",{className:"divide-y",children:S.map(n=>e.jsxs("li",{className:"flex flex-col gap-2 py-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs(ae,{to:`/customers/${n.customer.id}`,className:"text-sm text-primary hover:underline",children:[F(n.customer)," (",n.customer.label,") ·"," ",n.customer.identities.map(x=>ne(x.integration)).join(", ")]}),e.jsxs("span",{className:"flex gap-2",children:[e.jsx(v,{size:"sm",onClick:()=>O(n.customer),children:s("Merge")}),e.jsx(v,{size:"sm",variant:"outline",onClick:()=>B(n.id),children:s("Not the same")})]})]},n.id))})})]}),e.jsxs(ee,{children:[e.jsx(se,{children:e.jsx(te,{children:s("Sales")})}),e.jsx(re,{children:Q.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No sales credited from this customer’s visits yet.")}):e.jsx("ul",{className:"divide-y",children:Q.map(n=>e.jsxs("li",{className:"flex items-center justify-between py-2 text-sm",children:[e.jsxs(ae,{to:`/transactions/${n.id}`,className:"text-primary hover:underline",children:[s("Transaction")," #",n.id]}),e.jsxs("span",{className:"flex items-center gap-2 text-muted-foreground",children:[ue(n.date),e.jsx("span",{className:is[n.status]??"status-badge status-gray",children:s(os[n.status]??n.status)})]})]},n.id))})})]})]}),e.jsx(gs,{open:w,linkedIds:k.collaboratorIds,onClose:()=>N(!1),onLink:K}),e.jsx(ke,{open:y!==null,onOpenChange:n=>!n&&p(null),title:s("Unlink this customer?"),description:y!==null?`${T(y)} ${s("won’t earn from this customer’s future purchases. Rewards already earned stay.")}`:"",confirmLabel:s("Unlink"),busyLabel:s("Unlinking..."),onConfirm:()=>y!==null?Y(y):void 0}),e.jsx(ke,{open:h!==null,onOpenChange:n=>!n&&$(null),title:e.jsxs("span",{className:"flex items-center",children:[s("Split off this identity?"),e.jsx(R,{topic:"customer-split",side:"right"})]}),description:h?`${X(h)} ${s("becomes a new customer with the visits and sales that came through it, and no collaborator linked.")}`:"",confirmLabel:s("Split off"),busyLabel:s("Splitting..."),destructive:!1,onConfirm:()=>h?_(h):void 0}),D&&e.jsx(Ue,{customer:k,onClose:()=>b(!1),onMerged:J}),C&&e.jsx(ye,{customers:[k,C],defaultSurvivorId:k.id,onClose:()=>O(null),onMerged:J})]})}window.sirenConfig&&Je({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ce=document.getElementById("siren-customers");var Le;Ce&&Qe.createRoot(Ce).render(e.jsx(l.StrictMode,{children:e.jsxs(ns,{defaultRoute:"/customers",capabilities:(Le=window.sirenConfig)==null?void 0:Le.capabilities,children:[e.jsx(Xe,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Ye,{children:[e.jsx(de,{path:"/customers",element:e.jsx(Se,{})}),e.jsx(de,{path:"/customers/:id",element:e.jsx(fs,{})}),e.jsx(de,{index:!0,element:e.jsx(Se,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/engagements.js

    r3775642 r3788740  
    1 import{u as G,b as de,r as n,j as e,L as N,S as A,d as B,e as $,f as T,g as d,B as g,n as ce,a as me,w as xe,o as ue,C as V,p as H,q as O,s as z,E as ge,F as he,T as je,R as pe,G as L}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as J}from"./shared/engagements-BdjHp3Bf.js";import{F as k,H as fe,a as ve,D as Ne}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as Q}from"./shared/ActivityDrawer-iYDgZTH3.js";import{l as b,h as K}from"./shared/linked-record-D4sO5j3k.js";import{u as be}from"./shared/useListRequest-CKMUCtxK.js";import{A as v}from"./shared/arrow-left-W0B3m2vw.js";import{W as Ce}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/react-zvEYxxW2.js";const M={active:"Active",complete:"Complete",expired:"Expired"},Ie={active:"status-badge status-green",complete:"status-badge status-blue",expired:"status-badge status-gray"};function U(){const{translate:s}=G(),[r,l]=de(),{items:x,total:a,page:o,perPage:h,totalPages:j,isLoading:f,error:u,fetchList:C}=J(),X=r.get("status")||"all",Y=r.get("collaboratorId")||"",Z=r.get("programId")||"",[i,R]=n.useState(X),[c,I]=n.useState(Y),[m,S]=n.useState(Z),[D,_]=n.useState(10),[w,ee]=n.useState("dateCreated"),[y,se]=n.useState("desc");n.useEffect(()=>{const t=r.get("status"),p=r.get("collaboratorId"),E=r.get("programId");t&&t!==i&&R(t),p&&p!==c&&I(p),E&&E!==m&&S(E)},[r,i,c,m]);const te=be(C,{perPage:D,orderBy:w,order:y,status:i!=="all"?i:void 0,collaboratorId:c?parseInt(c):void 0,programId:m?parseInt(m):void 0}),F=t=>te.setPage(t),ae=t=>_(parseInt(t)),P=t=>{R(t),t!=="all"?r.set("status",t):r.delete("status"),l(r)},re=t=>{const p=w===t&&y==="asc"?"desc":"asc";ee(t),se(p)},le=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),ne=[{id:"id",header:s("ID"),cell:t=>e.jsxs("span",{className:"font-mono text-sm",children:["#",t.id]})},{id:"collaborator",header:s("Collaborator"),cell:t=>e.jsx(k,{filterKey:"collaboratorId",filterValue:t.collaboratorId.toString(),children:b(t.collaboratorName,"collaborator",s)})},{id:"program",header:s("Program"),cell:t=>e.jsx(k,{filterKey:"programId",filterValue:t.programId.toString(),children:b(t.programName,"program",s)})},{id:"score",header:s("Score"),sortable:!0,cell:t=>e.jsx("span",{className:"font-medium",children:t.score})},{id:"status",header:s("Status"),sortable:!0,cell:t=>e.jsx(k,{filterKey:"status",filterValue:t.status,children:e.jsx("span",{className:Ie[t.status],children:M[t.status]})})},{id:"conversion",header:s("Conversion"),cell:t=>t.conversionId?e.jsxs(N,{to:`/conversions/${t.conversionId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",t.conversionId]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"dateCreated",header:s("Created"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm text-muted-foreground",children:le(t.dateCreated)})}],oe=[{key:"status",label:"Status",value:i,displayValue:M[i]||i,onRemove:()=>P("all")},...c?[{key:"collaboratorId",label:"Collaborator",value:c,displayValue:`#${c}`,onRemove:()=>{I(""),r.delete("collaboratorId"),l(r)}}]:[],...m?[{key:"programId",label:"Program",value:m,displayValue:`#${m}`,onRemove:()=>{S(""),r.delete("programId"),l(r)}}]:[]],ie=()=>{P("all"),I(""),S(""),r.delete("collaboratorId"),r.delete("programId"),l(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Engagements"),e.jsx(fe,{topic:"what-is-engagement",side:"right"})]}),e.jsx(Q,{sourceType:"engagement",contextLabel:"all engagements"})]}),e.jsx(ve,{filters:oe,onClearAll:ie}),u&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:u}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap",children:e.jsxs(A,{value:i,onValueChange:P,children:[e.jsx(B,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx($,{placeholder:s("Status")})}),e.jsxs(T,{children:[e.jsx(d,{value:"all",children:s("All Statuses")}),e.jsx(d,{value:"active",children:s("Active")}),e.jsx(d,{value:"complete",children:s("Complete")}),e.jsx(d,{value:"expired",children:s("Expired")})]})]})}),e.jsx(Ne,{columns:ne,data:x,isLoading:f,emptyMessage:s("No engagements found."),getRowHref:t=>`/engagements/${t.id}`,sortField:w,sortOrder:y,onSort:re}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",a===0?0:(o-1)*h+1," to ",Math.min(o*h,a)," of"," ",a," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(A,{value:D.toString(),onValueChange:ae,children:[e.jsx(B,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx($,{})}),e.jsxs(T,{children:[e.jsx(d,{value:"10",children:"10"}),e.jsx(d,{value:"25",children:"25"}),e.jsx(d,{value:"50",children:"50"}),e.jsx(d,{value:"100",children:"100"})]})]})]})]}),j>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"outline",size:"sm",disabled:o===1,onClick:()=>F(o-1),children:s("Previous")}),e.jsx(g,{variant:"outline",size:"sm",disabled:o===j,onClick:()=>F(o+1),children:s("Next")})]})]})]})}const W={active:"Active",complete:"Complete",expired:"Expired"},Se={active:"status-badge status-green",complete:"status-badge status-blue",expired:"status-badge status-gray"};function we(){const{translate:s}=G(),{id:r}=ce(),l=me(),{isWordPress:x}=xe(),{current:a,isLoading:o,error:h,fetchOne:j,clearCurrent:f}=J();n.useEffect(()=>(r&&j(parseInt(r)),()=>{f()}),[r,j,f]);const u=C=>new Date(C).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"});return o?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ue,{})}):h?e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:h}),!x&&e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})]}):a?e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!x&&e.jsx(g,{variant:"ghost",size:"icon",onClick:()=>l("/engagements"),"aria-label":s("Back"),children:e.jsx(v,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Engagement #",a.id]}),e.jsx("p",{className:"text-muted-foreground",children:u(a.dateCreated)})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:Se[a.status],children:W[a.status]}),e.jsx(Q,{sourceType:"engagement",sourceId:a.id,contextLabel:`engagement #${a.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(V,{children:[e.jsx(H,{children:e.jsx(O,{children:s("Engagement Details")})}),e.jsx(z,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:W[a.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Score")}),e.jsx("dd",{className:"text-lg font-semibold mt-1",children:a.score})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created Date")}),e.jsx("dd",{className:"text-sm mt-1",children:u(a.dateCreated)})]}),a.dateExpires&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Expires Date")}),e.jsx("dd",{className:"text-sm mt-1",children:u(a.dateExpires)})]}),a.customerIdentifier&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Customer")}),e.jsx("dd",{className:"text-sm mt-1",children:a.customerIdentifier})]})]})})]}),e.jsxs(V,{children:[e.jsx(H,{children:e.jsx(O,{children:s("Related Entities")})}),e.jsx(z,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Collaborator")}),e.jsx("dd",{className:"text-sm mt-1",children:K(a.collaboratorName)?e.jsx(N,{to:`/collaborators/${a.collaboratorId}/view`,className:"text-primary hover:underline",children:a.collaboratorName}):e.jsx("span",{className:"text-muted-foreground",children:b(a.collaboratorName,"collaborator",s)})})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Program")}),e.jsx("dd",{className:"text-sm mt-1",children:K(a.programName)?e.jsx(N,{to:`/programs/${a.programId}/view`,className:"text-primary hover:underline",children:a.programName}):e.jsx("span",{className:"text-muted-foreground",children:b(a.programName,"program",s)})})]}),a.conversionId&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Conversion")}),e.jsx("dd",{className:"text-sm mt-1",children:e.jsxs(N,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline font-mono",children:["#",a.conversionId]})})]})]})})]})]}),!x&&e.jsx("div",{className:"mt-6",children:e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})})]}):e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Engagement not found.")}),!x&&e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})]})}window.sirenConfig&&ge({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const q=document.getElementById("siren-engagements");q&&he.createRoot(q).render(e.jsx(n.StrictMode,{children:e.jsxs(Ce,{defaultRoute:"/engagements",children:[e.jsx(je,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(pe,{children:[e.jsx(L,{path:"/engagements",element:e.jsx(U,{})}),e.jsx(L,{path:"/engagements/:id",element:e.jsx(we,{})}),e.jsx(L,{index:!0,element:e.jsx(U,{})})]})})]})}));
     1import{u as G,d as de,r as n,j as e,L as N,S as A,e as B,f as $,g as T,h as d,B as g,o as ce,b as me,a as xe,p as ue,C as V,q as H,s as K,t as O,E as ge,F as he,T as je,R as pe,G as L}from"./shared/wordpress-admin-D_eccjaB.js";import{u as J}from"./shared/engagements-6JbMv8n_.js";import{F as k,H as fe,a as ve,D as Ne}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as Q}from"./shared/ActivityDrawer-BZxDAdLe.js";import{l as b,h as z}from"./shared/linked-record-D4sO5j3k.js";import{u as be}from"./shared/useListRequest-BAYNcD8F.js";import{A as v}from"./shared/arrow-left-XvsxLAWy.js";import{W as Ce}from"./shared/WordPressRouter-CAYzko7X.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/react-Rq6nbqOn.js";const M={active:"Active",complete:"Complete",expired:"Expired"},Ie={active:"status-badge status-green",complete:"status-badge status-blue",expired:"status-badge status-gray"};function U(){const{translate:s}=G(),[r,l]=de(),{items:x,total:a,page:o,perPage:h,totalPages:j,isLoading:f,error:u,fetchList:C}=J(),X=r.get("status")||"all",Y=r.get("collaboratorId")||"",Z=r.get("programId")||"",[i,R]=n.useState(X),[c,I]=n.useState(Y),[m,S]=n.useState(Z),[D,_]=n.useState(10),[w,ee]=n.useState("dateCreated"),[y,se]=n.useState("desc");n.useEffect(()=>{const t=r.get("status"),p=r.get("collaboratorId"),E=r.get("programId");t&&t!==i&&R(t),p&&p!==c&&I(p),E&&E!==m&&S(E)},[r,i,c,m]);const te=be(C,{perPage:D,orderBy:w,order:y,status:i!=="all"?i:void 0,collaboratorId:c?parseInt(c):void 0,programId:m?parseInt(m):void 0}),F=t=>te.setPage(t),ae=t=>_(parseInt(t)),P=t=>{R(t),t!=="all"?r.set("status",t):r.delete("status"),l(r)},re=t=>{const p=w===t&&y==="asc"?"desc":"asc";ee(t),se(p)},le=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),ne=[{id:"id",header:s("ID"),cell:t=>e.jsxs("span",{className:"font-mono text-sm",children:["#",t.id]})},{id:"collaborator",header:s("Collaborator"),cell:t=>e.jsx(k,{filterKey:"collaboratorId",filterValue:t.collaboratorId.toString(),children:b(t.collaboratorName,"collaborator",s)})},{id:"program",header:s("Program"),cell:t=>e.jsx(k,{filterKey:"programId",filterValue:t.programId.toString(),children:b(t.programName,"program",s)})},{id:"score",header:s("Score"),sortable:!0,cell:t=>e.jsx("span",{className:"font-medium",children:t.score})},{id:"status",header:s("Status"),sortable:!0,cell:t=>e.jsx(k,{filterKey:"status",filterValue:t.status,children:e.jsx("span",{className:Ie[t.status],children:M[t.status]})})},{id:"conversion",header:s("Conversion"),cell:t=>t.conversionId?e.jsxs(N,{to:`/conversions/${t.conversionId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",t.conversionId]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"dateCreated",header:s("Created"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm text-muted-foreground",children:le(t.dateCreated)})}],oe=[{key:"status",label:"Status",value:i,displayValue:M[i]||i,onRemove:()=>P("all")},...c?[{key:"collaboratorId",label:"Collaborator",value:c,displayValue:`#${c}`,onRemove:()=>{I(""),r.delete("collaboratorId"),l(r)}}]:[],...m?[{key:"programId",label:"Program",value:m,displayValue:`#${m}`,onRemove:()=>{S(""),r.delete("programId"),l(r)}}]:[]],ie=()=>{P("all"),I(""),S(""),r.delete("collaboratorId"),r.delete("programId"),l(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Engagements"),e.jsx(fe,{topic:"what-is-engagement",side:"right"})]}),e.jsx(Q,{sourceType:"engagement",contextLabel:"all engagements"})]}),e.jsx(ve,{filters:oe,onClearAll:ie}),u&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:u}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap",children:e.jsxs(A,{value:i,onValueChange:P,children:[e.jsx(B,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx($,{placeholder:s("Status")})}),e.jsxs(T,{children:[e.jsx(d,{value:"all",children:s("All Statuses")}),e.jsx(d,{value:"active",children:s("Active")}),e.jsx(d,{value:"complete",children:s("Complete")}),e.jsx(d,{value:"expired",children:s("Expired")})]})]})}),e.jsx(Ne,{columns:ne,data:x,sampleKey:"engagements",isLoading:f,emptyMessage:s("No engagements found."),getRowHref:t=>`/engagements/${t.id}`,sortField:w,sortOrder:y,onSort:re}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",a===0?0:(o-1)*h+1," to ",Math.min(o*h,a)," of"," ",a," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(A,{value:D.toString(),onValueChange:ae,children:[e.jsx(B,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx($,{})}),e.jsxs(T,{children:[e.jsx(d,{value:"10",children:"10"}),e.jsx(d,{value:"25",children:"25"}),e.jsx(d,{value:"50",children:"50"}),e.jsx(d,{value:"100",children:"100"})]})]})]})]}),j>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{variant:"outline",size:"sm",disabled:o===1,onClick:()=>F(o-1),children:s("Previous")}),e.jsx(g,{variant:"outline",size:"sm",disabled:o===j,onClick:()=>F(o+1),children:s("Next")})]})]})]})}const W={active:"Active",complete:"Complete",expired:"Expired"},Se={active:"status-badge status-green",complete:"status-badge status-blue",expired:"status-badge status-gray"};function we(){const{translate:s}=G(),{id:r}=ce(),l=me(),{isWordPress:x}=xe(),{current:a,isLoading:o,error:h,fetchOne:j,clearCurrent:f}=J();n.useEffect(()=>(r&&j(parseInt(r)),()=>{f()}),[r,j,f]);const u=C=>new Date(C).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"});return o?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ue,{})}):h?e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:h}),!x&&e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})]}):a?e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!x&&e.jsx(g,{variant:"ghost",size:"icon",onClick:()=>l("/engagements"),"aria-label":s("Back"),children:e.jsx(v,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Engagement #",a.id]}),e.jsx("p",{className:"text-muted-foreground",children:u(a.dateCreated)})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:Se[a.status],children:W[a.status]}),e.jsx(Q,{sourceType:"engagement",sourceId:a.id,contextLabel:`engagement #${a.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(V,{children:[e.jsx(H,{children:e.jsx(K,{children:s("Engagement Details")})}),e.jsx(O,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:W[a.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Score")}),e.jsx("dd",{className:"text-lg font-semibold mt-1",children:a.score})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created Date")}),e.jsx("dd",{className:"text-sm mt-1",children:u(a.dateCreated)})]}),a.dateExpires&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Expires Date")}),e.jsx("dd",{className:"text-sm mt-1",children:u(a.dateExpires)})]}),a.customerIdentifier&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Customer")}),e.jsx("dd",{className:"text-sm mt-1",children:a.customerIdentifier})]})]})})]}),e.jsxs(V,{children:[e.jsx(H,{children:e.jsx(K,{children:s("Related Entities")})}),e.jsx(O,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Collaborator")}),e.jsx("dd",{className:"text-sm mt-1",children:z(a.collaboratorName)?e.jsx(N,{to:`/collaborators/${a.collaboratorId}/view`,className:"text-primary hover:underline",children:a.collaboratorName}):e.jsx("span",{className:"text-muted-foreground",children:b(a.collaboratorName,"collaborator",s)})})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Program")}),e.jsx("dd",{className:"text-sm mt-1",children:z(a.programName)?e.jsx(N,{to:`/programs/${a.programId}/view`,className:"text-primary hover:underline",children:a.programName}):e.jsx("span",{className:"text-muted-foreground",children:b(a.programName,"program",s)})})]}),a.conversionId&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Conversion")}),e.jsx("dd",{className:"text-sm mt-1",children:e.jsxs(N,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline font-mono",children:["#",a.conversionId]})})]})]})})]})]}),!x&&e.jsx("div",{className:"mt-6",children:e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})})]}):e.jsxs("div",{className:"max-w-2xl",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Engagement not found.")}),!x&&e.jsxs(g,{variant:"outline",onClick:()=>l("/engagements"),children:[e.jsx(v,{className:"h-4 w-4 mr-2"}),s("Back to Engagements")]})]})}window.sirenConfig&&ge({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const q=document.getElementById("siren-engagements");q&&he.createRoot(q).render(e.jsx(n.StrictMode,{children:e.jsxs(Ce,{defaultRoute:"/engagements",children:[e.jsx(je,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(pe,{children:[e.jsx(L,{path:"/engagements",element:e.jsx(U,{})}),e.jsx(L,{path:"/engagements/:id",element:e.jsx(we,{})}),e.jsx(L,{index:!0,element:e.jsx(U,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/fulfillments.js

    r3775642 r3788740  
    1 import{c as $e,v as u,u as ee,j as e,B as p,X as De,r as f,b as Te,L as Z,S as de,d as ue,e as me,f as fe,g as y,n as Oe,a as Ie,w as Me,o as Ue,D as pe,h as he,i as xe,k as ge,l as ye,m as be,E as Be,F as ze,T as Ve,R as We,G as J}from"./shared/wordpress-admin-DNnGQGoM.js";import{c as qe}from"./shared/request-sequence-CQbIQ_gd.js";import{f as g}from"./shared/fulfillments-DDk-ZIVs.js";import{c as Ge}from"./shared/react-zvEYxxW2.js";import{H as He,D as ve,B as _e}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as Ce}from"./shared/ActivityDrawer-iYDgZTH3.js";import{T as Ye}from"./shared/triangle-alert-B1idIoet.js";import{S as Xe}from"./shared/sparkles-ZTBJ8zt0.js";import{u as Je}from"./shared/unshipped-CGZcvpGp.js";import{l as je}from"./shared/linked-record-D4sO5j3k.js";import{u as Ke}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{w as Qe}from"./shared/payout-waiting-k6RU_ZQa.js";import{A as K}from"./shared/arrow-left-W0B3m2vw.js";import{W as Ze}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/registries-Ql2SZeKd.js";/**
     1import{c as Ue,w as d,u as se,j as e,B as h,X as ze,r as f,d as Ve,L as te,S as me,e as fe,f as pe,g as he,h as b,o as qe,b as We,a as _e,p as He,D as ge,i as xe,k as ye,l as be,m as je,n as Se,E as Ge,F as Ye,T as Ke,R as Xe,G as Z}from"./shared/wordpress-admin-D_eccjaB.js";import{c as ke}from"./shared/request-sequence-CQbIQ_gd.js";import{f as p}from"./shared/fulfillments-PrFHoXSm.js";import{c as Je}from"./shared/react-Rq6nbqOn.js";import{H as Qe,D as Le,u as Ze,b as et,B as tt}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as Fe}from"./shared/ActivityDrawer-BZxDAdLe.js";import{T as st}from"./shared/triangle-alert-BXQaBsm-.js";import{S as at}from"./shared/sparkles-Cs-c5bLd.js";import{u as rt}from"./shared/unshipped-CGZcvpGp.js";import{l as we}from"./shared/linked-record-D4sO5j3k.js";import{u as lt}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{i as Ft,w as nt}from"./shared/payout-waiting-k6RU_ZQa.js";import{A as ee}from"./shared/arrow-left-XvsxLAWy.js";import{W as it}from"./shared/WordPressRouter-CAYzko7X.js";import"./shared/registries-CatPSk3G.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const et=$e("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]),Q=qe(),Ne=Ge((t,n)=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,isSubmitting:!1,error:null,current:null,lastListParams:null,fetchList:async i=>{const a=Q.begin();t({isLoading:!0,error:null,lastListParams:i||null});try{const s=await g.list(i);if(!Q.isCurrent(a))return;t({items:s.items,total:s.total,page:s.page,perPage:s.perPage,totalPages:s.totalPages,isLoading:!1})}catch(s){if(!Q.isCurrent(a))return;t({error:s instanceof Error?s.message:"Failed to fetch fulfillments",isLoading:!1})}},fetchOne:async i=>{t({isLoading:!0,error:null,current:null});try{const a=await g.get(i);t({current:a,isLoading:!1})}catch(a){t({error:a instanceof Error?a.message:"Failed to fetch fulfillment",isLoading:!1})}},update:async(i,a)=>{t({isSubmitting:!0,error:null});try{const s=await g.update(i,a);return t({current:s,isSubmitting:!1}),u.success("Fulfillment updated successfully"),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage}),s}catch(s){const l=s instanceof Error?s.message:"Failed to update fulfillment";throw t({error:l,isSubmitting:!1}),u.error(l),s}},bulkProcess:async i=>{t({isSubmitting:!0,error:null});try{await g.bulk("process",i),t({isSubmitting:!1}),u.success(`${i.length} fulfillment(s) processing started`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to process fulfillments";throw t({error:s,isSubmitting:!1}),u.error(s),a}},bulkComplete:async i=>{t({isSubmitting:!0,error:null});try{await g.bulk("complete",i),t({isSubmitting:!1}),u.success(`${i.length} fulfillment(s) marked as complete`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to update fulfillments";throw t({error:s,isSubmitting:!1}),u.error(s),a}},bulkFail:async i=>{t({isSubmitting:!0,error:null});try{await g.bulk("fail",i),t({isSubmitting:!1}),u.success(`${i.length} fulfillment(s) marked as failed`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to update fulfillments";throw t({error:s,isSubmitting:!1}),u.error(s),a}},bulkDelete:async i=>{t({isSubmitting:!0,error:null});try{await g.bulk("delete",i),t({isSubmitting:!1}),u.success(`${i.length} fulfillment(s) deleted`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to delete fulfillments";throw t({error:s,isSubmitting:!1}),u.error(s),a}},fulfillPayouts:async(i,a)=>{t({isSubmitting:!0,error:null});try{let s=a;if(!s||s.length===0){const m=n().current;m!=null&&m.payouts&&(s=m.payouts.map(d=>d.id))}if(!s||s.length===0){u.error("No payouts to fulfill"),t({isSubmitting:!1});return}const l=await g.exportPayouts(s,!0);if(l.csv){const m=new Blob([l.csv],{type:"text/csv;charset=utf-8;"}),d=URL.createObjectURL(m),c=document.createElement("a");c.href=d,c.download=l.filename||"payouts_export.csv",document.body.appendChild(c),c.click(),document.body.removeChild(c),URL.revokeObjectURL(d)}t({isSubmitting:!1}),u.success(`${l.exported} payout(s) exported, ${l.marked} marked as paid`),n().fetchOne(i)}catch(s){const l=s instanceof Error?s.message:"Failed to fulfill payouts";throw t({error:l,isSubmitting:!1}),u.error(l),s}},exportPayouts:async(i,a=!1)=>{t({isSubmitting:!0,error:null});try{const s=await g.exportPayouts(i,a);if(s.csv){const m=new Blob([s.csv],{type:"text/csv;charset=utf-8;"}),d=URL.createObjectURL(m),c=document.createElement("a");c.href=d,c.download=s.filename||"payouts_export.csv",document.body.appendChild(c),c.click(),document.body.removeChild(c),URL.revokeObjectURL(d)}t({isSubmitting:!1});const l=a?`${s.exported} payout(s) exported, ${s.marked} marked as paid`:`${s.exported} payout(s) exported`;u.success(l)}catch(s){const l=s instanceof Error?s.message:"Failed to export payouts";throw t({error:l,isSubmitting:!1}),u.error(l),s}},bulkPayouts:async(i,a,s)=>{t({isSubmitting:!0,error:null});try{await g.bulkPayouts(a,s),t({isSubmitting:!1});const l=a==="markPaid"?"marked as paid":"marked as unpaid";u.success(`${s.length} payout(s) ${l}`),n().fetchOne(i)}catch(l){const m=l instanceof Error?l.message:"Failed to update payouts";throw t({error:m,isSubmitting:!1}),u.error(m),l}},retryPayout:async(i,a)=>{t({isSubmitting:!0});try{const s=await g.retryPayout(a);t({isSubmitting:!1}),s.status==="paid"?u.success(`Payout #${a} was paid`):u.success(`Payout #${a} is being sent again. Reload in a moment to see the result.`),n().fetchOne(i)}catch(s){const l=s instanceof Error?s.message:"Failed to retry payout";t({isSubmitting:!1}),u.error(l)}},autofulfill:async(i,a)=>{t({isSubmitting:!0});try{const s=await g.autofulfill(i);return t({isSubmitting:!1}),a!==void 0?n().fetchOne(a):n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage}),s}catch(s){const l=s instanceof Error?s.message:"Failed to send payouts";return t({isSubmitting:!1}),u.error(l),null}},clearCurrent:()=>t({current:null}),clearError:()=>t({error:null})})),tt=["noAutofulfiller","alreadyPaid","processing","notInPlan","waitingOnCollaborator","collaboratorGone","dispatchFailed"];function ke({result:t,onDismiss:n}){const{translate:i,translatePlural:a}=ee(),s={noAutofulfiller:i("No automatic payout method for the currency. Pay these with the CSV export."),alreadyPaid:i("Already paid"),processing:i("Already being sent"),notInPlan:i("The payout method is not part of your plan"),collaboratorGone:i("The collaborator is in the trash or deleted"),waitingOnCollaborator:i("Waiting on the collaborator's setup. Siren sends these once they finish."),dispatchFailed:i("Could not be queued. Try again.")},l=t.skipped.length,m=tt.map(d=>({reason:d,count:t.skippedCounts[d]??0})).filter(({count:d})=>d>0);return e.jsxs("div",{role:"status","data-testid":"autofulfill-result",className:"mb-4 flex items-start gap-3 rounded-md border bg-muted/30 p-4 text-sm",children:[e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("p",{className:"font-medium",children:[t.dispatched>0?a("%d payout is being sent.","%d payouts are being sent.",t.dispatched).replace("%d",String(t.dispatched)):i("No payouts were sent."),t.dispatched>0&&` ${i("Reload in a moment to see them marked paid.")}`]}),l>0&&e.jsxs("div",{children:[e.jsx("p",{children:a("%d payout was not sent:","%d payouts were not sent:",l).replace("%d",String(l))}),e.jsx("ul",{className:"mt-1 list-disc pl-5 text-muted-foreground",children:m.map(({reason:d,count:c})=>e.jsxs("li",{"data-testid":`autofulfill-skipped-${d}`,children:[s[d],": ",c]},d))})]})]}),e.jsx(p,{variant:"ghost",size:"icon",onClick:n,"aria-label":i("Dismiss"),children:e.jsx(De,{className:"h-4 w-4"})})]})}function we(t){return t==="all"?{}:t==="attention"?{payoutStatus:"failed"}:{status:t}}function Se(){const{translate:t}=ee(),{items:n,total:i,page:a,perPage:s,totalPages:l,isLoading:m,isSubmitting:d,error:c,fetchList:k,autofulfill:L}=Ne(),[v,$]=f.useState(10),[w,U]=f.useState("dateCreated"),[S,te]=f.useState("desc"),[D]=Te(),[se,ae]=f.useState(()=>D.get("setup")==="payouts"),[P,B]=f.useState(()=>D.get("filter")==="attention"?"attention":"all"),[h,b]=f.useState(new Set),[T,F]=f.useState(null);f.useEffect(()=>{b(new Set),k({page:1,perPage:v,orderBy:w,order:S,...we(P)})},[k,v,w,S,P]);const O=(o={})=>({page:o.page??1,perPage:o.perPage??v,orderBy:o.orderBy??w,order:o.order??S,...we(P)}),C=o=>{b(new Set),k(O({page:o}))},I=o=>{const j=parseInt(o);$(j),k(O({perPage:j}))},E=o=>{const j=w===o&&S==="asc"?"desc":"asc";U(o),te(j)},z=o=>new Date(o).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),A=[{id:"id",header:t("Fulfillment ID"),cell:o=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs(Z,{to:`/fulfillments/${o.id}`,className:"text-primary hover:underline font-mono",children:["#",o.id]}),(o.failedCount??0)>0&&e.jsxs("span",{className:"status-badge status-red inline-flex items-center gap-1","data-testid":`fulfillment-attention-${o.id}`,children:[e.jsx(Ye,{className:"h-3 w-3","aria-hidden":"true"}),t("Needs attention")]})]})},{id:"paidCount",header:t("Paid"),cell:o=>e.jsx("span",{className:"text-green-600 dark:text-green-400 font-medium",children:o.paidCount??0})},{id:"unpaidCount",header:t("Unpaid"),cell:o=>e.jsx("span",{className:"text-yellow-600 dark:text-yellow-400 font-medium",children:Math.max(0,(o.unpaidCount??0)-(o.failedCount??0))})},{id:"failedCount",header:t("Failed"),cell:o=>{const j=o.failedCount??0;return e.jsx("span",{className:j>0?"text-destructive font-medium":"text-muted-foreground","data-testid":`fulfillment-failed-count-${o.id}`,children:j})}},{id:"dateCreated",header:t("Created"),sortable:!0,cell:o=>e.jsx("span",{className:"text-sm text-muted-foreground",children:z(o.dateCreated)})}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-4",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[t("Fulfillments"),e.jsx(He,{topic:"what-is-fulfillment",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Ce,{sourceType:"fulfillment",contextLabel:"all fulfillments"}),e.jsxs(p,{variant:"ghost",disabled:!0,className:"opacity-60",children:[e.jsx(Xe,{className:"h-4 w-4 mr-2"}),t("Manage Autofulfillers"),e.jsx("span",{className:"ml-1.5 text-[10px] font-normal px-1.5 py-0.5 rounded bg-primary/10 text-primary",children:"Essentials"})]})]})]}),!1,c&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:c}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap",children:e.jsxs(de,{value:P,onValueChange:o=>B(o),children:[e.jsx(ue,{className:"w-[190px]","aria-label":t("Filter fulfillments"),children:e.jsx(me,{placeholder:t("Status")})}),e.jsxs(fe,{children:[e.jsx(y,{value:"all",children:t("All Statuses")}),e.jsx(y,{value:"attention",children:t("Needs attention")}),e.jsx(y,{value:"pending",children:t("Pending")}),e.jsx(y,{value:"processing",children:t("Processing")}),e.jsx(y,{value:"complete",children:t("Complete")}),e.jsx(y,{value:"failed",children:t("Failed")})]})]})}),T&&e.jsx(ke,{result:T,onDismiss:()=>F(null)}),!1,e.jsx(ve,{columns:A,data:n,isLoading:m,selectable:!1,selectedIds:h,onSelectionChange:b,emptyMessage:t(P==="attention"?"No fulfillments need attention.":P==="all"?"No fulfillments yet. To pay collaborators, select obligations on the Obligations screen and choose Create Fulfillments.":"No fulfillments found."),sortField:w,sortOrder:S,onSort:E}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",i===0?0:(a-1)*s+1," to ",Math.min(a*s,i)," of"," ",i," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(de,{value:v.toString(),onValueChange:I,children:[e.jsx(ue,{"aria-label":t("Rows per page"),className:"w-[80px] h-8",children:e.jsx(me,{})}),e.jsxs(fe,{children:[e.jsx(y,{value:"10",children:"10"}),e.jsx(y,{value:"25",children:"25"}),e.jsx(y,{value:"50",children:"50"}),e.jsx(y,{value:"100",children:"100"})]})]})]})]}),l>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(p,{variant:"outline",size:"sm",disabled:a===1,onClick:()=>C(a-1),children:t("Previous")}),e.jsx(p,{variant:"outline",size:"sm",disabled:a===l,onClick:()=>C(a+1),children:t("Next")})]})]})]})}const st=Je("src/service/stores/autofulfillers.ts"),at={paid:"status-badge status-green",unpaid:"status-badge status-yellow",processing:"status-badge status-blue",failed:"status-badge status-red"};function lt(){var oe,ce;const{translate:t,translatePlural:n}=ee(),{formatMoney:i,definitionFor:a}=Ke(),s={paid:t("Paid"),unpaid:t("Unpaid"),processing:t("Processing"),failed:t("Failed")},{id:l}=Oe(),m=Ie(),{isWordPress:d}=Me(),{current:c,isLoading:k,isSubmitting:L,error:v,fetchOne:$,clearCurrent:w,fulfillPayouts:U,bulkPayouts:S,retryPayout:te,autofulfill:D}=Ne(),{items:se,methods:ae,fetchAll:P,fetchMethods:B}=st.useAutofulfillersStore(),[h,b]=f.useState(new Set),[T,F]=f.useState(!1),[O,C]=f.useState(!1),[I,E]=f.useState(null);f.useEffect(()=>{},[P,B]),f.useEffect(()=>{E(null)},[l]),f.useEffect(()=>(l&&$(parseInt(l)),()=>{w()}),[l,$,w]);const z=r=>r?new Date(r).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"(none)",A=(r,x)=>i(r,x),o=async()=>{if(!l)return;const r=h.size>0?Array.from(h):void 0;await U(parseInt(l),r),b(new Set)},j=async()=>{if(!l)return;const r=await D([parseInt(l)],parseInt(l));r&&E(r)},Le=async()=>{l&&(await S(parseInt(l),"markPaid",Array.from(h)),b(new Set))},Fe=async()=>{l&&(await S(parseInt(l),"markUnpaid",Array.from(h)),b(new Set))};if(k)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ue,{})});if(v)return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:v}),!d&&e.jsxs(p,{variant:"outline",onClick:()=>m("/fulfillments"),children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),t("Back to Fulfillments")]})]});if(!c)return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:t("Fulfillment not found.")}),!d&&e.jsxs(p,{variant:"outline",onClick:()=>m("/fulfillments"),children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),t("Back to Fulfillments")]})]});const N=c.payouts||[],le=c.currency||((oe=N[0])==null?void 0:oe.currency)||"",M=((ce=a(le))==null?void 0:ce.code)??le,V=N.reduce((r,x)=>(r.total+=x.value,x.status==="paid"?r.paid+=x.value:r.unpaid+=x.value,r),{total:0,paid:0,unpaid:0}),W=r=>!1,q=N.filter(W).length,Ae=[{id:"id",header:t("Payout ID"),cell:r=>e.jsxs(Z,{to:`/obligations?payoutId=${r.id}`,className:"font-mono text-sm text-primary hover:underline",children:["#",r.id]})},{id:"collaborator",header:t("Collaborator"),cell:r=>e.jsx(Z,{to:`/collaborators/${r.collaboratorId}/view`,className:"text-foreground hover:underline",children:je(r.collaboratorName,"collaborator",t)})},{id:"status",header:t("Status"),cell:r=>e.jsxs("div",{children:[e.jsx("span",{className:at[r.status],children:W(r)?t("Waiting"):s[r.status]}),W(r)&&e.jsx("p",{className:"mt-1 max-w-md text-sm text-muted-foreground break-words","data-testid":`payout-waiting-${r.id}`,children:t("Waiting for %1$s to set up %2$s").replace("%1$s",je(r.collaboratorName,"collaborator",t)).replace("%2$s",Qe(r.waitingReason))}),!1]})},{id:"datePaid",header:t("Paid Date"),cell:r=>e.jsx("span",{className:"text-sm text-muted-foreground",children:z(r.datePaid)})},{id:"value",header:t("Amount"),cell:r=>e.jsx("span",{className:"font-medium",children:A(r.value,r.currency)})}],Ee=0,re=r=>{const x=se.find(X=>X.currency.toUpperCase()===r.toUpperCase());if(!x)return null;const Y=ae.find(X=>X.id===x.method);return!Y||Y.entitled===!1?null:Y},R=[],ie=R.filter(r=>r.status==="unpaid").length,ne=Array.from(new Set(R.map(r=>{var x;return((x=re(r.currency))==null?void 0:x.name)??""}))).filter(r=>r!==""),G=ne.length===1?t("Send with %s").replace("%s",ne[0]):t("Send automatically"),H=N.filter(r=>(r.status==="unpaid"||r.status==="failed")&&re(r.currency)===null).length,_=ie>0,Re=[{label:t("Mark Paid"),onClick:Le},{label:t("Mark Unpaid"),onClick:Fe}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!d&&e.jsx(p,{variant:"ghost",size:"icon",onClick:()=>m("/fulfillments"),"aria-label":t("Back"),children:e.jsx(K,{className:"h-4 w-4"})}),e.jsxs("h1",{className:"text-2xl font-semibold",children:["Fulfillment ",c.id]}),_&&e.jsxs(p,{onClick:()=>C(!0),disabled:L,children:[e.jsx(et,{className:"h-4 w-4 mr-2"}),G]}),e.jsx(p,{variant:"outline",onClick:()=>F(!0),disabled:L,children:L?"Processing...":_?t("Export CSV"):"Fulfill Payouts"}),e.jsxs("span",{className:"ml-auto text-sm text-muted-foreground",children:[N.length," item",N.length!==1?"s":""]}),e.jsx(Ce,{sourceType:"fulfillment",sourceId:c.id,contextLabel:`fulfillment #${c.id}`})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-4 mb-4",children:[e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Value"}),e.jsx("div",{className:"text-lg font-semibold",children:A(V.total,M)})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Currency"}),e.jsx("div",{className:"text-lg font-semibold",children:M})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Paid"}),e.jsx("div",{className:"text-lg font-semibold",children:A(V.paid,M)})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Unpaid"}),e.jsx("div",{className:"text-lg font-semibold",children:A(V.unpaid,M)})]})]}),I&&e.jsx(ke,{result:I,onDismiss:()=>E(null)}),q>0&&e.jsxs("div",{role:"status",className:"mb-4 p-4 bg-muted/50 rounded-md text-sm","data-testid":"payouts-waiting-notice",children:[q===1?t("1 automatic payout is waiting for its collaborator to set up Stripe or PayPal."):t("%d automatic payouts are waiting for their collaborators to set up Stripe or PayPal.").replace("%d",String(q))," ",t("Siren sends each one as soon as its collaborator finishes.")]}),Ee>0,e.jsx(_e,{selectedCount:h.size,actions:Re,onClear:()=>b(new Set),isProcessing:L}),e.jsx(ve,{columns:Ae,data:N,isLoading:!1,emptyMessage:t("No payouts in this fulfillment."),selectable:!0,selectedIds:h,onSelectionChange:b}),e.jsx(pe,{open:T,onOpenChange:F,children:e.jsxs(he,{children:[e.jsxs(xe,{children:[e.jsx(ge,{children:t("Confirm Fulfillment Export")}),e.jsxs(ye,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:"This action exports a CSV for mass payment and immediately marks the selected payouts as paid."}),e.jsx("p",{children:h.size>0?`You are about to fulfill ${h.size} selected payout${h.size===1?"":"s"}.`:"You are about to fulfill all payouts in this batch."}),e.jsx("p",{children:"If you prefer to pay individually, select payouts and use “Mark Paid” instead."}),_&&e.jsx("p",{children:t("Payouts in a currency with an automatic payout method can be sent with it instead. Exporting marks them paid without sending money.")})]})]}),e.jsxs(be,{children:[e.jsx(p,{variant:"outline",onClick:()=>F(!1),children:t("Cancel")}),e.jsx(p,{onClick:async()=>{await o(),F(!1)},children:t("Export & Mark Paid")})]})]})}),e.jsx(pe,{open:O,onOpenChange:C,children:e.jsxs(he,{children:[e.jsxs(xe,{children:[e.jsx(ge,{children:G}),e.jsx(ye,{asChild:!0,children:e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsxs("p",{children:[n("This sends %d payout through your automatic payout method now.","This sends %d payouts through your automatic payout method now.",R.length).replace("%d",String(R.length)),R.length>ie&&` ${t("Payouts that failed before are tried again.")}`]}),H>0&&e.jsx("p",{children:n("%d payout is in a currency with no automatic payout method. It is left unpaid. Pay it with the CSV export.","%d payouts are in a currency with no automatic payout method. They are left unpaid. Pay them with the CSV export.",H).replace("%d",String(H))}),h.size>0&&e.jsx("p",{children:t("This sends every payout in the fulfillment that can go automatically, not only the selected ones.")})]})})]}),e.jsxs(be,{children:[e.jsx(p,{variant:"outline",onClick:()=>C(!1),children:t("Cancel")}),e.jsx(p,{disabled:L,onClick:async()=>{C(!1),await j()},children:G})]})]})})]})}window.sirenConfig&&Be({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Pe=document.getElementById("siren-fulfillments");Pe&&ze.createRoot(Pe).render(e.jsx(f.StrictMode,{children:e.jsxs(Ze,{defaultRoute:"/fulfillments",children:[e.jsx(Ve,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(We,{children:[e.jsx(J,{path:"/fulfillments",element:e.jsx(Se,{})}),e.jsx(J,{path:"/fulfillments/:id",element:e.jsx(lt,{})}),e.jsx(J,{index:!0,element:e.jsx(Se,{})})]})})]})}));
     6 */const ot=Ue("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]),T=ke(),D=ke(),Ee=Je((t,n)=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,isSubmitting:!1,error:null,current:null,lastListParams:null,fetchList:async l=>{const a=T.begin();t({isLoading:!0,error:null,lastListParams:l||null});try{const s=await p.list(l);if(!T.isCurrent(a))return;t({items:s.items,total:s.total,page:s.page,perPage:s.perPage,totalPages:s.totalPages,isLoading:!1})}catch(s){if(!T.isCurrent(a))return;t({error:s instanceof Error?s.message:"Failed to fetch fulfillments",isLoading:!1})}},fetchOne:async l=>{const a=D.begin();t({isLoading:!0,error:null,current:null});try{const s=await p.get(l);if(!D.isCurrent(a))return;t({current:s,isLoading:!1})}catch(s){if(!D.isCurrent(a))return;t({error:s instanceof Error?s.message:"Failed to fetch fulfillment",isLoading:!1})}},refreshList:async()=>{if(n().isLoading)return;const l=T.begin();try{const a=await p.list(n().lastListParams||{page:n().page,perPage:n().perPage});if(!T.isCurrent(l))return;t({items:a.items,total:a.total,page:a.page,perPage:a.perPage,totalPages:a.totalPages})}catch{}},refreshCurrent:async l=>{var s,r;if(((s=n().current)==null?void 0:s.id)!==l)return;const a=D.begin();try{const u=await p.get(l);if(!D.isCurrent(a)||((r=n().current)==null?void 0:r.id)!==l)return;t({current:u})}catch{}},update:async(l,a)=>{t({isSubmitting:!0,error:null});try{const s=await p.update(l,a);return t({current:s,isSubmitting:!1}),d.success("Fulfillment updated successfully"),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage}),s}catch(s){const r=s instanceof Error?s.message:"Failed to update fulfillment";throw t({error:r,isSubmitting:!1}),d.error(r),s}},bulkProcess:async l=>{t({isSubmitting:!0,error:null});try{await p.bulk("process",l),t({isSubmitting:!1}),d.success(`${l.length} fulfillment(s) processing started`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to process fulfillments";throw t({error:s,isSubmitting:!1}),d.error(s),a}},bulkComplete:async l=>{t({isSubmitting:!0,error:null});try{await p.bulk("complete",l),t({isSubmitting:!1}),d.success(`${l.length} fulfillment(s) marked as complete`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to update fulfillments";throw t({error:s,isSubmitting:!1}),d.error(s),a}},bulkFail:async l=>{t({isSubmitting:!0,error:null});try{await p.bulk("fail",l),t({isSubmitting:!1}),d.success(`${l.length} fulfillment(s) marked as failed`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to update fulfillments";throw t({error:s,isSubmitting:!1}),d.error(s),a}},bulkDelete:async l=>{t({isSubmitting:!0,error:null});try{await p.bulk("delete",l),t({isSubmitting:!1}),d.success(`${l.length} fulfillment(s) deleted`),n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage})}catch(a){const s=a instanceof Error?a.message:"Failed to delete fulfillments";throw t({error:s,isSubmitting:!1}),d.error(s),a}},fulfillPayouts:async(l,a)=>{t({isSubmitting:!0,error:null});try{let s=a;if(!s||s.length===0){const u=n().current;u!=null&&u.payouts&&(s=u.payouts.map(c=>c.id))}if(!s||s.length===0){d.error("No payouts to fulfill"),t({isSubmitting:!1});return}const r=await p.exportPayouts(s,!0);if(r.csv){const u=new Blob([r.csv],{type:"text/csv;charset=utf-8;"}),c=URL.createObjectURL(u),m=document.createElement("a");m.href=c,m.download=r.filename||"payouts_export.csv",document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(c)}t({isSubmitting:!1}),d.success(`${r.exported} payout(s) exported, ${r.marked} marked as paid`),n().fetchOne(l)}catch(s){const r=s instanceof Error?s.message:"Failed to fulfill payouts";throw t({error:r,isSubmitting:!1}),d.error(r),s}},exportPayouts:async(l,a=!1)=>{t({isSubmitting:!0,error:null});try{const s=await p.exportPayouts(l,a);if(s.csv){const u=new Blob([s.csv],{type:"text/csv;charset=utf-8;"}),c=URL.createObjectURL(u),m=document.createElement("a");m.href=c,m.download=s.filename||"payouts_export.csv",document.body.appendChild(m),m.click(),document.body.removeChild(m),URL.revokeObjectURL(c)}t({isSubmitting:!1});const r=a?`${s.exported} payout(s) exported, ${s.marked} marked as paid`:`${s.exported} payout(s) exported`;d.success(r)}catch(s){const r=s instanceof Error?s.message:"Failed to export payouts";throw t({error:r,isSubmitting:!1}),d.error(r),s}},bulkPayouts:async(l,a,s)=>{t({isSubmitting:!0,error:null});try{await p.bulkPayouts(a,s),t({isSubmitting:!1});const r=a==="markPaid"?"marked as paid":"marked as unpaid";d.success(`${s.length} payout(s) ${r}`),n().fetchOne(l)}catch(r){const u=r instanceof Error?r.message:"Failed to update payouts";throw t({error:u,isSubmitting:!1}),d.error(u),r}},retryPayout:async(l,a)=>{t({isSubmitting:!0});try{const s=await p.retryPayout(a);t({isSubmitting:!1}),s.status==="paid"?d.success(`Payout #${a} was paid`):d.success(`Payout #${a} is being sent again. Reload in a moment to see the result.`),n().fetchOne(l)}catch(s){const r=s instanceof Error?s.message:"Failed to retry payout";t({isSubmitting:!1}),d.error(r)}},autofulfill:async(l,a)=>{t({isSubmitting:!0});try{const s=await p.autofulfill(l);return t({isSubmitting:!1}),a!==void 0?n().fetchOne(a):n().fetchList(n().lastListParams||{page:n().page,perPage:n().perPage}),s}catch(s){const r=s instanceof Error?s.message:"Failed to send payouts";return t({isSubmitting:!1}),d.error(r),null}},clearCurrent:()=>t({current:null}),clearError:()=>t({error:null})})),ut=["noAutofulfiller","alreadyPaid","processing","notInPlan","waitingOnCollaborator","collaboratorGone","dispatchFailed"];function Re({result:t,onDismiss:n}){const{translate:l,translatePlural:a}=se(),s={noAutofulfiller:l("No automatic payout method for the currency. Pay these with the CSV export."),alreadyPaid:l("Already paid"),processing:l("Already being sent"),notInPlan:l("The payout method is not part of your plan"),collaboratorGone:l("The collaborator is in the trash or deleted"),waitingOnCollaborator:l("Waiting on the collaborator's setup. Siren sends these once they finish."),dispatchFailed:l("Could not be queued. Try again.")},r=t.skipped.length,u=ut.map(c=>({reason:c,count:t.skippedCounts[c]??0})).filter(({count:c})=>c>0);return e.jsxs("div",{role:"status","data-testid":"autofulfill-result",className:"mb-4 flex items-start gap-3 rounded-md border bg-muted/30 p-4 text-sm",children:[e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("p",{className:"font-medium",children:[t.dispatched>0?a("%d payout is being sent.","%d payouts are being sent.",t.dispatched).replace("%d",String(t.dispatched)):l("No payouts were sent."),t.dispatched>0&&` ${l("Reload in a moment to see them marked paid.")}`]}),r>0&&e.jsxs("div",{children:[e.jsx("p",{children:a("%d payout was not sent:","%d payouts were not sent:",r).replace("%d",String(r))}),e.jsx("ul",{className:"mt-1 list-disc pl-5 text-muted-foreground",children:u.map(({reason:c,count:m})=>e.jsxs("li",{"data-testid":`autofulfill-skipped-${c}`,children:[s[c],": ",m]},c))})]})]}),e.jsx(h,{variant:"ghost",size:"icon",onClick:n,"aria-label":l("Dismiss"),children:e.jsx(ze,{className:"h-4 w-4"})})]})}const ct=rt("src/service/stores/autofulfillers.ts"),Pe=3e3,dt=3e4;function mt(t,n){const l=f.useRef(n);l.current=n,f.useEffect(()=>{if(!t)return;const a=Date.now()+dt;let s=!1,r;const u=()=>{s||Date.now()+Pe>a||(r=setTimeout(()=>{Promise.resolve(l.current()).then(u,u)},Pe))};return u(),()=>{s=!0,clearTimeout(r)}},[t])}function ft(t,n,l){if(!t)return null;const a=n.find(r=>r.currency.toUpperCase()===t.toUpperCase());if(!a)return null;const s=l.find(r=>r.id===a.method);return!s||s.entitled===!1?null:s}function ve(t){return t==="all"?{}:t==="attention"?{payoutStatus:"failed"}:{status:t}}function Ce(){const{translate:t}=se(),{items:n,total:l,page:a,perPage:s,totalPages:r,isLoading:u,isSubmitting:c,error:m,fetchList:k,autofulfill:L}=Ee(),[F,M]=f.useState(10),[P,I]=f.useState("dateCreated"),[v,O]=f.useState("desc"),[V]=Ve(),[ae,re]=f.useState(()=>V.get("setup")==="payouts"),[S,q]=f.useState(()=>V.get("filter")==="attention"?"attention":"all"),[W,E]=f.useState(new Set),[g,w]=f.useState(null);f.useEffect(()=>{E(new Set),k({page:1,perPage:F,orderBy:P,order:v,...ve(S)})},[k,F,P,v,S]);const B=(o={})=>({page:o.page??1,perPage:o.perPage??F,orderBy:o.orderBy??P,order:o.order??v,...ve(S)}),A=o=>{E(new Set),k(B({page:o}))},x=o=>{const y=parseInt(o);M(y),k(B({perPage:y}))},C=o=>{const y=P===o&&v==="asc"?"desc":"asc";I(o),O(y)},_=o=>new Date(o).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),R=[{id:"id",header:t("Fulfillment ID"),cell:o=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs(te,{to:`/fulfillments/${o.id}`,className:"text-primary hover:underline font-mono",children:["#",o.id]}),(o.failedCount??0)>0&&e.jsxs("span",{className:"status-badge status-red inline-flex items-center gap-1","data-testid":`fulfillment-attention-${o.id}`,children:[e.jsx(st,{className:"h-3 w-3","aria-hidden":"true"}),t("Needs attention")]})]})},{id:"paidCount",header:t("Paid"),cell:o=>e.jsx("span",{className:"text-green-600 dark:text-green-400 font-medium",children:o.paidCount??0})},{id:"unpaidCount",header:t("Unpaid"),cell:o=>e.jsx("span",{className:"text-yellow-600 dark:text-yellow-400 font-medium",children:Math.max(0,(o.unpaidCount??0)-(o.failedCount??0))})},{id:"failedCount",header:t("Failed"),cell:o=>{const y=o.failedCount??0;return e.jsx("span",{className:y>0?"text-destructive font-medium":"text-muted-foreground","data-testid":`fulfillment-failed-count-${o.id}`,children:y})}},{id:"dateCreated",header:t("Created"),sortable:!0,cell:o=>e.jsx("span",{className:"text-sm text-muted-foreground",children:_(o.dateCreated)})}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-4",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[t("Fulfillments"),e.jsx(Qe,{topic:"what-is-fulfillment",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Fe,{sourceType:"fulfillment",contextLabel:"all fulfillments"}),e.jsxs(h,{variant:"ghost",disabled:!0,className:"opacity-60","data-tour":"autofulfillers",children:[e.jsx(at,{className:"h-4 w-4 mr-2"}),t("Manage Autofulfillers"),e.jsx("span",{className:"ml-1.5 text-[10px] font-normal px-1.5 py-0.5 rounded bg-primary/10 text-primary",children:"Essentials"})]})]})]}),!1,!1,m&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:m}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap","data-tour":"fulfillments-filters",children:e.jsxs(me,{value:S,onValueChange:o=>q(o),children:[e.jsx(fe,{className:"w-[190px]","aria-label":t("Filter fulfillments"),children:e.jsx(pe,{placeholder:t("Status")})}),e.jsxs(he,{children:[e.jsx(b,{value:"all",children:t("All Statuses")}),e.jsx(b,{value:"attention",children:t("Needs attention")}),e.jsx(b,{value:"pending",children:t("Pending")}),e.jsx(b,{value:"processing",children:t("Processing")}),e.jsx(b,{value:"complete",children:t("Complete")}),e.jsx(b,{value:"failed",children:t("Failed")})]})]})}),g&&e.jsx(Re,{result:g,onDismiss:()=>w(null)}),!1,e.jsx(Le,{columns:R,data:n,sampleKey:"fulfillments",isLoading:u,selectable:!1,selectedIds:W,onSelectionChange:E,emptyMessage:t(S==="attention"?"No fulfillments need attention.":S==="all"?"No fulfillments yet. To pay collaborators, select obligations on the Obligations screen and choose Create Fulfillments.":"No fulfillments found."),sortField:P,sortOrder:v,onSort:C}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",l===0?0:(a-1)*s+1," to ",Math.min(a*s,l)," of"," ",l," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:t("Per page:")}),e.jsxs(me,{value:F.toString(),onValueChange:x,children:[e.jsx(fe,{"aria-label":t("Rows per page"),className:"w-[80px] h-8",children:e.jsx(pe,{})}),e.jsxs(he,{children:[e.jsx(b,{value:"10",children:"10"}),e.jsx(b,{value:"25",children:"25"}),e.jsx(b,{value:"50",children:"50"}),e.jsx(b,{value:"100",children:"100"})]})]})]})]}),r>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(h,{variant:"outline",size:"sm",disabled:a===1,onClick:()=>A(a-1),children:t("Previous")}),e.jsx(h,{variant:"outline",size:"sm",disabled:a===r,onClick:()=>A(a+1),children:t("Next")})]})]})]})}const pt={paid:"status-badge status-green",unpaid:"status-badge status-yellow",processing:"status-badge status-blue",failed:"status-badge status-red"};function ht(){var ce,de;const{translate:t,translatePlural:n}=se(),{formatMoney:l,definitionFor:a}=lt(),s={paid:t("Paid"),unpaid:t("Unpaid"),processing:t("Processing"),failed:t("Failed")},{id:r}=qe(),u=We(),{isWordPress:c}=_e(),{current:m,isLoading:k,isSubmitting:L,error:F,fetchOne:M,refreshCurrent:P,clearCurrent:I,fulfillPayouts:v,bulkPayouts:O,retryPayout:V,autofulfill:ae}=Ee(),{items:re,methods:S,fetchAll:q,fetchMethods:W}=ct.useAutofulfillersStore(),E=Ze("fulfillmentDetail"),g=E!==null,w=E??m,B=g?!1:k,A=g?null:F,[x,C]=f.useState(new Set),[_,R]=f.useState(!1),[o,y]=f.useState(!1),[le,H]=f.useState(null);f.useEffect(()=>{},[q,W]),f.useEffect(()=>{H(null)},[r]),f.useEffect(()=>(r&&!g&&/^\d+$/.test(r)&&M(parseInt(r)),()=>{I()}),[r,M,I,g]),mt(!1,()=>m?P(m.id):void 0);const Ae=i=>i?new Date(i).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"(none)",U=(i,j)=>l(i,j),$e=async()=>{if(!r)return;const i=x.size>0?Array.from(x):void 0;await v(parseInt(r),i),C(new Set)},Te=async()=>{if(!r)return;const i=await ae([parseInt(r)],parseInt(r));i&&H(i)},De=async()=>{r&&(await O(parseInt(r),"markPaid",Array.from(x)),C(new Set))},Me=async()=>{r&&(await O(parseInt(r),"markUnpaid",Array.from(x)),C(new Set))};if(B)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(He,{})});if(A)return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:A}),!c&&e.jsxs(h,{variant:"outline",onClick:()=>u("/fulfillments"),children:[e.jsx(ee,{className:"h-4 w-4 mr-2"}),t("Back to Fulfillments")]})]});if(!w)return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:t("Fulfillment not found.")}),!c&&e.jsxs(h,{variant:"outline",onClick:()=>u("/fulfillments"),children:[e.jsx(ee,{className:"h-4 w-4 mr-2"}),t("Back to Fulfillments")]})]});const N=w.payouts||[],ne=w.currency||((ce=N[0])==null?void 0:ce.currency)||"",z=((de=a(ne))==null?void 0:de.code)??ne,G=N.reduce((i,j)=>(i.total+=j.value,j.status==="paid"?i.paid+=j.value:i.unpaid+=j.value,i),{total:0,paid:0,unpaid:0}),Y=i=>!1,K=N.filter(Y).length,Ie=[{id:"id",header:t("Payout ID"),cell:i=>e.jsxs(te,{to:`/obligations?payoutId=${i.id}`,className:"font-mono text-sm text-primary hover:underline",children:["#",i.id]})},{id:"collaborator",header:t("Collaborator"),cell:i=>e.jsx(te,{to:`/collaborators/${i.collaboratorId}/view`,className:"text-foreground hover:underline",children:we(i.collaboratorName,"collaborator",t)})},{id:"status",header:t("Status"),cell:i=>e.jsxs("div",{children:[e.jsx("span",{className:pt[i.status],children:Y(i)?t("Waiting"):s[i.status]}),Y(i)&&e.jsx("p",{className:"mt-1 max-w-md text-sm text-muted-foreground break-words","data-testid":`payout-waiting-${i.id}`,children:t("Waiting for %1$s to set up %2$s").replace("%1$s",we(i.collaboratorName,"collaborator",t)).replace("%2$s",nt(i.waitingReason))}),!1]})},{id:"datePaid",header:t("Paid Date"),cell:i=>e.jsx("span",{className:"text-sm text-muted-foreground",children:Ae(i.datePaid)})},{id:"value",header:t("Amount"),cell:i=>e.jsx("span",{className:"font-medium",children:U(i.value,i.currency)})}],Oe=0,ie=i=>ft(i,re,S),$=[],oe=$.filter(i=>i.status==="unpaid").length,ue=Array.from(new Set($.map(i=>{var j;return((j=ie(i.currency))==null?void 0:j.name)??""}))).filter(i=>i!==""),X=ue.length===1?t("Send with %s").replace("%s",ue[0]):t("Send automatically"),J=N.filter(i=>(i.status==="unpaid"||i.status==="failed")&&ie(i.currency)===null).length,Q=oe>0,Be=[{label:t("Mark Paid"),onClick:De},{label:t("Mark Unpaid"),onClick:Me}];return e.jsxs("div",{children:[g&&e.jsx(et,{className:"mb-4 rounded-lg border"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!c&&e.jsx(h,{variant:"ghost",size:"icon",onClick:()=>u("/fulfillments"),"aria-label":t("Back"),children:e.jsx(ee,{className:"h-4 w-4"})}),e.jsxs("h1",{className:"text-2xl font-semibold",children:["Fulfillment ",w.id]}),Q&&e.jsxs(h,{onClick:()=>y(!0),disabled:L||g,"data-tour":"fulfillment-send-automatically",children:[e.jsx(ot,{className:"h-4 w-4 mr-2"}),X]}),e.jsx(h,{variant:"outline",onClick:()=>R(!0),disabled:L||g,"data-tour":"fulfill-payouts",children:L?"Processing...":Q?t("Export CSV"):"Fulfill Payouts"}),e.jsxs("span",{className:"ml-auto text-sm text-muted-foreground",children:[N.length," item",N.length!==1?"s":""]}),!g&&e.jsx(Fe,{sourceType:"fulfillment",sourceId:w.id,contextLabel:`fulfillment #${w.id}`})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-4 mb-4","data-tour":"fulfillment-totals",children:[e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Value"}),e.jsx("div",{className:"text-lg font-semibold",children:U(G.total,z)})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Currency"}),e.jsx("div",{className:"text-lg font-semibold",children:z})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Paid"}),e.jsx("div",{className:"text-lg font-semibold",children:U(G.paid,z)})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 px-4 py-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Total Unpaid"}),e.jsx("div",{className:"text-lg font-semibold",children:U(G.unpaid,z)})]})]}),le&&e.jsx(Re,{result:le,onDismiss:()=>H(null)}),K>0&&e.jsxs("div",{role:"status",className:"mb-4 p-4 bg-muted/50 rounded-md text-sm","data-testid":"payouts-waiting-notice",children:[K===1?t("1 automatic payout is waiting for its collaborator to set up Stripe or PayPal."):t("%d automatic payouts are waiting for their collaborators to set up Stripe or PayPal.").replace("%d",String(K))," ",t("Siren sends each one as soon as its collaborator finishes.")]}),Oe>0,e.jsx(tt,{selectedCount:x.size,actions:Be,onClear:()=>C(new Set),isProcessing:L}),e.jsx(Le,{columns:Ie,data:N,sample:g,isLoading:!1,emptyMessage:t("No payouts in this fulfillment."),selectable:!0,selectedIds:x,onSelectionChange:C}),e.jsx(ge,{open:_,onOpenChange:R,children:e.jsxs(xe,{children:[e.jsxs(ye,{children:[e.jsx(be,{children:t("Confirm Fulfillment Export")}),e.jsxs(je,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:"This action exports a CSV for mass payment and immediately marks the selected payouts as paid."}),e.jsx("p",{children:x.size>0?`You are about to fulfill ${x.size} selected payout${x.size===1?"":"s"}.`:"You are about to fulfill all payouts in this batch."}),e.jsx("p",{children:"If you prefer to pay individually, select payouts and use “Mark Paid” instead."}),Q&&e.jsx("p",{children:t("Payouts in a currency with an automatic payout method can be sent with it instead. Exporting marks them paid without sending money.")})]})]}),e.jsxs(Se,{children:[e.jsx(h,{variant:"outline",onClick:()=>R(!1),children:t("Cancel")}),e.jsx(h,{onClick:async()=>{await $e(),R(!1)},children:t("Export & Mark Paid")})]})]})}),e.jsx(ge,{open:o,onOpenChange:y,children:e.jsxs(xe,{children:[e.jsxs(ye,{children:[e.jsx(be,{children:X}),e.jsx(je,{asChild:!0,children:e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsxs("p",{children:[n("This sends %d payout through your automatic payout method now.","This sends %d payouts through your automatic payout method now.",$.length).replace("%d",String($.length)),$.length>oe&&` ${t("Payouts that failed before are tried again.")}`]}),J>0&&e.jsx("p",{children:n("%d payout is in a currency with no automatic payout method. It is left unpaid. Pay it with the CSV export.","%d payouts are in a currency with no automatic payout method. They are left unpaid. Pay them with the CSV export.",J).replace("%d",String(J))}),x.size>0&&e.jsx("p",{children:t("This sends every payout in the fulfillment that can go automatically, not only the selected ones.")})]})})]}),e.jsxs(Se,{children:[e.jsx(h,{variant:"outline",onClick:()=>y(!1),children:t("Cancel")}),e.jsx(h,{disabled:L,onClick:async()=>{y(!1),await Te()},children:X})]})]})})]})}window.sirenConfig&&Ge({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ne=document.getElementById("siren-fulfillments");Ne&&Ye.createRoot(Ne).render(e.jsx(f.StrictMode,{children:e.jsxs(it,{defaultRoute:"/fulfillments",children:[e.jsx(Ke,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Xe,{children:[e.jsx(Z,{path:"/fulfillments",element:e.jsx(Ce,{})}),e.jsx(Z,{path:"/fulfillments/:id",element:e.jsx(ht,{})}),e.jsx(Z,{index:!0,element:e.jsx(Ce,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/main-menu.js

    r3775642 r3788740  
    1 import{c as M,u as y,r as o,j as e,C as I,p as $,q as D,x as H,s as O,B as j,a2 as he,a3 as fe,a as Oe,L as G,o as B,w as $e,ax as De,ay as Me,t as A,v as Ae,D as Fe,h as Ue,i as Pe,k as ze,l as Be,y as ge,I as je,m as Je,M as Ve,X as _e,S as Q,d as ee,e as se,f as te,g as W,H as Ge,E as He,F as qe,T as We,R as Ze,G as C,az as re}from"./shared/wordpress-admin-DNnGQGoM.js";import{C as be}from"./shared/copy-j7vAIT70.js";import{d as Xe,l as Ke,I as Ye,e as Qe,S as es,f as ss,g as ts,c as rs,R as as,b as ns}from"./shared/RecipeDetailScreen-DcUFdtvj.js";import{T as ve}from"./shared/triangle-alert-B1idIoet.js";import{a as ye}from"./shared/clock-MPHmQLgH.js";import{S as is,W as ls}from"./shared/WordPressRouter-ifxiIFvs.js";import{u as os}from"./shared/unshipped-CGZcvpGp.js";import"./shared/react-zvEYxxW2.js";import"./shared/arrow-left-W0B3m2vw.js";import"./shared/link-2-CR4ULk7z.js";import"./shared/gift-Bbpi-vg_.js";import"./shared/markdown-renderer-s6F8PPyM.js";import"./shared/useMoneyFormatter-BaBJUw_5.js";import"./shared/registries-Ql2SZeKd.js";import"./shared/sparkles-ZTBJ8zt0.js";import"./shared/trending-up-B12dlnRi.js";/**
     1import{c as U,u as S,r as c,j as e,C as E,q as T,s as O,x as H,t as L,B as j,a2 as fe,a3 as ge,b as Me,L as G,p as B,a as Ae,ax as Fe,ay as Pe,v as D,w as je,D as Ue,i as Be,k as Je,l as ze,m as Ve,y as be,I as ve,n as _e,M as Ge,X as He,S as Q,e as ee,f as se,g as te,h as W,H as qe,E as We,F as Ze,T as Xe,R as Ke,G as R,az as re}from"./shared/wordpress-admin-D_eccjaB.js";import{C as ye,w as Ne}from"./shared/clipboard-Ch4rpUJU.js";import{d as Ye,I as Qe,e as es,c as ss,R as ts,b as rs}from"./shared/RecipeDetailScreen-CEcAya7w.js";import{T as we}from"./shared/triangle-alert-BXQaBsm-.js";import{a as Se}from"./shared/clock-3iWagaOq.js";import{a as ae,c as as,C as ns,l as is,b as ls,S as os,D as ke,e as cs,d as ds}from"./shared/CsvImport-Dumku5_r.js";import{S as us,W as ms}from"./shared/WordPressRouter-CAYzko7X.js";import{u as xs}from"./shared/unshipped-CGZcvpGp.js";import{U as ps}from"./shared/upload-ZoYz9lGb.js";import"./shared/react-Rq6nbqOn.js";import"./shared/arrow-left-XvsxLAWy.js";import"./shared/link-2-C4uE2qWf.js";import"./shared/gift-Bz0xaFMj.js";import"./shared/markdown-renderer-1IfYWwRA.js";import"./shared/useMoneyFormatter-B6sdhxKB.js";import"./shared/registries-CatPSk3G.js";import"./shared/sparkles-Cs-c5bLd.js";import"./shared/trending-up-Cg5-4LxH.js";import"./shared/collaborator-groups-BP0hAJf8.js";import"./shared/conversion.schema-BXGiWhtb.js";import"./shared/properties-ByxWotcN.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const Ne=M("CircleX",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/**
     6 */const Ce=U("CircleX",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/**
    77 * @license lucide-react v0.469.0 - ISC
    88 *
    99 * This source code is licensed under the ISC license.
    1010 * See the LICENSE file in the root directory of this source tree.
    11  */const cs=M("Cloud",[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]]);/**
     11 */const hs=U("Cloud",[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]]);/**
    1212 * @license lucide-react v0.469.0 - ISC
    1313 *
    1414 * This source code is licensed under the ISC license.
    1515 * See the LICENSE file in the root directory of this source tree.
    16  */const we=M("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);/**
     16 */const ne=U("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);/**
    1717 * @license lucide-react v0.469.0 - ISC
    1818 *
    1919 * This source code is licensed under the ISC license.
    2020 * See the LICENSE file in the root directory of this source tree.
    21  */const ae=M("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);/**
     21 */const fs=U("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
    2222 * @license lucide-react v0.469.0 - ISC
    2323 *
    2424 * This source code is licensed under the ISC license.
    2525 * See the LICENSE file in the root directory of this source tree.
    26  */const ds=M("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
    27  * @license lucide-react v0.469.0 - ISC
    28  *
    29  * This source code is licensed under the ISC license.
    30  * See the LICENSE file in the root directory of this source tree.
    31  */const z=M("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/**
    32  * @license lucide-react v0.469.0 - ISC
    33  *
    34  * This source code is licensed under the ISC license.
    35  * See the LICENSE file in the root directory of this source tree.
    36  */const us=M("Upload",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"17 8 12 3 7 8",key:"t8dd8p"}],["line",{x1:"12",x2:"12",y1:"3",y2:"15",key:"widbto"}]]);function ms(s){return new Promise((t,n)=>{const r=new FileReader;r.onerror=()=>n(r.error??new Error("FileReader error")),r.onload=()=>t(String(r.result??"")),r.readAsText(s)})}function xs({onRecipeLoaded:s}){const{translate:t}=y(),n=o.useRef(null),[r,a]=o.useState(!1),[l,u]=o.useState(null),i=async d=>{u(null);let f;try{f=await ms(d)}catch{u(t("Could not read that file."));return}let b;try{b=JSON.parse(f)}catch(c){const g=c instanceof Error?c.message:t("Unknown parse error.");u(t(`That file is not valid JSON: ${g}`));return}s(b)},m=d=>{d.preventDefault(),a(!1);const f=d.dataTransfer.files[0];f&&i(f)},h=d=>{var b;const f=(b=d.target.files)==null?void 0:b[0];f&&i(f),d.target.value=""};return e.jsxs(I,{children:[e.jsxs($,{children:[e.jsx(D,{children:t("Import Recipe")}),e.jsx(H,{children:t("Upload a recipe file to preview what it will create before applying it.")})]}),e.jsxs(O,{className:"space-y-4",children:[e.jsxs("div",{role:"button",tabIndex:0,"aria-label":t("Upload recipe file"),onClick:()=>{var d;return(d=n.current)==null?void 0:d.click()},onKeyDown:d=>{var f;(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),(f=n.current)==null||f.click())},onDragOver:d=>{d.preventDefault(),a(!0)},onDragLeave:()=>a(!1),onDrop:m,className:["flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed px-6 py-12 text-center cursor-pointer transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",r?"border-primary bg-primary/5":"border-muted-foreground/25 hover:border-muted-foreground/50"].join(" "),children:[e.jsx(us,{className:"h-10 w-10 text-muted-foreground","aria-hidden":"true"}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-sm font-medium",children:t("Drop a recipe JSON file here, or click to browse")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t("CSV import coming soon.")})]}),e.jsx("input",{ref:n,type:"file",accept:".json,application/json",className:"hidden",onChange:h,"data-testid":"recipe-upload-input"})]}),l&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",children:l}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(ds,{className:"h-4 w-4","aria-hidden":"true"}),e.jsx("span",{children:t("Recipes are JSON files that declare programs, program groups, distributors, collaborators, and mappings.")})]}),e.jsx("div",{children:e.jsx(j,{variant:"outline",size:"sm",onClick:()=>{var d;return(d=n.current)==null?void 0:d.click()},children:t("Choose file")})})]})]})}const ne={ready:{label:"Ready",className:"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300"},"requires-feature":{label:"Needs feature",className:"bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300"},"will-skip":{label:"Will skip",className:"bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300"},unknown:{label:"Unknown",className:"bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-300"}};function ps({section:s}){const{translate:t,translatePlural:n}=y(),[r,a]=o.useState(!0),l=ne[s.category]??ne.ready,u=n("item","items",s.count),i=s.count>s.samples.length;return e.jsxs("section",{className:"rounded-lg border bg-card",children:[e.jsxs("header",{className:"flex items-center justify-between gap-4 px-4 py-3",children:[e.jsxs("button",{type:"button",onClick:()=>a(m=>!m),className:"flex items-center gap-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-md","aria-expanded":r,children:[r?e.jsx(he,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(fe,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("h3",{className:"text-sm font-semibold",children:s.label}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[s.count.toLocaleString()," ",u]})]}),e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${l.className}`,children:t(l.label)})]}),r&&s.samples.length>0&&e.jsxs("div",{className:"border-t",children:[e.jsx("ul",{className:"divide-y",children:s.samples.map(m=>e.jsxs("li",{className:"px-4 py-2 text-sm",children:[e.jsx("div",{className:"font-medium",children:m.name||m.key}),m.meta.length>0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:m.meta.join(" · ")})]},m.key))}),i&&e.jsx("div",{className:"border-t px-4 py-2 text-xs text-muted-foreground",children:t(`+ ${(s.count-s.samples.length).toLocaleString()} more not shown.`)})]})]})}function hs({payload:s}){const{translate:t}=y(),n=Oe(),r=typeof window<"u"?new URLSearchParams(window.location.search):null,a=s??(r==null?void 0:r.get("recipe"))??null,l=a!==null&&(r==null?void 0:r.get("apply"))==="1",u=o.useRef(!1),{step:i,preview:m,errors:h,errorMessage:d,loadFromEncodedPayload:f,loadFromJson:b,approve:c,reset:g}=Xe();o.useEffect(()=>{a&&i==="idle"&&f(a)},[a,i,f]);const N=async()=>{const v=await c();v&&(g(),n(`/import/imports/${v.jobId}`))};o.useEffect(()=>{l&&i==="ready"&&m&&!u.current&&(u.current=!0,N())},[l,i,m]);const S=()=>{g(),a&&window.history.back()},E=()=>{g(),a&&f(a)},p=()=>{g(),a&&window.history.back()};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:t("Import Recipe")}),e.jsx(j,{variant:"outline",asChild:!0,children:e.jsx(G,{to:"/import/imports",children:t("View all imports")})})]}),i==="idle"&&!a&&e.jsx(xs,{onRecipeLoaded:b}),i==="previewing"&&e.jsx(ie,{message:t("Generating preview...")}),i==="ready"&&m&&e.jsx(fs,{preview:m,onApprove:N,onCancel:S}),i==="applying"&&e.jsx(ie,{message:t("Starting import…")}),i==="error"&&e.jsx(gs,{errors:h,errorMessage:d,onRetry:E,onGoBack:p})]})}function ie({message:s}){return e.jsx("div",{className:"flex items-center justify-center py-24",children:e.jsx(B,{label:s})})}function fs({preview:s,onApprove:t,onCancel:n}){const{translate:r}=y(),a=s.sections.reduce((l,u)=>l+u.count,0);return e.jsxs(I,{children:[e.jsxs($,{children:[e.jsx(D,{children:s.name}),s.description&&e.jsx("p",{className:"text-sm text-muted-foreground mt-1.5",children:s.description})]}),e.jsxs(O,{className:"space-y-4",children:[s.sections.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:r("This recipe does not declare any entities.")}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-sm font-medium",children:r(`This recipe will import ${a.toLocaleString()} item${a===1?"":"s"} across ${s.sections.length} section${s.sections.length===1?"":"s"}:`)}),e.jsx("div",{className:"space-y-3",children:s.sections.map(l=>e.jsx(ps,{section:l},l.type))})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(j,{onClick:t,children:r("Approve & Import")}),e.jsx(j,{variant:"outline",onClick:n,children:r("Cancel")})]})]})]})}function gs({errors:s,errorMessage:t,onRetry:n,onGoBack:r}){const{translate:a}=y(),[l,u]=o.useState(!1),i=s.filter(h=>h.humanMessage),m=s.filter(h=>!h.humanMessage);return e.jsxs(I,{children:[e.jsx($,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ve,{className:"h-6 w-6 text-destructive shrink-0"}),e.jsx(D,{children:a("Import Failed")})]})}),e.jsxs(O,{className:"space-y-4",children:[t&&e.jsx("p",{className:"text-sm text-destructive",children:t}),i.length>0&&e.jsx("ul",{className:"space-y-3",children:i.map((h,d)=>e.jsx("li",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm",children:h.humanMessage},d))}),m.length>0&&i.length===0&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-4 space-y-2 text-sm",children:m.map((h,d)=>e.jsxs("div",{children:[e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:h.path}),e.jsx("span",{className:"mx-2",children:"—"}),e.jsx("span",{children:h.message})]},d))}),s.length>0&&(i.length>0||m.length>0)&&e.jsxs("div",{className:"rounded-md border text-sm",children:[e.jsxs("button",{type:"button",onClick:()=>u(h=>!h),className:"flex w-full items-center gap-2 px-3 py-2 text-left text-xs font-medium text-muted-foreground hover:bg-muted/50","aria-expanded":l,children:[l?e.jsx(he,{className:"h-3.5 w-3.5","aria-hidden":"true"}):e.jsx(fe,{className:"h-3.5 w-3.5","aria-hidden":"true"}),a(l?"Hide technical details":"Show technical details")]}),l&&e.jsx("ul",{className:"divide-y border-t",children:s.map((h,d)=>e.jsxs("li",{className:"px-3 py-2 text-xs",children:[e.jsx("div",{className:"font-mono text-muted-foreground",children:h.path}),e.jsx("div",{className:"mt-0.5",children:h.message})]},d))})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(j,{onClick:n,children:a("Try Again")}),e.jsx(j,{variant:"outline",onClick:r,children:a("Go Back")})]})]})]})}const js=3e3,bs={queued:{label:"Queued",className:"bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300"},running:{label:"Running",className:"bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300"},complete:{label:"Complete",className:"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300"},failed:{label:"Failed",className:"bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-300"}};function vs(){const{translate:s}=y(),[t,n]=o.useState(null),[r,a]=o.useState(null);return o.useEffect(()=>{let l=!1;const u=async()=>{try{const m=await Ke();if(l)return;n(m.items),a(null)}catch(m){if(l)return;a(m instanceof Error?m.message:"Failed to load imports.")}};u();const i=setInterval(u,js);return()=>{l=!0,clearInterval(i)}},[]),e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold",children:s("Recipe Imports")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("Recent and in-progress recipe imports.")})]}),e.jsx(j,{asChild:!0,children:e.jsx(G,{to:"/import",children:s("New Import")})})]}),r&&e.jsx(I,{children:e.jsx(O,{className:"py-6 text-sm text-destructive",children:r})}),!t&&!r&&e.jsx("div",{className:"flex items-center justify-center py-24",children:e.jsx(B,{label:s("Loading imports…")})}),t&&t.length===0&&e.jsxs(I,{children:[e.jsxs($,{children:[e.jsx(D,{children:s("No imports yet")}),e.jsx(H,{children:s("Upload a recipe to get started.")})]}),e.jsx(O,{children:e.jsx(j,{asChild:!0,children:e.jsx(G,{to:"/import",children:s("Start an import")})})})]}),t&&t.length>0&&e.jsx("ul",{className:"space-y-3",children:t.map(l=>e.jsx("li",{children:e.jsx(ys,{item:l})},l.jobId))})]})}function ys({item:s}){const{translate:t}=y(),n=bs[s.status],r=Ns(s.processedItems,s.totalItems),a=s.dateCreated?ws(s.dateCreated):null;return e.jsx(G,{to:`/import/imports/${s.jobId}`,className:"block rounded-lg border bg-card hover:border-primary/40 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${n.className}`,children:t(n.label)}),e.jsx("span",{className:"text-sm font-mono text-muted-foreground truncate",children:s.jobId})]}),a&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t("Started")," ",a]})]}),e.jsxs("div",{className:"text-right text-sm shrink-0",children:[e.jsxs("div",{className:"font-medium",children:[s.processedItems.toLocaleString()," / ",s.totalItems.toLocaleString()]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[r,"%"]})]})]}),e.jsx("div",{className:"h-1.5 rounded-full bg-muted overflow-hidden",children:e.jsx("div",{className:`h-full transition-all ${s.status==="failed"?"bg-destructive":s.status==="complete"?"bg-green-600 dark:bg-green-500":"bg-primary"}`,style:{width:`${r}%`}})}),s.errorMessage&&e.jsx("p",{className:"text-xs text-destructive line-clamp-1",children:s.errorMessage})]})})}function Ns(s,t){const n=Math.max(t,1);return Math.min(100,Math.round(s/n*100))}function ws(s){try{return new Date(s).toLocaleString()}catch{return s}}const Ss=[{to:"import",label:"Import",capability:"recipeImport",localRecords:!0},{to:"export",label:"Export",capability:"recipeExport",localRecords:!0},{to:"utilities",label:"Utilities",capability:"utilities"},{to:"logs",label:"Logs",capability:"utilities"},{to:"siren-cloud",label:"Siren Cloud",capability:"utilities"}];function ks({notice:s,hideLocalRecordTabs:t=!1,connectOnly:n=!1}={}){const{translate:r}=y(),a=$e();a==null||a.tier;const l=(a==null?void 0:a.capabilities)??{},u=Ss.filter(i=>!(i.capability&&!l[i.capability]||t&&i.localRecords||n&&i.to!=="siren-cloud"));return e.jsxs("div",{className:"space-y-6",children:[e.jsx("header",{children:e.jsx("h1",{className:"text-2xl font-semibold",children:r("Siren")})}),s,e.jsx("nav",{className:"flex items-center gap-1 border-b overflow-x-auto siren-tabs","aria-label":r("Siren main menu"),children:u.map(i=>e.jsx(De,{to:i.to,end:i.to==="license",className:({isActive:m})=>["siren-tab",m?"siren-tab--active":"siren-tab--inactive"].join(" "),children:r(i.label)},i.to))}),e.jsx(Me,{})]})}function Cs(s){return A.get(`/jobs/${encodeURIComponent(s)}`)}const Rs=1e3,Is=1800*1e3;function Es(s){const[t,n]=o.useState(null),[r,a]=o.useState(!1),[l,u]=o.useState(null),i=o.useRef(!1);return o.useEffect(()=>{if(!s){n(null),u(null),a(!1);return}i.current=!1,a(!0),u(null);const m=Date.now()+Is,h=async()=>{try{const d=await Cs(s);if(i.current)return;if(n(d),d.status==="complete"||d.status==="failed"){a(!1);return}if(Date.now()>=m){u("Timed out waiting for the job to finish."),a(!1);return}setTimeout(h,Rs)}catch(d){if(i.current)return;u(d instanceof Error?d.message:"Failed to fetch job progress."),a(!1)}};return h(),()=>{i.current=!0}},[s]),{snapshot:t,isPolling:r,error:l}}function Ls(){return A.get("/utilities/info")}function Ts(){return A.get("/utilities/status")}function Os(){return A.get("/utilities/repairs")}function $s(s,t={}){return A.post(`/utilities/repairs/${encodeURIComponent(s)}`,t)}function Ds(s={}){const t={limit:s.limit??200};return s.level&&(t.level=s.level),s.search&&(t.search=s.search),s.since&&(t.since=s.since),s.offset&&s.offset>0&&(t.offset=s.offset),A.get("/utilities/logs",t)}function Ms(s={}){const t={};return s.level&&(t.level=s.level),s.search&&(t.search=s.search),s.since&&(t.since=s.since),s.limit&&s.limit>0&&(t.limit=s.limit),A.get("/utilities/logs/export",t)}function As({connectorBlock:s}={}){const{translate:t}=y(),[n,r]=o.useState(null),[a,l]=o.useState(null),[u,i]=o.useState({}),[m,h]=o.useState(null),[d,f]=o.useState(!1),[b,c]=o.useState(null),[g,N]=o.useState(!1),S=o.useCallback(async()=>{N(!0);try{h(null);const[p,v,w]=await Promise.all([Ts(),Ls(),Os()]);r(p),l(v),i(Object.fromEntries(w.actions.map(k=>[k.id,k])))}catch(p){h(p instanceof Error?p.message:t("Failed to load status."))}finally{N(!1)}},[t]);o.useEffect(()=>{S()},[S]);async function E(){if(!(!n||!a))try{await navigator.clipboard.writeText(Js(n,a)),f(!0),setTimeout(()=>f(!1),2e3)}catch{Ae.error(t("Clipboard copy blocked. Select the text manually."))}}return m?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:m}):!n||!a?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(B,{label:t("Collecting status…")})}):e.jsxs("div",{className:"space-y-4",children:[e.jsx(I,{children:e.jsxs($,{className:"flex flex-row flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(D,{children:t("System status")}),e.jsx(H,{children:t("Health checks, registries and environment details for this Siren setup. A row with a Repair button can run a fix.")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",onClick:()=>S(),disabled:g,children:t(g?"Refreshing...":"Refresh")}),e.jsxs(j,{variant:"outline",size:"sm",onClick:E,children:[e.jsx(be,{className:"mr-2 h-4 w-4"}),t(d?"Copied":"Copy for support")]})]})]})}),s,n.sections.map(p=>e.jsx(Fs,{section:p,repairs:u,onRepair:c},p.key)),Object.keys(u).length>0&&e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsx("header",{className:"border-b px-4 py-3 text-sm font-semibold",children:t("Manual repairs")}),e.jsx("ul",{className:"divide-y text-sm",children:Object.values(u).map(p=>e.jsxs("li",{className:"flex items-start justify-between gap-3 px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:p.label}),e.jsx("div",{className:"text-xs text-muted-foreground",children:p.description})]}),e.jsx(j,{variant:"outline",size:"sm",onClick:()=>c(p),children:p.activeJobId!==null?e.jsxs(e.Fragment,{children:[e.jsx(z,{className:"mr-2 h-3 w-3 animate-spin"}),t("View progress")]}):t("Run")})]},p.id))})]}),e.jsxs("p",{className:"text-xs text-muted-foreground text-right",children:[t("Generated at")," ",n.generatedAt]}),e.jsx(Ps,{action:b,onClose:()=>c(null),onComplete:()=>{c(null),S()}})]})}function Fs({section:s,repairs:t,onRepair:n}){const{translate:r}=y(),a=s.rows.reduce((u,i)=>(u[i.status]=(u[i.status]??0)+1,u),{ok:0,warn:0,error:0,info:0}),l=Bs(a);return e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsxs("header",{className:"flex items-center justify-between gap-3 border-b px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Se,{level:l}),e.jsx("h3",{className:"text-sm font-semibold",children:s.label})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[a.error>0&&e.jsx("span",{className:"text-destructive font-medium",children:a.error===1?r("1 error"):r("{count} errors").replace("{count}",String(a.error))}),a.warn>0&&e.jsx("span",{className:"text-amber-700 dark:text-amber-400 font-medium",children:a.warn===1?r("1 warning"):r("{count} warnings").replace("{count}",String(a.warn))}),a.ok>0&&e.jsxs("span",{children:[a.ok," OK"]})]})]}),e.jsx("ul",{className:"divide-y",children:s.rows.map((u,i)=>e.jsx(Us,{row:u,repair:u.repairId?t[u.repairId]:void 0,onRepair:n},`${s.key}-${i}`))})]})}function Us({row:s,repair:t,onRepair:n}){return e.jsxs("li",{className:"flex items-start justify-between gap-3 px-4 py-2 text-sm",children:[e.jsxs("div",{className:"flex items-start gap-2 min-w-0",children:[e.jsx(Se,{level:s.status}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-mono text-xs break-all",children:s.label}),s.detail&&e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:s.detail})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:s.value}),t&&e.jsx(j,{variant:"outline",size:"sm",onClick:()=>n(t),children:t.activeJobId!==null?e.jsxs(e.Fragment,{children:[e.jsx(z,{className:"mr-2 h-3 w-3 animate-spin"}),t.label]}):t.label})]})]})}function Ps({action:s,onClose:t,onComplete:n}){const{translate:r}=y(),a=o.useMemo(()=>s?Object.entries(s.args):[],[s]),[l,u]=o.useState({}),[i,m]=o.useState(!1),[h,d]=o.useState(null),[f,b]=o.useState(null),{snapshot:c,isPolling:g}=Es(f),N=c==null?void 0:c.status;o.useEffect(()=>{if(s){const p={};for(const[v,w]of Object.entries(s.args))p[v]=w.default!==null&&w.default!==void 0?String(w.default):"";u(p),d(null),b(s.activeJobId)}else b(null),d(null)},[s]),o.useEffect(()=>{if(N==="complete"||N==="failed"){const p=setTimeout(n,1200);return()=>clearTimeout(p)}},[N,n]);async function S(){if(s){m(!0),d(null);try{const p={};for(const[w,k]of Object.entries(s.args)){const L=l[w]??"";k.type==="int"?p[w]=Number(L):k.type==="bool"?p[w]=L==="true"||L==="1":p[w]=L}const v=await $s(s.id,p);if(!v.success||!v.jobId){d(v.message||r("Repair failed."));return}b(v.jobId)}catch(p){d(p instanceof Error?p.message:r("Repair failed."))}finally{m(!1)}}}if(!s)return null;const E=f!==null;return e.jsx(Fe,{open:s!==null,onOpenChange:p=>{!p&&!i&&t()},children:e.jsxs(Ue,{children:[e.jsxs(Pe,{children:[e.jsx(ze,{children:s.label}),e.jsx(Be,{children:s.description})]}),E?e.jsx(zs,{snapshot:c,isPolling:g}):e.jsxs("div",{className:"space-y-3",children:[a.map(([p,v])=>e.jsxs("div",{className:"space-y-1",children:[e.jsx(ge,{htmlFor:`arg-${p}`,children:v.label}),e.jsx(je,{id:`arg-${p}`,type:v.type==="int"?"number":"text",value:l[p]??"",onChange:w=>u(k=>({...k,[p]:w.target.value})),disabled:i}),v.description&&e.jsx("p",{className:"text-xs text-muted-foreground",children:v.description})]},p)),h&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive",children:h})]}),e.jsx(Je,{children:E?e.jsx(j,{onClick:t,children:r("Close")}):e.jsxs(e.Fragment,{children:[e.jsx(j,{variant:"outline",onClick:t,disabled:i,children:r("Cancel")}),e.jsx(j,{onClick:S,disabled:i,children:i?e.jsxs(e.Fragment,{children:[e.jsx(z,{className:"mr-2 h-4 w-4 animate-spin"}),r("Dispatching…")]}):r("Run repair")})]})})]})})}function zs({snapshot:s,isPolling:t}){const{translate:n}=y();if(!s)return e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(z,{className:"h-4 w-4 animate-spin"}),n("Starting repair…")]});if(s.status==="failed")return e.jsxs("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-xs text-destructive",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-sm",children:[e.jsx(Ne,{className:"h-4 w-4"}),n("Repair failed")]}),e.jsx("p",{className:"mt-1",children:s.errorMessage||s.message||n("Unknown error.")})]});if(s.status==="complete")return e.jsxs("div",{className:"rounded-md border border-green-500/30 bg-green-500/5 p-3 text-xs text-green-700 dark:text-green-300",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-sm",children:[e.jsx(ye,{className:"h-4 w-4"}),n("Repair complete")]}),s.message&&e.jsx("p",{className:"mt-1",children:s.message})]});const r=s.totalItems>0,a=r?Math.min(100,Math.round(s.processedItems/s.totalItems*100)):null;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(z,{className:"h-4 w-4 animate-spin"}),s.status==="queued"?n("Queued, waiting for a worker…"):n("Running…"),t&&!r&&e.jsxs("span",{className:"text-xs opacity-70",children:["(",n("polling every second"),")"]})]}),r&&a!==null&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-muted",children:e.jsx("div",{className:"h-full bg-primary transition-all duration-500",style:{width:`${a}%`}})}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[e.jsxs("span",{children:[s.processedItems.toLocaleString()," /"," ",s.totalItems.toLocaleString()]}),e.jsxs("span",{children:[a,"%"]})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground italic pt-1",children:n("Safe to close. This repair keeps running in the background even when you leave this page. Come back anytime to check progress.")})]})}function Se({level:s}){const t="h-4 w-4 shrink-0 mt-0.5";switch(s){case"ok":return e.jsx(ye,{className:`${t} text-green-600 dark:text-green-500`,"aria-label":"OK"});case"warn":return e.jsx(ve,{className:`${t} text-amber-600 dark:text-amber-500`,"aria-label":"Warning"});case"error":return e.jsx(Ne,{className:`${t} text-destructive`,"aria-label":"Error"});case"info":default:return e.jsx(Ye,{className:`${t} text-muted-foreground`,"aria-label":"Info"})}}function Bs(s){return s.error>0?"error":s.warn>0?"warn":s.ok>0?"ok":"info"}function Js(s,t){const n=["# Siren status",`Generated: ${s.generatedAt}`,""];for(const r of s.sections){n.push(`## ${r.label}`);for(const a of r.rows){const l=a.status==="ok"?"✓":a.status==="warn"?"!":a.status==="error"?"✗":"·";n.push(`${l} ${a.label}: ${a.value}`),a.detail&&n.push(`    ${a.detail}`)}n.push("")}n.push("# Siren utilities info");for(const r of t.sections){n.push(`## ${r.label}`);for(const[a,l]of Object.entries(r.rows))n.push(`${a}: ${Vs(l)}`);n.push("")}return n.join(`
    37 `)}function Vs(s){return s==null?"—":typeof s=="boolean"?s?"true":"false":typeof s=="number"||typeof s=="string"?String(s):Array.isArray(s)?s.length===0?"[]":s.map(String).join(", "):JSON.stringify(s)}function ke(s,t){const n=_s(t),r=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),a=URL.createObjectURL(r),l=document.createElement("a");l.href=a,l.download=n,document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(a)}function _s(s){const t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19);return`${s}-${t}.json`}const le=["programs","programGroups","distributors","collaborators","tracking","commerce","notifications"],Gs=["notifications"];function Hs(){const{translate:s}=y(),[t,n]=o.useState(null),[r,a]=o.useState(new Set(le)),[l,u]=o.useState(!1),[i,m]=o.useState(null),h=o.useCallback(async()=>{try{m(null);const c=await Qe();n(c.sizes)}catch(c){m(c instanceof Error?c.message:s("Failed to count export sizes."))}},[s]);o.useEffect(()=>{h()},[h]);function d(c){const g=new Set(r);g.has(c)?g.delete(c):g.add(c),a(g)}async function f(){if(r.size!==0){u(!0),m(null);try{const c=await ss(Array.from(r));ke(c.recipe,"siren-export")}catch(c){m(c instanceof Error?c.message:s("Export failed."))}finally{u(!1)}}}const b=Array.from(r).reduce((c,g)=>c+((t==null?void 0:t[g])??0),0);return e.jsxs(I,{children:[e.jsxs($,{children:[e.jsx(D,{children:s("Export configuration")}),e.jsx(H,{children:s("Save your current Siren setup as a recipe file. You can import it into another Siren site or account, or attach it to a support ticket.")})]}),e.jsxs(O,{className:"space-y-4",children:[i&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",children:i}),t?e.jsx("ul",{className:"space-y-2",children:le.filter(c=>!Gs.includes(c)||c in t).map(c=>{const g=t[c]??0,N=r.has(c),S=g===0;return e.jsxs("li",{className:"flex items-center justify-between gap-3 rounded-md border px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ve,{id:`export-${c}`,checked:N,disabled:S,onCheckedChange:()=>d(c)}),e.jsx(ge,{htmlFor:`export-${c}`,className:S?"font-normal text-muted-foreground":"font-normal",children:s(es[c])})]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:g.toLocaleString()})]},c)})}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(B,{label:s("Counting…")})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 pt-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:s(`Selected: ${b.toLocaleString()} item${b===1?"":"s"}`)}),e.jsxs(j,{onClick:f,disabled:l||r.size===0,children:[e.jsx(we,{className:"mr-2 h-4 w-4"}),s(l?"Generating…":"Download recipe JSON")]})]})]})]})}const Z=100,qs=[{value:"any",label:"Any time"},{value:"15m",label:"Last 15 min"},{value:"1h",label:"Last hour"},{value:"24h",label:"Last 24 hours"},{value:"7d",label:"Last 7 days"}],Ws={debug:"status-badge status-gray",info:"status-badge status-blue",notice:"status-badge status-blue",warning:"status-badge status-yellow",error:"status-badge status-red",critical:"status-badge status-red",alert:"status-badge status-red",emergency:"status-badge status-red"},X="all";function Zs(){const{translate:s}=y(),[t,n]=o.useState(null),[r,a]=o.useState(""),[l,u]=o.useState(""),[i,m]=o.useState("any"),[h,d]=o.useState(0),[f,b]=o.useState(null),[c,g]=o.useState(!1),[N,S]=o.useState(!1),[E,p]=o.useState(null),[v,w]=o.useState(null),k=o.useRef(null),L=o.useRef(null);o.useEffect(()=>(k.current&&clearTimeout(k.current),k.current=setTimeout(()=>{J(r,l,i,0),d(0)},250),()=>{k.current&&clearTimeout(k.current)}),[l]),o.useEffect(()=>{J(r,l,i,0),d(0)},[r,i]);async function J(x,T,R,P){g(!0),b(null);try{const F=await Ds({level:x||null,search:T||null,since:oe(R),limit:Z,offset:P});n(F)}catch(F){b(F instanceof Error?F.message:s("Failed to load logs."))}finally{g(!1)}}function Y(x){d(x),J(r,l,i,x)}async function Re(x){const T=Xs(x);try{await navigator.clipboard.writeText(T)}catch{const R=document.createElement("textarea");R.value=T,R.style.position="fixed",R.style.opacity="0",document.body.appendChild(R),R.select();try{document.execCommand("copy")}finally{document.body.removeChild(R)}}w(x.id),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>w(null),1500)}async function Ie(){S(!0),b(null);try{const x=await Ms({level:r||null,search:l||null,since:oe(i)});ke(x,"siren-logs")}catch(x){b(x instanceof Error?x.message:s("Export failed."))}finally{S(!1)}}const V=(t==null?void 0:t.entries)??[],q=(t==null?void 0:t.total)??0,Ee=(t==null?void 0:t.levels)??[],Le=h+V.length<q,Te=h>0;return e.jsxs(I,{children:[e.jsx($,{children:e.jsx(D,{children:s("Siren log")})}),e.jsxs(O,{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[16rem]",children:[e.jsx(is,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground","aria-hidden":"true"}),e.jsx(je,{value:l,onChange:x=>u(x.target.value),placeholder:s("Search message…"),className:"pl-9 pr-9"}),l&&e.jsx("button",{type:"button",onClick:()=>u(""),className:"absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-muted","aria-label":s("Clear search"),children:e.jsx(_e,{className:"h-3.5 w-3.5 text-muted-foreground"})})]}),e.jsxs(Q,{value:r||X,onValueChange:x=>a(x===X?"":x),disabled:c,children:[e.jsx(ee,{"aria-label":s("Filter by level"),className:"w-[140px]",children:e.jsx(se,{})}),e.jsxs(te,{children:[e.jsx(W,{value:X,children:s("All levels")}),Ee.map(x=>e.jsx(W,{value:x,children:x},x))]})]}),e.jsxs(Q,{value:i,onValueChange:x=>m(x),disabled:c,children:[e.jsx(ee,{"aria-label":s("Time range"),className:"w-[160px]",children:e.jsx(se,{})}),e.jsx(te,{children:qs.map(x=>e.jsx(W,{value:x.value,children:s(x.label)},x.value))})]}),e.jsxs(j,{variant:"outline",size:"sm",onClick:()=>J(r,l,i,h),disabled:c,children:[e.jsx(ts,{className:`mr-2 h-4 w-4 ${c?"animate-spin":""}`}),s("Refresh")]}),e.jsxs(j,{variant:"outline",size:"sm",onClick:Ie,disabled:N||c,"aria-describedby":"logs-export-note",children:[e.jsx(we,{className:`mr-2 h-4 w-4 ${N?"animate-pulse":""}`}),s(N?"Exporting…":"Export")]}),e.jsx("span",{id:"logs-export-note",className:"sr-only",children:s("Download the current filtered log as a JSON file (up to 10,000 entries).")})]}),f&&e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:f}),t?V.length===0?e.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:s("No entries match.")}):e.jsx("ul",{className:"divide-y rounded-md border text-xs",children:V.map(x=>{const T=E===x.id,R=Object.keys(x.context??{}).length>0,P=v===x.id;return e.jsxs("li",{className:"group relative px-3 py-2 font-mono",children:[e.jsxs("button",{type:"button",onClick:()=>p(T?null:x.id),className:"w-full text-left pr-10","aria-expanded":T,disabled:!R,children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px]",children:[e.jsx("span",{className:Ws[x.level]??"status-badge status-gray",children:x.level}),x.timestamp&&e.jsx("span",{className:"text-muted-foreground",children:Ks(x.timestamp)})]}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-all",children:x.message})]}),e.jsx("button",{type:"button",onClick:F=>{F.stopPropagation(),Re(x)},className:`absolute right-2 top-2 inline-flex items-center gap-1 rounded-md border bg-background px-2 py-1 text-[10px] font-sans shadow-sm transition-opacity focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring ${P?"opacity-100":"opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100"}`,"aria-label":s(P?"Copied":"Copy entry"),children:P?e.jsxs(e.Fragment,{children:[e.jsx(Ge,{className:"h-3 w-3","aria-hidden":"true"}),s("Copied")]}):e.jsxs(e.Fragment,{children:[e.jsx(be,{className:"h-3 w-3","aria-hidden":"true"}),s("Copy")]})}),T&&R&&e.jsx("pre",{className:"mt-2 overflow-x-auto rounded-md bg-muted/50 p-2 text-[10px] text-muted-foreground",children:JSON.stringify(x.context,null,2)})]},x.id)})}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(B,{label:s("Loading log…")})}),t&&e.jsxs("div",{className:"flex items-center justify-between pt-1 text-xs text-muted-foreground",children:[e.jsx("span",{children:s(q===0?"0 entries":`${h+1}–${h+V.length} of ${q.toLocaleString()}`)}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",onClick:()=>Y(Math.max(0,h-Z)),disabled:!Te||c,children:s("Previous")}),e.jsx(j,{variant:"outline",size:"sm",onClick:()=>Y(h+Z),disabled:!Le||c,children:s("Next")})]})]})]})]})}function Xs(s){const t=[`[${s.level}] ${s.timestamp??""}`.trim(),s.message],n=s.context??{};return Object.keys(n).length>0&&t.push("","Context:",JSON.stringify(n,null,2)),t.join(`
    38 `)}function Ks(s){try{return new Date(s).toLocaleString()}catch{return s}}function oe(s){if(s==="any")return null;const t=Date.now(),n={"15m":900*1e3,"1h":3600*1e3,"24h":1440*60*1e3,"7d":10080*60*1e3};return new Date(t-n[s]).toISOString()}function Ys({features:s,signInUrl:t,signUpUrl:n}){const{translate:r}=y();return e.jsx("div",{className:"max-w-3xl space-y-6","data-testid":"siren-cloud-call-to-action",children:e.jsxs(I,{children:[e.jsxs($,{className:"flex flex-row items-center gap-2 space-y-0",children:[e.jsx(cs,{className:"h-5 w-5 text-muted-foreground","aria-hidden":"true"}),e.jsx(D,{children:r("Run Siren on Siren Cloud")})]}),e.jsxs(O,{className:"space-y-6 text-sm",children:[e.jsx("p",{children:r("Siren Cloud does the commission and payout work for your programs, so your store no longer has to. You manage programs, collaborators and payouts from your Siren Cloud dashboard.")}),s,e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"font-semibold",children:r("How to switch")}),e.jsxs("ol",{className:"list-decimal space-y-1 pl-5",children:[e.jsx("li",{children:r("Sign in to Siren Cloud, or create an account. An account is all you need to get the connector.")}),e.jsx("li",{children:r("In Siren Cloud, open Settings, then Integrations, and choose Get the connector.")}),e.jsx("li",{children:r("Install the connector on this site. It moves your programs, collaborators and history to Siren Cloud, then takes over from this plugin. The move starts a free Pro trial.")})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[t?e.jsx(j,{asChild:!0,children:e.jsxs("a",{href:t,target:"_blank",rel:"noopener noreferrer",children:[r("Sign in to Siren Cloud"),e.jsx(ae,{className:"h-4 w-4","aria-hidden":"true"})]})}):null,n?e.jsx(j,{asChild:!0,variant:"outline",children:e.jsxs("a",{href:n,target:"_blank",rel:"noopener noreferrer",children:[r("Create an account"),e.jsx(ae,{className:"h-4 w-4","aria-hidden":"true"})]})}):null]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r("Until you install the connector, this plugin keeps working as it does now and sends nothing to Siren Cloud.")})]})]})})}function Qs(){const{translate:s}=y(),t=[s("Lead and renewal commissions"),s("Commissions per lead and per product"),s("Pooled commissions"),s("Content and product triggers"),s("Automatic payouts in store credit"),s("The collaborator portal"),s("Program groups and distributors")];return e.jsxs("section",{className:"space-y-2","data-testid":"features-gained",children:[e.jsx("h3",{className:"font-semibold",children:s("Included with every Siren Cloud plan")}),e.jsx("p",{className:"text-muted-foreground",children:s("Every Siren Cloud plan starts at Essentials, so you get these features without buying a paid edition. On WordPress they need Siren Essentials or higher.")}),e.jsx("ul",{className:"list-disc space-y-1 pl-5","aria-label":s("Included with every Siren Cloud plan"),children:t.map(n=>e.jsx("li",{children:n},n))})]})}const et=os("src/service/screens/main-menu/ManagedInCloudBanner.tsx");function st({connector:s,adminScope:t,managedInCloud:n,licensedTier:r}){return n?{defaultRoute:r?"/license":"/utilities",localRecords:!1,connectOnly:!1}:s?{defaultRoute:"/siren-cloud",localRecords:!1,connectOnly:!1}:{defaultRoute:r?"/license":"/import",localRecords:!0,connectOnly:!1}}window.sirenConfig&&He({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});var me;const tt=(me=window.sirenConfig)==null?void 0:me.tier;var xe;const rt=(xe=window.sirenConfig)==null?void 0:xe.capabilities,at=!1,K=void 0,nt=void 0,{defaultRoute:Ce,localRecords:ce,connectOnly:_}=st({connector:!1,adminScope:K==null?void 0:K.adminScope,managedInCloud:!!nt,licensedTier:at}),it=void 0,de=Ce.replace(/^\//,"");var pe;const U=(pe=window.sirenConfig)==null?void 0:pe.sirenCloud,lt=e.jsx(Ys,{features:e.jsx(Qs,{}),signInUrl:U==null?void 0:U.signInUrl,signUpUrl:U==null?void 0:U.signUpUrl}),ue=document.getElementById("siren-main-menu");ue&&qe.createRoot(ue).render(e.jsx(o.StrictMode,{children:e.jsxs(ls,{defaultRoute:Ce,tier:tt,capabilities:rt,children:[e.jsx(We,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsx(Ze,{children:e.jsxs(C,{element:e.jsx(ks,{notice:_?e.jsx(et.ConnectOnlyNotice,{}):void 0,hideLocalRecordTabs:!ce,connectOnly:_}),children:[e.jsx(C,{index:!0,element:e.jsx(re,{to:de,replace:!0})}),!1,ce&&e.jsxs(e.Fragment,{children:[e.jsx(C,{path:"import",element:e.jsx(hs,{})}),e.jsx(C,{path:"import/imports",element:e.jsx(vs,{})}),e.jsx(C,{path:"import/imports/:jobId",element:e.jsx(rs,{})}),e.jsx(C,{path:"recipes/browse",element:e.jsx(as,{})}),e.jsx(C,{path:"recipes/browse/:slug",element:e.jsx(ns,{})}),e.jsx(C,{path:"export",element:e.jsx(Hs,{})})]}),!_&&e.jsx(C,{path:"utilities",element:e.jsx(As,{connectorBlock:it})}),!_&&e.jsx(C,{path:"logs",element:e.jsx(Zs,{})}),e.jsx(C,{path:"siren-cloud",element:lt}),e.jsx(C,{path:"*",element:e.jsx(re,{to:de,replace:!0})})]})})})]})}));
     26 */const P=U("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);function gs(s){return new Promise((t,a)=>{const r=new FileReader;r.onerror=()=>a(r.error??new Error("FileReader error")),r.onload=()=>t(String(r.result??"")),r.readAsText(s)})}function js({onRecipeLoaded:s,onCsvLoaded:t}){const{translate:a}=S(),r=c.useRef(null),[n,i]=c.useState(!1),[u,o]=c.useState(null),m=async x=>{o(null);let l;try{l=await gs(x)}catch{o(a("Could not read that file."));return}const g=x.name.toLowerCase(),w=/\.(csv|tsv|txt)$/.test(g);if(t&&w){f(x.name,l);return}let y;try{y=JSON.parse(l)}catch(C){const d=t&&!g.endsWith(".json")?ae(l):null;if(d!=null&&d.ok){t==null||t({name:x.name,text:l,csv:d.csv});return}const b=C instanceof Error?C.message:a("Unknown parse error.");o(a(`That file is not valid JSON: ${b}`));return}s(y)},f=(x,l)=>{const g=ae(l);if(!g.ok){o(a(as(g.problem,g.rowCount)));return}t==null||t({name:x,text:l,csv:g.csv})},h=x=>{x.preventDefault(),i(!1);const l=x.dataTransfer.files[0];l&&m(l)},v=x=>{var g;const l=(g=x.target.files)==null?void 0:g[0];l&&m(l),x.target.value=""};return e.jsxs(E,{children:[e.jsxs(T,{children:[e.jsx(O,{children:a("Import Recipe")}),e.jsx(H,{children:a("Upload a recipe file to preview what it will create before applying it.")})]}),e.jsxs(L,{className:"space-y-4",children:[e.jsxs("div",{role:"button",tabIndex:0,"aria-label":a("Upload recipe file"),onClick:()=>{var x;return(x=r.current)==null?void 0:x.click()},onKeyDown:x=>{var l;(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),(l=r.current)==null||l.click())},onDragOver:x=>{x.preventDefault(),i(!0)},onDragLeave:()=>i(!1),onDrop:h,className:["flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed px-6 py-12 text-center cursor-pointer transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",n?"border-primary bg-primary/5":"border-muted-foreground/25 hover:border-muted-foreground/50"].join(" "),children:[e.jsx(ps,{className:"h-10 w-10 text-muted-foreground","aria-hidden":"true"}),e.jsx("div",{className:"space-y-1",children:e.jsx("p",{className:"text-sm font-medium",children:a(t?"Drop a recipe JSON or a CSV file here, or click to browse":"Drop a recipe JSON file here, or click to browse")})}),e.jsx("input",{ref:r,type:"file",accept:t?".json,application/json,.csv,text/csv,.tsv,.txt":".json,application/json",className:"hidden",onChange:v,"data-testid":"recipe-upload-input"})]}),u&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",children:u}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(fs,{className:"h-4 w-4","aria-hidden":"true"}),e.jsx("span",{children:a("Recipes are JSON files that declare programs, program groups, distributors, collaborators, and mappings.")})]}),e.jsx("div",{children:e.jsx(j,{variant:"outline",size:"sm",onClick:()=>{var x;return(x=r.current)==null?void 0:x.click()},children:a("Choose file")})}),t&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a("A CSV file from a spreadsheet or another platform works too. Siren asks what it holds and helps you match its columns.")})]})]})}const ie={ready:{label:"Ready",className:"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300"},"requires-feature":{label:"Needs feature",className:"bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300"},"will-skip":{label:"Will skip",className:"bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300"},unknown:{label:"Unknown",className:"bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-300"}};function bs({section:s}){const{translate:t,translatePlural:a}=S(),[r,n]=c.useState(!0),i=ie[s.category]??ie.ready,u=a("item","items",s.count),o=s.count>s.samples.length;return e.jsxs("section",{className:"rounded-lg border bg-card",children:[e.jsxs("header",{className:"flex items-center justify-between gap-4 px-4 py-3",children:[e.jsxs("button",{type:"button",onClick:()=>n(m=>!m),className:"flex items-center gap-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-md","aria-expanded":r,children:[r?e.jsx(fe,{className:"h-4 w-4 text-muted-foreground"}):e.jsx(ge,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("h3",{className:"text-sm font-semibold",children:s.label}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[s.count.toLocaleString()," ",u]})]}),e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${i.className}`,children:t(i.label)})]}),r&&s.samples.length>0&&e.jsxs("div",{className:"border-t",children:[e.jsx("ul",{className:"divide-y",children:s.samples.map(m=>e.jsxs("li",{className:"px-4 py-2 text-sm",children:[e.jsx("div",{className:"font-medium",children:m.name||m.key}),m.meta.length>0&&e.jsx("div",{className:"text-xs text-muted-foreground",children:m.meta.join(" · ")})]},m.key))}),o&&e.jsx("div",{className:"border-t px-4 py-2 text-xs text-muted-foreground",children:t(`+ ${(s.count-s.samples.length).toLocaleString()} more not shown.`)})]})]})}function vs({payload:s,allowAutoApply:t=!1}){const{translate:a}=S(),r=Me(),n=typeof window<"u"?new URLSearchParams(window.location.search):null,i=s??(n==null?void 0:n.get("recipe"))??null,u=t&&i!==null&&(n==null?void 0:n.get("apply"))==="1",o=c.useRef(!1),[m,f]=c.useState(null),{step:h,preview:v,errors:x,errorMessage:l,loadFromEncodedPayload:g,loadFromJson:w,approve:y,reset:C}=Ye();c.useEffect(()=>{i&&h==="idle"&&g(i)},[i,h,g]);const d=async()=>{const I=await y();I&&(C(),r(`/import/imports/${I.jobId}`))};c.useEffect(()=>{u&&h==="ready"&&v&&!o.current&&(o.current=!0,d())},[u,h,v]);const b=()=>{C(),i&&window.history.back()},N=()=>{C(),i&&g(i)},k=()=>{C(),i&&window.history.back()};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:a("Import Recipe")}),e.jsx(j,{variant:"outline",asChild:!0,children:e.jsx(G,{to:"/import/imports",children:a("View all imports")})})]}),h==="idle"&&!i&&m&&e.jsx(ns,{initialFile:m,onExit:()=>f(null)},m.name+m.text.length),h==="idle"&&!i&&!m&&e.jsx(js,{onRecipeLoaded:w,onCsvLoaded:f}),h==="previewing"&&e.jsx(le,{message:a("Generating preview...")}),h==="ready"&&v&&e.jsx(ys,{preview:v,onApprove:d,onCancel:b}),h==="applying"&&e.jsx(le,{message:a("Starting import…")}),h==="error"&&e.jsx(Ns,{errors:x,errorMessage:l,onRetry:N,onGoBack:k})]})}function le({message:s}){return e.jsx("div",{className:"flex items-center justify-center py-24",children:e.jsx(B,{label:s})})}function ys({preview:s,onApprove:t,onCancel:a}){const{translate:r}=S(),n=s.sections.reduce((i,u)=>i+u.count,0);return e.jsxs(E,{children:[e.jsxs(T,{children:[e.jsx(O,{children:s.name}),s.description&&e.jsx("p",{className:"text-sm text-muted-foreground mt-1.5",children:s.description})]}),e.jsxs(L,{className:"space-y-4",children:[s.sections.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:r("This recipe does not declare any entities.")}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-sm font-medium",children:r(`This recipe will import ${n.toLocaleString()} item${n===1?"":"s"} across ${s.sections.length} section${s.sections.length===1?"":"s"}:`)}),e.jsx("div",{className:"space-y-3",children:s.sections.map(i=>e.jsx(bs,{section:i},i.type))})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(j,{onClick:t,children:r("Approve & Import")}),e.jsx(j,{variant:"outline",onClick:a,children:r("Cancel")})]})]})]})}function Ns({errors:s,errorMessage:t,onRetry:a,onGoBack:r}){const{translate:n}=S(),[i,u]=c.useState(!1),o=s.filter(f=>f.humanMessage),m=s.filter(f=>!f.humanMessage);return e.jsxs(E,{children:[e.jsx(T,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(we,{className:"h-6 w-6 text-destructive shrink-0"}),e.jsx(O,{children:n("Import Failed")})]})}),e.jsxs(L,{className:"space-y-4",children:[t&&e.jsx("p",{className:"text-sm text-destructive",children:t}),o.length>0&&e.jsx("ul",{className:"space-y-3",children:o.map((f,h)=>e.jsx("li",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm",children:f.humanMessage},h))}),m.length>0&&o.length===0&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-4 space-y-2 text-sm",children:m.map((f,h)=>e.jsxs("div",{children:[e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:f.path}),e.jsx("span",{className:"mx-2",children:"—"}),e.jsx("span",{children:f.message})]},h))}),s.length>0&&(o.length>0||m.length>0)&&e.jsxs("div",{className:"rounded-md border text-sm",children:[e.jsxs("button",{type:"button",onClick:()=>u(f=>!f),className:"flex w-full items-center gap-2 px-3 py-2 text-left text-xs font-medium text-muted-foreground hover:bg-muted/50","aria-expanded":i,children:[i?e.jsx(fe,{className:"h-3.5 w-3.5","aria-hidden":"true"}):e.jsx(ge,{className:"h-3.5 w-3.5","aria-hidden":"true"}),n(i?"Hide technical details":"Show technical details")]}),i&&e.jsx("ul",{className:"divide-y border-t",children:s.map((f,h)=>e.jsxs("li",{className:"px-3 py-2 text-xs",children:[e.jsx("div",{className:"font-mono text-muted-foreground",children:f.path}),e.jsx("div",{className:"mt-0.5",children:f.message})]},h))})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(j,{onClick:a,children:n("Try Again")}),e.jsx(j,{variant:"outline",onClick:r,children:n("Go Back")})]})]})]})}const ws=3e3,Ss={queued:{label:"Queued",className:"bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300"},running:{label:"Running",className:"bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300"},complete:{label:"Complete",className:"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300"},failed:{label:"Failed",className:"bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-300"}};function ks(){const{translate:s}=S(),[t,a]=c.useState(null),[r,n]=c.useState(null);return c.useEffect(()=>{let i=!1;const u=async()=>{try{const m=await is();if(i)return;a(m.items),n(null)}catch(m){if(i)return;n(m instanceof Error?m.message:"Failed to load imports.")}};u();const o=setInterval(u,ws);return()=>{i=!0,clearInterval(o)}},[]),e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold",children:s("Recipe Imports")}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s("Recent and in-progress recipe imports.")})]}),e.jsx(j,{asChild:!0,children:e.jsx(G,{to:"/import",children:s("New Import")})})]}),r&&e.jsx(E,{children:e.jsx(L,{className:"py-6 text-sm text-destructive",children:r})}),!t&&!r&&e.jsx("div",{className:"flex items-center justify-center py-24",children:e.jsx(B,{label:s("Loading imports…")})}),t&&t.length===0&&e.jsxs(E,{children:[e.jsxs(T,{children:[e.jsx(O,{children:s("No imports yet")}),e.jsx(H,{children:s("Upload a recipe to get started.")})]}),e.jsx(L,{children:e.jsx(j,{asChild:!0,children:e.jsx(G,{to:"/import",children:s("Start an import")})})})]}),t&&t.length>0&&e.jsx("ul",{className:"space-y-3",children:t.map(i=>e.jsx("li",{children:e.jsx(Cs,{item:i})},i.jobId))})]})}function Cs({item:s}){const{translate:t}=S(),a=Ss[s.status],r=Rs(s.processedItems,s.totalItems),n=s.dateCreated?Is(s.dateCreated):null;return e.jsx(G,{to:`/import/imports/${s.jobId}`,className:"block rounded-lg border bg-card hover:border-primary/40 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${a.className}`,children:t(a.label)}),e.jsx("span",{className:"text-sm font-mono text-muted-foreground truncate",children:s.jobId})]}),n&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t("Started")," ",n]})]}),e.jsxs("div",{className:"text-right text-sm shrink-0",children:[e.jsxs("div",{className:"font-medium",children:[s.processedItems.toLocaleString()," / ",s.totalItems.toLocaleString()]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[r,"%"]})]})]}),e.jsx("div",{className:"h-1.5 rounded-full bg-muted overflow-hidden",children:e.jsx("div",{className:`h-full transition-all ${s.status==="failed"?"bg-destructive":s.status==="complete"?"bg-green-600 dark:bg-green-500":"bg-primary"}`,style:{width:`${r}%`}})}),s.errorMessage&&e.jsx("p",{className:"text-xs text-destructive line-clamp-1",children:s.errorMessage})]})})}function Rs(s,t){const a=Math.max(t,1);return Math.min(100,Math.round(s/a*100))}function Is(s){try{return new Date(s).toLocaleString()}catch{return s}}const Es=[{to:"import",label:"Import",capability:"recipeImport",localRecords:!0},{to:"export",label:"Export",capability:"recipeExport",localRecords:!0},{to:"utilities",label:"Utilities",capability:"utilities"},{to:"logs",label:"Logs",capability:"utilities"},{to:"siren-cloud",label:"Siren Cloud",capability:"utilities"}];function Ls({notice:s,hideLocalRecordTabs:t=!1,connectOnly:a=!1}={}){const{translate:r}=S(),n=Ae();n==null||n.tier;const i=(n==null?void 0:n.capabilities)??{},u=Es.filter(o=>!(o.capability&&!i[o.capability]||t&&o.localRecords||a&&o.to!=="siren-cloud"));return e.jsxs("div",{className:"space-y-6",children:[e.jsx("header",{children:e.jsx("h1",{className:"text-2xl font-semibold",children:r("Siren")})}),s,e.jsx("nav",{className:"flex items-center gap-1 border-b overflow-x-auto siren-tabs","aria-label":r("Siren main menu"),children:u.map(o=>e.jsx(Fe,{to:o.to,end:o.to==="license",className:({isActive:m})=>["siren-tab",m?"siren-tab--active":"siren-tab--inactive"].join(" "),children:r(o.label)},o.to))}),e.jsx(Pe,{})]})}function Ts(s){return D.get(`/jobs/${encodeURIComponent(s)}`)}const Os=1e3,$s=1800*1e3;function Ds(s){const[t,a]=c.useState(null),[r,n]=c.useState(!1),[i,u]=c.useState(null),o=c.useRef(!1);return c.useEffect(()=>{if(!s){a(null),u(null),n(!1);return}o.current=!1,n(!0),u(null);const m=Date.now()+$s,f=async()=>{try{const h=await Ts(s);if(o.current)return;if(a(h),h.status==="complete"||h.status==="failed"){n(!1);return}if(Date.now()>=m){u("Timed out waiting for the job to finish."),n(!1);return}setTimeout(f,Os)}catch(h){if(o.current)return;u(h instanceof Error?h.message:"Failed to fetch job progress."),n(!1)}};return f(),()=>{o.current=!0}},[s]),{snapshot:t,isPolling:r,error:i}}function Ms(){return D.get("/utilities/info")}function As(){return D.get("/utilities/status")}function Fs(){return D.get("/utilities/repairs")}function Ps(s,t={}){return D.post(`/utilities/repairs/${encodeURIComponent(s)}`,t)}function Us(s={}){const t={limit:s.limit??200};return s.level&&(t.level=s.level),s.search&&(t.search=s.search),s.since&&(t.since=s.since),s.offset&&s.offset>0&&(t.offset=s.offset),D.get("/utilities/logs",t)}function Bs(s={}){const t={};return s.level&&(t.level=s.level),s.search&&(t.search=s.search),s.since&&(t.since=s.since),s.limit&&s.limit>0&&(t.limit=s.limit),D.get("/utilities/logs/export",t)}function Js({connectorBlock:s}={}){const{translate:t}=S(),[a,r]=c.useState(null),[n,i]=c.useState(null),[u,o]=c.useState({}),[m,f]=c.useState(null),[h,v]=c.useState(!1),[x,l]=c.useState(null),[g,w]=c.useState(!1),y=c.useCallback(async()=>{w(!0);try{f(null);const[d,b,N]=await Promise.all([As(),Ms(),Fs()]);r(d),i(b),o(Object.fromEntries(N.actions.map(k=>[k.id,k])))}catch(d){f(d instanceof Error?d.message:t("Failed to load status."))}finally{w(!1)}},[t]);c.useEffect(()=>{y()},[y]);async function C(){if(!(!a||!n))try{await Ne(qs(a,n)),v(!0),setTimeout(()=>v(!1),2e3)}catch{je.error(t("Clipboard copy blocked. Select the text manually."))}}return m?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:m}):!a||!n?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(B,{label:t("Collecting status…")})}):e.jsxs("div",{className:"space-y-4",children:[e.jsx(E,{children:e.jsxs(T,{className:"flex flex-row flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(O,{children:t("System status")}),e.jsx(H,{children:t("Health checks, registries and environment details for this Siren setup. A row with a Repair button can run a fix.")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",onClick:()=>y(),disabled:g,children:t(g?"Refreshing...":"Refresh")}),e.jsxs(j,{variant:"outline",size:"sm",onClick:C,children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),t(h?"Copied":"Copy for support")]})]})]})}),s,a.sections.map(d=>e.jsx(zs,{section:d,repairs:u,onRepair:l},d.key)),Object.keys(u).length>0&&e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsx("header",{className:"border-b px-4 py-3 text-sm font-semibold",children:t("Manual repairs")}),e.jsx("ul",{className:"divide-y text-sm",children:Object.values(u).map(d=>e.jsxs("li",{className:"flex items-start justify-between gap-3 px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:d.label}),e.jsx("div",{className:"text-xs text-muted-foreground",children:d.description})]}),e.jsx(j,{variant:"outline",size:"sm",onClick:()=>l(d),children:d.activeJobId!==null?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"mr-2 h-3 w-3 animate-spin"}),t("View progress")]}):t("Run")})]},d.id))})]}),e.jsxs("p",{className:"text-xs text-muted-foreground text-right",children:[t("Generated at")," ",a.generatedAt]}),e.jsx(_s,{action:x,onClose:()=>l(null),onComplete:()=>{l(null),y()}})]})}function zs({section:s,repairs:t,onRepair:a}){const{translate:r}=S(),n=s.rows.reduce((u,o)=>(u[o.status]=(u[o.status]??0)+1,u),{ok:0,warn:0,error:0,info:0}),i=Hs(n);return e.jsxs("div",{className:"rounded-lg border bg-card",children:[e.jsxs("header",{className:"flex items-center justify-between gap-3 border-b px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Re,{level:i}),e.jsx("h3",{className:"text-sm font-semibold",children:s.label})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[n.error>0&&e.jsx("span",{className:"text-destructive font-medium",children:n.error===1?r("1 error"):r("{count} errors").replace("{count}",String(n.error))}),n.warn>0&&e.jsx("span",{className:"text-amber-700 dark:text-amber-400 font-medium",children:n.warn===1?r("1 warning"):r("{count} warnings").replace("{count}",String(n.warn))}),n.ok>0&&e.jsxs("span",{children:[n.ok," OK"]})]})]}),e.jsx("ul",{className:"divide-y",children:s.rows.map((u,o)=>e.jsx(Vs,{row:u,repair:u.repairId?t[u.repairId]:void 0,onRepair:a},`${s.key}-${o}`))})]})}function Vs({row:s,repair:t,onRepair:a}){return e.jsxs("li",{className:"flex items-start justify-between gap-3 px-4 py-2 text-sm",children:[e.jsxs("div",{className:"flex items-start gap-2 min-w-0",children:[e.jsx(Re,{level:s.status}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-mono text-xs break-all",children:s.label}),s.detail&&e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:s.detail})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:s.value}),t&&e.jsx(j,{variant:"outline",size:"sm",onClick:()=>a(t),children:t.activeJobId!==null?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"mr-2 h-3 w-3 animate-spin"}),t.label]}):t.label})]})]})}function _s({action:s,onClose:t,onComplete:a}){const{translate:r}=S(),n=c.useMemo(()=>s?Object.entries(s.args):[],[s]),[i,u]=c.useState({}),[o,m]=c.useState(!1),[f,h]=c.useState(null),[v,x]=c.useState(null),{snapshot:l,isPolling:g}=Ds(v),w=l==null?void 0:l.status;c.useEffect(()=>{if(s){const d={};for(const[b,N]of Object.entries(s.args))d[b]=N.default!==null&&N.default!==void 0?String(N.default):"";u(d),h(null),x(s.activeJobId)}else x(null),h(null)},[s]),c.useEffect(()=>{if(w==="complete"||w==="failed"){const d=setTimeout(a,1200);return()=>clearTimeout(d)}},[w,a]);async function y(){if(s){m(!0),h(null);try{const d={};for(const[N,k]of Object.entries(s.args)){const I=i[N]??"";k.type==="int"?d[N]=Number(I):k.type==="bool"?d[N]=I==="true"||I==="1":d[N]=I}const b=await Ps(s.id,d);if(!b.success||!b.jobId){h(b.message||r("Repair failed."));return}x(b.jobId)}catch(d){h(d instanceof Error?d.message:r("Repair failed."))}finally{m(!1)}}}if(!s)return null;const C=v!==null;return e.jsx(Ue,{open:s!==null,onOpenChange:d=>{!d&&!o&&t()},children:e.jsxs(Be,{children:[e.jsxs(Je,{children:[e.jsx(ze,{children:s.label}),e.jsx(Ve,{children:s.description})]}),C?e.jsx(Gs,{snapshot:l,isPolling:g}):e.jsxs("div",{className:"space-y-3",children:[n.map(([d,b])=>e.jsxs("div",{className:"space-y-1",children:[e.jsx(be,{htmlFor:`arg-${d}`,children:b.label}),e.jsx(ve,{id:`arg-${d}`,type:b.type==="int"?"number":"text",value:i[d]??"",onChange:N=>u(k=>({...k,[d]:N.target.value})),disabled:o}),b.description&&e.jsx("p",{className:"text-xs text-muted-foreground",children:b.description})]},d)),f&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive",children:f})]}),e.jsx(_e,{children:C?e.jsx(j,{onClick:t,children:r("Close")}):e.jsxs(e.Fragment,{children:[e.jsx(j,{variant:"outline",onClick:t,disabled:o,children:r("Cancel")}),e.jsx(j,{onClick:y,disabled:o,children:o?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"mr-2 h-4 w-4 animate-spin"}),r("Dispatching…")]}):r("Run repair")})]})})]})})}function Gs({snapshot:s,isPolling:t}){const{translate:a}=S();if(!s)return e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(P,{className:"h-4 w-4 animate-spin"}),a("Starting repair…")]});if(s.status==="failed")return e.jsxs("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-xs text-destructive",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-sm",children:[e.jsx(Ce,{className:"h-4 w-4"}),a("Repair failed")]}),e.jsx("p",{className:"mt-1",children:s.errorMessage||s.message||a("Unknown error.")})]});if(s.status==="complete")return e.jsxs("div",{className:"rounded-md border border-green-500/30 bg-green-500/5 p-3 text-xs text-green-700 dark:text-green-300",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-sm",children:[e.jsx(Se,{className:"h-4 w-4"}),a("Repair complete")]}),s.message&&e.jsx("p",{className:"mt-1",children:s.message})]});const r=s.totalItems>0,n=r?Math.min(100,Math.round(s.processedItems/s.totalItems*100)):null;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(P,{className:"h-4 w-4 animate-spin"}),s.status==="queued"?a("Queued, waiting for a worker…"):a("Running…"),t&&!r&&e.jsxs("span",{className:"text-xs opacity-70",children:["(",a("polling every second"),")"]})]}),r&&n!==null&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-muted",children:e.jsx("div",{className:"h-full bg-primary transition-all duration-500",style:{width:`${n}%`}})}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[e.jsxs("span",{children:[s.processedItems.toLocaleString()," /"," ",s.totalItems.toLocaleString()]}),e.jsxs("span",{children:[n,"%"]})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground italic pt-1",children:a("Safe to close. This repair keeps running in the background even when you leave this page. Come back anytime to check progress.")})]})}function Re({level:s}){const t="h-4 w-4 shrink-0 mt-0.5";switch(s){case"ok":return e.jsx(Se,{className:`${t} text-green-600 dark:text-green-500`,"aria-label":"OK"});case"warn":return e.jsx(we,{className:`${t} text-amber-600 dark:text-amber-500`,"aria-label":"Warning"});case"error":return e.jsx(Ce,{className:`${t} text-destructive`,"aria-label":"Error"});case"info":default:return e.jsx(Qe,{className:`${t} text-muted-foreground`,"aria-label":"Info"})}}function Hs(s){return s.error>0?"error":s.warn>0?"warn":s.ok>0?"ok":"info"}function qs(s,t){const a=["# Siren status",`Generated: ${s.generatedAt}`,""];for(const r of s.sections){a.push(`## ${r.label}`);for(const n of r.rows){const i=n.status==="ok"?"✓":n.status==="warn"?"!":n.status==="error"?"✗":"·";a.push(`${i} ${n.label}: ${n.value}`),n.detail&&a.push(`    ${n.detail}`)}a.push("")}a.push("# Siren utilities info");for(const r of t.sections){a.push(`## ${r.label}`);for(const[n,i]of Object.entries(r.rows))a.push(`${n}: ${Ws(i)}`);a.push("")}return a.join(`
     27`)}function Ws(s){return s==null?"—":typeof s=="boolean"?s?"true":"false":typeof s=="number"||typeof s=="string"?String(s):Array.isArray(s)?s.length===0?"[]":s.map(String).join(", "):JSON.stringify(s)}function Ie(s,t){const a=Zs(t),r=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),n=URL.createObjectURL(r),i=document.createElement("a");i.href=n,i.download=a,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(n)}function Zs(s){const t=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19);return`${s}-${t}.json`}const oe=["programs","programGroups","distributors","collaborators","tracking","commerce","notifications"],Xs=["notifications"];function Ks(){const{translate:s}=S(),[t,a]=c.useState(null),[r,n]=c.useState(new Set(oe)),[i,u]=c.useState(!1),[o,m]=c.useState(null),f=c.useCallback(async()=>{try{m(null);const l=await ls();a(l.sizes)}catch(l){m(l instanceof Error?l.message:s("Failed to count export sizes."))}},[s]);c.useEffect(()=>{f()},[f]);function h(l){const g=new Set(r);g.has(l)?g.delete(l):g.add(l),n(g)}async function v(){if(r.size!==0){u(!0),m(null);try{const l=await cs(Array.from(r));Ie(l.recipe,"siren-export")}catch(l){m(l instanceof Error?l.message:s("Export failed."))}finally{u(!1)}}}const x=Array.from(r).reduce((l,g)=>l+((t==null?void 0:t[g])??0),0);return e.jsxs(E,{children:[e.jsxs(T,{children:[e.jsx(O,{children:s("Export configuration")}),e.jsx(H,{children:s("Save your current Siren setup as a recipe file. You can import it into another Siren site or account, or attach it to a support ticket.")})]}),e.jsxs(L,{className:"space-y-4",children:[o&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",children:o}),t?e.jsx("ul",{className:"space-y-2",children:oe.filter(l=>!Xs.includes(l)||l in t).map(l=>{const g=t[l]??0,w=r.has(l),y=g===0;return e.jsxs("li",{className:"flex items-center justify-between gap-3 rounded-md border px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ge,{id:`export-${l}`,checked:w,disabled:y,onCheckedChange:()=>h(l)}),e.jsx(be,{htmlFor:`export-${l}`,className:y?"font-normal text-muted-foreground":"font-normal",children:s(os[l])})]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:g.toLocaleString()})]},l)})}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(B,{label:s("Counting…")})}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 pt-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:s(`Selected: ${x.toLocaleString()} item${x===1?"":"s"}`)}),e.jsxs(j,{onClick:v,disabled:i||r.size===0,children:[e.jsx(ke,{className:"mr-2 h-4 w-4"}),s(i?"Generating…":"Download recipe JSON")]})]})]})]})}const Z=100,Ys=[{value:"any",label:"Any time"},{value:"15m",label:"Last 15 min"},{value:"1h",label:"Last hour"},{value:"24h",label:"Last 24 hours"},{value:"7d",label:"Last 7 days"}],Qs={debug:"status-badge status-gray",info:"status-badge status-blue",notice:"status-badge status-blue",warning:"status-badge status-yellow",error:"status-badge status-red",critical:"status-badge status-red",alert:"status-badge status-red",emergency:"status-badge status-red"},X="all";function et(){const{translate:s}=S(),[t,a]=c.useState(null),[r,n]=c.useState(""),[i,u]=c.useState(""),[o,m]=c.useState("any"),[f,h]=c.useState(0),[v,x]=c.useState(null),[l,g]=c.useState(!1),[w,y]=c.useState(!1),[C,d]=c.useState(null),[b,N]=c.useState(null),k=c.useRef(null),I=c.useRef(null);c.useEffect(()=>(k.current&&clearTimeout(k.current),k.current=setTimeout(()=>{J(r,i,o,0),h(0)},250),()=>{k.current&&clearTimeout(k.current)}),[i]),c.useEffect(()=>{J(r,i,o,0),h(0)},[r,o]);async function J(p,$,V,F){g(!0),x(null);try{const M=await Us({level:p||null,search:$||null,since:ce(V),limit:Z,offset:F});a(M)}catch(M){x(M instanceof Error?M.message:s("Failed to load logs."))}finally{g(!1)}}function Y(p){h(p),J(r,i,o,p)}async function Le(p){const $=st(p);try{await Ne($)}catch{je.error(s("Copy failed. Select the text and copy it."));return}N(p.id),I.current&&clearTimeout(I.current),I.current=setTimeout(()=>N(null),1500)}async function Te(){y(!0),x(null);try{const p=await Bs({level:r||null,search:i||null,since:ce(o)});Ie(p,"siren-logs")}catch(p){x(p instanceof Error?p.message:s("Export failed."))}finally{y(!1)}}const z=(t==null?void 0:t.entries)??[],q=(t==null?void 0:t.total)??0,Oe=(t==null?void 0:t.levels)??[],$e=f+z.length<q,De=f>0;return e.jsxs(E,{children:[e.jsx(T,{children:e.jsx(O,{children:s("Siren log")})}),e.jsxs(L,{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[16rem]",children:[e.jsx(us,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground","aria-hidden":"true"}),e.jsx(ve,{value:i,onChange:p=>u(p.target.value),placeholder:s("Search message…"),className:"pl-9 pr-9"}),i&&e.jsx("button",{type:"button",onClick:()=>u(""),className:"absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-muted","aria-label":s("Clear search"),children:e.jsx(He,{className:"h-3.5 w-3.5 text-muted-foreground"})})]}),e.jsxs(Q,{value:r||X,onValueChange:p=>n(p===X?"":p),disabled:l,children:[e.jsx(ee,{"aria-label":s("Filter by level"),className:"w-[140px]",children:e.jsx(se,{})}),e.jsxs(te,{children:[e.jsx(W,{value:X,children:s("All levels")}),Oe.map(p=>e.jsx(W,{value:p,children:p},p))]})]}),e.jsxs(Q,{value:o,onValueChange:p=>m(p),disabled:l,children:[e.jsx(ee,{"aria-label":s("Time range"),className:"w-[160px]",children:e.jsx(se,{})}),e.jsx(te,{children:Ys.map(p=>e.jsx(W,{value:p.value,children:s(p.label)},p.value))})]}),e.jsxs(j,{variant:"outline",size:"sm",onClick:()=>J(r,i,o,f),disabled:l,children:[e.jsx(es,{className:`mr-2 h-4 w-4 ${l?"animate-spin":""}`}),s("Refresh")]}),e.jsxs(j,{variant:"outline",size:"sm",onClick:Te,disabled:w||l,"aria-describedby":"logs-export-note",children:[e.jsx(ke,{className:`mr-2 h-4 w-4 ${w?"animate-pulse":""}`}),s(w?"Exporting…":"Export")]}),e.jsx("span",{id:"logs-export-note",className:"sr-only",children:s("Download the current filtered log as a JSON file (up to 10,000 entries).")})]}),v&&e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",role:"alert",children:v}),t?z.length===0?e.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:s("No entries match.")}):e.jsx("ul",{className:"divide-y rounded-md border text-xs",children:z.map(p=>{const $=C===p.id,V=Object.keys(p.context??{}).length>0,F=b===p.id;return e.jsxs("li",{className:"group relative px-3 py-2 font-mono",children:[e.jsxs("button",{type:"button",onClick:()=>d($?null:p.id),className:"w-full text-left pr-10","aria-expanded":$,disabled:!V,children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px]",children:[e.jsx("span",{className:Qs[p.level]??"status-badge status-gray",children:p.level}),p.timestamp&&e.jsx("span",{className:"text-muted-foreground",children:tt(p.timestamp)})]}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-all",children:p.message})]}),e.jsx("button",{type:"button",onClick:M=>{M.stopPropagation(),Le(p)},className:`absolute right-2 top-2 inline-flex items-center gap-1 rounded-md border bg-background px-2 py-1 text-[10px] font-sans shadow-sm transition-opacity focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring ${F?"opacity-100":"opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100"}`,"aria-label":s(F?"Copied":"Copy entry"),children:F?e.jsxs(e.Fragment,{children:[e.jsx(qe,{className:"h-3 w-3","aria-hidden":"true"}),s("Copied")]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"h-3 w-3","aria-hidden":"true"}),s("Copy")]})}),$&&V&&e.jsx(ds,{className:"mt-2",code:JSON.stringify(p.context,null,2),language:"json",copy:!1,maxHeight:"sm"})]},p.id)})}):e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(B,{label:s("Loading log…")})}),t&&e.jsxs("div",{className:"flex items-center justify-between pt-1 text-xs text-muted-foreground",children:[e.jsx("span",{children:s(q===0?"0 entries":`${f+1}–${f+z.length} of ${q.toLocaleString()}`)}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(j,{variant:"outline",size:"sm",onClick:()=>Y(Math.max(0,f-Z)),disabled:!De||l,children:s("Previous")}),e.jsx(j,{variant:"outline",size:"sm",onClick:()=>Y(f+Z),disabled:!$e||l,children:s("Next")})]})]})]})]})}function st(s){const t=[`[${s.level}] ${s.timestamp??""}`.trim(),s.message],a=s.context??{};return Object.keys(a).length>0&&t.push("","Context:",JSON.stringify(a,null,2)),t.join(`
     28`)}function tt(s){try{return new Date(s).toLocaleString()}catch{return s}}function ce(s){if(s==="any")return null;const t=Date.now(),a={"15m":900*1e3,"1h":3600*1e3,"24h":1440*60*1e3,"7d":10080*60*1e3};return new Date(t-a[s]).toISOString()}function rt({features:s,signInUrl:t,signUpUrl:a}){const{translate:r}=S();return e.jsx("div",{className:"max-w-3xl space-y-6","data-testid":"siren-cloud-call-to-action",children:e.jsxs(E,{children:[e.jsxs(T,{className:"flex flex-row items-center gap-2 space-y-0",children:[e.jsx(hs,{className:"h-5 w-5 text-muted-foreground","aria-hidden":"true"}),e.jsx(O,{children:r("Run Siren on Siren Cloud")})]}),e.jsxs(L,{className:"space-y-6 text-sm",children:[e.jsx("p",{children:r("Siren Cloud does the commission and payout work for your programs, so your store no longer has to. You manage programs, collaborators and payouts from your Siren Cloud dashboard.")}),s,e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"font-semibold",children:r("How to switch")}),e.jsxs("ol",{className:"list-decimal space-y-1 pl-5",children:[e.jsx("li",{children:r("Sign in to Siren Cloud, or create an account. An account is all you need to get the connector.")}),e.jsx("li",{children:r("In Siren Cloud, open Settings, then Integrations, and choose Get the connector.")}),e.jsx("li",{children:r("Install the connector on this site. It moves your programs, collaborators and history to Siren Cloud, then takes over from this plugin. The move starts a free Pro trial.")})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[t?e.jsx(j,{asChild:!0,children:e.jsxs("a",{href:t,target:"_blank",rel:"noopener noreferrer",children:[r("Sign in to Siren Cloud"),e.jsx(ne,{className:"h-4 w-4","aria-hidden":"true"})]})}):null,a?e.jsx(j,{asChild:!0,variant:"outline",children:e.jsxs("a",{href:a,target:"_blank",rel:"noopener noreferrer",children:[r("Create an account"),e.jsx(ne,{className:"h-4 w-4","aria-hidden":"true"})]})}):null]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r("Until you install the connector, this plugin keeps working as it does now and sends nothing to Siren Cloud.")})]})]})})}function at(){const{translate:s}=S(),t=[s("Lead and renewal commissions"),s("Commissions per lead and per product"),s("Pooled commissions"),s("Content and product triggers"),s("Automatic payouts in store credit"),s("The collaborator portal"),s("Program groups and distributors")];return e.jsxs("section",{className:"space-y-2","data-testid":"features-gained",children:[e.jsx("h3",{className:"font-semibold",children:s("Included with every Siren Cloud plan")}),e.jsx("p",{className:"text-muted-foreground",children:s("Every Siren Cloud plan starts at Essentials, so you get these features without buying a paid edition. On WordPress they need Siren Essentials or higher.")}),e.jsx("ul",{className:"list-disc space-y-1 pl-5","aria-label":s("Included with every Siren Cloud plan"),children:t.map(a=>e.jsx("li",{children:a},a))})]})}const nt=xs("src/service/screens/main-menu/ManagedInCloudBanner.tsx");function it({connector:s,adminScope:t,managedInCloud:a,licensedTier:r}){return a?{defaultRoute:r?"/license":"/utilities",localRecords:!1,connectOnly:!1}:s?{defaultRoute:"/siren-cloud",localRecords:!1,connectOnly:!1}:{defaultRoute:r?"/license":"/import",localRecords:!0,connectOnly:!1}}window.sirenConfig&&We({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});var xe;const lt=(xe=window.sirenConfig)==null?void 0:xe.tier;var pe;const ot=(pe=window.sirenConfig)==null?void 0:pe.capabilities,ct=!1,K=void 0,dt=void 0,{defaultRoute:Ee,localRecords:de,connectOnly:_}=it({connector:!1,adminScope:K==null?void 0:K.adminScope,managedInCloud:!!dt,licensedTier:ct}),ut=void 0,ue=Ee.replace(/^\//,"");var he;const A=(he=window.sirenConfig)==null?void 0:he.sirenCloud,mt=e.jsx(rt,{features:e.jsx(at,{}),signInUrl:A==null?void 0:A.signInUrl,signUpUrl:A==null?void 0:A.signUpUrl}),me=document.getElementById("siren-main-menu");me&&Ze.createRoot(me).render(e.jsx(c.StrictMode,{children:e.jsxs(ms,{defaultRoute:Ee,tier:lt,capabilities:ot,children:[e.jsx(Xe,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsx(Ke,{children:e.jsxs(R,{element:e.jsx(Ls,{notice:_?e.jsx(nt.ConnectOnlyNotice,{}):void 0,hideLocalRecordTabs:!de,connectOnly:_}),children:[e.jsx(R,{index:!0,element:e.jsx(re,{to:ue,replace:!0})}),!1,de&&e.jsxs(e.Fragment,{children:[e.jsx(R,{path:"import",element:e.jsx(vs,{})}),e.jsx(R,{path:"import/imports",element:e.jsx(ks,{})}),e.jsx(R,{path:"import/imports/:jobId",element:e.jsx(ss,{})}),e.jsx(R,{path:"recipes/browse",element:e.jsx(ts,{})}),e.jsx(R,{path:"recipes/browse/:slug",element:e.jsx(rs,{})}),e.jsx(R,{path:"export",element:e.jsx(Ks,{})})]}),!_&&e.jsx(R,{path:"utilities",element:e.jsx(Js,{connectorBlock:ut})}),!_&&e.jsx(R,{path:"logs",element:e.jsx(et,{})}),e.jsx(R,{path:"siren-cloud",element:mt}),e.jsx(R,{path:"*",element:e.jsx(re,{to:ue,replace:!0})})]})})})]})}));
  • siren-affiliates/trunk/frontend/obligations.js

    r3775642 r3788740  
    1 import{u as q,r as l,j as e,b as ze,L as v,B as f,S as ne,d as oe,e as ie,f as de,g,D as He,h as We,i as Ge,k as _e,l as Ue,m as qe,n as Ke,a as Xe,w as Ye,o as Je,C as P,p as T,q as k,x as D,s as R,E as Qe,F as Ze,T as es,R as ss,G as J}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as ge}from"./shared/obligations-1RIdX1q5.js";import{F as ts,H as as,a as rs,B as ls,D as ns}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as fe}from"./shared/ActivityDrawer-iYDgZTH3.js";import{T as os}from"./shared/TestSaleBadge-DCBR_ipH.js";import{l as U,h as ce}from"./shared/linked-record-D4sO5j3k.js";import{u as Q}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{i as be,h as is}from"./shared/obligation-hold-JyNfYYW_.js";import"./shared/fulfillments-DDk-ZIVs.js";import{m as ds}from"./shared/payout-waiting-k6RU_ZQa.js";import{A as cs}from"./shared/arrow-left-W0B3m2vw.js";import{W as ms}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/react-zvEYxxW2.js";import"./shared/registries-Ql2SZeKd.js";import"./shared/unshipped-CGZcvpGp.js";function us({obligationIds:s}){const{translate:n}=q(),{formatMoney:c}=Q(),[b,r]=l.useState([]),N=s.join(",");return l.useEffect(()=>{{r([]);return}},[N]),b.length===0?null:e.jsxs("div",{role:"status","data-testid":"waiting-payouts-warning",className:"rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",children:[e.jsx("p",{className:"font-medium",children:b.length===1?n("1 payout will wait for its collaborator to set up payouts."):n("%d payouts will wait for their collaborators to set up payouts.").replace("%d",String(b.length))}),e.jsx("ul",{className:"mt-2 list-disc space-y-1 pl-5",children:b.map(m=>e.jsx("li",{children:n("%1$s needs to set up %2$s for %3$s.").replace("%1$s",U(m.collaboratorName,"collaborator",n)).replace("%2$s",ds(m.method)).replace("%3$s",c(m.value,m.currency))},`${m.collaboratorId}-${m.currency}`))}),e.jsx("p",{className:"mt-2",children:n("The fulfillment can still be generated. Siren sends each of these payouts as soon as its collaborator finishes.")})]})}const xs={draft:"status-badge status-gray",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},me="draft,approved,complete,rejected",hs=s=>s.status!=="draft";function ue(){const{translate:s}=q(),{formatMoney:n,definitionFor:c}=Q(),b={draft:s("Awaiting conversion approval"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},[r,N]=ze(),{items:m,total:a,page:w,perPage:A,totalPages:F,isLoading:z,isSubmitting:C,error:B,fetchList:I,bulkApprove:S,bulkReject:i,bulkDelete:$,bulkPermanentDelete:Z,bulkRestore:ee,generateFulfillments:ye}=ge(),ve=r.get("status")||"all",Ne=r.get("collaboratorId")||"",we=r.get("payoutId")||"",[d,se]=l.useState(ve),[h,K]=l.useState(Ne),[p,X]=l.useState(we),[H,Ce]=l.useState(10),[L,Ie]=l.useState("dateCreated"),[E,Se]=l.useState("desc"),[u,y]=l.useState(new Set),[te,W]=l.useState(!1),G=d==="deleted",Pe=t=>{const o=t??d;return o==="all"?me:o};l.useEffect(()=>{const t=r.get("status"),o=r.get("collaboratorId"),M=r.get("payoutId");t&&t!==d&&se(t),o&&o!==h&&K(o),M&&M!==p&&X(M)},[r,d,h,p]),l.useEffect(()=>{y(new Set)},[d,h,p]),l.useEffect(()=>{I({page:1,perPage:H,orderBy:L,order:E,status:d==="all"?me:d,collaboratorId:h?parseInt(h):void 0,payoutId:p?parseInt(p):void 0})},[I,H,L,E,d,h,p]);const ae=(t={})=>({page:t.page??1,perPage:t.perPage??H,status:Pe(t.status??d),collaboratorId:t.collaboratorId??h?parseInt(t.collaboratorId??h):void 0,payoutId:t.payoutId??p?parseInt(t.payoutId??p):void 0,orderBy:t.orderBy??L,order:t.order??E}),_=t=>{se(t),t!=="all"?r.set("status",t):r.delete("status"),N(r)},re=t=>{I(ae({page:t}))},Te=t=>{const o=parseInt(t);Ce(o),I(ae({perPage:o}))},ke=t=>{const o=L===t&&E==="asc"?"desc":"asc";Ie(t),Se(o)},De=async()=>{await S(Array.from(u)),y(new Set)},Re=async()=>{await i(Array.from(u)),y(new Set)},Ae=async()=>{await $(Array.from(u)),y(new Set)},Fe=async()=>{await ee(Array.from(u)),y(new Set)},Be=async()=>{await Z(Array.from(u)),y(new Set)},$e=async()=>{await ye(j.eligibleIds),y(new Set),W(!1)},j=l.useMemo(()=>{var le;const t=m.filter(x=>u.has(x.id)),o=t.filter(x=>x.status==="approved"),M=t.length-o.length,Y=new Map;for(const x of o){const O=((le=c(x.awardType))==null?void 0:le.code)??x.awardType??"",V=Y.get(O)||{obligations:[],total:0};V.obligations.push(x),V.total+=x.value,Y.set(O,V)}return{groups:Array.from(Y.entries()).map(([x,O],V)=>({index:V+1,currency:x,obligationCount:O.obligations.length,total:O.total})),excludedCount:M,eligibleIds:o.map(x=>x.id)}},[m,u,c]),Le=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),Ee=[{id:"id",header:s("ID"),cell:t=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",t.id]}),t.isTest&&e.jsx(os,{})]})},{id:"collaborator",header:s("Collaborator"),cell:t=>e.jsx(v,{to:`/collaborators/${t.collaboratorId}/view`,className:"text-primary hover:underline",children:U(t.collaboratorName,"collaborator",s)})},{id:"payout",header:s("Payout"),cell:t=>t.payoutId?e.jsxs(v,{to:`/obligations?payoutId=${t.payoutId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",t.payoutId]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"value",header:s("Amount"),sortable:!0,cell:t=>e.jsx("span",{className:"font-medium",children:n(t.value,t.awardType)})},{id:"status",header:s("Status"),sortable:!0,cell:t=>e.jsx(ts,{filterKey:"status",filterValue:t.status,children:be(t)?e.jsx("span",{className:"status-badge status-yellow",children:s("Held for review")}):e.jsx("span",{className:xs[t.status],children:b[t.status]})})},{id:"dateCreated",header:s("Created"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm text-muted-foreground",children:Le(t.dateCreated)})},...G?[{id:"actions",header:s("Actions"),cell:t=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(f,{variant:"outline",size:"sm",onClick:()=>ee([t.id]),children:s("Restore")}),e.jsx(f,{variant:"destructive",size:"sm",onClick:()=>Z([t.id]),children:s("Delete Permanently")})]})}]:[]],Me=G?[{label:s("Restore"),onClick:Fe},{label:s("Delete Permanently"),onClick:Be,variant:"destructive",confirmMessage:`Permanently delete ${u.size} obligation(s)? This action cannot be undone.`,confirmItems:Array.from(u).map(t=>`Obligation #${t}`)}]:[{label:s("Create Fulfillments"),onClick:()=>W(!0)},{label:s("Approve"),onClick:De},{label:s("Reject"),onClick:Re},{label:s("Delete"),onClick:Ae,variant:"destructive",confirmMessage:`Delete ${u.size} obligation(s)? You can undo from Trash.`}],Oe=[{key:"status",label:"Status",value:d,displayValue:b[d]||d,onRemove:()=>_("all")},...h?[{key:"collaboratorId",label:"Collaborator",value:h,displayValue:`#${h}`,onRemove:()=>{K(""),r.delete("collaboratorId"),N(r)}}]:[],...p?[{key:"payoutId",label:"Payout",value:p,displayValue:`#${p}`,onRemove:()=>{X(""),r.delete("payoutId"),N(r)}}]:[]],Ve=()=>{_("all"),K(""),X(""),r.delete("collaboratorId"),r.delete("payoutId"),N(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Obligations"),e.jsx(as,{topic:"what-is-obligation",side:"right"})]}),e.jsx(fe,{sourceType:"obligation",contextLabel:"all obligations"})]}),e.jsx(rs,{filters:Oe,onClearAll:Ve}),B&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:B}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap",children:e.jsxs(ne,{value:d,onValueChange:_,children:[e.jsx(oe,{"aria-label":s("Filter by status"),className:"w-[240px]",children:e.jsx(ie,{placeholder:s("Status")})}),e.jsxs(de,{children:[e.jsx(g,{value:"all",children:s("All Statuses")}),e.jsx(g,{value:"draft",children:s("Awaiting conversion approval")}),e.jsx(g,{value:"approved",children:s("Approved")}),e.jsx(g,{value:"complete",children:s("Complete")}),e.jsx(g,{value:"rejected",children:s("Rejected")}),e.jsx(g,{value:"deleted",children:s("Trashed")})]})]})}),e.jsx(ls,{selectedCount:u.size,actions:Me,onClear:()=>y(new Set),isProcessing:C}),e.jsx(ns,{columns:Ee,data:m,isLoading:z,emptyMessage:s("No obligations found."),selectable:!0,isRowSelectable:hs,selectedIds:u,onSelectionChange:y,getRowHref:t=>`/obligations/${t.id}`,sortField:L,sortOrder:E,onSort:ke}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",a===0?0:(w-1)*A+1," to ",Math.min(w*A,a)," of"," ",a," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(ne,{value:H.toString(),onValueChange:Te,children:[e.jsx(oe,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(ie,{})}),e.jsxs(de,{children:[e.jsx(g,{value:"10",children:"10"}),e.jsx(g,{value:"25",children:"25"}),e.jsx(g,{value:"50",children:"50"}),e.jsx(g,{value:"100",children:"100"})]})]})]})]}),F>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(f,{variant:"outline",size:"sm",disabled:w===1,onClick:()=>re(w-1),children:s("Previous")}),e.jsx(f,{variant:"outline",size:"sm",disabled:w===F,onClick:()=>re(w+1),children:s("Next")})]}),e.jsx(f,{variant:"link",className:"text-sm",onClick:()=>_(G?"all":"deleted"),children:s(G?"Back to active obligations":"Trash")})]}),e.jsx(He,{open:te,onOpenChange:W,children:e.jsxs(We,{children:[e.jsxs(Ge,{children:[e.jsx(_e,{children:s("Generate Fulfillments")}),e.jsxs(Ue,{children:['Choosing "',s("Generate Fulfillments"),'" will create ',j.groups.length===1?"one fulfillment":`${j.groups.length} fulfillments`,', and all approved Obligations will be marked as "complete".']})]}),e.jsxs("div",{className:"py-4 space-y-4",children:[j.groups.map(t=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("h4",{className:"font-semibold",children:["Fulfillment ",t.index," (",t.currency,")"]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Obligations Affected: ",t.obligationCount]}),e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Total: "}),e.jsx("span",{className:"font-medium",children:n(t.total,t.currency)})]})]},t.currency)),j.excludedCount>0&&e.jsxs("p",{className:"text-sm text-muted-foreground italic",children:[j.excludedCount," obligation",j.excludedCount!==1?"s are":" is"," excluded because ",j.excludedCount!==1?"they are":"it is"," not approved."]}),te&&e.jsx(us,{obligationIds:j.eligibleIds})]}),e.jsxs(qe,{children:[e.jsx(f,{variant:"outline",onClick:()=>W(!1),children:s("Cancel")}),e.jsx(f,{onClick:$e,disabled:C||j.groups.length===0,children:C?"Generating...":"Generate Fulfillments"})]})]})})]})}const xe={draft:"status-badge status-gray",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},ps={sale:"Sale",lead:"Lead",renewal:"Renewal"},he={refund:"The sale was partly refunded",transaction_changed:"The sale changed"},js="siren-refund-";function pe({reason:s,reference:n}){const{translate:c}=q();return n?s==="refund"&&n.startsWith(js)?e.jsxs(e.Fragment,{children:[", ",c("by a refund with no id from the platform")]}):e.jsxs(e.Fragment,{children:[", ",c(s==="refund"?"by refund":"by change")," ",e.jsx("span",{className:"font-mono",children:n})]}):null}const gs={paypal:"PayPal",bank_transfer:"Bank Transfer",manual:"Manual Payment",check:"Check",store_credit:"Store Credit"};function fs(){const{translate:s}=q(),n={draft:s("Awaiting conversion approval"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},{id:c}=Ke(),b=Xe(),{isWordPress:r}=Ye(),{formatMoney:N,currencyName:m}=Q(),{current:a,isLoading:w,error:A,fetchOne:F,clearCurrent:z}=ge();l.useEffect(()=>(c&&F(parseInt(c)),()=>{z()}),[c,F,z]);const C=i=>i?new Date(i).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",B=(i,$)=>N(i,$);if(w)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Je,{})});if(A)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:A})});if(!a)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Obligation not found.")})});const I=a.payoutStatus==="paid",S=be(a);return e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!r&&e.jsx(f,{variant:"ghost",size:"icon",onClick:()=>b("/obligations"),"aria-label":s("Back"),children:e.jsx(cs,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Obligation #",a.id]}),e.jsxs("p",{className:"text-muted-foreground",children:["Created ",C(a.dateCreated)]})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:S?"status-badge status-yellow":xe[a.status],children:S?s("Held for review"):n[a.status]}),e.jsx(fe,{sourceType:"obligation",sourceId:a.id,contextLabel:`obligation #${a.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[S&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",role:"status",children:[e.jsx("p",{className:"font-medium",children:s("Held for review")}),e.jsx("p",{className:"mt-1",children:s(is(a.holdReason))}),a.conversionId?e.jsx("p",{className:"mt-2",children:e.jsxs(v,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline",children:[s("Review conversion")," #",a.conversionId]})}):null]}),(a.supersededBy||a.supersedes&&a.supersedes.length>0)&&e.jsxs(P,{"data-testid":"obligation-supersession",children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Replacement")}),e.jsx(D,{children:s("Siren recalculated this reward after its sale changed")})]}),e.jsx(R,{children:e.jsxs("dl",{className:"space-y-3",children:[a.supersededBy&&e.jsxs("div",{children:[e.jsxs("dt",{className:"text-sm text-muted-foreground",children:[s(he[a.supersededBy.reason]??"The sale changed"),e.jsx(pe,{reason:a.supersededBy.reason,reference:a.supersededBy.changeReference})]}),e.jsx("dd",{className:"mt-1",children:a.supersededBy.obligationId?e.jsxs(e.Fragment,{children:[s("Replaced by")," ",e.jsxs(v,{to:`/obligations/${a.supersededBy.obligationId}`,className:"text-primary hover:underline",children:[s("obligation")," #",a.supersededBy.obligationId]})]}):s("Nothing replaced it, because the reward now comes to nothing.")})]}),(a.supersedes??[]).map((i,$)=>e.jsxs("div",{children:[e.jsxs("dt",{className:"text-sm text-muted-foreground",children:[s(he[i.reason]??"The sale changed"),e.jsx(pe,{reason:i.reason,reference:i.changeReference})]}),e.jsx("dd",{className:"mt-1",children:i.obligationId?e.jsxs(e.Fragment,{children:[s("Replaces")," ",e.jsxs(v,{to:`/obligations/${i.obligationId}`,className:"text-primary hover:underline",children:[s("obligation")," #",i.obligationId]})]}):s("Replaces an earlier obligation.")})]},(i.obligationId??0)+"-"+$))]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Reward Details")}),e.jsx(D,{children:s("The amount owed to the collaborator")})]}),e.jsx(R,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Value")}),e.jsx("dd",{className:"text-2xl font-semibold mt-1",children:B(a.value,a.awardType)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"mt-1",children:e.jsx("span",{className:S?"status-badge status-yellow":xe[a.status],children:S?s("Held for review"):n[a.status]})})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Currency")}),e.jsx("dd",{className:"text-sm mt-1",children:m(a.awardType)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created")}),e.jsx("dd",{className:"text-sm mt-1",children:C(a.dateCreated)})]})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Collaborator")}),e.jsx(D,{children:s("Who earned this reward")})]}),e.jsx(R,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:U(a.collaboratorName,"collaborator",s)}),a.collaboratorEmail&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a.collaboratorEmail})]}),ce(a.collaboratorName)&&e.jsx(f,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(v,{to:`/collaborators/${a.collaboratorId}/view`,children:s("View Profile")})})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Conversion Source")}),e.jsx(D,{children:s("The activity that triggered this reward")})]}),e.jsx(R,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion ID")}),e.jsx("dd",{children:e.jsxs(v,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline font-mono",children:["#",a.conversionId]})})]}),a.conversionType&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Type")}),e.jsx("dd",{children:ps[a.conversionType]||a.conversionType})]}),a.conversionAmount!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion Amount")}),e.jsx("dd",{className:"font-medium",children:B(a.conversionAmount)})]}),a.conversionDate&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion Date")}),e.jsx("dd",{children:C(a.conversionDate)})]})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Program")}),e.jsx(D,{children:s("The program that generated this obligation")})]}),e.jsx(R,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"font-medium",children:U(a.programName,"program",s)}),ce(a.programName)&&e.jsx(f,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(v,{to:`/programs/${a.programId}/view`,children:s("View Program")})})]})})]}),a.payoutId&&e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Fulfillment")}),e.jsx(D,{children:s(I?"This obligation has been paid":"This obligation is in a payout that has not been paid yet")})]}),e.jsx(R,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payout ID")}),e.jsxs("dd",{className:"font-mono",children:["#",a.payoutId]})]}),a.fulfillmentId&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Fulfillment")}),e.jsx("dd",{children:e.jsxs(v,{to:`/fulfillments/${a.fulfillmentId}`,className:"text-primary hover:underline font-mono",children:["#",a.fulfillmentId]})})]}),a.payoutStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payout Status")}),e.jsx("dd",{children:s(I?"Paid":"Unpaid")})]}),a.payoutMethod&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payment Method")}),e.jsx("dd",{children:gs[a.payoutMethod]||a.payoutMethod})]}),a.payoutDate&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Paid On")}),e.jsx("dd",{children:C(a.payoutDate)})]})]})})]})]})]})}window.sirenConfig&&Qe({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const je=document.getElementById("siren-obligations");je&&Ze.createRoot(je).render(e.jsx(l.StrictMode,{children:e.jsxs(ms,{defaultRoute:"/obligations",children:[e.jsx(es,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(ss,{children:[e.jsx(J,{path:"/obligations",element:e.jsx(ue,{})}),e.jsx(J,{path:"/obligations/:id",element:e.jsx(fs,{})}),e.jsx(J,{index:!0,element:e.jsx(ue,{})})]})})]})}));
     1import{u as K,r as l,j as e,d as Ge,L as v,B as f,S as ie,e as de,f as ce,g as ue,h as j,D as _e,i as Ue,k as Ke,l as qe,m as Xe,n as Ye,o as Je,b as Qe,a as Ze,p as es,C as P,q as T,s as k,x as R,t as D,E as ss,F as ts,T as as,R as rs,G as J}from"./shared/wordpress-admin-D_eccjaB.js";import{u as ye}from"./shared/obligations-tU6cfrpO.js";import{u as ls,F as ns,H as os,a as is,B as me,D as ds}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as ve}from"./shared/ActivityDrawer-BZxDAdLe.js";import{T as cs}from"./shared/TestSaleBadge--DG3xZwg.js";import{l as U,h as xe}from"./shared/linked-record-D4sO5j3k.js";import{u as Q}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{i as Ne,h as us}from"./shared/obligation-hold-JyNfYYW_.js";import"./shared/fulfillments-PrFHoXSm.js";import{m as ms}from"./shared/payout-waiting-k6RU_ZQa.js";import{A as xs}from"./shared/arrow-left-XvsxLAWy.js";import{W as hs}from"./shared/WordPressRouter-CAYzko7X.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/react-Rq6nbqOn.js";import"./shared/registries-CatPSk3G.js";import"./shared/unshipped-CGZcvpGp.js";function ps({obligationIds:s}){const{translate:n}=K(),{formatMoney:u}=Q(),[b,r]=l.useState([]),N=s.join(",");return l.useEffect(()=>{{r([]);return}},[N]),b.length===0?null:e.jsxs("div",{role:"status","data-testid":"waiting-payouts-warning",className:"rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-100",children:[e.jsx("p",{className:"font-medium",children:b.length===1?n("1 payout will wait for its collaborator to set up payouts."):n("%d payouts will wait for their collaborators to set up payouts.").replace("%d",String(b.length))}),e.jsx("ul",{className:"mt-2 list-disc space-y-1 pl-5",children:b.map(d=>e.jsx("li",{children:n("%1$s needs to set up %2$s for %3$s.").replace("%1$s",U(d.collaboratorName,"collaborator",n)).replace("%2$s",ms(d.method)).replace("%3$s",u(d.value,d.currency))},`${d.collaboratorId}-${d.currency}`))}),e.jsx("p",{className:"mt-2",children:n("The fulfillment can still be generated. Siren sends each of these payouts as soon as its collaborator finishes.")})]})}const gs={draft:"status-badge status-gray",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},he="draft,approved,complete,rejected",js=s=>s.status!=="draft";function pe(){const{translate:s}=K(),{formatMoney:n,definitionFor:u}=Q(),b={draft:s("Awaiting conversion approval"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},[r,N]=Ge(),{items:d,total:a,page:w,perPage:A,totalPages:F,isLoading:B,isSubmitting:C,error:$,fetchList:I,bulkApprove:S,bulkReject:i,bulkDelete:L,bulkPermanentDelete:Z,bulkRestore:ee,generateFulfillments:we}=ye(),Ce=r.get("status")||"all",Ie=r.get("collaboratorId")||"",Se=r.get("payoutId")||"",[c,se]=l.useState(Ce),[h,q]=l.useState(Ie),[p,X]=l.useState(Se),[H,Pe]=l.useState(10),[E,Te]=l.useState("dateCreated"),[M,ke]=l.useState("desc"),[m,y]=l.useState(new Set),[te,W]=l.useState(!1),G=c==="deleted",Re=t=>{const o=t??c;return o==="all"?he:o};l.useEffect(()=>{const t=r.get("status"),o=r.get("collaboratorId"),O=r.get("payoutId");t&&t!==c&&se(t),o&&o!==h&&q(o),O&&O!==p&&X(O)},[r,c,h,p]),l.useEffect(()=>{y(new Set)},[c,h,p]),l.useEffect(()=>{I({page:1,perPage:H,orderBy:E,order:M,status:c==="all"?he:c,collaboratorId:h?parseInt(h):void 0,payoutId:p?parseInt(p):void 0})},[I,H,E,M,c,h,p]);const ae=(t={})=>({page:t.page??1,perPage:t.perPage??H,status:Re(t.status??c),collaboratorId:t.collaboratorId??h?parseInt(t.collaboratorId??h):void 0,payoutId:t.payoutId??p?parseInt(t.payoutId??p):void 0,orderBy:t.orderBy??E,order:t.order??M}),_=t=>{se(t),t!=="all"?r.set("status",t):r.delete("status"),N(r)},re=t=>{I(ae({page:t}))},De=t=>{const o=parseInt(t);Pe(o),I(ae({perPage:o}))},Ae=t=>{const o=E===t&&M==="asc"?"desc":"asc";Te(t),ke(o)},Fe=async()=>{await S(Array.from(m)),y(new Set)},Be=async()=>{await i(Array.from(m)),y(new Set)},$e=async()=>{await L(Array.from(m)),y(new Set)},Le=async()=>{await ee(Array.from(m)),y(new Set)},Ee=async()=>{await Z(Array.from(m)),y(new Set)},Me=async()=>{await we(g.eligibleIds),y(new Set),W(!1)},g=l.useMemo(()=>{var oe;const t=d.filter(x=>m.has(x.id)),o=t.filter(x=>x.status==="approved"),O=t.length-o.length,Y=new Map;for(const x of o){const V=((oe=u(x.awardType))==null?void 0:oe.code)??x.awardType??"",z=Y.get(V)||{obligations:[],total:0};z.obligations.push(x),z.total+=x.value,Y.set(V,z)}return{groups:Array.from(Y.entries()).map(([x,V],z)=>({index:z+1,currency:x,obligationCount:V.obligations.length,total:V.total})),excludedCount:O,eligibleIds:o.map(x=>x.id)}},[d,m,u]),Oe=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),le=ls("obligations"),ne=le&&!B&&d.length===0?le.filter(t=>t.tourSelected).length:0,Ve=[{id:"id",header:s("ID"),cell:t=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",t.id]}),t.isTest&&e.jsx(cs,{})]})},{id:"collaborator",header:s("Collaborator"),cell:t=>e.jsx(v,{to:`/collaborators/${t.collaboratorId}/view`,className:"text-primary hover:underline",children:U(t.collaboratorName,"collaborator",s)})},{id:"payout",header:s("Payout"),cell:t=>t.payoutId?e.jsxs(v,{to:`/obligations?payoutId=${t.payoutId}`,className:"text-primary hover:underline font-mono text-sm",children:["#",t.payoutId]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"value",header:s("Amount"),sortable:!0,cell:t=>e.jsx("span",{className:"font-medium",children:n(t.value,t.awardType)})},{id:"status",header:s("Status"),sortable:!0,cell:t=>e.jsx(ns,{filterKey:"status",filterValue:t.status,children:Ne(t)?e.jsx("span",{className:"status-badge status-yellow",children:s("Held for review")}):e.jsx("span",{className:gs[t.status],children:b[t.status]})})},{id:"dateCreated",header:s("Created"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm text-muted-foreground",children:Oe(t.dateCreated)})},...G?[{id:"actions",header:s("Actions"),cell:t=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(f,{variant:"outline",size:"sm",onClick:()=>ee([t.id]),children:s("Restore")}),e.jsx(f,{variant:"destructive",size:"sm",onClick:()=>Z([t.id]),children:s("Delete Permanently")})]})}]:[]],ze=G?[{label:s("Restore"),onClick:Le},{label:s("Delete Permanently"),onClick:Ee,variant:"destructive",confirmMessage:`Permanently delete ${m.size} obligation(s)? This action cannot be undone.`,confirmItems:Array.from(m).map(t=>`Obligation #${t}`)}]:[{label:s("Create Fulfillments"),onClick:()=>W(!0)},{label:s("Approve"),onClick:Fe},{label:s("Reject"),onClick:Be},{label:s("Delete"),onClick:$e,variant:"destructive",confirmMessage:`Delete ${m.size} obligation(s)? You can undo from Trash.`}],He=[{key:"status",label:"Status",value:c,displayValue:b[c]||c,onRemove:()=>_("all")},...h?[{key:"collaboratorId",label:"Collaborator",value:h,displayValue:`#${h}`,onRemove:()=>{q(""),r.delete("collaboratorId"),N(r)}}]:[],...p?[{key:"payoutId",label:"Payout",value:p,displayValue:`#${p}`,onRemove:()=>{X(""),r.delete("payoutId"),N(r)}}]:[]],We=()=>{_("all"),q(""),X(""),r.delete("collaboratorId"),r.delete("payoutId"),N(r)};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Obligations"),e.jsx(os,{topic:"what-is-obligation",side:"right"})]}),e.jsx(ve,{sourceType:"obligation",contextLabel:"all obligations"})]}),e.jsx(is,{filters:He,onClearAll:We}),$&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:$}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap","data-tour":"obligations-filters",children:e.jsxs(ie,{value:c,onValueChange:_,children:[e.jsx(de,{"aria-label":s("Filter by status"),className:"w-[240px]",children:e.jsx(ce,{placeholder:s("Status")})}),e.jsxs(ue,{children:[e.jsx(j,{value:"all",children:s("All Statuses")}),e.jsx(j,{value:"draft",children:s("Awaiting conversion approval")}),e.jsx(j,{value:"approved",children:s("Approved")}),e.jsx(j,{value:"complete",children:s("Complete")}),e.jsx(j,{value:"rejected",children:s("Rejected")}),e.jsx(j,{value:"deleted",children:s("Trashed")})]})]})}),e.jsx(me,{selectedCount:m.size,actions:ze,onClear:()=>y(new Set),isProcessing:C}),ne>0&&e.jsx(me,{sample:!0,selectedCount:ne,actions:[{label:s("Create Fulfillments"),onClick:()=>{}}],onClear:()=>{}}),e.jsx(ds,{columns:Ve,data:d,sampleKey:"obligations",isLoading:B,emptyMessage:s("No obligations found."),selectable:!0,isRowSelectable:js,selectedIds:m,onSelectionChange:y,getRowHref:t=>`/obligations/${t.id}`,sortField:E,sortOrder:M,onSort:Ae}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",a===0?0:(w-1)*A+1," to ",Math.min(w*A,a)," of"," ",a," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(ie,{value:H.toString(),onValueChange:De,children:[e.jsx(de,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(ce,{})}),e.jsxs(ue,{children:[e.jsx(j,{value:"10",children:"10"}),e.jsx(j,{value:"25",children:"25"}),e.jsx(j,{value:"50",children:"50"}),e.jsx(j,{value:"100",children:"100"})]})]})]})]}),F>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(f,{variant:"outline",size:"sm",disabled:w===1,onClick:()=>re(w-1),children:s("Previous")}),e.jsx(f,{variant:"outline",size:"sm",disabled:w===F,onClick:()=>re(w+1),children:s("Next")})]}),e.jsx(f,{variant:"link",className:"text-sm",onClick:()=>_(G?"all":"deleted"),children:s(G?"Back to active obligations":"Trash")})]}),e.jsx(_e,{open:te,onOpenChange:W,children:e.jsxs(Ue,{children:[e.jsxs(Ke,{children:[e.jsx(qe,{children:s("Generate Fulfillments")}),e.jsxs(Xe,{children:['Choosing "',s("Generate Fulfillments"),'" will create ',g.groups.length===1?"one fulfillment":`${g.groups.length} fulfillments`,', and all approved Obligations will be marked as "complete".']})]}),e.jsxs("div",{className:"py-4 space-y-4",children:[g.groups.map(t=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("h4",{className:"font-semibold",children:["Fulfillment ",t.index," (",t.currency,")"]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Obligations Affected: ",t.obligationCount]}),e.jsxs("p",{className:"text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Total: "}),e.jsx("span",{className:"font-medium",children:n(t.total,t.currency)})]})]},t.currency)),g.excludedCount>0&&e.jsxs("p",{className:"text-sm text-muted-foreground italic",children:[g.excludedCount," obligation",g.excludedCount!==1?"s are":" is"," excluded because ",g.excludedCount!==1?"they are":"it is"," not approved."]}),te&&e.jsx(ps,{obligationIds:g.eligibleIds})]}),e.jsxs(Ye,{children:[e.jsx(f,{variant:"outline",onClick:()=>W(!1),children:s("Cancel")}),e.jsx(f,{onClick:Me,disabled:C||g.groups.length===0,children:C?"Generating...":"Generate Fulfillments"})]})]})})]})}const ge={draft:"status-badge status-gray",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red",deleted:"status-badge status-red"},fs={sale:"Sale",lead:"Lead",renewal:"Renewal"},je={refund:"The sale was partly refunded",transaction_changed:"The sale changed"},bs="siren-refund-";function fe({reason:s,reference:n}){const{translate:u}=K();return n?s==="refund"&&n.startsWith(bs)?e.jsxs(e.Fragment,{children:[", ",u("by a refund with no id from the platform")]}):e.jsxs(e.Fragment,{children:[", ",u(s==="refund"?"by refund":"by change")," ",e.jsx("span",{className:"font-mono",children:n})]}):null}const ys={paypal:"PayPal",bank_transfer:"Bank Transfer",manual:"Manual Payment",check:"Check",store_credit:"Store Credit"};function vs(){const{translate:s}=K(),n={draft:s("Awaiting conversion approval"),approved:s("Approved"),complete:s("Complete"),rejected:s("Rejected"),deleted:s("Trashed")},{id:u}=Je(),b=Qe(),{isWordPress:r}=Ze(),{formatMoney:N,currencyName:d}=Q(),{current:a,isLoading:w,error:A,fetchOne:F,clearCurrent:B}=ye();l.useEffect(()=>(u&&F(parseInt(u)),()=>{B()}),[u,F,B]);const C=i=>i?new Date(i).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",$=(i,L)=>N(i,L);if(w)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(es,{})});if(A)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:A})});if(!a)return e.jsx("div",{className:"max-w-2xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Obligation not found.")})});const I=a.payoutStatus==="paid",S=Ne(a);return e.jsxs("div",{className:"max-w-2xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!r&&e.jsx(f,{variant:"ghost",size:"icon",onClick:()=>b("/obligations"),"aria-label":s("Back"),children:e.jsx(xs,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Obligation #",a.id]}),e.jsxs("p",{className:"text-muted-foreground",children:["Created ",C(a.dateCreated)]})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:S?"status-badge status-yellow":ge[a.status],children:S?s("Held for review"):n[a.status]}),e.jsx(ve,{sourceType:"obligation",sourceId:a.id,contextLabel:`obligation #${a.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[S&&e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-100",role:"status",children:[e.jsx("p",{className:"font-medium",children:s("Held for review")}),e.jsx("p",{className:"mt-1",children:s(us(a.holdReason))}),a.conversionId?e.jsx("p",{className:"mt-2",children:e.jsxs(v,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline",children:[s("Review conversion")," #",a.conversionId]})}):null]}),(a.supersededBy||a.supersedes&&a.supersedes.length>0)&&e.jsxs(P,{"data-testid":"obligation-supersession",children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Replacement")}),e.jsx(R,{children:s("Siren recalculated this reward after its sale changed")})]}),e.jsx(D,{children:e.jsxs("dl",{className:"space-y-3",children:[a.supersededBy&&e.jsxs("div",{children:[e.jsxs("dt",{className:"text-sm text-muted-foreground",children:[s(je[a.supersededBy.reason]??"The sale changed"),e.jsx(fe,{reason:a.supersededBy.reason,reference:a.supersededBy.changeReference})]}),e.jsx("dd",{className:"mt-1",children:a.supersededBy.obligationId?e.jsxs(e.Fragment,{children:[s("Replaced by")," ",e.jsxs(v,{to:`/obligations/${a.supersededBy.obligationId}`,className:"text-primary hover:underline",children:[s("obligation")," #",a.supersededBy.obligationId]})]}):s("Nothing replaced it, because the reward now comes to nothing.")})]}),(a.supersedes??[]).map((i,L)=>e.jsxs("div",{children:[e.jsxs("dt",{className:"text-sm text-muted-foreground",children:[s(je[i.reason]??"The sale changed"),e.jsx(fe,{reason:i.reason,reference:i.changeReference})]}),e.jsx("dd",{className:"mt-1",children:i.obligationId?e.jsxs(e.Fragment,{children:[s("Replaces")," ",e.jsxs(v,{to:`/obligations/${i.obligationId}`,className:"text-primary hover:underline",children:[s("obligation")," #",i.obligationId]})]}):s("Replaces an earlier obligation.")})]},(i.obligationId??0)+"-"+L))]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Reward Details")}),e.jsx(R,{children:s("The amount owed to the collaborator")})]}),e.jsx(D,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Value")}),e.jsx("dd",{className:"text-2xl font-semibold mt-1",children:$(a.value,a.awardType)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"mt-1",children:e.jsx("span",{className:S?"status-badge status-yellow":ge[a.status],children:S?s("Held for review"):n[a.status]})})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Currency")}),e.jsx("dd",{className:"text-sm mt-1",children:d(a.awardType)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Created")}),e.jsx("dd",{className:"text-sm mt-1",children:C(a.dateCreated)})]})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Collaborator")}),e.jsx(R,{children:s("Who earned this reward")})]}),e.jsx(D,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:U(a.collaboratorName,"collaborator",s)}),a.collaboratorEmail&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a.collaboratorEmail})]}),xe(a.collaboratorName)&&e.jsx(f,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(v,{to:`/collaborators/${a.collaboratorId}/view`,children:s("View Profile")})})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Conversion Source")}),e.jsx(R,{children:s("The activity that triggered this reward")})]}),e.jsx(D,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion ID")}),e.jsx("dd",{children:e.jsxs(v,{to:`/conversions/${a.conversionId}`,className:"text-primary hover:underline font-mono",children:["#",a.conversionId]})})]}),a.conversionType&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Type")}),e.jsx("dd",{children:fs[a.conversionType]||a.conversionType})]}),a.conversionAmount!==void 0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion Amount")}),e.jsx("dd",{className:"font-medium",children:$(a.conversionAmount)})]}),a.conversionDate&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Conversion Date")}),e.jsx("dd",{children:C(a.conversionDate)})]})]})})]}),e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Program")}),e.jsx(R,{children:s("The program that generated this obligation")})]}),e.jsx(D,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"font-medium",children:U(a.programName,"program",s)}),xe(a.programName)&&e.jsx(f,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(v,{to:`/programs/${a.programId}/view`,children:s("View Program")})})]})})]}),a.payoutId&&e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(k,{children:s("Fulfillment")}),e.jsx(R,{children:s(I?"This obligation has been paid":"This obligation is in a payout that has not been paid yet")})]}),e.jsx(D,{children:e.jsxs("dl",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payout ID")}),e.jsxs("dd",{className:"font-mono",children:["#",a.payoutId]})]}),a.fulfillmentId&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Fulfillment")}),e.jsx("dd",{children:e.jsxs(v,{to:`/fulfillments/${a.fulfillmentId}`,className:"text-primary hover:underline font-mono",children:["#",a.fulfillmentId]})})]}),a.payoutStatus&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payout Status")}),e.jsx("dd",{children:s(I?"Paid":"Unpaid")})]}),a.payoutMethod&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Payment Method")}),e.jsx("dd",{children:ys[a.payoutMethod]||a.payoutMethod})]}),a.payoutDate&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:s("Paid On")}),e.jsx("dd",{children:C(a.payoutDate)})]})]})})]})]})]})}window.sirenConfig&&ss({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const be=document.getElementById("siren-obligations");be&&ts.createRoot(be).render(e.jsx(l.StrictMode,{children:e.jsxs(hs,{defaultRoute:"/obligations",children:[e.jsx(as,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(rs,{children:[e.jsx(J,{path:"/obligations",element:e.jsx(pe,{})}),e.jsx(J,{path:"/obligations/:id",element:e.jsx(vs,{})}),e.jsx(J,{index:!0,element:e.jsx(pe,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/programs.js

    r3775642 r3788740  
    1 import{c as Vt,u as xe,w as Qe,r as d,j as e,N as we,D as gt,h as xt,i as ft,k as vt,l as yt,a as qt,b as xn,L as pe,B as F,I as he,S as De,d as Me,e as Oe,f as Ge,g as S,O as fn,P as vn,A as yn,Q as jn,t as ks,y as A,M as re,C as K,p as J,q as Q,s as Z,o as Ut,J as Gt,K as jt,m as Bt,n as As,U as ys,x as ge,V as bn,v as Cn,E as Nn,F as Tn,T as In,R as Pn,G as Pe}from"./shared/wordpress-admin-DNnGQGoM.js";import{u as _t,P as Fs,D as wn,p as Sn,S as kn,b as Ls,a as An}from"./shared/useStagedMembership-C1sNy_D6.js";import{F as Rt,H as G,a as Fn,B as Ln,D as pt,P as En}from"./shared/HelpTooltip-DsFyDQG4.js";import{A as Es}from"./shared/ActivityDrawer-iYDgZTH3.js";import{u as Rn,A as Dn,I as Mn,i as Rs,a as On,P as Ds,R as Gn,b as Bn,c as Wn}from"./shared/RecipeDetailScreen-DcUFdtvj.js";import{u as $n}from"./shared/registries-Ql2SZeKd.js";import{C as Vn}from"./shared/clock-MPHmQLgH.js";import{S as Wt}from"./shared/sparkles-ZTBJ8zt0.js";import{P as qn}from"./shared/plus-xgV5QLEC.js";import{S as Un,W as _n}from"./shared/WordPressRouter-ifxiIFvs.js";import{c as Hn}from"./shared/react-zvEYxxW2.js";import{u as Ms,A as le,g as Ce,v as zn,h as Yn,w as Xn,r as js,m as bs}from"./shared/validation-f7jbdrjp.js";import{H as Kn}from"./shared/HelpDrawer-CQSl1exo.js";import{F as Ne}from"./shared/form-field-Dbux2jvw.js";import{p as Jn}from"./shared/plan-upgrade-notice-D9kRnx4x.js";import{p as Qn,a as $t}from"./shared/properties-Cx8gxvGK.js";import{T as Zn}from"./shared/triangle-alert-B1idIoet.js";import{u as er}from"./shared/conversions-HMIw6T3R.js";import{u as tr}from"./shared/engagements-BdjHp3Bf.js";import{l as Cs}from"./shared/linked-record-D4sO5j3k.js";import{u as sr}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{A as nr}from"./shared/arrow-left-W0B3m2vw.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/link-2-CR4ULk7z.js";import"./shared/gift-Bbpi-vg_.js";import"./shared/markdown-renderer-s6F8PPyM.js";import"./shared/trending-up-B12dlnRi.js";import"./shared/collaborators-BvingK76.js";/**
     1import{c as _t,u as pe,a as rt,r as m,j as e,N as ke,D as yt,i as jt,k as bt,l as Ct,m as Nt,b as Ht,d as vn,L as de,B as E,I as me,S as We,e as $e,f as Ve,g as qe,h as S,O as yn,P as jn,A as bn,Q as Cn,v as Rs,y as F,M as ee,C as z,q as Y,s as X,t as K,p as zt,J as $t,K as Tt,n as Vt,o as Ds,U as Cs,x as ue,V as Nn,w as Tn,E as Pn,F as In,T as wn,R as Sn,G as Se}from"./shared/wordpress-admin-D_eccjaB.js";import{u as Yt,P as Ms,D as kn,S as An,b as Os,a as Ln}from"./shared/useStagedMembership-pDKVh3Wd.js";import{F as Ot,u as Fn,H as G,a as En,B as Rn,D as ft,P as Dn}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as Gs}from"./shared/ActivityDrawer-BZxDAdLe.js";import{p as Ns}from"./shared/CsvImport-Dumku5_r.js";import{u as Mn,A as On,I as Gn,i as Bs,a as Bn,P as Ws,R as Wn,b as $n,c as Vn}from"./shared/RecipeDetailScreen-CEcAya7w.js";import{u as qn}from"./shared/registries-CatPSk3G.js";import{C as Un}from"./shared/clock-3iWagaOq.js";import{S as qt}from"./shared/sparkles-Cs-c5bLd.js";import{P as _n}from"./shared/plus-8fF9_2v-.js";import{S as Hn,W as zn}from"./shared/WordPressRouter-CAYzko7X.js";import{c as Yn}from"./shared/react-Rq6nbqOn.js";import{u as $s,A as ie,g as Ce,v as Xn,h as Kn,w as Jn,r as Ts,m as Ps}from"./shared/validation-D6cKTXRt.js";import{H as Qn}from"./shared/HelpDrawer-BOa5Le1J.js";import{F as Ne}from"./shared/form-field-CrfWqu5t.js";import{p as Zn}from"./shared/plan-upgrade-notice-D9kRnx4x.js";import{p as er,a as Ut}from"./shared/properties-ByxWotcN.js";import{T as tr}from"./shared/triangle-alert-BXQaBsm-.js";import{u as sr}from"./shared/conversions-D67NHe2F.js";import{u as nr}from"./shared/engagements-6JbMv8n_.js";import{l as Is}from"./shared/linked-record-D4sO5j3k.js";import{u as rr}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{c as ar}from"./shared/collaboratorDisplayName-DvmzsaZc.js";import{A as ir}from"./shared/arrow-left-XvsxLAWy.js";import"./shared/request-sequence-CQbIQ_gd.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/BulkPickerModal-DpL-mI_R.js";import"./shared/upload-ZoYz9lGb.js";import"./shared/collaborator-groups-BP0hAJf8.js";import"./shared/conversion.schema-BXGiWhtb.js";import"./shared/clipboard-Ch4rpUJU.js";import"./shared/link-2-C4uE2qWf.js";import"./shared/gift-Bz0xaFMj.js";import"./shared/markdown-renderer-1IfYWwRA.js";import"./shared/trending-up-Cg5-4LxH.js";/**
    22 * @license lucide-react v0.469.0 - ISC
    33 *
    44 * This source code is licensed under the ISC license.
    55 * See the LICENSE file in the root directory of this source tree.
    6  */const rr=Vt("Bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);/**
     6 */const or=_t("Bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);/**
    77 * @license lucide-react v0.469.0 - ISC
    88 *
    99 * This source code is licensed under the ISC license.
    1010 * See the LICENSE file in the root directory of this source tree.
    11  */const ar=Vt("Library",[["path",{d:"m16 6 4 14",key:"ji33uf"}],["path",{d:"M12 6v14",key:"1n7gus"}],["path",{d:"M8 8v12",key:"1gg7y9"}],["path",{d:"M4 4v16",key:"6qkkli"}]]);/**
     11 */const lr=_t("Library",[["path",{d:"m16 6 4 14",key:"ji33uf"}],["path",{d:"M12 6v14",key:"1n7gus"}],["path",{d:"M8 8v12",key:"1gg7y9"}],["path",{d:"M4 4v16",key:"6qkkli"}]]);/**
    1212 * @license lucide-react v0.469.0 - ISC
    1313 *
    1414 * This source code is licensed under the ISC license.
    1515 * See the LICENSE file in the root directory of this source tree.
    16  */const ir=Vt("WandSparkles",[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]]);function Os({kind:n,onBlank:s,onBrowse:u}){const{translate:h}=xe(),{status:v,recipes:p,load:C}=Rn(),{isWordPress:g}=Qe();d.useEffect(()=>{v==="idle"&&C({isWordPress:g})},[v,C,g]);const a=h(n==="distributors"?"distributor":"program"),x=p.length;return e.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[e.jsx(Dt,{icon:ir,title:h("Start from scratch"),description:`${h("Build a custom")} ${a} ${h("from a blank canvas. You control every rule.")}`,onClick:s}),e.jsx(Dt,{icon:ar,title:h("Browse ready-made recipes"),description:x>0?`${x} ${h("proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.")}`:h("Proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later."),cta:h("Browse recipes"),onClick:u}),e.jsx(Dt,{icon:rr,title:h("Describe what you want"),description:h("Tell Beacon in plain language and let your AI draft a custom recipe you review and apply like any other."),comingSoon:!0})]})}function Dt({icon:n,title:s,description:u,cta:h,onClick:v,comingSoon:p}){const{translate:C}=xe();return p?e.jsxs("div",{"aria-disabled":"true",className:"flex cursor-not-allowed flex-col rounded-xl border border-dashed bg-card p-6 text-left opacity-70",children:[e.jsx("span",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-muted text-muted-foreground",children:e.jsx(n,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-base font-medium text-muted-foreground",children:s}),e.jsxs("span",{className:"inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-dashed border-amber-400/40 bg-amber-400/[0.07] px-2 py-0.5 text-[0.7rem] font-medium text-amber-400",children:[e.jsx(Vn,{className:"h-3 w-3","aria-hidden":"true"}),C("Soon")]})]}),e.jsx("p",{className:"mt-2 flex-1 text-sm leading-relaxed text-muted-foreground",children:u})]}):e.jsxs("div",{role:"button",tabIndex:0,onClick:v,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),v==null||v())},className:we("flex cursor-pointer flex-col rounded-xl border bg-card p-6 text-left transition-all","hover:-translate-y-0.5 hover:border-primary/50 hover:shadow-md","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"),children:[e.jsx("span",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(n,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx("h3",{className:"text-base font-medium",children:s}),e.jsx("p",{className:"mt-2 flex-1 text-sm leading-relaxed text-muted-foreground",children:u}),h&&e.jsxs("span",{className:"mt-4 inline-flex items-center gap-1.5 text-sm font-medium text-primary",children:[h,e.jsx(Dn,{className:"h-4 w-4","aria-hidden":"true"})]})]})}function or({open:n,onOpenChange:s,kind:u,onBlank:h,onBrowse:v}){const{translate:p}=xe(),C=u==="distributors",g=()=>s(!1);return e.jsx(gt,{open:n,onOpenChange:s,children:e.jsxs(xt,{className:"max-w-4xl",children:[e.jsxs(ft,{children:[e.jsxs(vt,{className:"flex items-center gap-2 text-lg",children:[e.jsx(Wt,{className:"h-5 w-5 text-primary","aria-hidden":"true"}),p(C?"Add a distributor":"Add an incentive program")]}),e.jsx(yt,{children:p("Two ways to a working setup in minutes. Build your own, or start from a proven recipe.")})]}),e.jsx("div",{className:"pt-2",children:e.jsx(Os,{kind:u,onBlank:()=>{g(),h()},onBrowse:()=>{g(),v()}})})]})})}function Ns(){const{translate:s}=xe(),{extensions:u}=Qe(),h=u.programsListLinks;u.currenciesPath;const v={active:s("Active"),inactive:s("Inactive"),draft:s("Draft"),deleted:s("Trashed")},p={saleFixedPerTransaction:s("Fixed per Transaction"),saleTransactionPercentage:s("Percentage of Transaction"),saleFixedPerProduct:s("Fixed per Product"),leadFixed:s("Fixed per Lead")},C={newestBindingWins:s("Newest Engagement Wins"),oldestBindingWins:s("Oldest Engagement Wins"),evenlySharedPool:s("Even Split"),performanceSharedPool:s("Performance Weighted"),EveryBindingWins:s("All Get Paid"),topScoreWins:s("Top Score Wins")},g=qt(),[a,x]=xn(),{items:P,total:j,page:b,perPage:L,totalPages:k,isLoading:ee,hasLoaded:f,isSubmitting:z,error:_,fetchList:W,delete:T,bulkActivate:w,bulkDeactivate:E,bulkDelete:ce,bulkPermanentDelete:Se,bulkRestore:de,update:fe}=_t(),[ke,Be]=d.useState([]);new Map(ke.map(c=>[c.id,c.name]));const Te=a.get("status")||"all",ve=a.get("incentiveType")||"all",Ie=a.get("resolverType")||"all",Ae=a.get("programGroupId")||"",[te,m]=d.useState(""),[R,Ze]=d.useState(""),[$,et]=d.useState(Te),[D,tt]=d.useState(ve),[M,st]=d.useState(Ie),[H,_e]=d.useState(Ae),[se,He]=d.useState(null),[ae,bt]=d.useState(10),[Y,Ct]=d.useState("name"),[r,V]=d.useState("asc"),[B,me]=d.useState(new Set),[Nt,q]=d.useState(!1),[Fe,ze]=d.useState(!1),U=$==="deleted";d.useEffect(()=>{const c=a.get("status"),X=a.get("incentiveType"),je=a.get("resolverType"),ne=a.get("programGroupId");c&&c!==$&&et(c),X&&X!==D&&tt(X),je&&je!==M&&st(je),ne!==null&&ne!==H&&_e(ne)},[a,$,D,M,H]),d.useEffect(()=>{me(new Set)},[$,D,M,H]);const We=()=>$==="all"?"active,inactive,draft":$;d.useEffect(()=>{W({page:1,perPage:ae,search:R||void 0,orderBy:Y,order:r,status:$==="all"?"active,inactive,draft":$,incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:H?parseInt(H):void 0})},[W,ae,R,Y,r,$,D,M,H]),d.useEffect(()=>{},[!1]);const nt=()=>{if(te!==R){Ze(te);return}W({page:1,perPage:ae,search:te,status:We(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:H?parseInt(H):void 0,orderBy:Y,order:r})},ye=c=>{et(c),c!=="all"?a.set("status",c):a.delete("status"),x(a)},$e=c=>{tt(c),c!=="all"?a.set("incentiveType",c):a.delete("incentiveType"),x(a)},Le=c=>{st(c),c!=="all"?a.set("resolverType",c):a.delete("resolverType"),x(a)},Ye=c=>{W({page:c,perPage:ae,search:R||void 0,status:We(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:H?parseInt(H):void 0,orderBy:Y,order:r})},rt=c=>{const X=parseInt(c);bt(X),W({page:1,perPage:X,search:R||void 0,status:We(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:H?parseInt(H):void 0,orderBy:Y,order:r})},Tt=c=>{const X=Y===c&&r==="asc"?"desc":"asc";Ct(c),V(X)},Ve=(c,X)=>{const je={};return c.engagementTypes&&c.engagementTypes.forEach(ne=>{je[ne.type]={calculationType:ne.calculationType??"fixed",calculationArgs:ne.calculationArgs??{}}}),{name:c.name,description:c.description||"",status:X,incentiveType:c.incentiveType,incentiveResolverType:c.incentiveResolverType,units:c.units,programGroupId:c.programGroupId,expirationDays:c.expirationDays,engagementTypes:je,transactionCompilers:c.transactionCompilers,incentiveConfig:c.incentiveConfig,lineItemFilters:c.lineItemFilters}},at=async(c,X)=>{await fe(c.id,Ve(c,X))},Xe=async()=>{if(se){if(se.status==="deleted"||U){await Se([se.id]);return}await T(se.id)}},It=P.filter(c=>B.has(c.id)).map(c=>c.name),Ht=c=>{g(`/programs/${c.id}`)},zt=async()=>{await w(Array.from(B)),me(new Set)},Yt=async()=>{await E(Array.from(B)),me(new Set)},it=async()=>{await ce(Array.from(B)),me(new Set)},Pt=async()=>{await de(Array.from(B)),me(new Set)},Ke=async()=>{await Se(Array.from(B)),me(new Set)},ot=[{id:"name",header:s("Name"),sortable:!0,cell:c=>e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:c.name}),e.jsx("div",{className:"text-sm text-muted-foreground truncate max-w-xs",children:c.description})]})},{id:"resolverType",header:s("Attribution Model"),cell:c=>e.jsx(Rt,{filterKey:"resolverType",filterValue:c.incentiveResolverType,children:C[c.incentiveResolverType]||c.incentiveResolverType})},{id:"incentiveType",header:s("Incentive Type"),cell:c=>e.jsx(Rt,{filterKey:"incentiveType",filterValue:c.incentiveType,children:p[c.incentiveType]||c.incentiveType})},{id:"units",header:s("Currency"),cell:c=>e.jsx("span",{className:"font-mono text-sm text-muted-foreground",children:c.units})},{id:"collaboratorCount",header:s("Collaborators"),cell:c=>e.jsx(pe,{to:`/collaborators?programId=${c.id}`,className:"text-primary hover:underline",children:c.collaboratorCount??0})},{id:"engagementsCount",header:s("Engagements"),cell:c=>e.jsx("span",{className:"text-muted-foreground",children:c.engagementsCount??0})},{id:"status",header:s("Status"),sortable:!0,cell:c=>e.jsx(Rt,{filterKey:"status",filterValue:c.status,children:e.jsx(Fs,{status:c.status})})},...U?[{id:"actions",header:s("Actions"),cell:c=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{variant:"outline",size:"sm",onClick:()=>at(c,"inactive"),children:s("Restore")}),e.jsx(F,{variant:"destructive",size:"sm",onClick:()=>He(c),children:s("Delete Permanently")})]})}]:[]],wt=U?[{label:s("Restore (Inactive)"),onClick:Pt},{label:s("Delete Permanently"),onClick:Ke,variant:"destructive",confirmMessage:s("Permanently delete selected programs? This action cannot be undone."),confirmItems:It}]:[{label:s("Activate"),onClick:zt},{label:s("Deactivate"),onClick:Yt},{label:s("Delete"),onClick:it,variant:"destructive",confirmMessage:s("Delete selected programs? You can undo from Trash."),confirmItems:It}],St=c=>{_e(c),a.delete("programGroupId"),x(a)},Xt=[{key:"status",label:s("Status"),value:$,displayValue:v[$]||$,onRemove:()=>ye("all")},{key:"incentiveType",label:s("Incentive Type"),value:D,displayValue:p[D]||D,onRemove:()=>$e("all")},{key:"resolverType",label:s("Attribution Model"),value:M,displayValue:C[M]||M,onRemove:()=>Le("all")}],Kt=()=>{ye("all"),$e("all"),Le("all"),St("")},Jt=te.trim()!==""||R.trim()!==""||$!=="all"||D!=="all"||M!=="all"||H!=="",Qt=f&&!ee&&!_&&P.length===0&&!Jt;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Programs"),e.jsx(G,{topic:"what-is-program",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Es,{sourceType:"program",contextLabel:"all programs"}),h&&e.jsx(h,{}),e.jsxs(F,{variant:"ghost",disabled:!0,className:"opacity-60",children:[e.jsx(Wt,{className:"h-4 w-4 mr-2"}),s("Manage Currencies"),e.jsx("span",{className:"ml-1.5 text-[10px] font-normal px-1.5 py-0.5 rounded bg-primary/10 text-primary",children:"Essentials"})]}),e.jsxs(F,{onClick:()=>ze(!0),children:[e.jsx(qn,{className:"h-4 w-4"}),s("Add Program")]})]})]}),e.jsx(or,{open:Fe,onOpenChange:ze,kind:"programs",onBlank:()=>g("/programs/new"),onBrowse:()=>g("/recipes/browse")}),Qt?e.jsxs("div",{className:"animate-in fade-in duration-300",children:[e.jsxs("div",{className:"mb-1.5 flex items-center gap-3",children:[e.jsx("span",{className:"flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(Wt,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx("h2",{className:"text-lg font-medium",children:s("No programs yet")})]}),e.jsx("p",{className:"mb-6 max-w-xl text-sm leading-relaxed text-muted-foreground",children:s("The fastest way to launch your first incentive program is to start from a recipe. A recipe is a ready-made setup. You apply it in one step, then fine-tune it.")}),e.jsx(Os,{kind:"programs",onBlank:()=>g("/programs/new"),onBrowse:()=>g("/recipes/browse")})]}):e.jsxs(e.Fragment,{children:[e.jsx(Fn,{filters:Xt,onClearAll:Kt}),_&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:_}),e.jsxs("div",{className:"flex gap-2 mb-4 flex-wrap",children:[e.jsxs("div",{className:"relative flex-1 max-w-sm",children:[e.jsx(Un,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(he,{placeholder:s("Search programs..."),value:te,onChange:c=>m(c.target.value),onKeyDown:c=>c.key==="Enter"&&nt(),className:"pl-9"})]}),e.jsxs(De,{value:$,onValueChange:ye,children:[e.jsx(Me,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(Oe,{placeholder:s("Status")})}),e.jsxs(Ge,{children:[e.jsx(S,{value:"all",children:s("All Statuses")}),e.jsx(S,{value:"active",children:s("Active")}),e.jsx(S,{value:"inactive",children:s("Inactive")}),e.jsx(S,{value:"draft",children:s("Draft")}),e.jsx(S,{value:"deleted",children:s("Trashed")})]})]}),e.jsxs(De,{value:D,onValueChange:$e,children:[e.jsx(Me,{"aria-label":s("Filter by incentive Type"),className:"w-[180px]",children:e.jsx(Oe,{placeholder:s("Incentive Type")})}),e.jsxs(Ge,{children:[e.jsx(S,{value:"all",children:s("All Incentive Types")}),e.jsx(S,{value:"saleFixedPerTransaction",children:s("Fixed per Transaction")}),e.jsx(S,{value:"saleTransactionPercentage",children:s("Percentage of Transaction")}),e.jsx(S,{value:"saleFixedPerProduct",children:s("Fixed per Product")}),e.jsx(S,{value:"leadFixed",children:s("Fixed per Lead")})]})]}),e.jsxs(De,{value:M,onValueChange:Le,children:[e.jsx(Me,{"aria-label":s("Filter by attribution model"),className:"w-[180px]",children:e.jsx(Oe,{placeholder:s("Attribution Model")})}),e.jsxs(Ge,{children:[e.jsx(S,{value:"all",children:s("All Attribution Models")}),e.jsx(S,{value:"newestBindingWins",children:s("Newest Engagement Wins")}),e.jsx(S,{value:"oldestBindingWins",children:s("Oldest Engagement Wins")}),e.jsx(S,{value:"evenlySharedPool",children:s("Even Split")}),e.jsx(S,{value:"performanceSharedPool",children:s("Performance Weighted")}),e.jsx(S,{value:"EveryBindingWins",children:s("All Get Paid")}),e.jsx(S,{value:"topScoreWins",children:s("Top Score Wins")})]})]}),e.jsx(F,{variant:"secondary",onClick:nt,children:s("Search")})]}),e.jsx(Ln,{selectedCount:B.size,actions:wt,onClear:()=>me(new Set),isProcessing:z}),e.jsx(pt,{columns:ot,data:P,isLoading:ee,emptyMessage:s("No programs found."),selectable:!0,selectedIds:B,onSelectionChange:me,getRowHref:c=>`/programs/${c.id}/view`,onEdit:U?void 0:Ht,onDelete:U?void 0:c=>He(c),sortField:Y,sortOrder:r,onSort:Tt}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",j===0?0:(b-1)*L+1," to ",Math.min(b*L,j)," of"," ",j," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(De,{value:ae.toString(),onValueChange:rt,children:[e.jsx(Me,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(Oe,{})}),e.jsxs(Ge,{children:[e.jsx(S,{value:"10",children:"10"}),e.jsx(S,{value:"25",children:"25"}),e.jsx(S,{value:"50",children:"50"}),e.jsx(S,{value:"100",children:"100"})]})]})]})]}),k>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{variant:"outline",size:"sm",disabled:b===1,onClick:()=>Ye(b-1),children:s("Previous")}),e.jsx(F,{variant:"outline",size:"sm",disabled:b===k,onClick:()=>Ye(b+1),children:s("Next")})]}),e.jsx(F,{variant:"link",className:"text-sm",onClick:()=>ye(U?"all":"deleted"),children:s(U?"Back to active programs":"Trash")})]})]}),!1,e.jsx(wn,{open:!!se,onClose:()=>He(null),noun:s("program"),name:(se==null?void 0:se.name)||"",permanent:U,title:s(U?"Delete Permanently":"Delete Program"),onConfirm:Xe,loadBlockers:se?()=>Sn.deletionBlockers(se.id):void 0})]})}function lr(n){var h;if(!n)return;const s=document.getElementById(n);if(!s)return;(h=s.scrollIntoView)==null||h.call(s,{behavior:"smooth",block:"center"});const u=s.matches("input,select,textarea,button,[tabindex]")?s:s.querySelector('input,select,textarea,button,[role="checkbox"],[role="radio"]');u==null||u.focus({preventScroll:!0})}function cr({id:n,requirements:s,intro:u,className:h}){return s.length===0?null:e.jsxs("div",{id:n,role:"status","data-testid":"form-requirements",className:we("rounded-md border border-dashed bg-muted/40 px-3 py-2 text-sm",h),children:[e.jsx("p",{className:"font-medium",children:u}),e.jsx("ul",{className:"mt-1 list-disc space-y-0.5 pl-5",children:s.map(v=>e.jsx("li",{"data-requirement":v.key,children:v.targetId?e.jsx("button",{type:"button",className:"text-left underline decoration-dotted underline-offset-2 hover:text-primary",onClick:()=>lr(v.targetId),children:v.message}):v.message},v.key))})]})}function dr(n){return n.filter(([s])=>!s).map(([,s])=>s)}function mr(n){var u;const s=(u=n.label)==null?void 0:u.trim();return!s||s===n.code?n.code:`${n.code} - ${s}`}const ht=d.forwardRef(({value:n,onChange:s,definition:u,className:h,disabled:v,...p},C)=>{var j;const g=((j=u==null?void 0:u.symbol)==null?void 0:j.trim())||(u==null?void 0:u.code)||"",a=(u==null?void 0:u.symbolPosition)==="after",x=fn(u),P=n==null||!u?"":vn(n,u);return e.jsxs("div",{className:"relative",children:[g&&e.jsx("span",{"data-testid":"amount-input-symbol","data-position":a?"after":"before",className:we("absolute top-1/2 -translate-y-1/2 text-muted-foreground text-sm pointer-events-none select-none",a?"right-8":"left-2.5"),children:g}),e.jsx(he,{ref:C,type:"number",inputMode:x===0?"numeric":"decimal",step:jn(u),value:P,disabled:v||!u,onChange:b=>s(yn(parseFloat(b.target.value)||0,u)),className:h,style:a?void 0:{paddingLeft:`${Math.max(1.1,.55+g.length*.6)}rem`},...p})]})});ht.displayName="AmountInput";const ur=Hn((n,s)=>({options:[],isLoading:!1,hasLoaded:!1,error:null,fetch:async()=>{if(!(s().isLoading||s().hasLoaded)){n({isLoading:!0,error:null});try{const u=await ks.get("/engagements/calculations");n({options:u.options??[],isLoading:!1,hasLoaded:!0})}catch(u){n({error:u instanceof Error?u.message:"Failed to fetch engagement calculations",isLoading:!1})}}}}));function pr(n){return n.replace(/([A-Z])/g," $1").replace(/^./,s=>s.toUpperCase()).trim()}function hr({options:n,value:s,args:u,onChangeStrategy:h,onChangeArg:v,idPrefix:p="calc-strategy",label:C,helpTopic:g,helpTopicByArg:a,onHelpLearnMore:x,disabled:P=!1}){const j=n.find(b=>b.id===s);return d.useEffect(()=>{!s&&n.length>0&&h(n[0].id)},[s,n,h]),n.length===0?null:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[C&&e.jsxs(A,{htmlFor:`${p}-select`,className:"text-sm font-medium flex items-center",children:[C,g&&e.jsx(G,{topic:g,side:"right",onLearnMore:x})]}),e.jsxs(De,{value:s,onValueChange:h,disabled:P,children:[e.jsx(Me,{id:`${p}-select`,className:"w-full max-w-xs",children:e.jsx(Oe,{})}),e.jsx(Ge,{children:n.map(b=>e.jsx(S,{value:b.id,children:b.name},b.id))})]}),(j==null?void 0:j.description)&&e.jsx("p",{className:"text-xs text-muted-foreground",children:j.description})]}),j&&j.requiredArgs.length>0&&e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:j.requiredArgs.map(b=>{const L=a==null?void 0:a[b];return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(A,{htmlFor:`${p}-arg-${b}`,className:"text-sm font-medium flex items-center",children:[pr(b),L&&e.jsx(G,{topic:L,side:"right",onLearnMore:x})]}),e.jsx(he,{id:`${p}-arg-${b}`,type:"number",value:u[b]??"",onChange:k=>v(b,k.target.value===""?"":Number(k.target.value)),disabled:P})]},b)})})]})}function gr({options:n,enabled:s,onToggle:u,renderLineItemOptions:h,onLearnMore:v}){return e.jsx("div",{className:"space-y-4",children:n.map(p=>{const C=s[p.id],g=!!p.description;return p.id==="includeLineItems"&&h?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:p.id,checked:C,onCheckedChange:x=>u(p.id,x===!0)}),e.jsxs(A,{htmlFor:p.id,className:"font-normal flex items-center",children:[p.label,p.helpTopic&&e.jsx(G,{topic:p.helpTopic,side:"right",onLearnMore:v})]})]}),C&&e.jsx("div",{className:"ml-6 pl-4 border-l space-y-3",children:h()})]},p.id):e.jsxs("div",{className:g?"flex items-start space-x-2":"flex items-center space-x-2",children:[e.jsx(re,{id:p.id,checked:C,onCheckedChange:x=>u(p.id,x===!0)}),e.jsxs("div",{className:g?"grid gap-0.5 leading-none":"",children:[e.jsxs(A,{htmlFor:p.id,className:"font-normal flex items-center",children:[p.label,p.helpTopic&&e.jsx(G,{topic:p.helpTopic,side:"right",onLearnMore:v})]}),p.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:p.description})]})]},p.id)})})}function xr({options:n,selected:s,onChange:u,loading:h=!1,emptyText:v="No actions are available on your plan.",idPrefix:p="action"}){if(h)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"});if(n.length===0)return e.jsx("p",{className:"text-sm text-muted-foreground",children:v});const C=(g,a)=>{a?s.includes(g)||u([...s,g]):u(s.filter(x=>x!==g))};return e.jsx("div",{className:"space-y-3",children:n.map(g=>{const a=`${p}-${g.id}`;return e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(re,{id:a,checked:s.includes(g.id),onCheckedChange:x=>C(g.id,x===!0)}),e.jsxs("div",{className:"flex-1 space-y-0.5",children:[e.jsx(A,{htmlFor:a,className:"font-normal",children:g.name}),g.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:g.description})]})]},g.id)})})}function Gs(n=!0){const[s,u]=d.useState(null),[h,v]=d.useState(null);return d.useEffect(()=>{if(!n)return;let p=!1;return Qn.list().then(C=>{p||u(C)}).catch(C=>{p||v(C instanceof Error?C.message:"Failed to load the properties.")}),()=>{p=!0}},[n]),{properties:s,error:h}}const ut=10;function fr({draft:n}){const{translate:s}=xe(),{properties:u,saved:h,error:v,reach:p,setReach:C,staged:g,finalIds:a}=n,[x,P]=d.useState(""),[j,b]=d.useState(1),[L,k]=d.useState(null),ee=h??[],f=(u??[]).filter(T=>ee.includes(T.id)),z=(u??[]).filter(T=>{const w=x.trim().toLowerCase();return w===""||`${T.name} ${T.siteUrl}`.toLowerCase().includes(w)}),_={...g,stageRemove:T=>{a.filter(E=>!T.includes(E)).length===0?k(T):g.stageRemove(T)}},W=[{id:"name",header:s("Name"),cell:T=>T.name},{id:"siteUrl",header:s("Site URL"),cell:T=>e.jsx("span",{className:"break-all text-muted-foreground",children:T.siteUrl})}];return v?e.jsxs(K,{"data-testid":"program-properties",children:[e.jsx(J,{children:e.jsx(Q,{children:s("Where does it run?")})}),e.jsx(Z,{children:e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:v})})]}):u===null||h===void 0?e.jsxs(K,{"data-testid":"program-properties",children:[e.jsx(J,{children:e.jsx(Q,{children:s("Where does it run?")})}),e.jsx(Z,{children:e.jsx(Ut,{})})]}):e.jsxs(K,{"data-testid":"program-properties",children:[e.jsx(J,{children:e.jsxs(Q,{className:"inline-flex items-center",children:[s("Where does it run?"),e.jsx(G,{topic:"program-properties",side:"right"})]})}),e.jsxs(Z,{className:"space-y-3",children:[e.jsxs(Gt,{value:p,onValueChange:T=>C(T),"aria-label":s("Where this program runs"),children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(jt,{value:"every",id:"program-reach-every",className:"mt-0.5"}),e.jsx(A,{htmlFor:"program-reach-every",className:"font-normal leading-tight",children:e.jsx("span",{className:"font-medium",children:s("Runs on every property")})})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(jt,{value:"chosen",id:"program-reach-chosen",className:"mt-0.5"}),e.jsx(A,{htmlFor:"program-reach-chosen",className:"font-normal leading-tight",children:e.jsx("span",{className:"font-medium",children:s("Runs on the properties you choose")})})]})]}),p==="chosen"?e.jsx(kn,{title:s("Properties"),currentItems:f,currentColumns:W,emptyCurrentMessage:s("No property chosen yet. Click Add properties to choose some."),getCurrentStagingId:T=>T.id,staged:_,pendingAdditionColumns:W,getCandidateStagingId:T=>T.id,pickerTitle:s("Add properties to this program"),pickerDescription:s("Search and select properties. Selections are staged. Click Update to save."),pickerCandidates:z.slice((j-1)*ut,j*ut),pickerColumns:W,pickerPagination:{page:j,perPage:ut,total:z.length,totalPages:Math.max(1,Math.ceil(z.length/ut))},onPickerParamsChange:({search:T,page:w})=>{P(T),b(w)},onOpenPicker:()=>{P(""),b(1)},addButtonLabel:s("Add properties")}):null]}),e.jsx(gt,{open:L!==null,onOpenChange:T=>!T&&k(null),children:e.jsxs(xt,{children:[e.jsxs(ft,{children:[e.jsx(vt,{children:s("Run this program on every property?")}),e.jsx(yt,{children:s("Taking off its last property makes it run on every property, including ones you add later. To stop it instead, set its status to Inactive.")})]}),e.jsxs(Bt,{children:[e.jsx(F,{type:"button",variant:"outline",onClick:()=>k(null),children:s("Cancel")}),e.jsx(F,{type:"button",onClick:()=>{L&&g.stageRemove(L),C("every"),k(null)},children:s("Run on every property")})]})]})})]})}function vr({programId:n}){const{translate:s}=xe(),{properties:u,error:h}=Gs(),[v,p]=d.useState(void 0),[C,g]=d.useState(null);return d.useEffect(()=>{let x=!1;return $t.get(n).then(P=>{x||p(P)}).catch(P=>{x||g(P instanceof Error?P.message:s("Failed to load where this program runs."))}),()=>{x=!0}},[n,s]),C??h?e.jsx("span",{className:"text-sm text-destructive",role:"alert",children:s("Could not load where this program runs.")}):v===void 0||u===null?e.jsx("span",{className:"text-muted-foreground",children:"…"}):v===null||v.length===0?e.jsx("span",{"data-testid":"program-properties-summary",children:s("Every property")}):e.jsx("span",{"data-testid":"program-properties-summary",children:v.map((x,P)=>{const j=u.find(b=>b.id===x);return e.jsxs("span",{children:[P>0?", ":null,j?e.jsx(pe,{to:`/properties/${x}`,className:"text-primary hover:underline",children:j.name}):s("Property #%d").replace("%d",String(x))]},x)})})}function yr(n){const{translate:s}=xe(),u=n!==void 0,{properties:h,error:v}=Gs(u),[p,C]=d.useState(n===null?null:void 0),[g,a]=d.useState(null),[x,P]=d.useState("every"),j=Ls({getCandidateStagingId:d.useCallback(w=>w.id,[])}),b=j.reset;d.useEffect(()=>{if(n==null)return;let w=!1;return $t.get(n).then(E=>{w||(C(E),P(E===null||E.length===0?"every":"chosen"))}).catch(E=>{w||a(E instanceof Error?E.message:s("Failed to load where this program runs."))}),()=>{w=!0}},[n,s]);const L=d.useMemo(()=>p??[],[p]),k=d.useMemo(()=>[...L.filter(w=>!j.pendingRemovalIds.has(w)),...j.pendingAdditions.map(w=>w.id).filter(w=>!L.includes(w))],[L,j.pendingAdditions,j.pendingRemovalIds]),ee=p==null||p.length===0?"every":"chosen",f=k.length===L.length&&k.every(w=>L.includes(w)),z=p!==void 0&&(x!==ee||x==="chosen"&&!f),_=g??(u?v:null),W=x==="chosen"&&k.length===0?s("Choose at least one property, or choose Runs on every property."):null,T=d.useCallback(async w=>{if(!u||_!==null||!z)return;const E=await $t.set(w,x==="every"?[]:k);C(E.propertyIds),P(E.propertyIds===null||E.propertyIds.length===0?"every":"chosen"),b()},[u,_,z,x,k,b]);return{properties:h,saved:p,error:_,reach:x,setReach:P,staged:j,finalIds:k,isDirty:z,problem:W,save:T}}const jr={categorySupport:()=>ks.get("/line-item-filters/categories")};let Mt=null;function br(){return Mt===null&&(Mt=jr.categorySupport().then(n=>n.available!==!1).catch(()=>!0)),Mt}function Cr(){const{isWordPress:n}=Qe(),[s,u]=d.useState(n?{available:!0,loaded:!0}:{available:!0,loaded:!1});return d.useEffect(()=>{if(n)return;let h=!0;return br().then(v=>{h&&u({available:v,loaded:!0})}),()=>{h=!1}},[n]),s}function Ts({inUse:n}){const{translate:s}=xe();return n?e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 p-3 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-200","data-testid":"category-filter-unsupported",role:"alert",children:[e.jsx(Zn,{className:"mt-0.5 h-3.5 w-3.5 flex-shrink-0"}),e.jsx("span",{children:s("None of your sales sources send product categories, so this filter matches no sale and nothing is paid. Remove it, or connect a WordPress store that sends categories.")})]}):e.jsxs("div",{className:"flex items-start gap-2 rounded-md border bg-muted/40 p-3 text-xs text-muted-foreground","data-testid":"category-filter-hidden",children:[e.jsx(Mn,{className:"mt-0.5 h-3.5 w-3.5 flex-shrink-0"}),e.jsx("span",{children:s("Category filters need sales that carry product categories, such as orders from a connected WordPress store. Stripe and Shopify orders arrive without categories, so a category filter here would pay nothing.")})]})}function Is(n){return typeof n=="string"?n:n&&typeof n=="object"&&"id"in n?String(n.id):""}const Re={referredSiteVisit:"site-visited",boundPostUsed:"blog-post-visited",collaboratorProductSold:"collaborator-product-sold",manual:"manual-attribution",collaboratorFormSubmitted:"collaborator-form-submitted",boundCouponUsed:"coupon-code-used",saleFixedPerProduct:"incentive-fixed-per-product",saleFixedPerTransaction:"incentive-fixed-per-transaction",saleTransactionPercentage:"incentive-percentage",leadFixed:"incentive-fixed-per-lead",newestBindingWins:"newest-engagement-wins",oldestBindingWins:"oldest-engagement-wins",EveryBindingWins:"every-engagement-wins",evenlySharedPool:"evenly-shared-pool",performanceSharedPool:"performance-shared-pool",topScoreWins:"top-score-wins",includeDiscounts:"account-for-discounts",includeFees:"account-for-fees",includeLineItems:"commission-on-products",includeShipping:"account-for-shipping",includeTaxes:"account-for-taxes"},Ot={name:"",description:"",status:"active",units:"",programGroupId:void 0,collaboratorGroupId:null,collaboratorIds:[],expirationDays:void 0,incentiveType:"saleTransactionPercentage",incentiveResolverType:"newestBindingWins",engagementTypes:{},transactionCompilers:{},incentiveConfig:{transactionPercent:void 0,payoutPerTransaction:void 0,payoutPerProduct:void 0,payoutPerLead:void 0,autoApprove:!1,activeConversionTypes:["sale"],leadRequalificationDays:void 0},lineItemCategories:!1,lineItemCategoryIds:"",lineItemSkus:!1,lineItemSkuList:"",lineItemTypes:!1,lineItemProductTypes:{products:!0,subscriptions:!0},lineItemCollaboratorOwned:!1,postConversionActions:[],engagementFilters:[]},Ps="bindCollaboratorToOpportunity";function ws(){var rs,as,is,os,ls,cs,ds;const{translate:s}=xe(),{planAllows:u,isWordPress:h}=Qe(),v=u("customer-suppression-filters"),p=!1,C=!1,g=u("customer-linking"),a=Cr(),{id:x}=As(),P=qt(),j=!x,b=yr(h?void 0:j?null:Number(x)),[L,k]=d.useState(null),ee=b.problem;d.useEffect(()=>{ee===null&&k(null)},[ee]);const{current:f,isLoading:z,isSubmitting:_,error:W,fetchOne:T,create:w,update:E,clearCurrent:ce,clearError:Se}=_t(),{currencies:de,engagementTypes:fe,incentiveTypes:ke,incentiveResolvers:Be,transactionCompilers:Te,conversionTypes:ve,postConversionActionTypes:Ie,engagementFilterTypes:Ae,isLoading:te,hasLoaded:m,loadingStates:R,fetchCurrencies:Ze,fetchEngagementTypes:$,fetchIncentiveTypes:et,fetchIncentiveResolvers:D,fetchTransactionCompilers:tt,fetchConversionTypes:M,fetchPostConversionActionTypes:st,fetchEngagementFilterTypes:H}=$n(),{options:_e,hasLoaded:se,fetch:He}=ur(),ae=d.useMemo(()=>Object.fromEntries(fe.map(t=>[t.id,{enabled:!1,calculationType:"fixed",calculationArgs:{value:1}}])),[fe]),bt=d.useMemo(()=>Object.fromEntries((Ae??[]).map(t=>[t.id,t.name])),[Ae]),Y=d.useMemo(()=>Object.fromEntries(Te.map(t=>[t.id,t.id==="includeLineItems"])),[Te]),Ct=d.useMemo(()=>{const t={};return ve.forEach(o=>{var l;(l=o.supportedIncentives)==null||l.forEach(i=>{t[i]||(t[i]=[]),t[i].push(o.id)})}),t},[ve]),[r,V]=d.useState(Ot),[B,me]=d.useState([]),[Nt,q]=d.useState(null),[Fe,ze]=d.useState(null),[U,We]=d.useState(null),[nt,ye]=d.useState(!1),[$e,Le]=d.useState(null),[Ye,rt]=d.useState(!1),[Tt,Ve]=d.useState(!1),[at,Xe]=d.useState(null),[It,Ht]=d.useState([]),[zt,Yt]=d.useState(!1),[it,Pt]=d.useState(!1),{items:Ke,structures:ot,fetchList:wt,fetchStructures:St}=An(),{items:Xt,total:Kt,page:Jt,perPage:Qt,totalPages:c,isLoading:X,fetchList:je}=Ms(),[ne,Zt]=d.useState("direct"),es=Ls({getCandidateStagingId:t=>t.id});d.useEffect(()=>{je({page:1,perPage:200,status:"active,inactive,pending"})},[wt,St,je]);const Bs=d.useMemo(()=>{const t=r.collaboratorGroupId?Ke.find(i=>i.id===r.collaboratorGroupId):null,o=t?ot.find(i=>i.id===t.structure):null,l=(o==null?void 0:o.providedWalkerCapabilities)??null;return _e.filter(i=>{const y=i.requiredWalkerCapabilities??[];return y.length===0||l===null?!0:y.every(N=>l.includes(N))})},[_e,Ke,ot,r.collaboratorGroupId]);d.useEffect(()=>{f&&(f.collaboratorGroupId?Zt("group"):Zt("direct"))},[f]),d.useEffect(()=>{it||(R.engagementTypes||$(),se||He(),R.incentiveTypes||et(),R.incentiveResolvers||D(),R.transactionCompilers||tt(),R.conversionTypes||M(),R.postConversionActionTypes||st(),!m&&!te&&Ze(),Pt(!0))},[it]),d.useEffect(()=>{},[!1]);const Ws=d.useMemo(()=>Object.fromEntries(ve.map(t=>[t.id,t.name])),[ve]),$s=d.useRef(new Map);d.useEffect(()=>{const t=new IntersectionObserver(l=>{if(Ye)return;let i=0,y=null;l.forEach(N=>{N.isIntersecting&&N.intersectionRatio>i&&(i=N.intersectionRatio,y=N.target.id)}),y&&We(y)},{threshold:[0,.25,.5,.75,1],rootMargin:"-20% 0px -60% 0px"});return["engagement-tracking","attribution-model","commission-calculation","incentive-structure"].forEach(l=>{const i=document.getElementById(l);i&&(t.observe(i),$s.current.set(l,i))}),()=>t.disconnect()},[Ye]);const Vs=d.useCallback(t=>{const o=document.getElementById(t);o&&(rt(!0),ze(t),We(t),o.scrollIntoView({behavior:"smooth",block:"start"}),setTimeout(()=>{rt(!1),ze(null)},1500))},[]),qs=()=>{const t=[{field:"name",validate:js("Program name is required")},{field:"name",validate:bs(le.TEXT_LENGTH,"Program name must be 255 characters or fewer")},{field:"description",validate:bs(le.TEXT_LENGTH,"Description must be 255 characters or fewer")},{field:"units",validate:js("Currency is required")}];return r.incentiveType==="saleTransactionPercentage"&&t.push({field:"incentiveConfig",validate:o=>{const l=o,i=l==null?void 0:l.transactionPercent;return i==null?"Transaction percent is required":i<le.MIN_PERCENT||i>le.MAX_PERCENT?"Percent must be between 0.01 and 100":Yn(i,2)?null:"Percent can have at most 2 decimal places"}}),r.incentiveType==="saleFixedPerTransaction"&&t.push({field:"incentiveConfig",validate:o=>{const l=o,i=l==null?void 0:l.payoutPerTransaction;return i==null||i<=0?"Payout amount must be greater than 0":i>le.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),r.incentiveType==="saleFixedPerProduct"&&t.push({field:"incentiveConfig",validate:o=>{const l=o,i=l==null?void 0:l.payoutPerProduct;return i==null||i<=0?"Payout amount must be greater than 0":i>le.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),r.incentiveType==="leadFixed"&&(t.push({field:"incentiveConfig",validate:o=>{const l=o,i=l==null?void 0:l.payoutPerLead;return i==null||i<0?"Payout amount must be 0 or greater":i>le.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),t.push({field:"incentiveConfig",validate:o=>{const l=o,i=l==null?void 0:l.leadRequalificationDays;return i!=null&&(!Number.isInteger(i)||i<0||i>le.MAX_DAYS)?"Lead re-qualification window must be a whole number of days from 0 to 3650":null}})),t.push({field:"expirationDays",validate:Xn(0,le.MAX_DAYS,"Expiration days must be a whole number from 0 to 3650")}),t};d.useEffect(()=>(Se(),x?T(parseInt(x)):(ce(),V(Ot)),()=>{ce()}),[x,T,ce,Se]),d.useEffect(()=>{j&&Object.keys(ae).length>0&&V(t=>({...t,engagementTypes:{...ae,...Object.fromEntries(Object.entries(t.engagementTypes).filter(([,o])=>o.enabled))},transactionCompilers:{...Y,...Object.fromEntries(Object.entries(t.transactionCompilers).filter(([,o])=>o))}}))},[j,ae,Y]),d.useEffect(()=>{var t,o,l,i,y,N,O,Je,Ue,I,ue,ms,us,ps,hs;if(f){const gs={};Array.isArray(f.engagementTypes)&&f.engagementTypes.forEach(oe=>{gs[oe.type]={enabled:!0,calculationType:oe.calculationType??"fixed",calculationArgs:oe.calculationArgs??{}}});const dt={};(f.transactionCompilers??[]).forEach(oe=>{let be;if(typeof oe=="string")be=oe;else if(typeof oe=="object"&&oe!==null){const Et=oe;be=Et.compiler||Et.id||Et.type}be&&(dt[be]=!0)});const mt=Object.keys(dt).length>0?!!dt.includeLineItems:!0,xs=mt&&!!((o=(t=f.lineItemFilters)==null?void 0:t.inCategories)!=null&&o.length),un=xs&&((i=(l=f.lineItemFilters)==null?void 0:l.inCategories)==null?void 0:i.join(", "))||"",fs=mt&&!!((N=(y=f.lineItemFilters)==null?void 0:y.withSkus)!=null&&N.length),pn=fs&&((Je=(O=f.lineItemFilters)==null?void 0:O.withSkus)==null?void 0:Je.join(", "))||"",vs=mt&&!!((I=(Ue=f.lineItemFilters)==null?void 0:Ue.withTypes)!=null&&I.length),hn=vs?{products:((ms=(ue=f.lineItemFilters)==null?void 0:ue.withTypes)==null?void 0:ms.includes("products"))??!0,subscriptions:((ps=(us=f.lineItemFilters)==null?void 0:us.withTypes)==null?void 0:ps.includes("subscriptions"))??!0}:{products:!0,subscriptions:!0},gn=mt&&(((hs=f.lineItemFilters)==null?void 0:hs.collaboratorOwned)??!1);V({name:f.name,description:f.description,status:f.status,units:f.units,programGroupId:f.programGroupId,collaboratorGroupId:f.collaboratorGroupId??null,collaboratorIds:f.collaboratorIds??[],expirationDays:f.expirationDays,incentiveType:Is(f.incentiveType),incentiveResolverType:Is(f.incentiveResolverType),engagementTypes:gs,transactionCompilers:dt,incentiveConfig:Rs({...Ot.incentiveConfig,...Object.fromEntries(Object.entries(f.incentiveCalculation||f.incentiveConfig||{}).filter(([oe,be])=>!(be==null||oe==="activeConversionTypes"&&Array.isArray(be)&&be.length===0)))}),lineItemCategories:xs,lineItemCategoryIds:un,lineItemSkus:fs,lineItemSkuList:pn,lineItemTypes:vs,lineItemProductTypes:hn,lineItemCollaboratorOwned:gn,postConversionActions:f.postConversionActions??[],engagementFilters:f.engagementFilters??[]})}},[f]),d.useEffect(()=>{f&&V(t=>{const o=Object.keys(t.transactionCompilers).length>0;return{...t,engagementTypes:{...ae,...t.engagementTypes},transactionCompilers:o?{...Object.fromEntries(Object.keys(Y).map(l=>[l,!1])),...t.transactionCompilers}:{...Y}}})},[f,ae,Y]);const Us=async t=>{t.preventDefault();const o=zn(r,qs());if(me(o.errors),!o.valid)return;if(!h&&b.error===null&&b.problem!==null){k(b.problem);return}k(null);const l=new Set(fe.map(I=>I.id)),i={};Object.entries(r.engagementTypes).filter(([I,ue])=>ue.enabled&&(l.size===0||l.has(I))).forEach(([I,ue])=>{i[I]={calculationType:ue.calculationType,calculationArgs:ue.calculationArgs}});const y=Object.entries(r.transactionCompilers).filter(([,I])=>I).map(([I])=>I),N=ne==="direct"?[...(r.collaboratorIds??[]).filter(I=>!es.pendingRemovalIds.has(I)),...es.pendingAdditions.map(I=>I.id)]:[],O=ne==="group"?r.collaboratorGroupId??null:null,Je={name:r.name,description:r.description,status:r.status,units:r.units,programGroupId:r.programGroupId,collaboratorGroupId:O,collaboratorIds:N,expirationDays:r.expirationDays??0,incentiveType:r.incentiveType,incentiveResolverType:r.incentiveResolverType,engagementTypes:i,transactionCompilers:y,incentiveConfig:r.incentiveConfig,lineItemFilters:r.transactionCompilers.includeLineItems?{inCategories:r.lineItemCategories&&r.lineItemCategoryIds?r.lineItemCategoryIds.split(",").map(I=>I.trim()).filter(I=>I):void 0,withSkus:r.lineItemSkus&&r.lineItemSkuList?r.lineItemSkuList.split(",").map(I=>I.trim()).filter(I=>I):void 0,withTypes:r.lineItemTypes?Object.entries(r.lineItemProductTypes).filter(([,I])=>I).map(([I])=>I):void 0,collaboratorOwned:r.lineItemCollaboratorOwned}:void 0,postConversionActions:r.postConversionActions??[],...v?{engagementFilters:r.engagementFilters??[]}:{}};let Ue;try{Ue=j?await w(Je):await E(parseInt(x),Je)}catch{return}if(!h&&b.isDirty)try{await b.save(Ue.id)}catch(I){const ue=I instanceof Error?I.message:s("Failed to save where this program runs.");k(ue),Cn.error(ue),j&&P(`/programs/${Ue.id}`,{replace:!0});return}P("/programs")},ie=(t,o)=>{V(l=>({...l,[t]:o}))},ts=(t,o,l)=>{V(i=>({...i,engagementTypes:{...i.engagementTypes,[t]:{...i.engagementTypes[t],[o]:l}}}))},_s=(t,o,l)=>{V(i=>({...i,engagementTypes:{...i.engagementTypes,[t]:{...i.engagementTypes[t],calculationArgs:{...i.engagementTypes[t].calculationArgs,[o]:l}}}}))},kt=(t,o)=>{V(l=>{const i={...l,transactionCompilers:{...l.transactionCompilers,[t]:o}};return t==="includeLineItems"&&!o&&(i.lineItemCategories=!1,i.lineItemCategoryIds="",i.lineItemSkus=!1,i.lineItemSkuList="",i.lineItemTypes=!1,i.lineItemProductTypes={products:!0,subscriptions:!0},i.lineItemCollaboratorOwned=!1),i})},At=(t,o)=>{V(l=>{const i={...l,[t]:o};if(!o)switch(t){case"lineItemCategories":i.lineItemCategoryIds="";break;case"lineItemSkus":i.lineItemSkuList="";break;case"lineItemTypes":i.lineItemProductTypes={products:!0,subscriptions:!0};break}return i})},Ee=(t,o)=>{V(l=>({...l,incentiveConfig:{...l.incentiveConfig,[t]:o}}))},Ft=()=>{var t;return e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"auto-approve",checked:(t=r.incentiveConfig)==null?void 0:t.autoApprove,onCheckedChange:o=>Ee("autoApprove",o===!0)}),e.jsx(A,{htmlFor:"auto-approve",className:"font-normal",children:"Auto Approve Completed Transactions"})]})},Hs=t=>{var y;const o=(y=r.incentiveConfig)==null?void 0:y.activeConversionTypes,l=Array.isArray(o)?o:[],i=l.includes(t)?l.filter(N=>N!==t):[...l,t];Ee("activeConversionTypes",i)},qe=f==null?void 0:f.featureSupport,zs=(qe==null?void 0:qe.recurringCommissions)!==!1,Ys=(qe==null?void 0:qe.leads)!==!1,Xs=Object.values(r.engagementTypes).some(t=>t.enabled),Ks=(Array.isArray((rs=r.incentiveConfig)==null?void 0:rs.activeConversionTypes)?r.incentiveConfig.activeConversionTypes:[]).length>0,Js=Object.values(r.transactionCompilers).some(t=>t),Qs=r.lineItemCategories&&!r.lineItemCategoryIds.trim(),Zs=r.lineItemSkus&&!r.lineItemSkuList.trim(),en=r.lineItemTypes&&!Object.values(r.lineItemProductTypes).some(t=>t),tn=Qs||Zs||en,sn=(()=>{var t,o,l,i;switch(r.incentiveType){case"saleTransactionPercentage":{const y=(t=r.incentiveConfig)==null?void 0:t.transactionPercent;return y!=null&&y>=le.MIN_PERCENT&&y<=le.MAX_PERCENT}case"saleFixedPerTransaction":{const y=(o=r.incentiveConfig)==null?void 0:o.payoutPerTransaction;return y!=null&&y>0}case"saleFixedPerProduct":{const y=(l=r.incentiveConfig)==null?void 0:l.payoutPerProduct;return y!=null&&y>0}case"leadFixed":{const y=(i=r.incentiveConfig)==null?void 0:i.payoutPerLead;return y!=null&&y>=0}default:return!0}})(),lt=d.useMemo(()=>ys(r.units,de),[r.units,de]),ss=(f==null?void 0:f.postConversionActions)??[],nn=!g&&Ie.some(t=>t.id===Ps&&!ss.includes(t.id)),rn=Ie.filter(t=>t.id!==Ps||g||ss.includes(t.id)),Lt=dr([[r.name.trim()!=="",{key:"name",message:s("Enter a name."),targetId:"name"}],[!!r.units,{key:"units",message:s("Choose a currency."),targetId:"units"}],[!(ne==="group"&&!r.collaboratorGroupId),{key:"collaboratorGroup",message:s("Choose a collaborator group, or switch to adding collaborators directly."),targetId:"collaboratorGroup"}],[Xs,{key:"engagementTypes",message:s("Choose at least one engagement type."),targetId:"engagement-tracking"}],[Js,{key:"commissionComponents",message:s("Under Commission Calculation, choose at least one part of the transaction, such as Line Items."),targetId:"commission-calculation"}],[!tn,{key:"lineItemFilters",message:s("Finish the line item filter you turned on, or turn it off."),targetId:"commission-calculation"}],[sn,{key:"commissionAmount",message:r.incentiveType==="saleTransactionPercentage"?s("Enter a commission rate from 0 to 100."):s("Enter the commission amount."),targetId:"incentive-structure"}],[Ks,{key:"conversionTypes",message:s("Choose at least one conversion type to credit."),targetId:"incentive-structure"}]]),an=_||Lt.length>0,ns=t=>{let o=Ct[t]||[];return zs||(o=o.filter(l=>l!=="renewal")),Ys||(o=o.filter(l=>l!=="lead")),o},on=t=>{const o=ns(t);V(l=>{var N;if(o.length===0)return{...l,incentiveType:t};const y=(Array.isArray((N=l.incentiveConfig)==null?void 0:N.activeConversionTypes)?l.incentiveConfig.activeConversionTypes:[]).filter(O=>o.includes(O));return{...l,incentiveType:t,incentiveConfig:{...l.incentiveConfig,activeConversionTypes:y.length>0?y:[o[0]]}}})},ct=t=>{var y;const o=ns(t);if(o.length===0)return e.jsxs("div",{className:"space-y-2",children:[e.jsx(A,{children:"Credit Conversions For..."}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No conversion types available."})]});const l=(y=r.incentiveConfig)==null?void 0:y.activeConversionTypes,i=Array.isArray(l)?l:[];return e.jsxs("div",{className:"space-y-2",children:[e.jsx(A,{children:"Credit Conversions For..."}),e.jsx("div",{className:"space-y-2",children:o.map(N=>e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:`conversion-${N}`,checked:i.includes(N),onCheckedChange:()=>Hs(N)}),e.jsx(A,{htmlFor:`conversion-${N}`,className:"font-normal",children:Ws[N]||N})]},N))})]})},ln=t=>{!t||m||te||Ze()},cn=t=>{if(t&&!r.transactionCompilers.includeTaxes){Xe(!0),Ve(!0);return}kt("includeTaxes",t)},dn=!a.available&&!r.lineItemCategories,mn=()=>e.jsxs(e.Fragment,{children:[dn?e.jsx(Ts,{inUse:!1}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"lineItemCategories",checked:r.lineItemCategories,onCheckedChange:t=>At("lineItemCategories",t===!0)}),e.jsxs(A,{htmlFor:"lineItemCategories",className:"font-normal flex items-center",children:["In all of these Categories",e.jsx(G,{topic:"filter-by-category",side:"right",onLearnMore:q})]})]}),r.lineItemCategories&&e.jsx("div",{className:"ml-6 pl-4 border-l",children:e.jsx(he,{placeholder:s("Enter category slugs (comma-separated)"),value:r.lineItemCategoryIds||"",onChange:t=>ie("lineItemCategoryIds",t.target.value)})})]}),!a.available&&r.lineItemCategories&&e.jsx(Ts,{inUse:!0}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"lineItemSkus",checked:r.lineItemSkus,onCheckedChange:t=>At("lineItemSkus",t===!0)}),e.jsxs(A,{htmlFor:"lineItemSkus",className:"font-normal flex items-center",children:["With Any of these SKUs",e.jsx(G,{topic:"filter-by-sku",side:"right",onLearnMore:q})]})]}),r.lineItemSkus&&e.jsx("div",{className:"ml-6 pl-4 border-l",children:e.jsx(he,{placeholder:s("Enter SKUs (comma-separated)"),value:r.lineItemSkuList||"",onChange:t=>ie("lineItemSkuList",t.target.value)})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"lineItemTypes",checked:r.lineItemTypes,onCheckedChange:t=>At("lineItemTypes",t===!0)}),e.jsxs(A,{htmlFor:"lineItemTypes",className:"font-normal flex items-center",children:["With Any of these Types",e.jsx(G,{topic:"filter-by-type",side:"right",onLearnMore:q})]})]}),r.lineItemTypes&&e.jsxs("div",{className:"ml-6 pl-4 border-l space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"typeProducts",checked:r.lineItemProductTypes.products,onCheckedChange:t=>V(o=>({...o,lineItemProductTypes:{...o.lineItemProductTypes,products:t===!0}}))}),e.jsx(A,{htmlFor:"typeProducts",className:"font-normal",children:"Products"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"typeSubscriptions",checked:r.lineItemProductTypes.subscriptions,onCheckedChange:t=>V(o=>({...o,lineItemProductTypes:{...o.lineItemProductTypes,subscriptions:t===!0}}))}),e.jsx(A,{htmlFor:"typeSubscriptions",className:"font-normal",children:"Subscriptions"})]})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(re,{id:"lineItemCollaboratorOwned",checked:r.lineItemCollaboratorOwned,onCheckedChange:t=>ie("lineItemCollaboratorOwned",t===!0)}),e.jsxs(A,{htmlFor:"lineItemCollaboratorOwned",className:"font-normal flex items-center",children:["Collaborator Owned Products Only",e.jsx(G,{topic:"filter-collaborator-owned",side:"right",onLearnMore:q})]})]})]});return z&&!j?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ut,{})}):e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:s(j?"New Program":"Edit Program")}),W&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:W}),e.jsxs("div",{className:"flex gap-8 items-start relative",children:[e.jsxs("form",{onSubmit:Us,className:"flex-1 min-w-0 max-w-2xl space-y-6 min-h-0 pb-[50vh]",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsx(Ne,{label:s("Name"),htmlFor:"name",required:!0,error:Ce(B,"name"),children:e.jsx(he,{id:"name",value:r.name,onChange:t=>ie("name",t.target.value),placeholder:s("e.g., Referral Program - Lead Gen")})}),e.jsx(Ne,{label:s("Description"),htmlFor:"description",error:Ce(B,"description"),children:e.jsx(he,{id:"description",value:r.description,onChange:t=>ie("description",t.target.value),placeholder:s("Describe what this program offers")})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(A,{htmlFor:"status",children:s("Status")}),e.jsxs(De,{value:r.status,onValueChange:t=>ie("status",t),children:[e.jsx(Me,{id:"status",children:e.jsx(Oe,{})}),e.jsxs(Ge,{children:[e.jsx(S,{value:"draft",children:s("Draft")}),e.jsx(S,{value:"active",children:s("Active")}),e.jsx(S,{value:"inactive",children:s("Inactive")})]})]})]}),e.jsx(Ne,{label:"Currency",htmlFor:"units",required:!0,error:Ce(B,"units"),children:e.jsxs(De,{value:r.units,onValueChange:t=>{if(!t||t===r.units)return;const o=ys(t,de);ie("units",t),V(l=>({...l,incentiveConfig:l.incentiveConfig?On(l.incentiveConfig,lt,o):l.incentiveConfig}))},onOpenChange:ln,children:[e.jsx(Me,{id:"units",children:e.jsx(Oe,{placeholder:s("Select currency")})}),e.jsx(Ge,{children:te?e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:"Loading currencies..."}):de.length>0?de.map(t=>e.jsx(S,{value:t.code,children:mr(t)},t.code)):e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:"No currencies available"})})]})})]}),!1,e.jsx(Ne,{label:e.jsxs("span",{children:["Engagement Expiration (Days)",e.jsx(G,{topic:"expiration-days",onLearnMore:q})]}),htmlFor:"expirationDays",description:"How long an engagement remains valid. Leave empty for no expiration.",error:Ce(B,"expirationDays"),children:e.jsx(he,{id:"expirationDays",type:"number",min:"0",value:r.expirationDays??"",onChange:t=>ie("expirationDays",t.target.value?parseInt(t.target.value):void 0),placeholder:s("e.g., 60")})})]}),!h&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(fr,{draft:b}),L?e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:L}):null]}),!1,C,p,e.jsxs(K,{id:"engagement-tracking",className:we("transition-all duration-300",Fe==="engagement-tracking"&&"animate-glow ring-2 ring-primary",U==="engagement-tracking"&&"ring-2 ring-primary/40"),children:[e.jsxs(J,{children:[e.jsxs(Q,{children:["Engagement Tracking Events",e.jsx(G,{topic:"what-is-engagement",onLearnMore:q})]}),e.jsx(ge,{children:"Select which customer interactions create engagements for attribution"})]}),e.jsx(Z,{className:"space-y-4",children:R.engagementTypes?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading engagement types..."}):fe.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No engagement types available. Please check your backend configuration."}):fe.map(t=>{var o,l,i,y;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(re,{id:`engagement-${t.id}`,checked:((o=r.engagementTypes[t.id])==null?void 0:o.enabled)??!1,onCheckedChange:N=>ts(t.id,"enabled",N===!0)}),e.jsxs("div",{className:"grid gap-1.5 leading-none",children:[e.jsxs(A,{htmlFor:`engagement-${t.id}`,className:"font-normal flex items-center",children:[t.name,Re[t.id]&&e.jsx(G,{topic:Re[t.id],side:"right",onLearnMore:q})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]}),((l=r.engagementTypes[t.id])==null?void 0:l.enabled)&&e.jsx("div",{className:"ml-6 pl-4 border-l space-y-2",children:e.jsx(hr,{options:Bs,value:((i=r.engagementTypes[t.id])==null?void 0:i.calculationType)??"fixed",args:((y=r.engagementTypes[t.id])==null?void 0:y.calculationArgs)??{},onChangeStrategy:N=>ts(t.id,"calculationType",N),onChangeArg:(N,O)=>_s(t.id,N,O),idPrefix:`engagement-calc-${t.id}`,label:"Calculation",helpTopic:"engagement-calculation",helpTopicByArg:{value:"engagement-points",pointsAtLayer1:"engagement-cascade-layer",pointsAtLayer2:"engagement-cascade-layer",pointsAtLayer3:"engagement-cascade-layer",pointsAtLayer4:"engagement-cascade-layer",pointsAtLayer5:"engagement-cascade-layer"},onHelpLearnMore:q})})]},t.id)})})]}),e.jsxs(K,{id:"attribution-model",className:we("transition-all duration-300",Fe==="attribution-model"&&"animate-glow ring-2 ring-primary",U==="attribution-model"&&"ring-2 ring-primary/40"),children:[e.jsxs(J,{children:[e.jsxs(Q,{children:["Attribution Model",e.jsx(G,{topic:"attribution-model",onLearnMore:q})]}),e.jsx(ge,{children:"How credit is assigned when multiple collaborators engage a customer before conversion"})]}),e.jsx(Z,{children:R.incentiveResolvers?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading attribution models..."}):Be.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No attribution models available. Please check your backend configuration."}):e.jsx(Gt,{value:r.incentiveResolverType,onValueChange:t=>{t==="EveryBindingWins"&&r.incentiveResolverType!=="EveryBindingWins"?(Le(t),ye(!0)):ie("incentiveResolverType",t)},children:Be.map(t=>e.jsxs("div",{className:"flex items-start space-x-2 py-1",children:[e.jsx(jt,{value:t.id,id:`resolver-${t.id}`,className:"mt-0.5"}),e.jsxs("div",{className:"grid gap-0.5 leading-none",children:[e.jsxs(A,{htmlFor:`resolver-${t.id}`,className:"font-normal flex items-center",children:[t.name,Re[t.id]&&e.jsx(G,{topic:Re[t.id],side:"right",onLearnMore:q})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]},t.id))})})]}),e.jsxs(K,{id:"commission-calculation",className:we("transition-all duration-300",Fe==="commission-calculation"&&"animate-glow ring-2 ring-primary",U==="commission-calculation"&&"ring-2 ring-primary/40"),children:[e.jsxs(J,{children:[e.jsxs(Q,{children:["Commission Calculation",e.jsx(G,{topic:"commission-calculation",onLearnMore:q})]}),e.jsx(ge,{children:"Select which parts of the transaction are included when calculating commissions"})]}),e.jsx(Z,{className:"space-y-4",children:R.transactionCompilers?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading transaction compilers..."}):e.jsx(gr,{options:Te.map(t=>({id:t.id,label:t.name,description:t.description,helpTopic:Re[t.id]})),enabled:r.transactionCompilers,onToggle:(t,o)=>t==="includeTaxes"?cn(o):kt(t,o),renderLineItemOptions:mn,onLearnMore:q})})]}),e.jsxs(K,{id:"incentive-structure",className:we("transition-all duration-300",Fe==="incentive-structure"&&"animate-glow ring-2 ring-primary",U==="incentive-structure"&&"ring-2 ring-primary/40"),children:[e.jsxs(J,{children:[e.jsxs(Q,{children:["Incentive Structure",e.jsx(G,{topic:"incentive-structure",onLearnMore:q})]}),e.jsx(ge,{children:"Define how rewards are calculated for conversions"})]}),e.jsx(Z,{className:"space-y-4",children:R.incentiveTypes?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading incentive types..."}):ke.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No incentive types available. Please check your backend configuration."}):e.jsx(Gt,{value:r.incentiveType,onValueChange:on,children:ke.map(t=>{var o,l,i,y,N;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(jt,{value:t.id,id:`incentive-${t.id}`,className:"mt-0.5"}),e.jsxs("div",{className:"grid gap-0.5 leading-none",children:[e.jsxs(A,{htmlFor:`incentive-${t.id}`,className:"font-normal flex items-center",children:[t.name,Re[t.id]&&e.jsx(G,{topic:Re[t.id],side:"right",onLearnMore:q})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]}),r.incentiveType===t.id&&e.jsxs("div",{className:"ml-6 pl-4 border-l space-y-4",children:[t.id==="saleTransactionPercentage"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Percent",htmlFor:"transactionPercent",required:!0,error:Ce(B,"incentiveConfig"),children:e.jsx(he,{id:"transactionPercent",type:"number",min:"0",max:"100",step:"0.01",value:((o=r.incentiveConfig)==null?void 0:o.transactionPercent)??"",onChange:O=>Ee("transactionPercent",parseFloat(O.target.value)||0)})}),ct(t.id),Ft()]}),t.id==="saleFixedPerTransaction"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerTransaction",required:!0,error:Ce(B,"incentiveConfig"),children:e.jsx(ht,{id:"payoutPerTransaction",min:"0",definition:lt,value:(l=r.incentiveConfig)==null?void 0:l.payoutPerTransaction,onChange:O=>Ee("payoutPerTransaction",O)})}),ct(t.id),Ft()]}),t.id==="saleFixedPerProduct"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerProduct",required:!0,error:Ce(B,"incentiveConfig"),children:e.jsx(ht,{id:"payoutPerProduct",min:"0",definition:lt,value:(i=r.incentiveConfig)==null?void 0:i.payoutPerProduct,onChange:O=>Ee("payoutPerProduct",O)})}),ct(t.id),Ft()]}),t.id==="leadFixed"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerLead",required:!0,error:Ce(B,"incentiveConfig"),children:e.jsx(ht,{id:"payoutPerLead",min:"0",definition:lt,value:(y=r.incentiveConfig)==null?void 0:y.payoutPerLead,onChange:O=>Ee("payoutPerLead",O)})}),e.jsx(Ne,{label:"Lead Re-Qualification Window (Days)",htmlFor:"leadRequalificationDays",description:"How long before the same lead can qualify again.",error:Ce(B,"incentiveConfig"),children:e.jsx(he,{id:"leadRequalificationDays",type:"number",min:"0",value:((N=r.incentiveConfig)==null?void 0:N.leadRequalificationDays)??"",onChange:O=>Ee("leadRequalificationDays",O.target.value?parseInt(O.target.value):void 0),placeholder:s("e.g., 90")})}),ct(t.id)]})]})]},t.id)})})})]}),Ie.length>0&&e.jsxs(K,{id:"post-conversion-actions",className:we("transition-all duration-300",Fe==="post-conversion-actions"&&"animate-glow ring-2 ring-primary",U==="post-conversion-actions"&&"ring-2 ring-primary/40"),children:[e.jsxs(J,{children:[e.jsx(Q,{children:s("Post-Conversion Actions")}),e.jsx(ge,{children:s("Automatically run these actions whenever a conversion in this program is approved.")})]}),e.jsxs(Z,{children:[e.jsx(xr,{options:rn,selected:r.postConversionActions??[],onChange:t=>ie("postConversionActions",t),loading:R.postConversionActionTypes,idPrefix:"post-conversion-action"}),nn&&e.jsx(Jn.PlanUpgradeNotice,{className:"mt-3",feature:s("lifetime customer links"),plan:"plus"})]})]}),e.jsx(cr,{id:"program-requirements",intro:s(j?"Before you can create this program:":"Before you can save this program:"),requirements:Lt}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{type:"submit",disabled:an,"aria-describedby":Lt.length>0?"program-requirements":void 0,children:_?"Saving...":s(j?"Create":"Update")}),e.jsx(F,{type:"button",variant:"outline",onClick:()=>P("/programs"),children:s("Cancel")})]})]}),e.jsx("aside",{className:"hidden lg:block w-72 flex-shrink-0 sticky top-4 h-fit max-h-[calc(100vh-2rem)] overflow-y-auto",children:e.jsx(Ds,{engagementTypes:Object.entries(r.engagementTypes).filter(([,t])=>t.enabled).map(([t])=>t),resolverType:r.incentiveResolverType,incentiveType:r.incentiveType,collaboratorGroupName:ne==="group"&&r.collaboratorGroupId?((as=Ke.find(t=>t.id===r.collaboratorGroupId))==null?void 0:as.name)??null:null,transactionCompilers:Object.entries(r.transactionCompilers).filter(([,t])=>t).map(([t])=>t),lineItemFilters:r.transactionCompilers.includeLineItems?{hasCategories:r.lineItemCategories,hasSkus:r.lineItemSkus,hasTypes:r.lineItemTypes,productTypes:r.lineItemTypes?Object.entries(r.lineItemProductTypes).filter(([,t])=>t).map(([t])=>t):void 0,collaboratorOwned:r.lineItemCollaboratorOwned,categoryIds:r.lineItemCategoryIds,skuList:r.lineItemSkuList}:void 0,commissionConfig:{transactionPercent:(is=r.incentiveConfig)==null?void 0:is.transactionPercent,payoutPerTransaction:(os=r.incentiveConfig)==null?void 0:os.payoutPerTransaction,payoutPerProduct:(ls=r.incentiveConfig)==null?void 0:ls.payoutPerProduct,payoutPerLead:(cs=r.incentiveConfig)==null?void 0:cs.payoutPerLead},formatAmount:t=>bn(t,r.units,{definitions:de}),conversionTypes:(ds=r.incentiveConfig)==null?void 0:ds.activeConversionTypes,postConversionActions:r.postConversionActions,engagementFilters:r.engagementFilters,engagementFilterLabels:bt,onStepClick:Vs,activeSection:U})})]}),e.jsx(Kn,{topic:Nt,open:!!Nt,onOpenChange:t=>!t&&q(null)}),e.jsx(gt,{open:nt,onOpenChange:ye,children:e.jsxs(xt,{children:[e.jsxs(ft,{children:[e.jsx(vt,{children:"Confirm: All Get Paid"}),e.jsxs(yt,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:e.jsx("strong",{children:"This attribution model pays the FULL commission to EVERY collaborator."})}),e.jsxs("p",{children:["Example: If your commission is $100 per order and 3 collaborators have engagements, you will pay ",e.jsx("strong",{children:"$300 total"})," ($100 × 3 collaborators)."]}),e.jsx("p",{className:"text-amber-700 dark:text-amber-400",children:"This is not a split. Your payout costs multiply with each engaged collaborator."})]})]}),e.jsxs(Bt,{children:[e.jsx(F,{variant:"outline",onClick:()=>{ye(!1),Le(null)},children:s("Cancel")}),e.jsx(F,{onClick:()=>{$e&&ie("incentiveResolverType",$e),ye(!1),Le(null)},children:"I Understand, Enable It"})]})]})}),e.jsx(gt,{open:Tt,onOpenChange:Ve,children:e.jsxs(xt,{children:[e.jsxs(ft,{children:[e.jsx(vt,{children:"Include Taxes in Commission?"}),e.jsxs(yt,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:"Including taxes means you will pay commissions on amounts that are typically passed directly to the government."}),e.jsx("p",{children:"Most programs exclude taxes. If you enable this, your total commission costs will increase."})]})]}),e.jsxs(Bt,{children:[e.jsx(F,{variant:"outline",onClick:()=>{Ve(!1),Xe(null)},children:s("Cancel")}),e.jsx(F,{onClick:()=>{at!==null&&kt("includeTaxes",at),Ve(!1),Xe(null)},children:"Include Taxes"})]})]})})]})}function Nr(n){return n?Array.isArray(n)?n.map(s=>s.type):Object.keys(n):[]}const Tr={saleFixedPerTransaction:"Fixed per Transaction",saleTransactionPercentage:"Percentage of Transaction",saleFixedPerProduct:"Fixed per Product",leadFixed:"Fixed per Lead"},Ir={newestBindingWins:"Newest Engagement Wins",oldestBindingWins:"Oldest Engagement Wins",evenlySharedPool:"Even Split",performanceSharedPool:"Performance Weighted",EveryBindingWins:"All Get Paid",topScoreWins:"Top Score Wins"},Pr={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red"},wr={active:"status-badge status-green",expired:"status-badge status-gray",converted:"status-badge status-blue"},Sr={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red"};function kr(){var ke,Be,Te,ve,Ie,Ae,te;const{translate:n}=xe(),{formatMoney:s,currencyName:u}=sr(),{id:h}=As(),v=qt(),{isWordPress:p,extensions:C}=Qe(),g=C.programApplicationForms,{current:a,isLoading:x,error:P,fetchOne:j,clearCurrent:b}=_t(),{items:L,isLoading:k,fetchList:ee}=er(),{items:f,isLoading:z,fetchList:_}=tr(),{items:W,isLoading:T,fetchList:w}=Ms();d.useEffect(()=>{if(h){const m=parseInt(h);j(m),ee({programId:m,perPage:10,status:"pending,approved,complete,rejected"}),_({programId:m,perPage:10,status:"active,complete,expired"}),w({programId:m,perPage:10,status:"active,pending,inactive,rejected"})}return()=>b()},[h,j,b,ee,_,w]);const E=m=>m?new Date(m).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",ce=(m,R)=>s(m,R),Se=[{id:"id",header:n("ID"),cell:m=>e.jsxs(pe,{to:`/conversions/${m.id}`,className:"font-mono text-primary hover:underline",children:["#",m.id]})},{id:"collaborator",header:n("Collaborator"),cell:m=>Cs(m.collaboratorName,"collaborator",n)},{id:"type",header:n("Type"),cell:m=>e.jsx("span",{className:"capitalize",children:m.type})},{id:"amount",header:n("Amount"),cell:m=>ce(m.amount,m.obligationAwardType||(a==null?void 0:a.units))},{id:"status",header:n("Status"),cell:m=>e.jsx("span",{className:Pr[m.status],children:m.status})},{id:"date",header:n("Date"),cell:m=>E(m.dateCreated)}],de=[{id:"id",header:n("ID"),cell:m=>e.jsxs(pe,{to:`/engagements/${m.id}`,className:"font-mono text-primary hover:underline",children:["#",m.id]})},{id:"collaborator",header:n("Collaborator"),cell:m=>Cs(m.collaboratorName,"collaborator",n)},{id:"score",header:n("Score"),cell:m=>m.score},{id:"status",header:n("Status"),cell:m=>e.jsx("span",{className:wr[m.status],children:m.status})},{id:"date",header:n("Date"),cell:m=>E(m.dateCreated)}],fe=[{id:"name",header:n("Name"),cell:m=>e.jsx(pe,{to:`/collaborators/${m.id}/view`,className:"text-primary hover:underline",children:m.fullName})},{id:"email",header:n("Email"),cell:m=>m.email},{id:"status",header:n("Status"),cell:m=>e.jsx("span",{className:Sr[m.status],children:m.status})}];return x?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ut,{label:n("Loading program...")})}):P?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:P}):a?e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!p&&e.jsx(F,{variant:"ghost",size:"icon",onClick:()=>v("/programs"),"aria-label":n("Back"),children:e.jsx(nr,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:a.name}),e.jsx(Fs,{status:a.status})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:a.description})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Es,{sourceType:"program",sourceId:a.id,contextLabel:a.name}),e.jsx(F,{asChild:!0,children:e.jsxs(pe,{to:`/programs/${a.id}`,children:[e.jsx(En,{className:"h-4 w-4 mr-2"}),n("Edit Program")]})})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-3",children:[e.jsx(Ds,{engagementTypes:Nr(a.engagementTypes),resolverType:a.incentiveResolverType,incentiveType:a.incentiveType,transactionCompilers:a.transactionCompilers||[],lineItemFilters:a.lineItemFilters?{hasCategories:(((ke=a.lineItemFilters.inCategories)==null?void 0:ke.length)??0)>0,hasSkus:(((Be=a.lineItemFilters.withSkus)==null?void 0:Be.length)??0)>0,hasTypes:(((Te=a.lineItemFilters.withTypes)==null?void 0:Te.length)??0)>0,productTypes:a.lineItemFilters.withTypes,collaboratorOwned:a.lineItemFilters.collaboratorOwned,categoryIds:((ve=a.lineItemFilters.inCategories)==null?void 0:ve.join(", "))||"",skuList:((Ie=a.lineItemFilters.withSkus)==null?void 0:Ie.join(", "))||""}:void 0,commissionConfig:Rs(a.incentiveCalculation||a.incentiveConfig||{}),formatAmount:m=>s(m,a.units),conversionTypes:((Ae=a.incentiveCalculation)==null?void 0:Ae.activeConversionTypes)||((te=a.incentiveConfig)==null?void 0:te.activeConversionTypes),postConversionActions:a.postConversionActions,engagementFilters:a.engagementFilters}),e.jsxs(K,{children:[e.jsxs(J,{children:[e.jsx(Q,{children:n("Configuration")}),e.jsx(ge,{children:n("Program settings and incentive structure")})]}),e.jsxs(Z,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Incentive Type")}),e.jsx("dd",{className:"font-medium",children:Tr[a.incentiveType]||a.incentiveType})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Credit Split")}),e.jsx("dd",{className:"font-medium",children:Ir[a.incentiveResolverType]||a.incentiveResolverType})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Currency")}),e.jsx("dd",{className:"font-medium",children:u(a.units)})]}),typeof a.expirationDays=="number"&&a.expirationDays>0&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Engagement Expiration")}),e.jsxs("dd",{className:"font-medium",children:[a.expirationDays," days"]})]}),!p&&e.jsxs("dl",{className:"min-w-0",children:[e.jsxs("dt",{className:"text-sm text-muted-foreground flex items-center",children:[n("Runs on"),e.jsx(G,{topic:"program-properties",side:"right"})]}),e.jsx("dd",{className:"font-medium break-words",children:e.jsx(vr,{programId:a.id})})]})]}),(a.incentiveCalculation||a.incentiveConfig)&&(()=>{const m=a.incentiveCalculation||a.incentiveConfig;return e.jsxs("div",{className:"pt-4 border-t space-y-2",children:[(m==null?void 0:m.transactionPercent)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Commission Rate")}),e.jsxs("span",{className:"font-medium",children:[m.transactionPercent,"%"]})]}),(m==null?void 0:m.payoutPerTransaction)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Transaction")}),e.jsx("span",{className:"font-medium",children:ce(m.payoutPerTransaction,a.units)})]}),(m==null?void 0:m.payoutPerProduct)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Product")}),e.jsx("span",{className:"font-medium",children:ce(m.payoutPerProduct,a.units)})]}),(m==null?void 0:m.payoutPerLead)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Lead")}),e.jsx("span",{className:"font-medium",children:ce(m.payoutPerLead,a.units)})]}),(m==null?void 0:m.autoApprove)!==void 0&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Auto-Approve")}),e.jsx("span",{className:"font-medium",children:m.autoApprove?"Yes":"No"})]})]})})()]})]}),e.jsxs(K,{children:[e.jsxs(J,{children:[e.jsx(Q,{children:n("Statistics")}),e.jsx(ge,{children:n("Program performance metrics")})]}),e.jsxs(Z,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Collaborators")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(pe,{to:`/collaborators?programId=${a.id}`,className:"text-primary hover:underline",children:[a.collaboratorCount??0," enrolled"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Engagements")}),e.jsxs("dd",{className:"font-medium",children:[a.engagementsCount??0," total"]})]}),!1,a.engagementTypes&&a.engagementTypes.length>0&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Tracked Engagement Types")}),e.jsx("dd",{className:"font-medium text-sm",children:a.engagementTypes.map(m=>m.type.replace(/([A-Z])/g," $1").trim()).join(", ")})]}),a.createdDate&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Created")}),e.jsx("dd",{className:"font-medium",children:E(a.createdDate)})]})]})]})]}),g&&a&&e.jsx("div",{className:"mt-8",children:e.jsx(g,{programId:a.id})}),e.jsx("div",{className:"mt-8",children:e.jsxs(K,{children:[e.jsxs(J,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:n("Recent Conversions")}),e.jsx(ge,{children:n("Latest conversions for this program")})]}),e.jsx(F,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(pe,{to:`/conversions?programId=${a.id}`,children:n("View All")})})]}),e.jsx(Z,{children:e.jsx(pt,{columns:Se,data:L,isLoading:k,emptyMessage:n("No conversions yet for this program.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(K,{children:[e.jsxs(J,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:n("Recent Engagements")}),e.jsx(ge,{children:n("Latest engagements for this program")})]}),e.jsx(F,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(pe,{to:`/engagements?programId=${a.id}`,children:n("View All")})})]}),e.jsx(Z,{children:e.jsx(pt,{columns:de,data:f,isLoading:z,emptyMessage:n("No engagements yet for this program.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(K,{children:[e.jsxs(J,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:n("Enrolled Collaborators")}),e.jsx(ge,{children:n("Collaborators participating in this program")})]}),e.jsx(F,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(pe,{to:`/collaborators?programId=${a.id}`,children:n("View All")})})]}),e.jsx(Z,{children:e.jsx(pt,{columns:fe,data:W,isLoading:T,emptyMessage:n("No collaborators enrolled yet.")})})]})})]}):e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx("p",{className:"text-muted-foreground",children:n("Program not found.")})})}window.sirenConfig&&Nn({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ss=document.getElementById("siren-programs");Ss&&Tn.createRoot(Ss).render(e.jsx(d.StrictMode,{children:e.jsxs(_n,{defaultRoute:"/programs",children:[e.jsx(In,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Pn,{children:[e.jsx(Pe,{path:"/programs",element:e.jsx(Ns,{})}),e.jsx(Pe,{path:"/programs/new",element:e.jsx(ws,{})}),e.jsx(Pe,{path:"/programs/:id",element:e.jsx(ws,{})}),e.jsx(Pe,{path:"/programs/:id/view",element:e.jsx(kr,{})}),e.jsx(Pe,{path:"/recipes/browse",element:e.jsx(Gn,{})}),e.jsx(Pe,{path:"/recipes/browse/:slug",element:e.jsx(Bn,{})}),e.jsx(Pe,{path:"/import/imports/:jobId",element:e.jsx(Wn,{})}),e.jsx(Pe,{index:!0,element:e.jsx(Ns,{})})]})})]})}));
     16 */const cr=_t("WandSparkles",[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]]);function Vs({kind:n,onBlank:s,onBrowse:u}){const{translate:h}=pe(),{status:v,recipes:g,load:C}=Mn(),{isWordPress:x,capabilities:a}=rt(),p=a.recipeExport===!0;m.useEffect(()=>{p&&v==="idle"&&C({isWordPress:x})},[p,v,C,x]);const P=h(n==="distributors"?"distributor":"program"),y=g.length;return e.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[e.jsx(Gt,{icon:cr,title:h("Start from scratch"),description:`${h("Build a custom")} ${P} ${h("from a blank canvas. You control every rule.")}`,onClick:s}),p&&e.jsx(Gt,{icon:lr,title:h("Browse ready-made recipes"),description:y>0?`${y} ${h("proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later.")}`:h("Proven setups for affiliate, referral, rewards, and more. Apply one in a single step. Tune it later."),cta:h("Browse recipes"),onClick:u}),e.jsx(Gt,{icon:or,title:h("Describe what you want"),description:h("Tell Beacon in plain language and let your AI draft a custom recipe you review and apply like any other."),comingSoon:!0})]})}function Gt({icon:n,title:s,description:u,cta:h,onClick:v,comingSoon:g}){const{translate:C}=pe();return g?e.jsxs("div",{"aria-disabled":"true",className:"flex cursor-not-allowed flex-col rounded-xl border border-dashed bg-card p-6 text-left opacity-70",children:[e.jsx("span",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-muted text-muted-foreground",children:e.jsx(n,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-base font-medium text-muted-foreground",children:s}),e.jsxs("span",{className:"inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-dashed border-amber-400/40 bg-amber-400/[0.07] px-2 py-0.5 text-[0.7rem] font-medium text-amber-400",children:[e.jsx(Un,{className:"h-3 w-3","aria-hidden":"true"}),C("Soon")]})]}),e.jsx("p",{className:"mt-2 flex-1 text-sm leading-relaxed text-muted-foreground",children:u})]}):e.jsxs("div",{role:"button",tabIndex:0,onClick:v,onKeyDown:x=>{(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),v==null||v())},className:ke("flex cursor-pointer flex-col rounded-xl border bg-card p-6 text-left transition-all","hover:-translate-y-0.5 hover:border-primary/50 hover:shadow-md","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"),children:[e.jsx("span",{className:"mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(n,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx("h3",{className:"text-base font-medium",children:s}),e.jsx("p",{className:"mt-2 flex-1 text-sm leading-relaxed text-muted-foreground",children:u}),h&&e.jsxs("span",{className:"mt-4 inline-flex items-center gap-1.5 text-sm font-medium text-primary",children:[h,e.jsx(On,{className:"h-4 w-4","aria-hidden":"true"})]})]})}function dr({open:n,onOpenChange:s,kind:u,onBlank:h,onBrowse:v}){const{translate:g}=pe(),C=u==="distributors",x=()=>s(!1);return e.jsx(yt,{open:n,onOpenChange:s,children:e.jsxs(jt,{className:"max-w-4xl",children:[e.jsxs(bt,{children:[e.jsxs(Ct,{className:"flex items-center gap-2 text-lg",children:[e.jsx(qt,{className:"h-5 w-5 text-primary","aria-hidden":"true"}),g(C?"Add a distributor":"Add an incentive program")]}),e.jsx(Nt,{children:g("Two ways to a working setup in minutes. Build your own, or start from a proven recipe.")})]}),e.jsx("div",{className:"pt-2",children:e.jsx(Vs,{kind:u,onBlank:()=>{x(),h()},onBrowse:()=>{x(),v()}})})]})})}function ws(){const{translate:s}=pe(),{extensions:u}=rt(),h=u.programsListLinks,v=u.currenciesPath,g={active:s("Active"),inactive:s("Inactive"),draft:s("Draft"),deleted:s("Trashed")},C={saleFixedPerTransaction:s("Fixed per Transaction"),saleTransactionPercentage:s("Percentage of Transaction"),saleFixedPerProduct:s("Fixed per Product"),leadFixed:s("Fixed per Lead")},x={newestBindingWins:s("Newest Engagement Wins"),oldestBindingWins:s("Oldest Engagement Wins"),evenlySharedPool:s("Even Split"),performanceSharedPool:s("Performance Weighted"),EveryBindingWins:s("All Get Paid"),topScoreWins:s("Top Score Wins")},a=Ht(),[p,P]=vn(),{items:y,total:b,page:k,perPage:A,totalPages:J,isLoading:f,hasLoaded:_,isSubmitting:H,error:U,fetchList:N,delete:w,bulkActivate:R,bulkDeactivate:oe,bulkDelete:Ue,bulkPermanentDelete:te,bulkRestore:ge,update:Ae}=Yt(),[Le,Fe]=m.useState([]);new Map(Le.map(i=>[i.id,i.name]));const he=p.get("status")||"all",Te=p.get("incentiveType")||"all",Ee=p.get("resolverType")||"all",Pe=p.get("programGroupId")||"",[d,q]=m.useState(""),[xe,Pt]=m.useState(""),[B,at]=m.useState(he),[D,it]=m.useState(Te),[M,It]=m.useState(Ee),[W,ot]=m.useState(Pe),[Q,fe]=m.useState(null),[Re,De]=m.useState(10),[ve,r]=m.useState("name"),[L,se]=m.useState("asc"),[le,ne]=m.useState(new Set),[$,_e]=m.useState(!1),[lt,ye]=m.useState(!1),Z=B==="deleted";m.useEffect(()=>{const i=p.get("status"),V=p.get("incentiveType"),we=p.get("resolverType"),je=p.get("programGroupId");i&&i!==B&&at(i),V&&V!==D&&it(V),we&&we!==M&&It(we),je!==null&&je!==W&&ot(je)},[p,B,D,M,W]),m.useEffect(()=>{ne(new Set)},[B,D,M,W]);const Qe=()=>B==="all"?"active,inactive,draft":B;m.useEffect(()=>{N({page:1,perPage:Re,search:xe||void 0,orderBy:ve,order:L,status:B==="all"?"active,inactive,draft":B,incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:W?parseInt(W):void 0})},[N,Re,xe,ve,L,B,D,M,W]),m.useEffect(()=>{},[!1]);const Me=()=>{if(d!==xe){Pt(d);return}N({page:1,perPage:Re,search:d,status:Qe(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:W?parseInt(W):void 0,orderBy:ve,order:L})},Ie=i=>{at(i),i!=="all"?p.set("status",i):p.delete("status"),P(p)},Oe=i=>{it(i),i!=="all"?p.set("incentiveType",i):p.delete("incentiveType"),P(p)},He=i=>{It(i),i!=="all"?p.set("resolverType",i):p.delete("resolverType"),P(p)},Ze=i=>{N({page:i,perPage:Re,search:xe||void 0,status:Qe(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:W?parseInt(W):void 0,orderBy:ve,order:L})},wt=i=>{const V=parseInt(i);De(V),N({page:1,perPage:V,search:xe||void 0,status:Qe(),incentiveType:D!=="all"?D:void 0,resolverType:M!=="all"?M:void 0,programGroupId:W?parseInt(W):void 0,orderBy:ve,order:L})},ze=i=>{const V=ve===i&&L==="asc"?"desc":"asc";r(i),se(V)},ct=(i,V)=>{const we={};return i.engagementTypes&&i.engagementTypes.forEach(je=>{we[je.type]={calculationType:je.calculationType??"fixed",calculationArgs:je.calculationArgs??{}}}),{name:i.name,description:i.description||"",status:V,incentiveType:i.incentiveType,incentiveResolverType:i.incentiveResolverType,units:i.units,programGroupId:i.programGroupId,expirationDays:i.expirationDays,engagementTypes:we,transactionCompilers:i.transactionCompilers,incentiveConfig:i.incentiveConfig,lineItemFilters:i.lineItemFilters}},et=async(i,V)=>{await Ae(i.id,ct(i,V))},Xt=async()=>{if(Q){if(Q.status==="deleted"||Z){await te([Q.id]);return}await w(Q.id)}},St=y.filter(i=>le.has(i.id)).map(i=>i.name),Kt=i=>{a(`/programs/${i.id}`)},Jt=async()=>{await R(Array.from(le)),ne(new Set)},dt=async()=>{await oe(Array.from(le)),ne(new Set)},kt=async()=>{await Ue(Array.from(le)),ne(new Set)},tt=async()=>{await ge(Array.from(le)),ne(new Set)},mt=async()=>{await te(Array.from(le)),ne(new Set)},At=[{id:"name",header:s("Name"),sortable:!0,cell:i=>e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:i.name}),e.jsx("div",{className:"text-sm text-muted-foreground truncate max-w-xs",children:i.description})]})},{id:"resolverType",header:s("Attribution Model"),cell:i=>e.jsx(Ot,{filterKey:"resolverType",filterValue:i.incentiveResolverType,children:x[i.incentiveResolverType]||i.incentiveResolverType})},{id:"incentiveType",header:s("Incentive Type"),cell:i=>e.jsx(Ot,{filterKey:"incentiveType",filterValue:i.incentiveType,children:C[i.incentiveType]||i.incentiveType})},{id:"units",header:s("Currency"),cell:i=>e.jsx("span",{className:"font-mono text-sm text-muted-foreground",children:i.units})},{id:"collaboratorCount",header:s("Collaborators"),cell:i=>e.jsx(de,{to:`/collaborators?programId=${i.id}`,className:"text-primary hover:underline",children:i.collaboratorCount??0})},{id:"engagementsCount",header:s("Engagements"),cell:i=>e.jsx("span",{className:"text-muted-foreground",children:i.engagementsCount??0})},{id:"status",header:s("Status"),sortable:!0,cell:i=>e.jsx(Ot,{filterKey:"status",filterValue:i.status,children:e.jsx(Ms,{status:i.status})})},...Z?[{id:"actions",header:s("Actions"),cell:i=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(E,{variant:"outline",size:"sm",onClick:()=>et(i,"inactive"),children:s("Restore")}),e.jsx(E,{variant:"destructive",size:"sm",onClick:()=>fe(i),children:s("Delete Permanently")})]})}]:[]],Lt=Z?[{label:s("Restore (Inactive)"),onClick:tt},{label:s("Delete Permanently"),onClick:mt,variant:"destructive",confirmMessage:s("Permanently delete selected programs? This action cannot be undone."),confirmItems:St}]:[{label:s("Activate"),onClick:Jt},{label:s("Deactivate"),onClick:dt},{label:s("Delete"),onClick:kt,variant:"destructive",confirmMessage:s("Delete selected programs? You can undo from Trash."),confirmItems:St}],Qt=i=>{ot(i),p.delete("programGroupId"),P(p)},Zt=[{key:"status",label:s("Status"),value:B,displayValue:g[B]||B,onRemove:()=>Ie("all")},{key:"incentiveType",label:s("Incentive Type"),value:D,displayValue:C[D]||D,onRemove:()=>Oe("all")},{key:"resolverType",label:s("Attribution Model"),value:M,displayValue:x[M]||M,onRemove:()=>He("all")}],es=()=>{Ie("all"),Oe("all"),He("all"),Qt("")},ts=d.trim()!==""||xe.trim()!==""||B!=="all"||D!=="all"||M!=="all"||W!=="",ss=_&&!f&&!U&&y.length===0&&!ts,ns=Fn("programs"),Ye=ss&&ns===null,[Xe,st]=m.useState(!1);return m.useEffect(()=>{if(!Ye)return;let i=!1;return Ns.list({status:"deleted",perPage:1,fields:["id"]}).then(V=>{i||st(V.items.length>0)}).catch(()=>{i||st(!1)}),()=>{i=!0}},[Ye]),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Programs"),e.jsx(G,{topic:"what-is-program",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Gs,{sourceType:"program",contextLabel:"all programs"}),h&&e.jsx(h,{}),v?null:e.jsxs(E,{variant:"ghost",disabled:!0,className:"opacity-60",children:[e.jsx(qt,{className:"h-4 w-4 mr-2"}),s("Manage Currencies"),e.jsx("span",{className:"ml-1.5 text-[10px] font-normal px-1.5 py-0.5 rounded bg-primary/10 text-primary",children:"Essentials"})]}),e.jsxs(E,{onClick:()=>ye(!0),"data-tour":"add-program",children:[e.jsx(_n,{className:"h-4 w-4"}),s("Add Program")]})]})]}),e.jsx(dr,{open:lt,onOpenChange:ye,kind:"programs",onBlank:()=>a("/programs/new"),onBrowse:()=>a("/recipes/browse")}),Ye?e.jsxs("div",{className:"animate-in fade-in duration-300",children:[e.jsxs("div",{className:"mb-1.5 flex items-center gap-3",children:[e.jsx("span",{className:"flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary",children:e.jsx(qt,{className:"h-5 w-5","aria-hidden":"true"})}),e.jsx("h2",{className:"text-lg font-medium",children:s("No programs yet")})]}),e.jsx("p",{className:"mb-6 max-w-xl text-sm leading-relaxed text-muted-foreground",children:s("The fastest way to launch your first incentive program is to start from a recipe. A recipe is a ready-made setup. You apply it in one step, then fine-tune it.")}),e.jsx(Vs,{kind:"programs",onBlank:()=>a("/programs/new"),onBrowse:()=>a("/recipes/browse")}),Xe&&e.jsxs("p",{className:"mt-6 text-sm text-muted-foreground","data-testid":"programs-trash-link",children:[s("Looking for programs you deleted?")," ",e.jsx("button",{type:"button",className:"text-primary hover:underline",onClick:()=>Ie("deleted"),children:s("View trashed programs")})]})]}):e.jsxs(e.Fragment,{children:[e.jsx(En,{filters:Zt,onClearAll:es}),U&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:U}),e.jsxs("div",{className:"flex gap-2 mb-4 flex-wrap","data-tour":"programs-filters",children:[e.jsxs("div",{className:"relative flex-1 max-w-sm",children:[e.jsx(Hn,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(me,{placeholder:s("Search programs..."),value:d,onChange:i=>q(i.target.value),onKeyDown:i=>i.key==="Enter"&&Me(),className:"pl-9"})]}),e.jsxs(We,{value:B,onValueChange:Ie,children:[e.jsx($e,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(Ve,{placeholder:s("Status")})}),e.jsxs(qe,{children:[e.jsx(S,{value:"all",children:s("All Statuses")}),e.jsx(S,{value:"active",children:s("Active")}),e.jsx(S,{value:"inactive",children:s("Inactive")}),e.jsx(S,{value:"draft",children:s("Draft")}),e.jsx(S,{value:"deleted",children:s("Trashed")})]})]}),e.jsxs(We,{value:D,onValueChange:Oe,children:[e.jsx($e,{"aria-label":s("Filter by incentive Type"),className:"w-[180px]",children:e.jsx(Ve,{placeholder:s("Incentive Type")})}),e.jsxs(qe,{children:[e.jsx(S,{value:"all",children:s("All Incentive Types")}),e.jsx(S,{value:"saleFixedPerTransaction",children:s("Fixed per Transaction")}),e.jsx(S,{value:"saleTransactionPercentage",children:s("Percentage of Transaction")}),e.jsx(S,{value:"saleFixedPerProduct",children:s("Fixed per Product")}),e.jsx(S,{value:"leadFixed",children:s("Fixed per Lead")})]})]}),e.jsxs(We,{value:M,onValueChange:He,children:[e.jsx($e,{"aria-label":s("Filter by attribution model"),className:"w-[180px]",children:e.jsx(Ve,{placeholder:s("Attribution Model")})}),e.jsxs(qe,{children:[e.jsx(S,{value:"all",children:s("All Attribution Models")}),e.jsx(S,{value:"newestBindingWins",children:s("Newest Engagement Wins")}),e.jsx(S,{value:"oldestBindingWins",children:s("Oldest Engagement Wins")}),e.jsx(S,{value:"evenlySharedPool",children:s("Even Split")}),e.jsx(S,{value:"performanceSharedPool",children:s("Performance Weighted")}),e.jsx(S,{value:"EveryBindingWins",children:s("All Get Paid")}),e.jsx(S,{value:"topScoreWins",children:s("Top Score Wins")})]})]}),e.jsx(E,{variant:"secondary",onClick:Me,children:s("Search")})]}),e.jsx(Rn,{selectedCount:le.size,actions:Lt,onClear:()=>ne(new Set),isProcessing:H}),e.jsx(ft,{columns:At,data:y,sampleKey:"programs",isLoading:f,emptyMessage:s("No programs found."),selectable:!0,selectedIds:le,onSelectionChange:ne,getRowHref:i=>`/programs/${i.id}/view`,onEdit:Z?void 0:Kt,onDelete:Z?void 0:i=>fe(i),sortField:ve,sortOrder:L,onSort:ze}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",b===0?0:(k-1)*A+1," to ",Math.min(k*A,b)," of"," ",b," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(We,{value:Re.toString(),onValueChange:wt,children:[e.jsx($e,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(Ve,{})}),e.jsxs(qe,{children:[e.jsx(S,{value:"10",children:"10"}),e.jsx(S,{value:"25",children:"25"}),e.jsx(S,{value:"50",children:"50"}),e.jsx(S,{value:"100",children:"100"})]})]})]})]}),J>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(E,{variant:"outline",size:"sm",disabled:k===1,onClick:()=>Ze(k-1),children:s("Previous")}),e.jsx(E,{variant:"outline",size:"sm",disabled:k===J,onClick:()=>Ze(k+1),children:s("Next")})]}),e.jsx(E,{variant:"link",className:"text-sm",onClick:()=>Ie(Z?"all":"deleted"),children:s(Z?"Back to active programs":"Trash")})]})]}),!1,e.jsx(kn,{open:!!Q,onClose:()=>fe(null),noun:s("program"),name:(Q==null?void 0:Q.name)||"",permanent:Z,title:s(Z?"Delete Permanently":"Delete Program"),onConfirm:Xt,loadBlockers:Q?()=>Ns.deletionBlockers(Q.id):void 0})]})}function mr(n){var h;if(!n)return;const s=document.getElementById(n);if(!s)return;(h=s.scrollIntoView)==null||h.call(s,{behavior:"smooth",block:"center"});const u=s.matches("input,select,textarea,button,[tabindex]")?s:s.querySelector('input,select,textarea,button,[role="checkbox"],[role="radio"]');u==null||u.focus({preventScroll:!0})}function ur({id:n,requirements:s,intro:u,className:h}){return s.length===0?null:e.jsxs("div",{id:n,role:"status","data-testid":"form-requirements",className:ke("rounded-md border border-dashed bg-muted/40 px-3 py-2 text-sm",h),children:[e.jsx("p",{className:"font-medium",children:u}),e.jsx("ul",{className:"mt-1 list-disc space-y-0.5 pl-5",children:s.map(v=>e.jsx("li",{"data-requirement":v.key,children:v.targetId?e.jsx("button",{type:"button",className:"text-left underline decoration-dotted underline-offset-2 hover:text-primary",onClick:()=>mr(v.targetId),children:v.message}):v.message},v.key))})]})}function pr(n){return n.filter(([s])=>!s).map(([,s])=>s)}function gr(n){var u;const s=(u=n.label)==null?void 0:u.trim();return!s||s===n.code?n.code:`${n.code} - ${s}`}const vt=m.forwardRef(({value:n,onChange:s,definition:u,className:h,disabled:v,...g},C)=>{var y;const x=((y=u==null?void 0:u.symbol)==null?void 0:y.trim())||(u==null?void 0:u.code)||"",a=(u==null?void 0:u.symbolPosition)==="after",p=yn(u),P=n==null||!u?"":jn(n,u);return e.jsxs("div",{className:"relative",children:[x&&e.jsx("span",{"data-testid":"amount-input-symbol","data-position":a?"after":"before",className:ke("absolute top-1/2 -translate-y-1/2 text-muted-foreground text-sm pointer-events-none select-none",a?"right-8":"left-2.5"),children:x}),e.jsx(me,{ref:C,type:"number",inputMode:p===0?"numeric":"decimal",step:Cn(u),value:P,disabled:v||!u,onChange:b=>s(bn(parseFloat(b.target.value)||0,u)),className:h,style:a?void 0:{paddingLeft:`${Math.max(1.1,.55+x.length*.6)}rem`},...g})]})});vt.displayName="AmountInput";const hr=Yn((n,s)=>({options:[],isLoading:!1,hasLoaded:!1,error:null,fetch:async()=>{if(!(s().isLoading||s().hasLoaded)){n({isLoading:!0,error:null});try{const u=await Rs.get("/engagements/calculations");n({options:u.options??[],isLoading:!1,hasLoaded:!0})}catch(u){n({error:u instanceof Error?u.message:"Failed to fetch engagement calculations",isLoading:!1})}}}}));function xr(n){return n.replace(/([A-Z])/g," $1").replace(/^./,s=>s.toUpperCase()).trim()}function fr({options:n,value:s,args:u,onChangeStrategy:h,onChangeArg:v,idPrefix:g="calc-strategy",label:C,helpTopic:x,helpTopicByArg:a,onHelpLearnMore:p,disabled:P=!1}){const y=n.find(b=>b.id===s);return m.useEffect(()=>{!s&&n.length>0&&h(n[0].id)},[s,n,h]),n.length===0?null:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[C&&e.jsxs(F,{htmlFor:`${g}-select`,className:"text-sm font-medium flex items-center",children:[C,x&&e.jsx(G,{topic:x,side:"right",onLearnMore:p})]}),e.jsxs(We,{value:s,onValueChange:h,disabled:P,children:[e.jsx($e,{id:`${g}-select`,className:"w-full max-w-xs",children:e.jsx(Ve,{})}),e.jsx(qe,{children:n.map(b=>e.jsx(S,{value:b.id,children:b.name},b.id))})]}),(y==null?void 0:y.description)&&e.jsx("p",{className:"text-xs text-muted-foreground",children:y.description})]}),y&&y.requiredArgs.length>0&&e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:y.requiredArgs.map(b=>{const k=a==null?void 0:a[b];return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(F,{htmlFor:`${g}-arg-${b}`,className:"text-sm font-medium flex items-center",children:[xr(b),k&&e.jsx(G,{topic:k,side:"right",onLearnMore:p})]}),e.jsx(me,{id:`${g}-arg-${b}`,type:"number",value:u[b]??"",onChange:A=>v(b,A.target.value===""?"":Number(A.target.value)),disabled:P})]},b)})})]})}function vr({options:n,enabled:s,onToggle:u,renderLineItemOptions:h,onLearnMore:v}){return e.jsx("div",{className:"space-y-4",children:n.map(g=>{const C=s[g.id],x=!!g.description;return g.id==="includeLineItems"&&h?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:g.id,checked:C,onCheckedChange:p=>u(g.id,p===!0)}),e.jsxs(F,{htmlFor:g.id,className:"font-normal flex items-center",children:[g.label,g.helpTopic&&e.jsx(G,{topic:g.helpTopic,side:"right",onLearnMore:v})]})]}),C&&e.jsx("div",{className:"ml-6 pl-4 border-l space-y-3",children:h()})]},g.id):e.jsxs("div",{className:x?"flex items-start space-x-2":"flex items-center space-x-2",children:[e.jsx(ee,{id:g.id,checked:C,onCheckedChange:p=>u(g.id,p===!0)}),e.jsxs("div",{className:x?"grid gap-0.5 leading-none":"",children:[e.jsxs(F,{htmlFor:g.id,className:"font-normal flex items-center",children:[g.label,g.helpTopic&&e.jsx(G,{topic:g.helpTopic,side:"right",onLearnMore:v})]}),g.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:g.description})]})]},g.id)})})}function yr({options:n,selected:s,onChange:u,loading:h=!1,emptyText:v="No actions are available on your plan.",idPrefix:g="action"}){if(h)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"});if(n.length===0)return e.jsx("p",{className:"text-sm text-muted-foreground",children:v});const C=(x,a)=>{a?s.includes(x)||u([...s,x]):u(s.filter(p=>p!==x))};return e.jsx("div",{className:"space-y-3",children:n.map(x=>{const a=`${g}-${x.id}`;return e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(ee,{id:a,checked:s.includes(x.id),onCheckedChange:p=>C(x.id,p===!0)}),e.jsxs("div",{className:"flex-1 space-y-0.5",children:[e.jsx(F,{htmlFor:a,className:"font-normal",children:x.name}),x.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:x.description})]})]},x.id)})})}function qs(n=!0){const[s,u]=m.useState(null),[h,v]=m.useState(null);return m.useEffect(()=>{if(!n)return;let g=!1;return er.list().then(C=>{g||u(C)}).catch(C=>{g||v(C instanceof Error?C.message:"Failed to load the properties.")}),()=>{g=!0}},[n]),{properties:s,error:h}}const xt=10;function jr({draft:n}){const{translate:s}=pe(),{properties:u,saved:h,error:v,reach:g,setReach:C,staged:x,finalIds:a}=n,[p,P]=m.useState(""),[y,b]=m.useState(1),[k,A]=m.useState(null),J=h??[],f=(u??[]).filter(N=>J.includes(N.id)),_=(u??[]).filter(N=>{const w=p.trim().toLowerCase();return w===""||`${N.name} ${N.siteUrl}`.toLowerCase().includes(w)}),H={...x,stageRemove:N=>{a.filter(R=>!N.includes(R)).length===0?A(N):x.stageRemove(N)}},U=[{id:"name",header:s("Name"),cell:N=>N.name},{id:"siteUrl",header:s("Site URL"),cell:N=>e.jsx("span",{className:"break-all text-muted-foreground",children:N.siteUrl})}];return v?e.jsxs(z,{"data-testid":"program-properties",children:[e.jsx(Y,{children:e.jsx(X,{children:s("Where does it run?")})}),e.jsx(K,{children:e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:v})})]}):u===null||h===void 0?e.jsxs(z,{"data-testid":"program-properties",children:[e.jsx(Y,{children:e.jsx(X,{children:s("Where does it run?")})}),e.jsx(K,{children:e.jsx(zt,{})})]}):e.jsxs(z,{"data-testid":"program-properties",children:[e.jsx(Y,{children:e.jsxs(X,{className:"inline-flex items-center",children:[s("Where does it run?"),e.jsx(G,{topic:"program-properties",side:"right"})]})}),e.jsxs(K,{className:"space-y-3",children:[e.jsxs($t,{value:g,onValueChange:N=>C(N),"aria-label":s("Where this program runs"),children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Tt,{value:"every",id:"program-reach-every",className:"mt-0.5"}),e.jsx(F,{htmlFor:"program-reach-every",className:"font-normal leading-tight",children:e.jsx("span",{className:"font-medium",children:s("Runs on every property")})})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(Tt,{value:"chosen",id:"program-reach-chosen",className:"mt-0.5"}),e.jsx(F,{htmlFor:"program-reach-chosen",className:"font-normal leading-tight",children:e.jsx("span",{className:"font-medium",children:s("Runs on the properties you choose")})})]})]}),g==="chosen"?e.jsx(An,{title:s("Properties"),currentItems:f,currentColumns:U,emptyCurrentMessage:s("No property chosen yet. Click Add properties to choose some."),getCurrentStagingId:N=>N.id,staged:H,pendingAdditionColumns:U,getCandidateStagingId:N=>N.id,pickerTitle:s("Add properties to this program"),pickerDescription:s("Search and select properties. Selections are staged. Click Update to save."),pickerCandidates:_.slice((y-1)*xt,y*xt),pickerColumns:U,pickerPagination:{page:y,perPage:xt,total:_.length,totalPages:Math.max(1,Math.ceil(_.length/xt))},onPickerParamsChange:({search:N,page:w})=>{P(N),b(w)},onOpenPicker:()=>{P(""),b(1)},addButtonLabel:s("Add properties")}):null]}),e.jsx(yt,{open:k!==null,onOpenChange:N=>!N&&A(null),children:e.jsxs(jt,{children:[e.jsxs(bt,{children:[e.jsx(Ct,{children:s("Run this program on every property?")}),e.jsx(Nt,{children:s("Taking off its last property makes it run on every property, including ones you add later. To stop it instead, set its status to Inactive.")})]}),e.jsxs(Vt,{children:[e.jsx(E,{type:"button",variant:"outline",onClick:()=>A(null),children:s("Cancel")}),e.jsx(E,{type:"button",onClick:()=>{k&&x.stageRemove(k),C("every"),A(null)},children:s("Run on every property")})]})]})})]})}function br({programId:n}){const{translate:s}=pe(),{properties:u,error:h}=qs(),[v,g]=m.useState(void 0),[C,x]=m.useState(null);return m.useEffect(()=>{let p=!1;return Ut.get(n).then(P=>{p||g(P)}).catch(P=>{p||x(P instanceof Error?P.message:s("Failed to load where this program runs."))}),()=>{p=!0}},[n,s]),C??h?e.jsx("span",{className:"text-sm text-destructive",role:"alert",children:s("Could not load where this program runs.")}):v===void 0||u===null?e.jsx("span",{className:"text-muted-foreground",children:"…"}):v===null||v.length===0?e.jsx("span",{"data-testid":"program-properties-summary",children:s("Every property")}):e.jsx("span",{"data-testid":"program-properties-summary",children:v.map((p,P)=>{const y=u.find(b=>b.id===p);return e.jsxs("span",{children:[P>0?", ":null,y?e.jsx(de,{to:`/properties/${p}`,className:"text-primary hover:underline",children:y.name}):s("Property #%d").replace("%d",String(p))]},p)})})}function Cr(n){const{translate:s}=pe(),u=n!==void 0,{properties:h,error:v}=qs(u),[g,C]=m.useState(n===null?null:void 0),[x,a]=m.useState(null),[p,P]=m.useState("every"),y=Os({getCandidateStagingId:m.useCallback(w=>w.id,[])}),b=y.reset;m.useEffect(()=>{if(n==null)return;let w=!1;return Ut.get(n).then(R=>{w||(C(R),P(R===null||R.length===0?"every":"chosen"))}).catch(R=>{w||a(R instanceof Error?R.message:s("Failed to load where this program runs."))}),()=>{w=!0}},[n,s]);const k=m.useMemo(()=>g??[],[g]),A=m.useMemo(()=>[...k.filter(w=>!y.pendingRemovalIds.has(w)),...y.pendingAdditions.map(w=>w.id).filter(w=>!k.includes(w))],[k,y.pendingAdditions,y.pendingRemovalIds]),J=g==null||g.length===0?"every":"chosen",f=A.length===k.length&&A.every(w=>k.includes(w)),_=g!==void 0&&(p!==J||p==="chosen"&&!f),H=x??(u?v:null),U=p==="chosen"&&A.length===0?s("Choose at least one property, or choose Runs on every property."):null,N=m.useCallback(async w=>{if(!u||H!==null||!_)return;const R=await Ut.set(w,p==="every"?[]:A);C(R.propertyIds),P(R.propertyIds===null||R.propertyIds.length===0?"every":"chosen"),b()},[u,H,_,p,A,b]);return{properties:h,saved:g,error:H,reach:p,setReach:P,staged:y,finalIds:A,isDirty:_,problem:U,save:N}}const Nr={categorySupport:()=>Rs.get("/line-item-filters/categories")};let Bt=null;function Tr(){return Bt===null&&(Bt=Nr.categorySupport().then(n=>n.available!==!1).catch(()=>!0)),Bt}function Pr(){const{isWordPress:n}=rt(),[s,u]=m.useState(n?{available:!0,loaded:!0}:{available:!0,loaded:!1});return m.useEffect(()=>{if(n)return;let h=!0;return Tr().then(v=>{h&&u({available:v,loaded:!0})}),()=>{h=!1}},[n]),s}function Ss({inUse:n}){const{translate:s}=pe();return n?e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 p-3 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-200","data-testid":"category-filter-unsupported",role:"alert",children:[e.jsx(tr,{className:"mt-0.5 h-3.5 w-3.5 flex-shrink-0"}),e.jsx("span",{children:s("None of your sales sources send product categories, so this filter matches no sale and nothing is paid. Remove it, or connect a WordPress store that sends categories.")})]}):e.jsxs("div",{className:"flex items-start gap-2 rounded-md border bg-muted/40 p-3 text-xs text-muted-foreground","data-testid":"category-filter-hidden",children:[e.jsx(Gn,{className:"mt-0.5 h-3.5 w-3.5 flex-shrink-0"}),e.jsx("span",{children:s("Category filters need sales that carry product categories, such as orders from a connected WordPress store. Stripe and Shopify orders arrive without categories, so a category filter here would pay nothing.")})]})}function ks(n){return typeof n=="string"?n:n&&typeof n=="object"&&"id"in n?String(n.id):""}const Be={referredSiteVisit:"site-visited",boundPostUsed:"blog-post-visited",collaboratorProductSold:"collaborator-product-sold",manual:"manual-attribution",collaboratorFormSubmitted:"collaborator-form-submitted",boundCouponUsed:"coupon-code-used",saleFixedPerProduct:"incentive-fixed-per-product",saleFixedPerTransaction:"incentive-fixed-per-transaction",saleTransactionPercentage:"incentive-percentage",leadFixed:"incentive-fixed-per-lead",newestBindingWins:"newest-engagement-wins",oldestBindingWins:"oldest-engagement-wins",EveryBindingWins:"every-engagement-wins",evenlySharedPool:"evenly-shared-pool",performanceSharedPool:"performance-shared-pool",topScoreWins:"top-score-wins",includeDiscounts:"account-for-discounts",includeFees:"account-for-fees",includeLineItems:"commission-on-products",includeShipping:"account-for-shipping",includeTaxes:"account-for-taxes"},Wt={name:"",description:"",status:"active",units:"",programGroupId:void 0,collaboratorGroupId:null,collaboratorIds:[],expirationDays:void 0,incentiveType:"saleTransactionPercentage",incentiveResolverType:"newestBindingWins",engagementTypes:{},transactionCompilers:{},incentiveConfig:{transactionPercent:void 0,payoutPerTransaction:void 0,payoutPerProduct:void 0,payoutPerLead:void 0,autoApprove:!1,activeConversionTypes:["sale"],leadRequalificationDays:void 0},lineItemCategories:!1,lineItemCategoryIds:"",lineItemSkus:!1,lineItemSkuList:"",lineItemTypes:!1,lineItemProductTypes:{products:!0,subscriptions:!0},lineItemCollaboratorOwned:!1,postConversionActions:[],engagementFilters:[]},As="bindCollaboratorToOpportunity";function Ls(){var os,ls,cs,ds,ms,us,ps;const{translate:s}=pe(),{planAllows:u,isWordPress:h}=rt(),v=u("customer-suppression-filters"),g=!1,C=!1,x=u("customer-linking"),a=Pr(),{id:p}=Ds(),P=Ht(),y=!p,b=Cr(h?void 0:y?null:Number(p)),[k,A]=m.useState(null),J=b.problem;m.useEffect(()=>{J===null&&A(null)},[J]);const{current:f,isLoading:_,isSubmitting:H,error:U,fetchOne:N,create:w,update:R,clearCurrent:oe,clearError:Ue}=Yt(),{currencies:te,engagementTypes:ge,incentiveTypes:Ae,incentiveResolvers:Le,transactionCompilers:Fe,conversionTypes:he,postConversionActionTypes:Te,engagementFilterTypes:Ee,isLoading:Pe,hasLoaded:d,loadingStates:q,fetchCurrencies:xe,fetchEngagementTypes:Pt,fetchIncentiveTypes:B,fetchIncentiveResolvers:at,fetchTransactionCompilers:D,fetchConversionTypes:it,fetchPostConversionActionTypes:M,fetchEngagementFilterTypes:It}=qn(),{options:W,hasLoaded:ot,fetch:Q}=hr(),fe=m.useMemo(()=>Object.fromEntries(ge.map(t=>[t.id,{enabled:!1,calculationType:"fixed",calculationArgs:{value:1}}])),[ge]),Re=m.useMemo(()=>Object.fromEntries((Ee??[]).map(t=>[t.id,t.name])),[Ee]),De=m.useMemo(()=>Object.fromEntries(Fe.map(t=>[t.id,t.id==="includeLineItems"])),[Fe]),ve=m.useMemo(()=>{const t={};return he.forEach(l=>{var c;(c=l.supportedIncentives)==null||c.forEach(o=>{t[o]||(t[o]=[]),t[o].push(l.id)})}),t},[he]),[r,L]=m.useState(Wt),[se,le]=m.useState([]),[ne,$]=m.useState(null),[_e,lt]=m.useState(null),[ye,Z]=m.useState(null),[Qe,Me]=m.useState(!1),[Ie,Oe]=m.useState(null),[He,Ze]=m.useState(!1),[wt,ze]=m.useState(!1),[ct,et]=m.useState(null),[Xt,St]=m.useState([]),[Kt,Jt]=m.useState(!1),[dt,kt]=m.useState(!1),{items:tt,structures:mt,fetchList:At,fetchStructures:Lt}=Ln(),{items:Qt,total:Zt,page:es,perPage:ts,totalPages:ss,isLoading:ns,fetchList:Ye}=$s(),[Xe,st]=m.useState("direct"),i=Os({getCandidateStagingId:t=>t.id});m.useEffect(()=>{Ye({page:1,perPage:200,status:"active,inactive,pending"})},[At,Lt,Ye]);const V=m.useMemo(()=>{const t=r.collaboratorGroupId?tt.find(o=>o.id===r.collaboratorGroupId):null,l=t?mt.find(o=>o.id===t.structure):null,c=(l==null?void 0:l.providedWalkerCapabilities)??null;return W.filter(o=>{const j=o.requiredWalkerCapabilities??[];return j.length===0||c===null?!0:j.every(T=>c.includes(T))})},[W,tt,mt,r.collaboratorGroupId]);m.useEffect(()=>{f&&(f.collaboratorGroupId?st("group"):st("direct"))},[f]),m.useEffect(()=>{dt||(q.engagementTypes||Pt(),ot||Q(),q.incentiveTypes||B(),q.incentiveResolvers||at(),q.transactionCompilers||D(),q.conversionTypes||it(),q.postConversionActionTypes||M(),!d&&!Pe&&xe(),kt(!0))},[dt]),m.useEffect(()=>{},[!1]);const we=m.useMemo(()=>Object.fromEntries(he.map(t=>[t.id,t.name])),[he]),je=m.useRef(new Map);m.useEffect(()=>{const t=new IntersectionObserver(c=>{if(He)return;let o=0,j=null;c.forEach(T=>{T.isIntersecting&&T.intersectionRatio>o&&(o=T.intersectionRatio,j=T.target.id)}),j&&Z(j)},{threshold:[0,.25,.5,.75,1],rootMargin:"-20% 0px -60% 0px"});return["engagement-tracking","attribution-model","commission-calculation","incentive-structure"].forEach(c=>{const o=document.getElementById(c);o&&(t.observe(o),je.current.set(c,o))}),()=>t.disconnect()},[He]);const Us=m.useCallback(t=>{const l=document.getElementById(t);l&&(Ze(!0),lt(t),Z(t),l.scrollIntoView({behavior:"smooth",block:"start"}),setTimeout(()=>{Ze(!1),lt(null)},1500))},[]),_s=()=>{const t=[{field:"name",validate:Ts("Program name is required")},{field:"name",validate:Ps(ie.TEXT_LENGTH,"Program name must be 255 characters or fewer")},{field:"description",validate:Ps(ie.TEXT_LENGTH,"Description must be 255 characters or fewer")},{field:"units",validate:Ts("Currency is required")}];return r.incentiveType==="saleTransactionPercentage"&&t.push({field:"incentiveConfig",validate:l=>{const c=l,o=c==null?void 0:c.transactionPercent;return o==null?"Transaction percent is required":o<ie.MIN_PERCENT||o>ie.MAX_PERCENT?"Percent must be between 0.01 and 100":Kn(o,2)?null:"Percent can have at most 2 decimal places"}}),r.incentiveType==="saleFixedPerTransaction"&&t.push({field:"incentiveConfig",validate:l=>{const c=l,o=c==null?void 0:c.payoutPerTransaction;return o==null||o<=0?"Payout amount must be greater than 0":o>ie.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),r.incentiveType==="saleFixedPerProduct"&&t.push({field:"incentiveConfig",validate:l=>{const c=l,o=c==null?void 0:c.payoutPerProduct;return o==null||o<=0?"Payout amount must be greater than 0":o>ie.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),r.incentiveType==="leadFixed"&&(t.push({field:"incentiveConfig",validate:l=>{const c=l,o=c==null?void 0:c.payoutPerLead;return o==null||o<0?"Payout amount must be 0 or greater":o>ie.MAX_MONEY_MAJOR?"Payout amount must be 999,999,999.99 or less":null}}),t.push({field:"incentiveConfig",validate:l=>{const c=l,o=c==null?void 0:c.leadRequalificationDays;return o!=null&&(!Number.isInteger(o)||o<0||o>ie.MAX_DAYS)?"Lead re-qualification window must be a whole number of days from 0 to 3650":null}})),t.push({field:"expirationDays",validate:Jn(0,ie.MAX_DAYS,"Expiration days must be a whole number from 0 to 3650")}),t};m.useEffect(()=>(Ue(),p?N(parseInt(p)):(oe(),L(Wt)),()=>{oe()}),[p,N,oe,Ue]),m.useEffect(()=>{y&&Object.keys(fe).length>0&&L(t=>({...t,engagementTypes:{...fe,...Object.fromEntries(Object.entries(t.engagementTypes).filter(([,l])=>l.enabled))},transactionCompilers:{...De,...Object.fromEntries(Object.entries(t.transactionCompilers).filter(([,l])=>l))}}))},[y,fe,De]),m.useEffect(()=>{var t,l,c,o,j,T,O,nt,Je,I,ce,gs,hs,xs,fs;if(f){const vs={};Array.isArray(f.engagementTypes)&&f.engagementTypes.forEach(ae=>{vs[ae.type]={enabled:!0,calculationType:ae.calculationType??"fixed",calculationArgs:ae.calculationArgs??{}}});const gt={};(f.transactionCompilers??[]).forEach(ae=>{let be;if(typeof ae=="string")be=ae;else if(typeof ae=="object"&&ae!==null){const Mt=ae;be=Mt.compiler||Mt.id||Mt.type}be&&(gt[be]=!0)});const ht=Object.keys(gt).length>0?!!gt.includeLineItems:!0,ys=ht&&!!((l=(t=f.lineItemFilters)==null?void 0:t.inCategories)!=null&&l.length),gn=ys&&((o=(c=f.lineItemFilters)==null?void 0:c.inCategories)==null?void 0:o.join(", "))||"",js=ht&&!!((T=(j=f.lineItemFilters)==null?void 0:j.withSkus)!=null&&T.length),hn=js&&((nt=(O=f.lineItemFilters)==null?void 0:O.withSkus)==null?void 0:nt.join(", "))||"",bs=ht&&!!((I=(Je=f.lineItemFilters)==null?void 0:Je.withTypes)!=null&&I.length),xn=bs?{products:((gs=(ce=f.lineItemFilters)==null?void 0:ce.withTypes)==null?void 0:gs.includes("products"))??!0,subscriptions:((xs=(hs=f.lineItemFilters)==null?void 0:hs.withTypes)==null?void 0:xs.includes("subscriptions"))??!0}:{products:!0,subscriptions:!0},fn=ht&&(((fs=f.lineItemFilters)==null?void 0:fs.collaboratorOwned)??!1);L({name:f.name,description:f.description,status:f.status,units:f.units,programGroupId:f.programGroupId,collaboratorGroupId:f.collaboratorGroupId??null,collaboratorIds:f.collaboratorIds??[],expirationDays:f.expirationDays,incentiveType:ks(f.incentiveType),incentiveResolverType:ks(f.incentiveResolverType),engagementTypes:vs,transactionCompilers:gt,incentiveConfig:Bs({...Wt.incentiveConfig,...Object.fromEntries(Object.entries(f.incentiveCalculation||f.incentiveConfig||{}).filter(([ae,be])=>!(be==null||ae==="activeConversionTypes"&&Array.isArray(be)&&be.length===0)))}),lineItemCategories:ys,lineItemCategoryIds:gn,lineItemSkus:js,lineItemSkuList:hn,lineItemTypes:bs,lineItemProductTypes:xn,lineItemCollaboratorOwned:fn,postConversionActions:f.postConversionActions??[],engagementFilters:f.engagementFilters??[]})}},[f]),m.useEffect(()=>{f&&L(t=>{const l=Object.keys(t.transactionCompilers).length>0;return{...t,engagementTypes:{...fe,...t.engagementTypes},transactionCompilers:l?{...Object.fromEntries(Object.keys(De).map(c=>[c,!1])),...t.transactionCompilers}:{...De}}})},[f,fe,De]);const Hs=async t=>{t.preventDefault();const l=Xn(r,_s());if(le(l.errors),!l.valid)return;if(!h&&b.error===null&&b.problem!==null){A(b.problem);return}A(null);const c=new Set(ge.map(I=>I.id)),o={};Object.entries(r.engagementTypes).filter(([I,ce])=>ce.enabled&&(c.size===0||c.has(I))).forEach(([I,ce])=>{o[I]={calculationType:ce.calculationType,calculationArgs:ce.calculationArgs}});const j=Object.entries(r.transactionCompilers).filter(([,I])=>I).map(([I])=>I),T=Xe==="direct"?[...(r.collaboratorIds??[]).filter(I=>!i.pendingRemovalIds.has(I)),...i.pendingAdditions.map(I=>I.id)]:[],O=Xe==="group"?r.collaboratorGroupId??null:null,nt={name:r.name,description:r.description,status:r.status,units:r.units,programGroupId:r.programGroupId,collaboratorGroupId:O,collaboratorIds:T,expirationDays:r.expirationDays??0,incentiveType:r.incentiveType,incentiveResolverType:r.incentiveResolverType,engagementTypes:o,transactionCompilers:j,incentiveConfig:r.incentiveConfig,lineItemFilters:r.transactionCompilers.includeLineItems?{inCategories:r.lineItemCategories&&r.lineItemCategoryIds?r.lineItemCategoryIds.split(",").map(I=>I.trim()).filter(I=>I):void 0,withSkus:r.lineItemSkus&&r.lineItemSkuList?r.lineItemSkuList.split(",").map(I=>I.trim()).filter(I=>I):void 0,withTypes:r.lineItemTypes?Object.entries(r.lineItemProductTypes).filter(([,I])=>I).map(([I])=>I):void 0,collaboratorOwned:r.lineItemCollaboratorOwned}:void 0,postConversionActions:r.postConversionActions??[],...v?{engagementFilters:r.engagementFilters??[]}:{}};let Je;try{Je=y?await w(nt):await R(parseInt(p),nt)}catch{return}if(!h&&b.isDirty)try{await b.save(Je.id)}catch(I){const ce=I instanceof Error?I.message:s("Failed to save where this program runs.");A(ce),Tn.error(ce),y&&P(`/programs/${Je.id}`,{replace:!0});return}P("/programs")},re=(t,l)=>{L(c=>({...c,[t]:l}))},rs=(t,l,c)=>{L(o=>({...o,engagementTypes:{...o.engagementTypes,[t]:{...o.engagementTypes[t],[l]:c}}}))},zs=(t,l,c)=>{L(o=>({...o,engagementTypes:{...o.engagementTypes,[t]:{...o.engagementTypes[t],calculationArgs:{...o.engagementTypes[t].calculationArgs,[l]:c}}}}))},Ft=(t,l)=>{L(c=>{const o={...c,transactionCompilers:{...c.transactionCompilers,[t]:l}};return t==="includeLineItems"&&!l&&(o.lineItemCategories=!1,o.lineItemCategoryIds="",o.lineItemSkus=!1,o.lineItemSkuList="",o.lineItemTypes=!1,o.lineItemProductTypes={products:!0,subscriptions:!0},o.lineItemCollaboratorOwned=!1),o})},Et=(t,l)=>{L(c=>{const o={...c,[t]:l};if(!l)switch(t){case"lineItemCategories":o.lineItemCategoryIds="";break;case"lineItemSkus":o.lineItemSkuList="";break;case"lineItemTypes":o.lineItemProductTypes={products:!0,subscriptions:!0};break}return o})},Ge=(t,l)=>{L(c=>({...c,incentiveConfig:{...c.incentiveConfig,[t]:l}}))},Rt=()=>{var t;return e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"auto-approve",checked:(t=r.incentiveConfig)==null?void 0:t.autoApprove,onCheckedChange:l=>Ge("autoApprove",l===!0)}),e.jsx(F,{htmlFor:"auto-approve",className:"font-normal",children:"Auto Approve Completed Transactions"})]})},Ys=t=>{var j;const l=(j=r.incentiveConfig)==null?void 0:j.activeConversionTypes,c=Array.isArray(l)?l:[],o=c.includes(t)?c.filter(T=>T!==t):[...c,t];Ge("activeConversionTypes",o)},Ke=f==null?void 0:f.featureSupport,Xs=(Ke==null?void 0:Ke.recurringCommissions)!==!1,Ks=(Ke==null?void 0:Ke.leads)!==!1,Js=Object.values(r.engagementTypes).some(t=>t.enabled),Qs=(Array.isArray((os=r.incentiveConfig)==null?void 0:os.activeConversionTypes)?r.incentiveConfig.activeConversionTypes:[]).length>0,Zs=Object.values(r.transactionCompilers).some(t=>t),en=r.lineItemCategories&&!r.lineItemCategoryIds.trim(),tn=r.lineItemSkus&&!r.lineItemSkuList.trim(),sn=r.lineItemTypes&&!Object.values(r.lineItemProductTypes).some(t=>t),nn=en||tn||sn,rn=(()=>{var t,l,c,o;switch(r.incentiveType){case"saleTransactionPercentage":{const j=(t=r.incentiveConfig)==null?void 0:t.transactionPercent;return j!=null&&j>=ie.MIN_PERCENT&&j<=ie.MAX_PERCENT}case"saleFixedPerTransaction":{const j=(l=r.incentiveConfig)==null?void 0:l.payoutPerTransaction;return j!=null&&j>0}case"saleFixedPerProduct":{const j=(c=r.incentiveConfig)==null?void 0:c.payoutPerProduct;return j!=null&&j>0}case"leadFixed":{const j=(o=r.incentiveConfig)==null?void 0:o.payoutPerLead;return j!=null&&j>=0}default:return!0}})(),ut=m.useMemo(()=>Cs(r.units,te),[r.units,te]),as=(f==null?void 0:f.postConversionActions)??[],an=!x&&Te.some(t=>t.id===As&&!as.includes(t.id)),on=Te.filter(t=>t.id!==As||x||as.includes(t.id)),Dt=pr([[r.name.trim()!=="",{key:"name",message:s("Enter a name."),targetId:"name"}],[!!r.units,{key:"units",message:s("Choose a currency."),targetId:"units"}],[!(Xe==="group"&&!r.collaboratorGroupId),{key:"collaboratorGroup",message:s("Choose a collaborator group, or switch to adding collaborators directly."),targetId:"collaboratorGroup"}],[Js,{key:"engagementTypes",message:s("Choose at least one engagement type."),targetId:"engagement-tracking"}],[Zs,{key:"commissionComponents",message:s("Under Commission Calculation, choose at least one part of the transaction, such as Line Items."),targetId:"commission-calculation"}],[!nn,{key:"lineItemFilters",message:s("Finish the line item filter you turned on, or turn it off."),targetId:"commission-calculation"}],[rn,{key:"commissionAmount",message:r.incentiveType==="saleTransactionPercentage"?s("Enter a commission rate from 0 to 100."):s("Enter the commission amount."),targetId:"incentive-structure"}],[Qs,{key:"conversionTypes",message:s("Choose at least one conversion type to credit."),targetId:"incentive-structure"}]]),ln=H||Dt.length>0,is=t=>{let l=ve[t]||[];return Xs||(l=l.filter(c=>c!=="renewal")),Ks||(l=l.filter(c=>c!=="lead")),l},cn=t=>{const l=is(t);L(c=>{var T;if(l.length===0)return{...c,incentiveType:t};const j=(Array.isArray((T=c.incentiveConfig)==null?void 0:T.activeConversionTypes)?c.incentiveConfig.activeConversionTypes:[]).filter(O=>l.includes(O));return{...c,incentiveType:t,incentiveConfig:{...c.incentiveConfig,activeConversionTypes:j.length>0?j:[l[0]]}}})},pt=t=>{var j;const l=is(t);if(l.length===0)return e.jsxs("div",{className:"space-y-2",children:[e.jsx(F,{children:"Credit Conversions For..."}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"No conversion types available."})]});const c=(j=r.incentiveConfig)==null?void 0:j.activeConversionTypes,o=Array.isArray(c)?c:[];return e.jsxs("div",{className:"space-y-2",children:[e.jsx(F,{children:"Credit Conversions For..."}),e.jsx("div",{className:"space-y-2",children:l.map(T=>e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:`conversion-${T}`,checked:o.includes(T),onCheckedChange:()=>Ys(T)}),e.jsx(F,{htmlFor:`conversion-${T}`,className:"font-normal",children:we[T]||T})]},T))})]})},dn=t=>{!t||d||Pe||xe()},mn=t=>{if(t&&!r.transactionCompilers.includeTaxes){et(!0),ze(!0);return}Ft("includeTaxes",t)},un=!a.available&&!r.lineItemCategories,pn=()=>e.jsxs(e.Fragment,{children:[un?e.jsx(Ss,{inUse:!1}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"lineItemCategories",checked:r.lineItemCategories,onCheckedChange:t=>Et("lineItemCategories",t===!0)}),e.jsxs(F,{htmlFor:"lineItemCategories",className:"font-normal flex items-center",children:["In all of these Categories",e.jsx(G,{topic:"filter-by-category",side:"right",onLearnMore:$})]})]}),r.lineItemCategories&&e.jsx("div",{className:"ml-6 pl-4 border-l",children:e.jsx(me,{placeholder:s("Enter category slugs (comma-separated)"),value:r.lineItemCategoryIds||"",onChange:t=>re("lineItemCategoryIds",t.target.value)})})]}),!a.available&&r.lineItemCategories&&e.jsx(Ss,{inUse:!0}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"lineItemSkus",checked:r.lineItemSkus,onCheckedChange:t=>Et("lineItemSkus",t===!0)}),e.jsxs(F,{htmlFor:"lineItemSkus",className:"font-normal flex items-center",children:["With Any of these SKUs",e.jsx(G,{topic:"filter-by-sku",side:"right",onLearnMore:$})]})]}),r.lineItemSkus&&e.jsx("div",{className:"ml-6 pl-4 border-l",children:e.jsx(me,{placeholder:s("Enter SKUs (comma-separated)"),value:r.lineItemSkuList||"",onChange:t=>re("lineItemSkuList",t.target.value)})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"lineItemTypes",checked:r.lineItemTypes,onCheckedChange:t=>Et("lineItemTypes",t===!0)}),e.jsxs(F,{htmlFor:"lineItemTypes",className:"font-normal flex items-center",children:["With Any of these Types",e.jsx(G,{topic:"filter-by-type",side:"right",onLearnMore:$})]})]}),r.lineItemTypes&&e.jsxs("div",{className:"ml-6 pl-4 border-l space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"typeProducts",checked:r.lineItemProductTypes.products,onCheckedChange:t=>L(l=>({...l,lineItemProductTypes:{...l.lineItemProductTypes,products:t===!0}}))}),e.jsx(F,{htmlFor:"typeProducts",className:"font-normal",children:"Products"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"typeSubscriptions",checked:r.lineItemProductTypes.subscriptions,onCheckedChange:t=>L(l=>({...l,lineItemProductTypes:{...l.lineItemProductTypes,subscriptions:t===!0}}))}),e.jsx(F,{htmlFor:"typeSubscriptions",className:"font-normal",children:"Subscriptions"})]})]})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(ee,{id:"lineItemCollaboratorOwned",checked:r.lineItemCollaboratorOwned,onCheckedChange:t=>re("lineItemCollaboratorOwned",t===!0)}),e.jsxs(F,{htmlFor:"lineItemCollaboratorOwned",className:"font-normal flex items-center",children:["Collaborator Owned Products Only",e.jsx(G,{topic:"filter-collaborator-owned",side:"right",onLearnMore:$})]})]})]});return _&&!y?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(zt,{})}):e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:s(y?"New Program":"Edit Program")}),U&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:U}),e.jsxs("div",{className:"flex gap-8 items-start relative",children:[e.jsxs("form",{onSubmit:Hs,className:"flex-1 min-w-0 max-w-2xl space-y-6 min-h-0 pb-[50vh]",children:[e.jsxs("div",{className:"space-y-4","data-tour":"program-form-basics",children:[e.jsx(Ne,{label:s("Name"),htmlFor:"name",required:!0,error:Ce(se,"name"),children:e.jsx(me,{id:"name",value:r.name,onChange:t=>re("name",t.target.value),placeholder:s("e.g., Referral Program - Lead Gen")})}),e.jsx(Ne,{label:s("Description"),htmlFor:"description",error:Ce(se,"description"),children:e.jsx(me,{id:"description",value:r.description,onChange:t=>re("description",t.target.value),placeholder:s("Describe what this program offers")})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(F,{htmlFor:"status",children:s("Status")}),e.jsxs(We,{value:r.status,onValueChange:t=>re("status",t),children:[e.jsx($e,{id:"status",children:e.jsx(Ve,{})}),e.jsxs(qe,{children:[e.jsx(S,{value:"draft",children:s("Draft")}),e.jsx(S,{value:"active",children:s("Active")}),e.jsx(S,{value:"inactive",children:s("Inactive")})]})]})]}),e.jsx(Ne,{label:"Currency",htmlFor:"units",required:!0,error:Ce(se,"units"),children:e.jsxs(We,{value:r.units,onValueChange:t=>{if(!t||t===r.units)return;const l=Cs(t,te);re("units",t),L(c=>({...c,incentiveConfig:c.incentiveConfig?Bn(c.incentiveConfig,ut,l):c.incentiveConfig}))},onOpenChange:dn,children:[e.jsx($e,{id:"units",children:e.jsx(Ve,{placeholder:s("Select currency")})}),e.jsx(qe,{children:Pe?e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:"Loading currencies..."}):te.length>0?te.map(t=>e.jsx(S,{value:t.code,children:gr(t)},t.code)):e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:"No currencies available"})})]})})]}),!1,e.jsx(Ne,{label:e.jsxs("span",{children:["Engagement Expiration (Days)",e.jsx(G,{topic:"expiration-days",onLearnMore:$})]}),htmlFor:"expirationDays",description:"How long an engagement remains valid. Leave empty for no expiration.",error:Ce(se,"expirationDays"),children:e.jsx(me,{id:"expirationDays",type:"number",min:"0",value:r.expirationDays??"",onChange:t=>re("expirationDays",t.target.value?parseInt(t.target.value):void 0),placeholder:s("e.g., 60")})})]}),!h&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(jr,{draft:b}),k?e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:k}):null]}),!1,C,g,e.jsxs(z,{id:"engagement-tracking","data-tour":"program-form-engagements",className:ke("transition-all duration-300",_e==="engagement-tracking"&&"animate-glow ring-2 ring-primary",ye==="engagement-tracking"&&"ring-2 ring-primary/40"),children:[e.jsxs(Y,{children:[e.jsxs(X,{children:["Engagement Tracking Events",e.jsx(G,{topic:"what-is-engagement",onLearnMore:$})]}),e.jsx(ue,{children:"Select which customer interactions create engagements for attribution"})]}),e.jsx(K,{className:"space-y-4",children:q.engagementTypes?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading engagement types..."}):ge.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No engagement types available. Please check your backend configuration."}):ge.map(t=>{var l,c,o,j;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(ee,{id:`engagement-${t.id}`,checked:((l=r.engagementTypes[t.id])==null?void 0:l.enabled)??!1,onCheckedChange:T=>rs(t.id,"enabled",T===!0)}),e.jsxs("div",{className:"grid gap-1.5 leading-none",children:[e.jsxs(F,{htmlFor:`engagement-${t.id}`,className:"font-normal flex items-center",children:[t.name,Be[t.id]&&e.jsx(G,{topic:Be[t.id],side:"right",onLearnMore:$})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]}),((c=r.engagementTypes[t.id])==null?void 0:c.enabled)&&e.jsx("div",{className:"ml-6 pl-4 border-l space-y-2",children:e.jsx(fr,{options:V,value:((o=r.engagementTypes[t.id])==null?void 0:o.calculationType)??"fixed",args:((j=r.engagementTypes[t.id])==null?void 0:j.calculationArgs)??{},onChangeStrategy:T=>rs(t.id,"calculationType",T),onChangeArg:(T,O)=>zs(t.id,T,O),idPrefix:`engagement-calc-${t.id}`,label:"Calculation",helpTopic:"engagement-calculation",helpTopicByArg:{value:"engagement-points",pointsAtLayer1:"engagement-cascade-layer",pointsAtLayer2:"engagement-cascade-layer",pointsAtLayer3:"engagement-cascade-layer",pointsAtLayer4:"engagement-cascade-layer",pointsAtLayer5:"engagement-cascade-layer"},onHelpLearnMore:$})})]},t.id)})})]}),e.jsxs(z,{id:"attribution-model","data-tour":"program-form-attribution",className:ke("transition-all duration-300",_e==="attribution-model"&&"animate-glow ring-2 ring-primary",ye==="attribution-model"&&"ring-2 ring-primary/40"),children:[e.jsxs(Y,{children:[e.jsxs(X,{children:["Attribution Model",e.jsx(G,{topic:"attribution-model",onLearnMore:$})]}),e.jsx(ue,{children:"How credit is assigned when multiple collaborators engage a customer before conversion"})]}),e.jsx(K,{children:q.incentiveResolvers?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading attribution models..."}):Le.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No attribution models available. Please check your backend configuration."}):e.jsx($t,{value:r.incentiveResolverType,onValueChange:t=>{t==="EveryBindingWins"&&r.incentiveResolverType!=="EveryBindingWins"?(Oe(t),Me(!0)):re("incentiveResolverType",t)},children:Le.map(t=>e.jsxs("div",{className:"flex items-start space-x-2 py-1",children:[e.jsx(Tt,{value:t.id,id:`resolver-${t.id}`,className:"mt-0.5"}),e.jsxs("div",{className:"grid gap-0.5 leading-none",children:[e.jsxs(F,{htmlFor:`resolver-${t.id}`,className:"font-normal flex items-center",children:[t.name,Be[t.id]&&e.jsx(G,{topic:Be[t.id],side:"right",onLearnMore:$})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]},t.id))})})]}),e.jsxs(z,{id:"commission-calculation",className:ke("transition-all duration-300",_e==="commission-calculation"&&"animate-glow ring-2 ring-primary",ye==="commission-calculation"&&"ring-2 ring-primary/40"),children:[e.jsxs(Y,{children:[e.jsxs(X,{children:["Commission Calculation",e.jsx(G,{topic:"commission-calculation",onLearnMore:$})]}),e.jsx(ue,{children:"Select which parts of the transaction are included when calculating commissions"})]}),e.jsx(K,{className:"space-y-4",children:q.transactionCompilers?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading transaction compilers..."}):e.jsx(vr,{options:Fe.map(t=>({id:t.id,label:t.name,description:t.description,helpTopic:Be[t.id]})),enabled:r.transactionCompilers,onToggle:(t,l)=>t==="includeTaxes"?mn(l):Ft(t,l),renderLineItemOptions:pn,onLearnMore:$})})]}),e.jsxs(z,{id:"incentive-structure","data-tour":"program-form-rewards",className:ke("transition-all duration-300",_e==="incentive-structure"&&"animate-glow ring-2 ring-primary",ye==="incentive-structure"&&"ring-2 ring-primary/40"),children:[e.jsxs(Y,{children:[e.jsxs(X,{children:["Incentive Structure",e.jsx(G,{topic:"incentive-structure",onLearnMore:$})]}),e.jsx(ue,{children:"Define how rewards are calculated for conversions"})]}),e.jsx(K,{className:"space-y-4",children:q.incentiveTypes?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading incentive types..."}):Ae.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No incentive types available. Please check your backend configuration."}):e.jsx($t,{value:r.incentiveType,onValueChange:cn,children:Ae.map(t=>{var l,c,o,j,T;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(Tt,{value:t.id,id:`incentive-${t.id}`,className:"mt-0.5"}),e.jsxs("div",{className:"grid gap-0.5 leading-none",children:[e.jsxs(F,{htmlFor:`incentive-${t.id}`,className:"font-normal flex items-center",children:[t.name,Be[t.id]&&e.jsx(G,{topic:Be[t.id],side:"right",onLearnMore:$})]}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description})]})]}),r.incentiveType===t.id&&e.jsxs("div",{className:"ml-6 pl-4 border-l space-y-4",children:[t.id==="saleTransactionPercentage"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Percent",htmlFor:"transactionPercent",required:!0,error:Ce(se,"incentiveConfig"),children:e.jsx(me,{id:"transactionPercent",type:"number",min:"0",max:"100",step:"0.01",value:((l=r.incentiveConfig)==null?void 0:l.transactionPercent)??"",onChange:O=>Ge("transactionPercent",parseFloat(O.target.value)||0)})}),pt(t.id),Rt()]}),t.id==="saleFixedPerTransaction"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerTransaction",required:!0,error:Ce(se,"incentiveConfig"),children:e.jsx(vt,{id:"payoutPerTransaction",min:"0",definition:ut,value:(c=r.incentiveConfig)==null?void 0:c.payoutPerTransaction,onChange:O=>Ge("payoutPerTransaction",O)})}),pt(t.id),Rt()]}),t.id==="saleFixedPerProduct"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerProduct",required:!0,error:Ce(se,"incentiveConfig"),children:e.jsx(vt,{id:"payoutPerProduct",min:"0",definition:ut,value:(o=r.incentiveConfig)==null?void 0:o.payoutPerProduct,onChange:O=>Ge("payoutPerProduct",O)})}),pt(t.id),Rt()]}),t.id==="leadFixed"&&e.jsxs(e.Fragment,{children:[e.jsx(Ne,{label:"Payout Amount",htmlFor:"payoutPerLead",required:!0,error:Ce(se,"incentiveConfig"),children:e.jsx(vt,{id:"payoutPerLead",min:"0",definition:ut,value:(j=r.incentiveConfig)==null?void 0:j.payoutPerLead,onChange:O=>Ge("payoutPerLead",O)})}),e.jsx(Ne,{label:"Lead Re-Qualification Window (Days)",htmlFor:"leadRequalificationDays",description:"How long before the same lead can qualify again.",error:Ce(se,"incentiveConfig"),children:e.jsx(me,{id:"leadRequalificationDays",type:"number",min:"0",value:((T=r.incentiveConfig)==null?void 0:T.leadRequalificationDays)??"",onChange:O=>Ge("leadRequalificationDays",O.target.value?parseInt(O.target.value):void 0),placeholder:s("e.g., 90")})}),pt(t.id)]})]})]},t.id)})})})]}),Te.length>0&&e.jsxs(z,{id:"post-conversion-actions",className:ke("transition-all duration-300",_e==="post-conversion-actions"&&"animate-glow ring-2 ring-primary",ye==="post-conversion-actions"&&"ring-2 ring-primary/40"),children:[e.jsxs(Y,{children:[e.jsx(X,{children:s("Post-Conversion Actions")}),e.jsx(ue,{children:s("Automatically run these actions whenever a conversion in this program is approved.")})]}),e.jsxs(K,{children:[e.jsx(yr,{options:on,selected:r.postConversionActions??[],onChange:t=>re("postConversionActions",t),loading:q.postConversionActionTypes,idPrefix:"post-conversion-action"}),an&&e.jsx(Zn.PlanUpgradeNotice,{className:"mt-3",feature:s("lifetime customer links"),plan:"plus"})]})]}),e.jsx(ur,{id:"program-requirements",intro:s(y?"Before you can create this program:":"Before you can save this program:"),requirements:Dt}),e.jsxs("div",{className:"flex gap-2","data-tour":"program-form-save",children:[e.jsx(E,{type:"submit",disabled:ln,"aria-describedby":Dt.length>0?"program-requirements":void 0,children:H?"Saving...":s(y?"Create":"Update")}),e.jsx(E,{type:"button",variant:"outline",onClick:()=>P("/programs"),children:s("Cancel")})]})]}),e.jsx("aside",{className:"hidden lg:block w-72 flex-shrink-0 sticky top-4 h-fit max-h-[calc(100vh-2rem)] overflow-y-auto",children:e.jsx(Ws,{engagementTypes:Object.entries(r.engagementTypes).filter(([,t])=>t.enabled).map(([t])=>t),resolverType:r.incentiveResolverType,incentiveType:r.incentiveType,collaboratorGroupName:Xe==="group"&&r.collaboratorGroupId?((ls=tt.find(t=>t.id===r.collaboratorGroupId))==null?void 0:ls.name)??null:null,transactionCompilers:Object.entries(r.transactionCompilers).filter(([,t])=>t).map(([t])=>t),lineItemFilters:r.transactionCompilers.includeLineItems?{hasCategories:r.lineItemCategories,hasSkus:r.lineItemSkus,hasTypes:r.lineItemTypes,productTypes:r.lineItemTypes?Object.entries(r.lineItemProductTypes).filter(([,t])=>t).map(([t])=>t):void 0,collaboratorOwned:r.lineItemCollaboratorOwned,categoryIds:r.lineItemCategoryIds,skuList:r.lineItemSkuList}:void 0,commissionConfig:{transactionPercent:(cs=r.incentiveConfig)==null?void 0:cs.transactionPercent,payoutPerTransaction:(ds=r.incentiveConfig)==null?void 0:ds.payoutPerTransaction,payoutPerProduct:(ms=r.incentiveConfig)==null?void 0:ms.payoutPerProduct,payoutPerLead:(us=r.incentiveConfig)==null?void 0:us.payoutPerLead},formatAmount:t=>Nn(t,r.units,{definitions:te}),conversionTypes:(ps=r.incentiveConfig)==null?void 0:ps.activeConversionTypes,postConversionActions:r.postConversionActions,engagementFilters:r.engagementFilters,engagementFilterLabels:Re,onStepClick:Us,activeSection:ye})})]}),e.jsx(Qn,{topic:ne,open:!!ne,onOpenChange:t=>!t&&$(null)}),e.jsx(yt,{open:Qe,onOpenChange:Me,children:e.jsxs(jt,{children:[e.jsxs(bt,{children:[e.jsx(Ct,{children:"Confirm: All Get Paid"}),e.jsxs(Nt,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:e.jsx("strong",{children:"This attribution model pays the FULL commission to EVERY collaborator."})}),e.jsxs("p",{children:["Example: If your commission is $100 per order and 3 collaborators have engagements, you will pay ",e.jsx("strong",{children:"$300 total"})," ($100 × 3 collaborators)."]}),e.jsx("p",{className:"text-amber-700 dark:text-amber-400",children:"This is not a split. Your payout costs multiply with each engaged collaborator."})]})]}),e.jsxs(Vt,{children:[e.jsx(E,{variant:"outline",onClick:()=>{Me(!1),Oe(null)},children:s("Cancel")}),e.jsx(E,{onClick:()=>{Ie&&re("incentiveResolverType",Ie),Me(!1),Oe(null)},children:"I Understand, Enable It"})]})]})}),e.jsx(yt,{open:wt,onOpenChange:ze,children:e.jsxs(jt,{children:[e.jsxs(bt,{children:[e.jsx(Ct,{children:"Include Taxes in Commission?"}),e.jsxs(Nt,{className:"space-y-3 pt-2",children:[e.jsx("p",{children:"Including taxes means you will pay commissions on amounts that are typically passed directly to the government."}),e.jsx("p",{children:"Most programs exclude taxes. If you enable this, your total commission costs will increase."})]})]}),e.jsxs(Vt,{children:[e.jsx(E,{variant:"outline",onClick:()=>{ze(!1),et(null)},children:s("Cancel")}),e.jsx(E,{onClick:()=>{ct!==null&&Ft("includeTaxes",ct),ze(!1),et(null)},children:"Include Taxes"})]})]})})]})}function Ir(n){return n?Array.isArray(n)?n.map(s=>s.type):Object.keys(n):[]}const wr={saleFixedPerTransaction:"Fixed per Transaction",saleTransactionPercentage:"Percentage of Transaction",saleFixedPerProduct:"Fixed per Product",leadFixed:"Fixed per Lead"},Sr={newestBindingWins:"Newest Engagement Wins",oldestBindingWins:"Oldest Engagement Wins",evenlySharedPool:"Even Split",performanceSharedPool:"Performance Weighted",EveryBindingWins:"All Get Paid",topScoreWins:"Top Score Wins"},kr={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red"},Ar={active:"status-badge status-green",expired:"status-badge status-gray",converted:"status-badge status-blue"},Lr={active:"status-badge status-green",pending:"status-badge status-yellow",inactive:"status-badge status-gray",rejected:"status-badge status-red"};function Fr(){var Ae,Le,Fe,he,Te,Ee,Pe;const{translate:n}=pe(),{formatMoney:s,currencyName:u}=rr(),{id:h}=Ds(),v=Ht(),{isWordPress:g,extensions:C}=rt(),x=C.programApplicationForms,{current:a,isLoading:p,error:P,fetchOne:y,clearCurrent:b}=Yt(),{items:k,isLoading:A,fetchList:J}=sr(),{items:f,isLoading:_,fetchList:H}=nr(),{items:U,isLoading:N,fetchList:w}=$s();m.useEffect(()=>{if(h){const d=parseInt(h);y(d),J({programId:d,perPage:10,status:"pending,approved,complete,rejected",orderBy:"dateCreated",order:"desc"}),H({programId:d,perPage:10,status:"active,complete,expired",orderBy:"dateCreated",order:"desc"}),w({programId:d,perPage:10,status:"active,pending,inactive,rejected"})}return()=>b()},[h,y,b,J,H,w]);const R=d=>d?new Date(d).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}):"—",oe=(d,q)=>s(d,q),Ue=[{id:"id",header:n("ID"),cell:d=>e.jsxs(de,{to:`/conversions/${d.id}`,className:"font-mono text-primary hover:underline",children:["#",d.id]})},{id:"collaborator",header:n("Collaborator"),cell:d=>Is(d.collaboratorName,"collaborator",n)},{id:"type",header:n("Type"),cell:d=>e.jsx("span",{className:"capitalize",children:d.type})},{id:"amount",header:n("Amount"),cell:d=>oe(d.amount,d.obligationAwardType||(a==null?void 0:a.units))},{id:"status",header:n("Status"),cell:d=>e.jsx("span",{className:kr[d.status],children:d.status})},{id:"date",header:n("Date"),cell:d=>R(d.dateCreated)}],te=[{id:"id",header:n("ID"),cell:d=>e.jsxs(de,{to:`/engagements/${d.id}`,className:"font-mono text-primary hover:underline",children:["#",d.id]})},{id:"collaborator",header:n("Collaborator"),cell:d=>Is(d.collaboratorName,"collaborator",n)},{id:"score",header:n("Score"),cell:d=>d.score},{id:"status",header:n("Status"),cell:d=>e.jsx("span",{className:Ar[d.status],children:d.status})},{id:"date",header:n("Date"),cell:d=>R(d.dateCreated)}],ge=[{id:"name",header:n("Name"),cell:d=>e.jsx(de,{to:`/collaborators/${d.id}/view`,className:"text-primary hover:underline",children:ar(d)})},{id:"email",header:n("Email"),cell:d=>d.email},{id:"status",header:n("Status"),cell:d=>e.jsx("span",{className:Lr[d.status],children:d.status})}];return p?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(zt,{label:n("Loading program...")})}):P?e.jsx("div",{className:"p-4 bg-destructive/10 text-destructive rounded-md",children:P}):a?e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!g&&e.jsx(E,{variant:"ghost",size:"icon",onClick:()=>v("/programs"),"aria-label":n("Back"),children:e.jsx(ir,{className:"h-4 w-4"})}),e.jsxs("div",{className:"flex-1 min-w-[min(100%,14rem)]","data-tour":"program-heading",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:a.name}),e.jsx(Ms,{status:a.status})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:a.description})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Gs,{sourceType:"program",sourceId:a.id,contextLabel:a.name}),e.jsx(E,{asChild:!0,"data-tour":"program-edit",children:e.jsxs(de,{to:`/programs/${a.id}`,children:[e.jsx(Dn,{className:"h-4 w-4 mr-2"}),n("Edit Program")]})})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-3",children:[e.jsx(Ws,{engagementTypes:Ir(a.engagementTypes),resolverType:a.incentiveResolverType,incentiveType:a.incentiveType,transactionCompilers:a.transactionCompilers||[],lineItemFilters:a.lineItemFilters?{hasCategories:(((Ae=a.lineItemFilters.inCategories)==null?void 0:Ae.length)??0)>0,hasSkus:(((Le=a.lineItemFilters.withSkus)==null?void 0:Le.length)??0)>0,hasTypes:(((Fe=a.lineItemFilters.withTypes)==null?void 0:Fe.length)??0)>0,productTypes:a.lineItemFilters.withTypes,collaboratorOwned:a.lineItemFilters.collaboratorOwned,categoryIds:((he=a.lineItemFilters.inCategories)==null?void 0:he.join(", "))||"",skuList:((Te=a.lineItemFilters.withSkus)==null?void 0:Te.join(", "))||""}:void 0,commissionConfig:Bs(a.incentiveCalculation||a.incentiveConfig||{}),formatAmount:d=>s(d,a.units),conversionTypes:((Ee=a.incentiveCalculation)==null?void 0:Ee.activeConversionTypes)||((Pe=a.incentiveConfig)==null?void 0:Pe.activeConversionTypes),postConversionActions:a.postConversionActions,engagementFilters:a.engagementFilters}),e.jsxs(z,{"data-tour":"program-rewards",children:[e.jsxs(Y,{children:[e.jsx(X,{children:n("Configuration")}),e.jsx(ue,{children:n("Program settings and incentive structure")})]}),e.jsxs(K,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Incentive Type")}),e.jsx("dd",{className:"font-medium",children:wr[a.incentiveType]||a.incentiveType})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Credit Split")}),e.jsx("dd",{className:"font-medium",children:Sr[a.incentiveResolverType]||a.incentiveResolverType})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Currency")}),e.jsx("dd",{className:"font-medium",children:u(a.units)})]}),typeof a.expirationDays=="number"&&a.expirationDays>0&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Engagement Expiration")}),e.jsxs("dd",{className:"font-medium",children:[a.expirationDays," days"]})]}),!g&&e.jsxs("dl",{className:"min-w-0",children:[e.jsxs("dt",{className:"text-sm text-muted-foreground flex items-center",children:[n("Runs on"),e.jsx(G,{topic:"program-properties",side:"right"})]}),e.jsx("dd",{className:"font-medium break-words",children:e.jsx(br,{programId:a.id})})]})]}),(a.incentiveCalculation||a.incentiveConfig)&&(()=>{const d=a.incentiveCalculation||a.incentiveConfig;return e.jsxs("div",{className:"pt-4 border-t space-y-2",children:[(d==null?void 0:d.transactionPercent)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Commission Rate")}),e.jsxs("span",{className:"font-medium",children:[d.transactionPercent,"%"]})]}),(d==null?void 0:d.payoutPerTransaction)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Transaction")}),e.jsx("span",{className:"font-medium",children:oe(d.payoutPerTransaction,a.units)})]}),(d==null?void 0:d.payoutPerProduct)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Product")}),e.jsx("span",{className:"font-medium",children:oe(d.payoutPerProduct,a.units)})]}),(d==null?void 0:d.payoutPerLead)!=null&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Payout per Lead")}),e.jsx("span",{className:"font-medium",children:oe(d.payoutPerLead,a.units)})]}),(d==null?void 0:d.autoApprove)!==void 0&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:n("Auto-Approve")}),e.jsx("span",{className:"font-medium",children:d.autoApprove?"Yes":"No"})]})]})})()]})]}),e.jsxs(z,{"data-tour":"program-stats",children:[e.jsxs(Y,{children:[e.jsx(X,{children:n("Statistics")}),e.jsx(ue,{children:n("Program performance metrics")})]}),e.jsxs(K,{className:"space-y-4",children:[e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Collaborators")}),e.jsx("dd",{className:"font-medium",children:e.jsxs(de,{to:`/collaborators?programId=${a.id}`,className:"text-primary hover:underline",children:[a.collaboratorCount??0," enrolled"]})})]}),e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Engagements")}),e.jsxs("dd",{className:"font-medium",children:[a.engagementsCount??0," total"]})]}),!1,a.engagementTypes&&a.engagementTypes.length>0&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Tracked Engagement Types")}),e.jsx("dd",{className:"font-medium text-sm",children:a.engagementTypes.map(d=>d.type.replace(/([A-Z])/g," $1").trim()).join(", ")})]}),a.createdDate&&e.jsxs("dl",{children:[e.jsx("dt",{className:"text-sm text-muted-foreground",children:n("Created")}),e.jsx("dd",{className:"font-medium",children:R(a.createdDate)})]})]})]})]}),x&&a&&e.jsx("div",{className:"mt-8",children:e.jsx(x,{programId:a.id})}),e.jsx("div",{className:"mt-8",children:e.jsxs(z,{children:[e.jsxs(Y,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(X,{children:n("Recent Conversions")}),e.jsx(ue,{children:n("Latest conversions for this program")})]}),e.jsx(E,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(de,{to:`/conversions?programId=${a.id}`,children:n("View All")})})]}),e.jsx(K,{children:e.jsx(ft,{columns:Ue,data:k,isLoading:A,emptyMessage:n("No conversions yet for this program.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(z,{children:[e.jsxs(Y,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(X,{children:n("Recent Engagements")}),e.jsx(ue,{children:n("Latest engagements for this program")})]}),e.jsx(E,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(de,{to:`/engagements?programId=${a.id}`,children:n("View All")})})]}),e.jsx(K,{children:e.jsx(ft,{columns:te,data:f,isLoading:_,emptyMessage:n("No engagements yet for this program.")})})]})}),e.jsx("div",{className:"mt-6",children:e.jsxs(z,{"data-tour":"program-collaborators",children:[e.jsxs(Y,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(X,{children:n("Enrolled Collaborators")}),e.jsx(ue,{children:n("Collaborators participating in this program")})]}),e.jsx(E,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(de,{to:`/collaborators?programId=${a.id}`,children:n("View All")})})]}),e.jsx(K,{children:e.jsx(ft,{columns:ge,data:U,isLoading:N,emptyMessage:n("No collaborators enrolled yet.")})})]})})]}):e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx("p",{className:"text-muted-foreground",children:n("Program not found.")})})}window.sirenConfig&&Pn({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Fs=document.getElementById("siren-programs");var Es;Fs&&In.createRoot(Fs).render(e.jsx(m.StrictMode,{children:e.jsxs(zn,{defaultRoute:"/programs",capabilities:(Es=window.sirenConfig)==null?void 0:Es.capabilities,children:[e.jsx(wn,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(Sn,{children:[e.jsx(Se,{path:"/programs",element:e.jsx(ws,{})}),e.jsx(Se,{path:"/programs/new",element:e.jsx(Ls,{})}),e.jsx(Se,{path:"/programs/:id",element:e.jsx(Ls,{})}),e.jsx(Se,{path:"/programs/:id/view",element:e.jsx(Fr,{})}),e.jsx(Se,{path:"/recipes/browse",element:e.jsx(Wn,{})}),e.jsx(Se,{path:"/recipes/browse/:slug",element:e.jsx($n,{})}),e.jsx(Se,{path:"/import/imports/:jobId",element:e.jsx(Vn,{})}),e.jsx(Se,{index:!0,element:e.jsx(ws,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/transactions.js

    r3775642 r3788740  
    1 import{t as Z,v as ee,u as xe,r as x,b as _e,j as e,B as S,L as oe,S as G,d as K,e as J,f as X,g as E,D as Me,h as $e,i as ze,k as Ue,l as He,m as Qe,n as We,a as Ce,w as Ge,o as Ke,C as z,p as U,q as H,s as Q,x as Je,I as ie,W as Xe,A as Ye,E as Ze,F as es,T as ss,R as ts,G as W}from"./shared/wordpress-admin-DNnGQGoM.js";import{c as as}from"./shared/request-sequence-CQbIQ_gd.js";import{e as ns,o as te,s as b,n as h,a as de,b as Se,r as rs,c as ls,A as we}from"./shared/ActivityDrawer-iYDgZTH3.js";import{c as is}from"./shared/react-zvEYxxW2.js";import{u as cs,g as ge,v as os}from"./shared/validation-f7jbdrjp.js";import{u as Te}from"./shared/registries-Ql2SZeKd.js";import{a as Ie,t as De,T as ds}from"./shared/transaction-status-DFlw8wS1.js";import{F as us,H as ue,a as ms,B as xs,D as Pe,T as hs}from"./shared/HelpTooltip-DsFyDQG4.js";import{T as ps}from"./shared/TestSaleBadge-DCBR_ipH.js";import{u as he}from"./shared/useMoneyFormatter-BaBJUw_5.js";import{P as Le}from"./shared/plus-xgV5QLEC.js";import{u as fs}from"./shared/conversions-HMIw6T3R.js";import{l as js}from"./shared/linked-record-D4sO5j3k.js";import{A as gs}from"./shared/arrow-left-W0B3m2vw.js";import{W as bs}from"./shared/WordPressRouter-ifxiIFvs.js";import"./shared/collaborators-BvingK76.js";import"./shared/unshipped-CGZcvpGp.js";const vs=ns(["pending","complete","failed","cancelled","refunded","unknown"]),ys=te({id:h(),transactionId:h(),name:b(),description:b().nullish(),type:b(),value:h(),quantity:h(),units:b()}),Ns=te({id:h(),refundOf:h().nullish(),name:b().default(""),value:h().default(0),quantity:h().default(0),currency:b().default("")}),Cs=te({refundId:b().nullish(),refundIdFromPlatform:Se().default(!1),refundedAt:b().nullish(),amount:h().default(0),currency:b().default(""),lines:de(Ns).default([])}),Ss=te({id:h(),status:vs.catch("unknown"),dateCreated:b().default(""),dateModified:b().nullish(),source:b().nullish(),sourceId:b().nullish(),details:de(ys).nullish(),totalValue:h().nullish(),totalsByCurrency:rs(b(),h()).nullish(),currency:b().nullish(),conversionCount:h().nullish(),isTest:Se().nullish(),subtotal:h().nullish(),taxTotal:h().nullish(),shippingTotal:h().nullish(),discountTotal:h().nullish(),feeTotal:h().nullish(),refunds:de(Cs).nullish(),refundedValue:h().nullish()}),me=Ss.passthrough(),ws=ls(me),se={list:s=>{const m=(s==null?void 0:s.perPage)??(s==null?void 0:s.number)??10,i=(s==null?void 0:s.page)??1,d=(s==null?void 0:s.offset)??(i-1)*m,I=(s==null?void 0:s.number)??m;return Z.get("/transactions",{offset:d,number:I,s:s==null?void 0:s.search,status:s==null?void 0:s.status,orderBy:s==null?void 0:s.orderBy,order:s==null?void 0:s.order,fields:"id,status,dateCreated,details,totalValue,totalsByCurrency,currency,source,isTest"}).then(k=>ws.parse(k))},get:s=>Z.get(`/transactions/${s}`,{fields:"id,status,dateCreated,details,detailCount,totalValue,totalsByCurrency,totalQuantity,currency,refunds,refundedValue,isTest"}).then(m=>me.parse(m)),create:s=>Z.post("/transactions",s).then(m=>me.parse(m)),creditCollaborator:s=>Z.post("/transactions/credit-collaborator",s)},ce=as(),pe=is(s=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,isSubmitting:!1,error:null,current:null,fetchList:async m=>{const i=ce.begin();s({isLoading:!0,error:null});try{const d=await se.list(m);if(!ce.isCurrent(i))return;s({items:d.items,total:d.total,page:d.page,perPage:d.perPage,totalPages:d.totalPages,isLoading:!1})}catch(d){if(!ce.isCurrent(i))return;s({error:d instanceof Error?d.message:"Failed to fetch transactions",isLoading:!1})}},fetchOne:async m=>{s({isLoading:!0,error:null,current:null});try{const i=await se.get(m);s({current:i,isLoading:!1})}catch(i){s({error:i instanceof Error?i.message:"Failed to fetch transaction",isLoading:!1})}},create:async m=>{s({isSubmitting:!0,error:null});try{const i=await se.create(m);return s({isSubmitting:!1}),ee.success("Transaction created successfully"),i}catch(i){const d=i instanceof Error?i.message:"Failed to create transaction";throw s({error:d,isSubmitting:!1}),ee.error(d),i}},creditCollaborator:async m=>{s({isSubmitting:!0,error:null});try{const i=await se.creditCollaborator(m);s({isSubmitting:!1}),ee.success(`Credited ${i.affected} transaction(s) to collaborator`)}catch(i){const d=i instanceof Error?i.message:"Failed to credit collaborator";throw s({error:d,isSubmitting:!1}),ee.error(d),i}},clearCurrent:()=>s({current:null}),clearError:()=>s({error:null})}));function be(){const{translate:s}=xe(),{formatMoney:m}=he(),i=Object.fromEntries(Object.entries(Ie).map(([a,u])=>[a,s(u)])),{transactionSources:d,fetchTransactionSources:I}=Te(),k=x.useMemo(()=>Object.fromEntries(d.map(a=>[a.id,a.name])),[d]),[v,_]=_e(),{items:A,total:n,page:w,perPage:C,totalPages:D,isLoading:B,isSubmitting:R,error:M,fetchList:T,creditCollaborator:y}=pe(),{items:f,fetchList:$}=cs(),P=v.get("status")||"all",[p,r]=x.useState(P),[c,l]=x.useState(10),[N,j]=x.useState("dateCreated"),[t,o]=x.useState("desc"),[g,F]=x.useState(new Set),[L,V]=x.useState(!1),[O,fe]=x.useState("");x.useEffect(()=>{I()},[I]),x.useEffect(()=>{const a=v.get("status");a&&a!==p&&r(a)},[v,p]),x.useEffect(()=>{F(new Set)},[p]),x.useEffect(()=>{L&&$({perPage:100,status:"active,pending,inactive,rejected"})},[L,$]),x.useEffect(()=>{T({page:1,perPage:c,orderBy:N,order:t,status:p!=="all"?p:void 0})},[T,c,N,t,p]);const ae=(a={})=>({page:a.page??1,perPage:a.perPage??c,status:(a.status??p)!=="all"?a.status??p:void 0,orderBy:a.orderBy??N,order:a.order??t}),ne=a=>{r(a),a!=="all"?v.set("status",a):v.delete("status"),_(v)},je=a=>{T(ae({page:a}))},Ee=a=>{const u=parseInt(a);l(u),T(ae({perPage:u}))},Ae=a=>{const u=N===a&&t==="asc"?"desc":"asc";j(a),o(u)},Re=async()=>{O&&(await y({transactionIds:Array.from(g),collaboratorId:parseInt(O)}),F(new Set),V(!1),fe(""),T(ae()))},re=x.useMemo(()=>A.filter(a=>g.has(a.id)),[A,g]),ke=a=>new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),le=(a,u)=>m(a,u),Be=[{id:"id",header:s("ID"),cell:a=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",a.id]}),a.isTest&&e.jsx(ps,{})]})},{id:"source",header:s("Source"),cell:a=>a.source?e.jsx("span",{className:"text-sm",children:k[a.source]||a.source}):e.jsx("span",{className:"text-muted-foreground",children:"—"})},{id:"details",header:s("Details"),cell:a=>{const u=(a.details??[]).filter(q=>q.type!=="refund");return u.length===0?e.jsx("span",{className:"text-muted-foreground",children:"—"}):e.jsxs("div",{className:"max-w-xs",children:[u.slice(0,2).map((q,Y)=>e.jsx("div",{className:"text-sm truncate",children:q.name},Y)),u.length>2&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["+",u.length-2," more"]})]})}},{id:"totalValue",header:s("Total"),cell:a=>e.jsx("span",{className:"font-medium",children:a.totalsByCurrency?Object.entries(a.totalsByCurrency).map(([u,q])=>e.jsx("span",{className:"block",children:le(q,u)},u)):le(a.totalValue,a.currency)})},{id:"dateCreated",header:s("Date"),sortable:!0,cell:a=>e.jsx("span",{className:"text-sm text-muted-foreground",children:ke(a.dateCreated)})},{id:"status",header:s("Status"),sortable:!0,cell:a=>e.jsx(us,{filterKey:"status",filterValue:a.status,children:e.jsx("span",{className:De[a.status],children:i[a.status]})})}],Fe=[{key:"status",label:"Status",value:p,displayValue:i[p]||p,onRemove:()=>ne("all")}],Ve=()=>{ne("all")},Oe=[{label:s("Credit Collaborator"),onClick:()=>V(!0)}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Transactions"),e.jsx(ue,{topic:"what-is-transaction",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(we,{sourceType:"transaction",contextLabel:"all transactions"}),e.jsx(S,{asChild:!0,children:e.jsxs(oe,{to:"/transactions/new",children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),s("New Transaction")]})})]})]}),e.jsx(ms,{filters:Fe,onClearAll:Ve}),M&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:M}),e.jsx("div",{className:"flex gap-2 mb-4 flex-wrap",children:e.jsxs(G,{value:p,onValueChange:ne,children:[e.jsx(K,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(J,{placeholder:s("Status")})}),e.jsxs(X,{children:[e.jsx(E,{value:"all",children:s("All Statuses")}),ds.map(a=>e.jsx(E,{value:a,children:i[a]},a))]})]})}),e.jsx(xs,{selectedCount:g.size,actions:Oe,onClear:()=>F(new Set),isProcessing:R}),e.jsx(Pe,{columns:Be,data:A,isLoading:B,emptyMessage:s("No transactions found."),selectable:!0,selectedIds:g,onSelectionChange:F,getRowHref:a=>`/transactions/${a.id}`,sortField:N,sortOrder:t,onSort:Ae}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",n===0?0:(w-1)*C+1," to ",Math.min(w*C,n)," of"," ",n," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs(G,{value:c.toString(),onValueChange:Ee,children:[e.jsx(K,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(J,{})}),e.jsxs(X,{children:[e.jsx(E,{value:"10",children:"10"}),e.jsx(E,{value:"25",children:"25"}),e.jsx(E,{value:"50",children:"50"}),e.jsx(E,{value:"100",children:"100"})]})]})]})]}),D>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(S,{variant:"outline",size:"sm",disabled:w===1,onClick:()=>je(w-1),children:s("Previous")}),e.jsx(S,{variant:"outline",size:"sm",disabled:w===D,onClick:()=>je(w+1),children:s("Next")})]})]}),e.jsx(Me,{open:L,onOpenChange:V,children:e.jsxs($e,{children:[e.jsxs(ze,{children:[e.jsx(Ue,{children:s("Credit Collaborator")}),e.jsx(He,{children:"Select a collaborator to credit with the selected transactions."})]}),e.jsxs("div",{className:"py-4 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:"Collaborator"}),e.jsxs(G,{value:O,onValueChange:fe,children:[e.jsx(K,{"aria-label":s("Select a collaborator"),children:e.jsx(J,{placeholder:s("Select a collaborator")})}),e.jsx(X,{children:f.map(a=>e.jsx(E,{value:a.id.toString(),children:a.fullName||a.email||`Collaborator #${a.id}`},a.id))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h4",{className:"text-sm font-medium",children:"Transactions to credit"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[re.length," transaction",re.length!==1?"s":""," selected"]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["Total value:"," ",Array.from(re.reduce((a,u)=>{const q=u.totalsByCurrency??(u.currency?{[u.currency]:u.totalValue??0}:{});return Object.entries(q).forEach(([Y,qe])=>a.set(Y,(a.get(Y)??0)+qe)),a},new Map)).map(([a,u])=>e.jsx("span",{className:"ml-2 font-medium text-foreground",children:le(u,a)},a))]})]})]}),e.jsxs(Qe,{children:[e.jsx(S,{variant:"outline",onClick:()=>V(!1),children:s("Cancel")}),e.jsx(S,{onClick:Re,disabled:R||!O,children:R?"Crediting...":"Credit Collaborator"})]})]})})]})}const Ts={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red"};function Is(){const{translate:s}=xe(),{formatMoney:m}=he(),i=Object.fromEntries(Object.entries(Ie).map(([t,o])=>[t,s(o)])),{transactionSources:d,fetchTransactionSources:I}=Te(),k=x.useMemo(()=>Object.fromEntries(d.map(t=>[t.id,t.name])),[d]),{id:v}=We(),_=Ce(),{isWordPress:A}=Ge(),{current:n,isLoading:w,error:C,fetchOne:D,clearCurrent:B}=pe(),{items:R,isLoading:M,fetchList:T}=fs();x.useEffect(()=>{I()},[I]),x.useEffect(()=>{if(v){const t=parseInt(v);D(t),T({transactionId:t,perPage:20})}return()=>{B()}},[v,D,B,T]);const y=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"}),f=(t,o)=>m(t,o),$=[{id:"id",header:s("ID"),cell:t=>e.jsxs(oe,{to:`/conversions/${t.id}`,className:"font-mono text-primary hover:underline",children:["#",t.id]})},{id:"collaborator",header:s("Collaborator"),cell:t=>js(t.collaboratorName,"collaborator",s)},{id:"type",header:s("Type"),cell:t=>e.jsx("span",{className:"capitalize",children:t.type})},{id:"amount",header:s("Amount"),cell:t=>f(t.amount,t.obligationAwardType)},{id:"status",header:s("Status"),cell:t=>e.jsx("span",{className:Ts[t.status],children:t.status})}];if(w)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(Ke,{})});if(C)return e.jsx("div",{className:"max-w-3xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:C})});if(!n)return e.jsx("div",{className:"max-w-3xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Transaction not found.")})});const P=(t,o=!1)=>{var F;const g=new Map;return(F=n.details)==null||F.filter(L=>t.includes(L.type)).forEach(L=>{const V=L.units||n.currency||"",O=L.value*(L.quantity||1);g.set(V,(g.get(V)??0)+(o?Math.abs(O):O))}),Array.from(g.entries())},p=n.subtotal===void 0?P(["line_item","product"]):[[n.currency||"",n.subtotal]],r=n.taxTotal===void 0?P(["tax"]):[[n.currency||"",n.taxTotal]],c=n.shippingTotal===void 0?P(["shipping"]):[[n.currency||"",n.shippingTotal]],l=n.discountTotal===void 0?P(["discount"],!0):[[n.currency||"",n.discountTotal]],N=P(["refund"]).map(([t,o])=>[t,-o]),j=n.refunds??[];return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!A&&e.jsx(S,{variant:"ghost",size:"icon",onClick:()=>_("/transactions"),"aria-label":s("Back"),children:e.jsx(gs,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Transaction #",n.id]}),e.jsx("p",{className:"text-muted-foreground",children:y(n.dateCreated)})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:De[n.status],children:i[n.status]}),e.jsx(we,{sourceType:"transaction",sourceId:n.id,contextLabel:`transaction #${n.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(z,{children:[e.jsx(U,{children:e.jsx(H,{children:s("Summary")})}),e.jsx(Q,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:i[n.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Date")}),e.jsx("dd",{className:"text-sm mt-1",children:y(n.dateCreated)})]}),n.source&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Source")}),e.jsx("dd",{className:"text-sm mt-1",children:k[n.source]||n.source})]}),n.sourceId&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Source ID")}),e.jsx("dd",{className:"text-sm mt-1 font-mono",children:n.sourceId})]})]})})]}),e.jsxs(z,{children:[e.jsx(U,{children:e.jsx(H,{children:s("Order Details")})}),e.jsx(Q,{children:n.details&&n.details.length>0?e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"space-y-2",children:n.details.filter(t=>t.type==="line_item"||t.type==="product"||!["tax","shipping","discount","fee","refund"].includes(t.type)).map(t=>e.jsxs("div",{className:"flex justify-between items-start py-2 border-b last:border-b-0",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium",children:t.name}),t.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:t.description}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[t.quantity," × ",f(t.value,t.units)]})]}),e.jsx("div",{className:"font-medium text-right",children:f(t.value*t.quantity,t.units)})]},t.id))}),e.jsxs("div",{className:"pt-4 border-t space-y-2",children:[p.map(([t,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Subtotal"}),e.jsx("span",{children:f(o,t)})]},"subtotals-"+t)),l.map(([t,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm text-green-600",children:[e.jsx("span",{children:"Discount"}),e.jsxs("span",{children:["-",f(o,t)]})]},"discounts-"+t)),c.map(([t,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Shipping"}),e.jsx("span",{children:f(o,t)})]},"shipping-"+t)),r.map(([t,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Tax"}),e.jsx("span",{children:f(o,t)})]},"taxes-"+t)),N.map(([t,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm text-destructive",children:[e.jsx("span",{children:s("Refunded")}),e.jsxs("span",{children:["-",f(o,t)]})]},"refunded-"+t)),e.jsxs("div",{className:"flex justify-between pt-2 border-t font-semibold text-lg",children:[e.jsx("span",{children:"Total"}),e.jsx("span",{children:n.totalsByCurrency?Object.entries(n.totalsByCurrency).map(([t,o])=>e.jsx("span",{className:"block",children:f(o,t)},t)):f(n.totalValue,n.currency)})]})]})]}):e.jsx("p",{className:"text-muted-foreground text-sm",children:s("No details available.")})})]}),j.length>0&&e.jsxs(z,{children:[e.jsx(U,{children:e.jsx(H,{children:s("Refunds")})}),e.jsx(Q,{children:e.jsx("div",{className:"space-y-4",children:j.map((t,o)=>e.jsxs("div",{className:"border-b last:border-b-0 pb-4 last:pb-0","data-testid":"transaction-refund",children:[e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:t.refundIdFromPlatform&&t.refundId?e.jsx("span",{className:"font-mono",children:t.refundId}):s("No id from the platform")}),t.refundedAt&&e.jsx("p",{className:"text-sm text-muted-foreground",children:y(t.refundedAt)})]}),e.jsxs("div",{className:"font-medium text-right",children:["-",f(t.amount,t.currency)]})]}),t.lines.length>0&&e.jsx("ul",{className:"mt-2 space-y-1",children:t.lines.map(g=>e.jsxs("li",{className:"flex justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[g.name.replace(/^Refund: /,""),g.quantity>0&&` × ${g.quantity}`]}),e.jsx("span",{children:f(g.value,g.currency)})]},g.id))})]},(t.refundId??"")+"-"+o))})})]}),e.jsxs(z,{children:[e.jsxs(U,{className:"flex flex-row items-center justify-between",children:[e.jsx(H,{children:s("Related Conversions")}),R.length>0&&e.jsx(S,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(oe,{to:`/conversions?transactionId=${n.id}`,children:s("View All")})})]}),e.jsx(Q,{children:e.jsx(Pe,{columns:$,data:R,isLoading:M,emptyMessage:s("No conversions created from this transaction.")})})]})]})]})}const ve=()=>({tempId:crypto.randomUUID(),quantity:1,name:"",description:"",type:"product",value:0,units:""}),Ds=[{value:"product",label:"Product"},{value:"service",label:"Service"},{value:"subscription",label:"Subscription"},{value:"fee",label:"Fee"},{value:"discount",label:"Discount"},{value:"shipping",label:"Shipping"},{value:"tax",label:"Tax"},{value:"other",label:"Other"}];function ye(){const{translate:s}=xe(),{formatShownMoney:m,definitionFor:i,definitions:d,ready:I}=he(),k=d.filter(r=>r.type!=="internal"),v=Ce(),{isSubmitting:_,error:A,create:n,clearError:w}=pe(),[C,D]=x.useState([ve()]),[B,R]=x.useState([]),M=()=>{D(r=>[...r,ve()])},T=r=>{D(c=>c.length<=1?c:c.filter(l=>l.tempId!==r))},y=(r,c,l)=>{D(N=>N.map(j=>j.tempId===r?{...j,[c]:l}:j))},f=()=>[{field:"details",validate:r=>{const c=r;if(c.length===0)return"At least one detail is required";for(let l=0;l<c.length;l++){if(!c[l].name.trim())return`Detail #${l+1}: Name is required`;if(c[l].value<0)return`Detail #${l+1}: Value must be 0 or greater`;if(c[l].quantity<1)return`Detail #${l+1}: Quantity must be at least 1`}return null}}],$=async r=>{r.preventDefault(),w();const c=os({details:C},f());if(R(c.errors),!!c.valid)try{const l=await n({details:C.map(({tempId:N,...j})=>{const t=i(j.units);return{...j,units:(t==null?void 0:t.code)??j.units,value:Ye(j.value,t)}})});v(`/transactions/${l.id}`)}catch{}},P=(r,c)=>m(r,c),p=C.reduce((r,c)=>{var j;const l=((j=i(c.units))==null?void 0:j.code)??c.units,N=c.value*c.quantity;return r[l]=(r[l]||0)+N,r},{});return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:"Create New Transaction"}),A&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:A}),ge(B,"details")&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:ge(B,"details")}),e.jsxs("form",{onSubmit:$,className:"space-y-6",children:[e.jsxs(z,{children:[e.jsxs(U,{children:[e.jsxs(H,{children:["Transaction Details",e.jsx(ue,{topic:"what-is-transaction",side:"right"})]}),e.jsx(Je,{children:"Add line items that make up this transaction. Each type affects how commissions are calculated."})]}),e.jsxs(Q,{className:"space-y-4",children:[e.jsxs("div",{className:"hidden lg:grid grid-cols-[60px_1fr_1fr_120px_100px_100px_40px] gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx("div",{children:"Qty"}),e.jsx("div",{children:"Name"}),e.jsx("div",{children:"Description"}),e.jsxs("div",{className:"flex items-center",children:["Type",e.jsx(ue,{topic:"transaction-detail-type",side:"top"})]}),e.jsx("div",{children:"Price"}),e.jsx("div",{children:"Currency"}),e.jsx("div",{})]}),C.map(r=>{var c;return e.jsxs("div",{className:"grid grid-cols-6 gap-2 items-start rounded-md border p-2 lg:grid-cols-[60px_1fr_1fr_120px_100px_100px_40px] lg:rounded-none lg:border-0 lg:p-0",children:[e.jsx(ie,{type:"number",min:"1",value:r.quantity,onChange:l=>y(r.tempId,"quantity",parseInt(l.target.value)||1),className:"h-9 col-span-2 lg:col-span-1","aria-label":s("Quantity")}),e.jsx(ie,{value:r.name,onChange:l=>y(r.tempId,"name",l.target.value),placeholder:s("Item name"),"aria-label":s("Item name"),className:"h-9 col-span-4 lg:col-span-1"}),e.jsx(ie,{value:r.description||"",onChange:l=>y(r.tempId,"description",l.target.value),placeholder:s("Description (optional)"),"aria-label":s("Description"),className:"h-9 col-span-6 lg:col-span-1"}),e.jsxs(G,{value:r.type,onValueChange:l=>y(r.tempId,"type",l),children:[e.jsx(K,{className:"h-9 col-span-3 lg:col-span-1","aria-label":s("Item type"),children:e.jsx(J,{})}),e.jsx(X,{children:Ds.map(l=>e.jsx(E,{value:l.value,children:l.label},l.value))})]}),e.jsx(Xe,{value:r.value,onChange:l=>y(r.tempId,"value",l),definition:i(r.units),className:"h-9 col-span-3 lg:col-span-1","aria-label":s("Price")}),e.jsxs(G,{value:((c=i(r.units))==null?void 0:c.code)??"",onValueChange:l=>{l&&y(r.tempId,"units",l)},children:[e.jsx(K,{className:"h-9 col-span-4 lg:col-span-1","aria-label":s("Currency"),children:e.jsx(J,{})}),e.jsx(X,{children:k.map(l=>e.jsx(E,{value:l.code,children:l.code},l.code))})]}),e.jsx(S,{type:"button",variant:"ghost",size:"icon",className:"h-9 w-9 col-span-2 justify-self-end lg:col-span-1",onClick:()=>T(r.tempId),disabled:C.length<=1,"aria-label":s("Remove item"),children:e.jsx(hs,{className:"h-4 w-4"})})]},r.tempId)}),e.jsxs(S,{type:"button",variant:"outline",size:"sm",onClick:M,className:"mt-2",children:[e.jsx(Le,{className:"h-4 w-4 mr-2"}),s("Add Detail")]})]})]}),e.jsxs(z,{children:[e.jsx(U,{children:e.jsx(H,{children:s("Summary")})}),e.jsx(Q,{children:e.jsxs("div",{className:"space-y-2",children:[Object.entries(p).map(([r,c])=>e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:["Total (",r,")"]}),e.jsx("span",{className:"font-medium",children:P(c,r)})]},r)),Object.keys(p).length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No items added yet")})]})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(S,{type:"submit",disabled:_||!I,children:_?"Creating...":"Create Transaction"}),e.jsx(S,{type:"button",variant:"outline",onClick:()=>v("/transactions"),children:s("Cancel")})]})]})]})}window.sirenConfig&&Ze({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ne=document.getElementById("siren-transactions");Ne&&es.createRoot(Ne).render(e.jsx(x.StrictMode,{children:e.jsxs(bs,{defaultRoute:"/transactions",children:[e.jsx(ss,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(ts,{children:[e.jsx(W,{path:"/transactions",element:e.jsx(be,{})}),e.jsx(W,{path:"/transactions/new",element:e.jsx(ye,{})}),e.jsx(W,{path:"/transactions/:id",element:e.jsx(Is,{})}),e.jsx(W,{path:"/transactions/:id/edit",element:e.jsx(ye,{})}),e.jsx(W,{index:!0,element:e.jsx(be,{})})]})})]})}));
     1import{v as ae,w as re,u as be,r as m,d as Xe,j as e,B as T,L as pe,S as $,e as z,f as H,g as Q,h as C,D as Ye,i as Ze,k as es,l as ss,m as ts,n as as,o as rs,b as Le,a as ns,p as ls,C as W,q as K,s as G,t as J,x as is,I as he,W as cs,A as os,E as ds,F as us,T as ms,R as hs,G as Y}from"./shared/wordpress-admin-D_eccjaB.js";import{c as xs}from"./shared/request-sequence-CQbIQ_gd.js";import{e as ps,o as le,s as y,n as x,a as fe,b as Ae,r as fs,c as js,W as gs}from"./shared/WordPressRouter-CAYzko7X.js";import{c as bs}from"./shared/react-Rq6nbqOn.js";import{u as ys,g as Se,v as vs}from"./shared/validation-D6cKTXRt.js";import{u as Re}from"./shared/registries-CatPSk3G.js";import{a as Fe,t as ke,T as Ns}from"./shared/transaction-status-DFlw8wS1.js";import{F as Cs,H as je,a as Ss,B as ws,D as Oe,T as Ts}from"./shared/HelpTooltip-YN4U7Ym7.js";import{A as _e}from"./shared/ActivityDrawer-BZxDAdLe.js";import{T as Is}from"./shared/TestSaleBadge--DG3xZwg.js";import{u as ye}from"./shared/useMoneyFormatter-B6sdhxKB.js";import{c as Ps}from"./shared/collaboratorDisplayName-DvmzsaZc.js";import{p as Be}from"./shared/properties-ByxWotcN.js";import{P as Ve}from"./shared/plus-8fF9_2v-.js";import{u as Ds}from"./shared/conversions-D67NHe2F.js";import{l as Es}from"./shared/linked-record-D4sO5j3k.js";import{A as Ls}from"./shared/arrow-left-XvsxLAWy.js";import"./shared/collaborator-groups-BP0hAJf8.js";import"./shared/unshipped-CGZcvpGp.js";import"./shared/conversion.schema-BXGiWhtb.js";const As=ps(["pending","complete","failed","cancelled","refunded","unknown"]),Rs=le({id:x(),transactionId:x(),name:y(),description:y().nullish(),type:y(),value:x(),quantity:x(),units:y()}),Fs=le({id:x(),refundOf:x().nullish(),name:y().default(""),value:x().default(0),quantity:x().default(0),currency:y().default("")}),ks=le({refundId:y().nullish(),refundIdFromPlatform:Ae().default(!1),refundedAt:y().nullish(),amount:x().default(0),currency:y().default(""),lines:fe(Fs).default([])}),Os=le({id:x(),status:As.catch("unknown"),dateCreated:y().default(""),dateModified:y().nullish(),source:y().nullish(),sourceId:y().nullish(),sourcePropertyId:x().nullish(),details:fe(Rs).nullish(),totalValue:x().nullish(),totalsByCurrency:fs(y(),x()).nullish(),currency:y().nullish(),conversionCount:x().nullish(),isTest:Ae().nullish(),subtotal:x().nullish(),taxTotal:x().nullish(),shippingTotal:x().nullish(),discountTotal:x().nullish(),feeTotal:x().nullish(),refunds:fe(ks).nullish(),refundedValue:x().nullish()}),ge=Os.passthrough(),_s=js(ge),ne={list:s=>{const h=(s==null?void 0:s.perPage)??(s==null?void 0:s.number)??10,c=(s==null?void 0:s.page)??1,u=(s==null?void 0:s.offset)??(c-1)*h,f=(s==null?void 0:s.number)??h;return ae.get("/transactions",{offset:u,number:f,s:s==null?void 0:s.search,status:s==null?void 0:s.status,credited:(s==null?void 0:s.credited)===void 0?void 0:s.credited?"1":"0",orderBy:s==null?void 0:s.orderBy,order:s==null?void 0:s.order,fields:"id,status,dateCreated,details,totalValue,totalsByCurrency,currency,source,sourceId,sourcePropertyId,isTest"}).then(F=>_s.parse(F))},get:s=>ae.get(`/transactions/${s}`,{fields:"id,status,dateCreated,details,detailCount,totalValue,totalsByCurrency,totalQuantity,currency,refunds,refundedValue,isTest,source,sourceId,sourcePropertyId"}).then(h=>ge.parse(h)),create:s=>ae.post("/transactions",s).then(h=>ge.parse(h)),creditCollaborator:s=>ae.post("/transactions/credit-collaborator",s)},xe=xs(),ve=bs(s=>({items:[],total:0,page:1,perPage:10,totalPages:0,isLoading:!1,isSubmitting:!1,error:null,current:null,fetchList:async h=>{const c=xe.begin();s({isLoading:!0,error:null});try{const u=await ne.list(h);if(!xe.isCurrent(c))return;s({items:u.items,total:u.total,page:u.page,perPage:u.perPage,totalPages:u.totalPages,isLoading:!1})}catch(u){if(!xe.isCurrent(c))return;s({error:u instanceof Error?u.message:"Failed to fetch transactions",isLoading:!1})}},fetchOne:async h=>{s({isLoading:!0,error:null,current:null});try{const c=await ne.get(h);s({current:c,isLoading:!1})}catch(c){s({error:c instanceof Error?c.message:"Failed to fetch transaction",isLoading:!1})}},create:async h=>{s({isSubmitting:!0,error:null});try{const c=await ne.create(h);return s({isSubmitting:!1}),re.success("Transaction created successfully"),c}catch(c){const u=c instanceof Error?c.message:"Failed to create transaction";throw s({error:u,isSubmitting:!1}),re.error(u),c}},creditCollaborator:async h=>{s({isSubmitting:!0,error:null});try{const c=await ne.creditCollaborator(h);s({isSubmitting:!1}),re.success(`Credited ${c.affected} transaction(s) to collaborator`)}catch(c){const u=c instanceof Error?c.message:"Failed to credit collaborator";throw s({error:u,isSubmitting:!1}),re.error(u),c}},clearCurrent:()=>s({current:null}),clearError:()=>s({error:null})})),Bs=["wc_order","edd_order","llms_order","llms_transaction","nc_order","ld_transaction"];function qe(s){return!!s&&Bs.includes(s)}function Me(s,h){var u;if(s.source!=="wc_order"||!s.sourceId||!s.sourcePropertyId)return null;const c=(u=h.find(f=>f.id===s.sourcePropertyId))==null?void 0:u.siteUrl.trim();if(!c)return null;try{const f=new URL(c);return f.protocol!=="http:"&&f.protocol!=="https:"?null:(f.pathname=`${f.pathname.replace(/\/$/,"")}/wp-admin/admin.php`,f.search=new URLSearchParams({page:"wc-orders",action:"edit",id:s.sourceId}).toString(),f.toString())}catch{return null}}const Vs={credited:"1",uncredited:"0"};function we(s){return s==="1"?"credited":s==="0"?"uncredited":"all"}function Te(s){return s==="all"?void 0:s==="credited"}function Ie(){const{translate:s}=be(),{formatMoney:h}=ye(),c=Object.fromEntries(Object.entries(Fe).map(([t,d])=>[t,s(d)])),{transactionSources:u,fetchTransactionSources:f}=Re(),F=m.useMemo(()=>Object.fromEntries(u.map(t=>[t.id,t.name])),[u]),[p,k]=Xe(),{items:I,total:O,page:S,perPage:r,totalPages:L,isLoading:_,isSubmitting:A,error:B,fetchList:P,creditCollaborator:D}=ve(),{items:U,fetchList:R}=ys(),j=p.get("status")||"all",[g,n]=m.useState(j),[i,l]=m.useState(we(p.get("credited"))),[w,b]=m.useState(10),[N,ie]=m.useState("dateCreated"),[V,Z]=m.useState("desc"),[a,o]=m.useState(new Set),[v,q]=m.useState(!1),[E,X]=m.useState(""),[ee,Ne]=m.useState([]);m.useEffect(()=>{I.some(t=>t.sourcePropertyId)&&Be.list().then(Ne).catch(()=>Ne([]))},[I]),m.useEffect(()=>{f()},[f]),m.useEffect(()=>{const t=p.get("status");t&&t!==g&&n(t)},[p,g]),m.useEffect(()=>{const t=we(p.get("credited"));t!==i&&l(t)},[p,i]),m.useEffect(()=>{o(new Set)},[g,i]),m.useEffect(()=>{v&&R({perPage:100,status:"active,pending,inactive,rejected"})},[v,R]),m.useEffect(()=>{P({page:1,perPage:w,orderBy:N,order:V,status:g!=="all"?g:void 0,credited:Te(i)})},[P,w,N,V,g,i]);const ce=(t={})=>({page:t.page??1,perPage:t.perPage??w,status:(t.status??g)!=="all"?t.status??g:void 0,credited:Te(i),orderBy:t.orderBy??N,order:t.order??V}),oe=t=>{n(t),t!=="all"?p.set("status",t):p.delete("status"),k(p)},de=t=>{const d=t;l(d),d!=="all"?p.set("credited",Vs[d]):p.delete("credited"),k(p)},Ce=t=>{P(ce({page:t}))},Ue=t=>{const d=parseInt(t);b(d),P(ce({perPage:d}))},$e=t=>{const d=N===t&&V==="asc"?"desc":"asc";ie(t),Z(d)},ze=async()=>{E&&(await D({transactionIds:Array.from(a),collaboratorId:parseInt(E)}),o(new Set),q(!1),X(""),P(ce()))},ue=m.useMemo(()=>I.filter(t=>a.has(t.id)),[I,a]),He=t=>new Date(t).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),me=(t,d)=>h(t,d),Qe=[{id:"id",header:s("ID"),cell:t=>e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsxs("span",{className:"font-mono text-sm",children:["#",t.id]}),t.isTest&&e.jsx(Is,{})]})},{id:"source",header:s("Source"),cell:t=>{const d=Me(t,ee);return t.source?e.jsxs("span",{className:"text-sm",children:[F[t.source]||t.source,t.sourceId&&e.jsx("span",{className:"block font-mono",children:qe(t.source)?d?e.jsxs("a",{href:d,className:"text-primary hover:underline",children:["#",t.sourceId]}):e.jsxs(e.Fragment,{children:["#",t.sourceId]}):t.sourceId})]}):e.jsx("span",{className:"text-muted-foreground",children:"—"})}},{id:"details",header:s("Details"),cell:t=>{const d=(t.details??[]).filter(M=>!["tax","discount","shipping","fee","refund"].includes(M.type));return d.length===0?e.jsx("span",{className:"text-muted-foreground",children:"—"}):e.jsxs("div",{className:"max-w-xs",children:[d.slice(0,2).map((M,te)=>e.jsx("div",{className:"text-sm truncate",children:M.name},te)),d.length>2&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["+",d.length-2," more"]})]})}},{id:"totalValue",header:s("Total"),cell:t=>e.jsx("span",{className:"font-medium",children:t.totalsByCurrency?Object.entries(t.totalsByCurrency).map(([d,M])=>e.jsx("span",{className:"block",children:me(M,d)},d)):me(t.totalValue,t.currency)})},{id:"dateCreated",header:s("Date"),sortable:!0,cell:t=>e.jsx("span",{className:"text-sm text-muted-foreground",children:He(t.dateCreated)})},{id:"status",header:s("Status"),sortable:!0,cell:t=>e.jsx(Cs,{filterKey:"status",filterValue:t.status,children:e.jsx("span",{className:ke[t.status],children:c[t.status]})})}],se={all:s("All Sales"),credited:s("Credited"),uncredited:s("Not Credited")},We=[{key:"status",label:"Status",value:g,displayValue:c[g]||g,onRemove:()=>oe("all")},{key:"credited",label:"Credited",value:i,displayValue:se[i],onRemove:()=>de("all")}],Ke=()=>{oe("all"),de("all")},Ge=[{label:s("Credit Collaborator"),onClick:()=>q(!0)}];return e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-2",children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center",children:[s("Transactions"),e.jsx(je,{topic:"what-is-transaction",side:"right"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(_e,{sourceType:"transaction",contextLabel:"all transactions"}),e.jsx(T,{asChild:!0,children:e.jsxs(pe,{to:"/transactions/new",children:[e.jsx(Ve,{className:"h-4 w-4 mr-2"}),s("New Transaction")]})})]})]}),e.jsx(Ss,{filters:We,onClearAll:Ke}),B&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:B}),e.jsxs("div",{className:"flex gap-2 mb-4 flex-wrap",children:[e.jsxs($,{value:g,onValueChange:oe,children:[e.jsx(z,{"aria-label":s("Filter by status"),className:"w-[140px]",children:e.jsx(H,{placeholder:s("Status")})}),e.jsxs(Q,{children:[e.jsx(C,{value:"all",children:s("All Statuses")}),Ns.map(t=>e.jsx(C,{value:t,children:c[t]},t))]})]}),e.jsxs($,{value:i,onValueChange:de,children:[e.jsx(z,{"aria-label":s("Filter by credit"),className:"w-[160px]",children:e.jsx(H,{placeholder:s("Credited")})}),e.jsxs(Q,{children:[e.jsx(C,{value:"all",children:se.all}),e.jsx(C,{value:"credited",children:se.credited}),e.jsx(C,{value:"uncredited",children:se.uncredited})]})]})]}),e.jsx(ws,{selectedCount:a.size,actions:Ge,onClear:()=>o(new Set),isProcessing:A}),e.jsx(Oe,{columns:Qe,data:I,sampleKey:"transactions",isLoading:_,emptyMessage:s("No transactions found."),selectable:!0,selectedIds:a,onSelectionChange:o,getRowHref:t=>`/transactions/${t.id}`,sortField:N,sortOrder:V,onSort:$e}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mt-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Showing ",O===0?0:(S-1)*r+1," to ",Math.min(S*r,O)," of"," ",O," results"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:s("Per page:")}),e.jsxs($,{value:w.toString(),onValueChange:Ue,children:[e.jsx(z,{"aria-label":s("Rows per page"),className:"w-[80px] h-8",children:e.jsx(H,{})}),e.jsxs(Q,{children:[e.jsx(C,{value:"10",children:"10"}),e.jsx(C,{value:"25",children:"25"}),e.jsx(C,{value:"50",children:"50"}),e.jsx(C,{value:"100",children:"100"})]})]})]})]}),L>1&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{variant:"outline",size:"sm",disabled:S===1,onClick:()=>Ce(S-1),children:s("Previous")}),e.jsx(T,{variant:"outline",size:"sm",disabled:S===L,onClick:()=>Ce(S+1),children:s("Next")})]})]}),e.jsx(Ye,{open:v,onOpenChange:q,children:e.jsxs(Ze,{children:[e.jsxs(es,{children:[e.jsx(ss,{children:s("Credit Collaborator")}),e.jsx(ts,{children:"Select a collaborator to credit with the selected transactions. Each sale credited this way creates an engagement for the collaborator, which counts toward your usage."})]}),e.jsxs("div",{className:"py-4 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium",children:"Collaborator"}),e.jsxs($,{value:E,onValueChange:X,children:[e.jsx(z,{"aria-label":s("Select a collaborator"),children:e.jsx(H,{placeholder:s("Select a collaborator")})}),e.jsx(Q,{children:U.map(t=>e.jsx(C,{value:t.id.toString(),children:Ps(t)},t.id))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h4",{className:"text-sm font-medium",children:"Transactions to credit"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[ue.length," transaction",ue.length!==1?"s":""," selected"]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["Total value:"," ",Array.from(ue.reduce((t,d)=>{const M=d.totalsByCurrency??(d.currency?{[d.currency]:d.totalValue??0}:{});return Object.entries(M).forEach(([te,Je])=>t.set(te,(t.get(te)??0)+Je)),t},new Map)).map(([t,d])=>e.jsx("span",{className:"ml-2 font-medium text-foreground",children:me(d,t)},t))]})]})]}),e.jsxs(as,{children:[e.jsx(T,{variant:"outline",onClick:()=>q(!1),children:s("Cancel")}),e.jsx(T,{onClick:ze,disabled:A||!E,children:A?"Crediting...":"Credit Collaborator"})]})]})})]})}const qs={pending:"status-badge status-yellow",approved:"status-badge status-blue",complete:"status-badge status-green",rejected:"status-badge status-red"};function Ms(){const{translate:s}=be(),{formatMoney:h}=ye(),c=Object.fromEntries(Object.entries(Fe).map(([a,o])=>[a,s(o)])),{transactionSources:u,fetchTransactionSources:f}=Re(),F=m.useMemo(()=>Object.fromEntries(u.map(a=>[a.id,a.name])),[u]),{id:p}=rs(),k=Le(),{isWordPress:I}=ns(),[O,S]=m.useState([]),{current:r,isLoading:L,error:_,fetchOne:A,clearCurrent:B}=ve(),{items:P,isLoading:D,fetchList:U}=Ds();m.useEffect(()=>{f()},[f]),m.useEffect(()=>{if(p){const a=parseInt(p);A(a),U({transactionId:a,perPage:20,orderBy:"dateCreated",order:"desc"})}return()=>{B()}},[p,A,B,U]),m.useEffect(()=>{r!=null&&r.sourcePropertyId&&Be.list().then(S).catch(()=>S([]))},[r==null?void 0:r.sourcePropertyId]);const R=a=>new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"2-digit",minute:"2-digit"}),j=(a,o)=>h(a,o),g=[{id:"id",header:s("ID"),cell:a=>e.jsxs(pe,{to:`/conversions/${a.id}`,className:"font-mono text-primary hover:underline",children:["#",a.id]})},{id:"collaborator",header:s("Collaborator"),cell:a=>Es(a.collaboratorName,"collaborator",s)},{id:"type",header:s("Type"),cell:a=>e.jsx("span",{className:"capitalize",children:a.type})},{id:"amount",header:s("Amount"),cell:a=>j(a.amount,a.obligationAwardType)},{id:"status",header:s("Status"),cell:a=>e.jsx("span",{className:qs[a.status],children:a.status})}];if(L)return e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ls,{})});if(_)return e.jsx("div",{className:"max-w-3xl",children:e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:_})});if(!r)return e.jsx("div",{className:"max-w-3xl",children:e.jsx("p",{className:"text-muted-foreground mb-4",children:s("Transaction not found.")})});const n=(a,o=!1)=>{var q;const v=new Map;return(q=r.details)==null||q.filter(E=>a.includes(E.type)).forEach(E=>{const X=E.units||r.currency||"",ee=E.value*(E.quantity||1);v.set(X,(v.get(X)??0)+(o?Math.abs(ee):ee))}),Array.from(v.entries())},i=r.subtotal==null?n(["line_item","product","subscription"]):[[r.currency||"",r.subtotal]],l=r.taxTotal===void 0?n(["tax"]):[[r.currency||"",r.taxTotal]],w=r.shippingTotal===void 0?n(["shipping"]):[[r.currency||"",r.shippingTotal]],b=r.discountTotal===void 0?n(["discount"],!0):[[r.currency||"",r.discountTotal]],N=Me(r,O),ie=r.feeTotal===void 0?n(["fee"]):[[r.currency||"",r.feeTotal]],V=n(["refund"]).map(([a,o])=>[a,-o]),Z=r.refunds??[];return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 mb-6",children:[!I&&e.jsx(T,{variant:"ghost",size:"icon",onClick:()=>k("/transactions"),"aria-label":s("Back"),children:e.jsx(Ls,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold",children:["Transaction #",r.id]}),e.jsx("p",{className:"text-muted-foreground",children:R(r.dateCreated)})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:ke[r.status],children:c[r.status]}),e.jsx(_e,{sourceType:"transaction",sourceId:r.id,contextLabel:`transaction #${r.id}`})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(W,{children:[e.jsx(K,{children:e.jsx(G,{children:s("Summary")})}),e.jsx(J,{children:e.jsxs("dl",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Status")}),e.jsx("dd",{className:"text-sm mt-1",children:c[r.status]})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Date")}),e.jsx("dd",{className:"text-sm mt-1",children:R(r.dateCreated)})]}),r.source&&e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Source")}),e.jsx("dd",{className:"text-sm mt-1",children:F[r.source]||r.source})]}),r.sourceId&&(qe(r.source)?e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Order")}),e.jsx("dd",{className:"text-sm mt-1 font-mono",children:N?e.jsxs("a",{href:N,className:"text-primary hover:underline",children:["#",r.sourceId]}):e.jsxs(e.Fragment,{children:["#",r.sourceId]})})]}):e.jsxs("div",{children:[e.jsx("dt",{className:"text-sm font-medium text-muted-foreground",children:s("Source ID")}),e.jsx("dd",{className:"text-sm mt-1 font-mono",children:r.sourceId})]}))]})})]}),e.jsxs(W,{children:[e.jsx(K,{children:e.jsx(G,{children:s("Order Details")})}),e.jsx(J,{children:r.details&&r.details.length>0?e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"space-y-2",children:r.details.filter(a=>a.type==="line_item"||a.type==="product"||!["tax","shipping","discount","fee","refund"].includes(a.type)).map(a=>e.jsxs("div",{className:"flex justify-between items-start py-2 border-b last:border-b-0",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium",children:a.name}),a.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a.description}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[a.quantity," × ",j(a.value,a.units)]})]}),e.jsx("div",{className:"font-medium text-right",children:j(a.value*a.quantity,a.units)})]},a.id))}),e.jsxs("div",{className:"pt-4 border-t space-y-2",children:[i.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Subtotal"}),e.jsx("span",{children:j(o,a)})]},"subtotals-"+a)),b.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm text-green-600",children:[e.jsx("span",{children:"Discount"}),e.jsxs("span",{children:["-",j(o,a)]})]},"discounts-"+a)),w.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Shipping"}),e.jsx("span",{children:j(o,a)})]},"shipping-"+a)),ie.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:s("Fee")}),e.jsx("span",{children:j(o,a)})]},"fees-"+a)),l.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Tax"}),e.jsx("span",{children:j(o,a)})]},"taxes-"+a)),V.map(([a,o])=>o>0&&e.jsxs("div",{className:"flex justify-between text-sm text-destructive",children:[e.jsx("span",{children:s("Refunded")}),e.jsxs("span",{children:["-",j(o,a)]})]},"refunded-"+a)),e.jsxs("div",{className:"flex justify-between pt-2 border-t font-semibold text-lg",children:[e.jsx("span",{children:"Total"}),e.jsx("span",{children:r.totalsByCurrency?Object.entries(r.totalsByCurrency).map(([a,o])=>e.jsx("span",{className:"block",children:j(o,a)},a)):j(r.totalValue,r.currency)})]})]})]}):e.jsx("p",{className:"text-muted-foreground text-sm",children:s("No details available.")})})]}),Z.length>0&&e.jsxs(W,{children:[e.jsx(K,{children:e.jsx(G,{children:s("Refunds")})}),e.jsx(J,{children:e.jsx("div",{className:"space-y-4",children:Z.map((a,o)=>e.jsxs("div",{className:"border-b last:border-b-0 pb-4 last:pb-0","data-testid":"transaction-refund",children:[e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:a.refundIdFromPlatform&&a.refundId?e.jsx("span",{className:"font-mono",children:a.refundId}):s("No id from the platform")}),a.refundedAt&&e.jsx("p",{className:"text-sm text-muted-foreground",children:R(a.refundedAt)})]}),e.jsxs("div",{className:"font-medium text-right",children:["-",j(a.amount,a.currency)]})]}),a.lines.length>0&&e.jsx("ul",{className:"mt-2 space-y-1",children:a.lines.map(v=>e.jsxs("li",{className:"flex justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[v.name.replace(/^Refund: /,""),v.quantity>0&&` × ${v.quantity}`]}),e.jsx("span",{children:j(v.value,v.currency)})]},v.id))})]},(a.refundId??"")+"-"+o))})})]}),e.jsxs(W,{children:[e.jsxs(K,{className:"flex flex-row items-center justify-between",children:[e.jsx(G,{children:s("Related Conversions")}),P.length>0&&e.jsx(T,{variant:"outline",size:"sm",asChild:!0,children:e.jsx(pe,{to:`/conversions?transactionId=${r.id}`,children:s("View All")})})]}),e.jsx(J,{children:e.jsx(Oe,{columns:g,data:P,isLoading:D,emptyMessage:s("No conversions created from this transaction.")})})]})]})]})}const Pe=()=>({tempId:crypto.randomUUID(),quantity:1,name:"",description:"",type:"product",value:0,units:""}),Us=[{value:"product",label:"Product"},{value:"service",label:"Service"},{value:"subscription",label:"Subscription"},{value:"fee",label:"Fee"},{value:"discount",label:"Discount"},{value:"shipping",label:"Shipping"},{value:"tax",label:"Tax"},{value:"other",label:"Other"}];function De(){const{translate:s}=be(),{formatShownMoney:h,definitionFor:c,definitions:u,ready:f}=ye(),F=u.filter(n=>n.type!=="internal"),p=Le(),{isSubmitting:k,error:I,create:O,clearError:S}=ve(),[r,L]=m.useState([Pe()]),[_,A]=m.useState([]),B=()=>{L(n=>[...n,Pe()])},P=n=>{L(i=>i.length<=1?i:i.filter(l=>l.tempId!==n))},D=(n,i,l)=>{L(w=>w.map(b=>b.tempId===n?{...b,[i]:l}:b))},U=()=>[{field:"details",validate:n=>{const i=n;if(i.length===0)return"At least one detail is required";for(let l=0;l<i.length;l++){if(!i[l].name.trim())return`Detail #${l+1}: Name is required`;if(i[l].value<0)return`Detail #${l+1}: Value must be 0 or greater`;if(i[l].quantity<1)return`Detail #${l+1}: Quantity must be at least 1`}return null}}],R=async n=>{n.preventDefault(),S();const i=vs({details:r},U());if(A(i.errors),!!i.valid)try{const l=await O({details:r.map(({tempId:w,...b})=>{const N=c(b.units);return{...b,units:(N==null?void 0:N.code)??b.units,value:os(b.value,N)}})});p(`/transactions/${l.id}`)}catch{}},j=(n,i)=>h(n,i),g=r.reduce((n,i)=>{var b;const l=((b=c(i.units))==null?void 0:b.code)??i.units,w=i.value*i.quantity;return n[l]=(n[l]||0)+w,n},{});return e.jsxs("div",{className:"max-w-4xl",children:[e.jsx("h1",{className:"text-2xl font-semibold mb-6",children:"Create New Transaction"}),I&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:I}),Se(_,"details")&&e.jsx("div",{className:"mb-4 p-4 bg-destructive/10 text-destructive rounded-md",children:Se(_,"details")}),e.jsxs("form",{onSubmit:R,className:"space-y-6",children:[e.jsxs(W,{children:[e.jsxs(K,{children:[e.jsxs(G,{children:["Transaction Details",e.jsx(je,{topic:"what-is-transaction",side:"right"})]}),e.jsx(is,{children:"Add line items that make up this transaction. Each type affects how commissions are calculated."})]}),e.jsxs(J,{className:"space-y-4",children:[e.jsxs("div",{className:"hidden lg:grid grid-cols-[60px_1fr_1fr_120px_100px_100px_40px] gap-2 text-sm font-medium text-muted-foreground",children:[e.jsx("div",{children:"Qty"}),e.jsx("div",{children:"Name"}),e.jsx("div",{children:"Description"}),e.jsxs("div",{className:"flex items-center",children:["Type",e.jsx(je,{topic:"transaction-detail-type",side:"top"})]}),e.jsx("div",{children:"Price"}),e.jsx("div",{children:"Currency"}),e.jsx("div",{})]}),r.map(n=>{var i;return e.jsxs("div",{className:"grid grid-cols-6 gap-2 items-start rounded-md border p-2 lg:grid-cols-[60px_1fr_1fr_120px_100px_100px_40px] lg:rounded-none lg:border-0 lg:p-0",children:[e.jsx(he,{type:"number",min:"1",value:n.quantity,onChange:l=>D(n.tempId,"quantity",parseInt(l.target.value)||1),className:"h-9 col-span-2 lg:col-span-1","aria-label":s("Quantity")}),e.jsx(he,{value:n.name,onChange:l=>D(n.tempId,"name",l.target.value),placeholder:s("Item name"),"aria-label":s("Item name"),className:"h-9 col-span-4 lg:col-span-1"}),e.jsx(he,{value:n.description||"",onChange:l=>D(n.tempId,"description",l.target.value),placeholder:s("Description (optional)"),"aria-label":s("Description"),className:"h-9 col-span-6 lg:col-span-1"}),e.jsxs($,{value:n.type,onValueChange:l=>D(n.tempId,"type",l),children:[e.jsx(z,{className:"h-9 col-span-3 lg:col-span-1","aria-label":s("Item type"),children:e.jsx(H,{})}),e.jsx(Q,{children:Us.map(l=>e.jsx(C,{value:l.value,children:l.label},l.value))})]}),e.jsx(cs,{value:n.value,onChange:l=>D(n.tempId,"value",l),definition:c(n.units),className:"h-9 col-span-3 lg:col-span-1","aria-label":s("Price")}),e.jsxs($,{value:((i=c(n.units))==null?void 0:i.code)??"",onValueChange:l=>{l&&D(n.tempId,"units",l)},children:[e.jsx(z,{className:"h-9 col-span-4 lg:col-span-1","aria-label":s("Currency"),children:e.jsx(H,{})}),e.jsx(Q,{children:F.map(l=>e.jsx(C,{value:l.code,children:l.code},l.code))})]}),e.jsx(T,{type:"button",variant:"ghost",size:"icon",className:"h-9 w-9 col-span-2 justify-self-end lg:col-span-1",onClick:()=>P(n.tempId),disabled:r.length<=1,"aria-label":s("Remove item"),children:e.jsx(Ts,{className:"h-4 w-4"})})]},n.tempId)}),e.jsxs(T,{type:"button",variant:"outline",size:"sm",onClick:B,className:"mt-2",children:[e.jsx(Ve,{className:"h-4 w-4 mr-2"}),s("Add Detail")]})]})]}),e.jsxs(W,{children:[e.jsx(K,{children:e.jsx(G,{children:s("Summary")})}),e.jsx(J,{children:e.jsxs("div",{className:"space-y-2",children:[Object.entries(g).map(([n,i])=>e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:["Total (",n,")"]}),e.jsx("span",{className:"font-medium",children:j(i,n)})]},n)),Object.keys(g).length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:s("No items added yet")})]})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"submit",disabled:k||!f,children:k?"Creating...":"Create Transaction"}),e.jsx(T,{type:"button",variant:"outline",onClick:()=>p("/transactions"),children:s("Cancel")})]})]})]})}window.sirenConfig&&ds({baseUrl:window.sirenConfig.apiBase,nonce:window.sirenConfig.nonce});const Ee=document.getElementById("siren-transactions");Ee&&us.createRoot(Ee).render(e.jsx(m.StrictMode,{children:e.jsxs(gs,{defaultRoute:"/transactions",children:[e.jsx(ms,{position:"top-right",richColors:!0}),e.jsx("div",{className:"p-4",children:e.jsxs(hs,{children:[e.jsx(Y,{path:"/transactions",element:e.jsx(Ie,{})}),e.jsx(Y,{path:"/transactions/new",element:e.jsx(De,{})}),e.jsx(Y,{path:"/transactions/:id",element:e.jsx(Ms,{})}),e.jsx(Y,{path:"/transactions/:id/edit",element:e.jsx(De,{})}),e.jsx(Y,{index:!0,element:e.jsx(Ie,{})})]})})]})}));
  • siren-affiliates/trunk/frontend/wordpress-admin.css

    r3775642 r3788740  
    1 *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 220 20% 15%;--card: 0 0% 100%;--card-foreground: 220 20% 15%;--popover: 0 0% 100%;--popover-foreground: 220 20% 15%;--primary: 164 84% 27%;--primary-foreground: 0 0% 100%;--secondary: 210 20% 96%;--secondary-foreground: 220 20% 15%;--muted: 210 20% 96%;--muted-foreground: 220 10% 45%;--accent: 164 100% 95%;--accent-foreground: 164 100% 25%;--destructive: 0 84% 60%;--destructive-foreground: 0 0% 100%;--border: 220 13% 90%;--input: 220 13% 90%;--ring: 164 84% 27%;--radius: .5rem}.dark{--background: 236 100% 5%;--foreground: 210 20% 95%;--card: 236 80% 8%;--card-foreground: 210 20% 95%;--popover: 236 80% 8%;--popover-foreground: 210 20% 95%;--primary: 164 100% 50%;--primary-foreground: 236 100% 5%;--secondary: 235 58% 17%;--secondary-foreground: 210 20% 95%;--muted: 235 58% 17%;--muted-foreground: 215 15% 60%;--accent: 180 30% 20%;--accent-foreground: 164 100% 50%;--destructive: 0 70% 45%;--destructive-foreground: 210 20% 95%;--border: 235 58% 17%;--input: 235 58% 17%;--ring: 164 100% 50%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.status-badge{display:inline-flex;align-items:center;border-radius:9999px;border-width:1px;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:500}.status-green{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.dark .status-green{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1));background-color:#052e1680;--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.status-yellow{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.dark .status-yellow{--tw-border-opacity: 1;border-color:rgb(234 179 8 / var(--tw-border-opacity, 1));background-color:#42200680;--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.status-gray{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.dark .status-gray{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1));background-color:#03071280;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.status-red{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.dark .status-red{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));background-color:#450a0a80;--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.status-blue{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.dark .status-blue{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1));background-color:#2e106580;--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.left-0{left:0}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-1\.5{top:.375rem}.top-1\/2{top:50%}.top-2{top:.5rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[999999\]{z-index:999999}.col-span-2{grid-column:span 2 / span 2}.col-span-3{grid-column:span 3 / span 3}.col-span-4{grid-column:span 4 / span 4}.col-span-6{grid-column:span 6 / span 6}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-2{margin-left:.5rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-2\.5{margin-top:.625rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.mt-px{margin-top:1px}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[280px\]{height:280px}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-96{max-height:24rem}.max-h-\[360px\]{max-height:360px}.max-h-\[88vh\]{max-height:88vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.min-h-0{min-height:0px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-4{width:1rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[100cqw\]{width:100cqw}.w-\[10rem\]{width:10rem}.w-\[11rem\]{width:11rem}.w-\[120px\]{width:120px}.w-\[140px\]{width:140px}.w-\[150px\]{width:150px}.w-\[160px\]{width:160px}.w-\[180px\]{width:180px}.w-\[190px\]{width:190px}.w-\[1px\]{width:1px}.w-\[240px\]{width:240px}.w-\[40px\]{width:40px}.w-\[80px\]{width:80px}.w-\[9rem\]{width:9rem}.w-\[calc\(100\%-2rem\)\]{width:calc(100% - 2rem)}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[1\.25rem\]{min-width:1.25rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[16rem\]{min-width:16rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[min\(100\%\,14rem\)\]{min-width:min(100%,14rem)}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[16rem\]{max-width:16rem}.max-w-\[640px\]{max-width:640px}.max-w-\[68ch\]{max-width:68ch}.max-w-\[85vw\]{max-width:85vw}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes glow{0%{box-shadow:0 0 hsl(var(--primary) / .7)}50%{box-shadow:0 0 20px 4px hsl(var(--primary) / .5)}to{box-shadow:0 0 hsl(var(--primary) / 0)}}.animate-glow{animation:glow 1s ease-out}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.scroll-mt-4{scroll-margin-top:1rem}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-\[60px_1fr_1fr_120px_100px_100px_40px\]{grid-template-columns:60px 1fr 1fr 120px 100px 100px 40px}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-16{-moz-column-gap:4rem;column-gap:4rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-1\.5{row-gap:.375rem}.gap-y-14{row-gap:3.5rem}.gap-y-2{row-gap:.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(3rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3rem * var(--tw-space-y-reverse))}.space-y-14>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(3.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.625rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.space-y-px>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1px * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.justify-self-end{justify-self:end}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-amber-400\/40{border-color:#fbbf2466}.border-amber-400\/50{border-color:#fbbf2480}.border-amber-500\/30{border-color:#f59e0b4d}.border-border{border-color:hsl(var(--border))}.border-destructive{border-color:hsl(var(--destructive))}.border-destructive\/30{border-color:hsl(var(--destructive) / .3)}.border-emerald-400\/50{border-color:#34d39980}.border-emerald-500\/30{border-color:#10b9814d}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-green-500\/30{border-color:#22c55e4d}.border-input{border-color:hsl(var(--input))}.border-muted-foreground\/25{border-color:hsl(var(--muted-foreground) / .25)}.border-primary{border-color:hsl(var(--primary))}.border-primary\/20{border-color:hsl(var(--primary) / .2)}.border-primary\/25{border-color:hsl(var(--primary) / .25)}.border-primary\/40{border-color:hsl(var(--primary) / .4)}.border-primary\/50{border-color:hsl(var(--primary) / .5)}.border-purple-400\/50{border-color:#c084fc80}.border-sky-400\/50{border-color:#38bdf880}.bg-accent{background-color:hsl(var(--accent))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-400\/10{background-color:#fbbf241a}.bg-amber-400\/\[0\.07\]{background-color:#fbbf2412}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/15{background-color:#f59e0b26}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-background{background-color:hsl(var(--background))}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-destructive\/5{background-color:hsl(var(--destructive) / .05)}.bg-emerald-400\/10{background-color:#34d3991a}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/15{background-color:#10b98126}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-50\/50{background-color:#f0fdf480}.bg-green-500\/5{background-color:#22c55e0d}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted-foreground{background-color:hsl(var(--muted-foreground))}.bg-muted-foreground\/40{background-color:hsl(var(--muted-foreground) / .4)}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/40{background-color:hsl(var(--muted) / .4)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/5{background-color:hsl(var(--primary) / .05)}.bg-purple-400\/10{background-color:#c084fc1a}.bg-rose-100{--tw-bg-opacity: 1;background-color:rgb(255 228 230 / var(--tw-bg-opacity, 1))}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sky-400\/10{background-color:#38bdf81a}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-primary\/10{--tw-gradient-from: hsl(var(--primary) / .1) var(--tw-gradient-from-position);--tw-gradient-to: hsl(var(--primary) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-primary\/5{--tw-gradient-to: hsl(var(--primary) / .05) var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.object-contain{-o-object-fit:contain;object-fit:contain}.p-0{padding:0}.p-1{padding:.25rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-\[50vh\]{padding-bottom:50vh}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-10{padding-right:2.5rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pr-8{padding-right:2rem}.pr-9{padding-right:2.25rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-10{padding-top:2.5rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.ordinal{--tw-ordinal: ordinal;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-destructive\/70{color:hsl(var(--destructive) / .7)}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/80{color:hsl(var(--foreground) / .8)}.text-foreground\/90{color:hsl(var(--foreground) / .9)}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-primary\/60{color:hsl(var(--primary) / .6)}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-rose-800{--tw-text-opacity: 1;color:rgb(159 18 57 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-sky-600{--tw-text-opacity: 1;color:rgb(2 132 199 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/25{--tw-shadow-color: rgb(0 0 0 / .25);--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-primary{--tw-ring-color: hsl(var(--primary))}.ring-primary\/40{--tw-ring-color: hsl(var(--primary) / .4)}.ring-primary\/50{--tw-ring-color: hsl(var(--primary) / .5)}.ring-offset-2{--tw-ring-offset-width: 2px}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[transform\,visibility\,width\]{transition-property:transform,visibility,width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.\[container-type\:inline-size\]{container-type:inline-size}.\[grid-template-columns\:repeat\(auto-fill\,minmax\(260px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}.dark [data-color-mode=dark] .w-tc-editor-text,.dark [data-color-mode=dark] textarea{caret-color:#e2e8f0!important}.dark [data-color-mode=dark] .w-tc-editor{--color-prettylights-syntax-entity: #93c5fd;--color-prettylights-syntax-string: #86efac;--color-prettylights-syntax-constant: #c4b5fd;--color-prettylights-syntax-keyword: #f9a8d4}body.admin-bar [data-radix-portal] [role=dialog]{top:32px!important;height:calc(100vh - 32px)!important}body.admin-bar [data-radix-portal] [data-state][class*=inset-0]{top:32px!important}@media screen and (max-width:782px){body.admin-bar [data-radix-portal] [role=dialog]{top:46px!important;height:calc(100vh - 46px)!important}body.admin-bar [data-radix-portal] [data-state][class*=inset-0]{top:46px!important}}.siren-tabs .siren-tab{position:relative;display:inline-flex;align-items:center;padding:.5rem 1rem;margin-bottom:-1px;font-size:.875rem;font-weight:500;white-space:nowrap;border-bottom:2px solid transparent;color:hsl(var(--muted-foreground));transition:color .12s,border-color .12s;text-decoration:none;outline:none;box-shadow:none}.siren-tabs .siren-tab:hover{color:hsl(var(--foreground));border-bottom-color:hsl(var(--muted-foreground) / .3);text-decoration:none}.siren-tabs .siren-tab:focus,.siren-tabs .siren-tab:active{outline:none;box-shadow:none}.siren-tabs .siren-tab:focus-visible{outline:2px dotted hsl(var(--ring));outline-offset:2px;border-radius:2px}.siren-tabs .siren-tab--active{color:hsl(var(--foreground));border-bottom-color:hsl(var(--primary))}.siren-tabs .siren-tab--active:hover{border-bottom-color:hsl(var(--primary))}.siren-notification-body p{margin:0 0 .75rem}.siren-notification-body ul{list-style:disc;padding-left:1.25rem;margin:0 0 .75rem}.siren-notification-body ol{list-style:decimal;padding-left:1.25rem;margin:0 0 .75rem}.siren-notification-body a{color:hsl(var(--primary));text-decoration:underline}.siren-notification-body p.is-editor-empty:first-child:before{content:attr(data-placeholder);float:left;height:0;pointer-events:none;color:hsl(var(--muted-foreground))}.siren-merge-tag{border-radius:.25rem;padding:0 .25rem;background:hsl(var(--primary) / .1);color:hsl(var(--primary));font-weight:500;white-space:nowrap}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-foreground::file-selector-button{color:hsl(var(--foreground))}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:bottom-1:before{content:var(--tw-content);bottom:.25rem}.before\:left-\[1\.05rem\]:before{content:var(--tw-content);left:1.05rem}.before\:top-1:before{content:var(--tw-content);top:.25rem}.before\:w-px:before{content:var(--tw-content);width:1px}.before\:bg-border:before{content:var(--tw-content);background-color:hsl(var(--border))}.last\:mb-0:last-child{margin-bottom:0}.last\:border-0:last-child{border-width:0px}.last\:border-b-0:last-child{border-bottom-width:0px}.last\:pb-0:last-child{padding-bottom:0}.hover\:-translate-y-0\.5:hover{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border:hover{border-width:1px}.hover\:border-current:hover{border-color:currentColor}.hover\:border-destructive:hover{border-color:hsl(var(--destructive))}.hover\:border-muted-foreground\/50:hover{border-color:hsl(var(--muted-foreground) / .5)}.hover\:border-primary\/30:hover{border-color:hsl(var(--primary) / .3)}.hover\:border-primary\/40:hover{border-color:hsl(var(--primary) / .4)}.hover\:border-primary\/50:hover{border-color:hsl(var(--primary) / .5)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/30:hover{background-color:hsl(var(--muted) / .3)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-muted\/60:hover{background-color:hsl(var(--muted) / .6)}.hover\:bg-primary\/10:hover{background-color:hsl(var(--primary) / .1)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-transparent:hover{background-color:transparent}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-primary:hover{color:hsl(var(--primary))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:fixed:focus{position:fixed}.focus\:left-4:focus{left:1rem}.focus\:top-4:focus{top:1rem}.focus\:z-\[100\]:focus{z-index:100}.focus\:rounded-md:focus{border-radius:calc(var(--radius) - 2px)}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-primary:focus{background-color:hsl(var(--primary))}.focus\:px-4:focus{padding-left:1rem;padding-right:1rem}.focus\:py-2:focus{padding-top:.5rem;padding-bottom:.5rem}.focus\:text-sm:focus{font-size:.875rem;line-height:1.25rem}.focus\:font-medium:focus{font-weight:500}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:text-destructive:focus{color:hsl(var(--destructive))}.focus\:text-primary-foreground:focus{color:hsl(var(--primary-foreground))}.focus\:opacity-100:focus{opacity:1}.focus\:shadow-lg:focus{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group.toaster .group-\[\.toaster\]\:border-border{border-color:hsl(var(--border))}.group.toaster .group-\[\.toaster\]\:border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.group.toaster .group-\[\.toaster\]\:border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.group.toast .group-\[\.toast\]\:bg-muted{background-color:hsl(var(--muted))}.group.toast .group-\[\.toast\]\:bg-primary{background-color:hsl(var(--primary))}.group.toaster .group-\[\.toaster\]\:bg-background{background-color:hsl(var(--background))}.group.toaster .group-\[\.toaster\]\:bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.group.toaster .group-\[\.toaster\]\:bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.group.toast .group-\[\.toast\]\:text-muted-foreground{color:hsl(var(--muted-foreground))}.group.toast .group-\[\.toast\]\:text-primary-foreground{color:hsl(var(--primary-foreground))}.group.toaster .group-\[\.toaster\]\:text-foreground{color:hsl(var(--foreground))}.group.toaster .group-\[\.toaster\]\:text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.group.toaster .group-\[\.toaster\]\:text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.group.toaster .group-\[\.toaster\]\:shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=open\]\:bg-secondary[data-state=open]{background-color:hsl(var(--secondary))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[state\=closed\]\:duration-300[data-state=closed]{transition-duration:.3s}.data-\[state\=open\]\:duration-500[data-state=open]{transition-duration:.5s}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-amber-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:bg-amber-900\/30:is(.dark *){background-color:#78350f4d}.dark\:bg-amber-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(69 26 3 / var(--tw-bg-opacity, 1))}.dark\:bg-amber-950\/30:is(.dark *){background-color:#451a034d}.dark\:bg-amber-950\/40:is(.dark *){background-color:#451a0366}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-blue-950\/30:is(.dark *){background-color:#1725544d}.dark\:bg-green-500:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-rose-900\/30:is(.dark *){background-color:#8813374d}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:text-amber-100:is(.dark *){--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity, 1))}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-amber-500:is(.dark *){--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.dark\:text-blue-200:is(.dark *){--tw-text-opacity: 1;color:rgb(191 219 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-emerald-400:is(.dark *){--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-green-500:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-purple-300:is(.dark *){--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.dark\:text-rose-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.dark\:text-sky-300:is(.dark *){--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:shadow-black\/50:is(.dark *){--tw-shadow-color: rgb(0 0 0 / .5);--tw-shadow: var(--tw-shadow-colored)}.dark\:ring-1:is(.dark *){--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.dark\:ring-white\/10:is(.dark *){--tw-ring-color: rgb(255 255 255 / .1)}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:hidden{display:none}.sm\:w-40{width:10rem}.sm\:w-\[160px\]{width:160px}.sm\:w-\[200px\]{width:200px}.sm\:w-\[220px\]{width:220px}.sm\:w-full{width:100%}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-lg{max-width:32rem}.sm\:max-w-md{max-width:28rem}.sm\:max-w-sm{max-width:24rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-between{justify-content:space-between}.sm\:gap-8{gap:2rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:p-6{padding:1.5rem}.sm\:pl-11{padding-left:2.75rem}.sm\:text-left{text-align:left}.sm\:opacity-0{opacity:0}.group:focus-within .sm\:group-focus-within\:opacity-100{opacity:1}.group:hover .sm\:group-hover\:opacity-100{opacity:1}}@media(min-width:768px){.md\:visible{visibility:visible}.md\:sticky{position:sticky}.md\:top-0{top:0}.md\:z-auto{z-index:auto}.md\:col-span-2{grid-column:span 2 / span 2}.md\:inline-flex{display:inline-flex}.md\:table-cell{display:table-cell}.md\:hidden{display:none}.md\:h-screen{height:100vh}.md\:w-16{width:4rem}.md\:w-56{width:14rem}.md\:max-w-none{max-width:none}.md\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}@media(min-width:1024px){.lg\:sticky{position:sticky}.lg\:top-6{top:1.5rem}.lg\:col-span-1{grid-column:span 1 / span 1}.lg\:col-span-3{grid-column:span 3 / span 3}.lg\:block{display:block}.lg\:grid{display:grid}.lg\:w-60{width:15rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-\[60px_1fr_1fr_120px_100px_100px_40px\]{grid-template-columns:60px 1fr 1fr 120px 100px 100px 40px}.lg\:grid-cols-\[minmax\(0\,1fr\)_344px\]{grid-template-columns:minmax(0,1fr) 344px}.lg\:flex-row{flex-direction:row}.lg\:self-start{align-self:flex-start}.lg\:rounded-none{border-radius:0}.lg\:border-0{border-width:0px}.lg\:p-0{padding:0}}@media(min-width:1280px){.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>\*\]\:min-w-0>*{min-width:0px}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>svg\]\:size-4>svg{width:1rem;height:1rem}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}body.wp-admin{--background: 0 0% 94.1%;--foreground: 210 14% 14%;--card: 0 0% 100%;--card-foreground: 210 14% 14%;--popover: 0 0% 100%;--popover-foreground: 210 14% 14%;--primary: 206 69% 41%;--primary-foreground: 0 0% 100%;--secondary: 220 4% 96%;--secondary-foreground: 210 14% 14%;--muted: 220 4% 96%;--muted-foreground: 210 7% 46%;--accent: 206 69% 95%;--accent-foreground: 206 69% 30%;--destructive: 359 74% 52%;--destructive-foreground: 0 0% 100%;--border: 225 4% 77%;--input: 225 4% 77%;--ring: 206 69% 41%;--radius: 4px}body.wp-admin [id^=siren-]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:1.4}body.wp-admin [id^=siren-]{padding-top:32px}@media screen and (max-width:782px){body.wp-admin [id^=siren-]{padding-top:46px}}body.wp-admin [id^=siren-] input[type=text],body.wp-admin [id^=siren-] input[type=email],body.wp-admin [id^=siren-] input[type=number],body.wp-admin [id^=siren-] input[type=password],body.wp-admin [id^=siren-] input[type=search],body.wp-admin [id^=siren-] input[type=url],body.wp-admin [id^=siren-] input:not([type]),body.wp-admin [id^=siren-] select,body.wp-admin [id^=siren-] textarea,body.wp-admin [id^=siren-] [role=combobox],body.wp-admin [id^=siren-] button[data-slot=trigger]{background-color:#fff!important;border:1px solid #8c8f94!important;border-radius:4px!important;color:#1d2327!important}body.wp-admin [id^=siren-] [data-radix-select-trigger],body.wp-admin [id^=siren-] [cmdk-input]{background-color:#fff!important;border:1px solid #8c8f94!important}body.wp-admin [id^=siren-] input:focus,body.wp-admin [id^=siren-] select:focus,body.wp-admin [id^=siren-] textarea:focus{border-color:#2271b1!important;box-shadow:0 0 0 1px #2271b1!important;outline:none!important}body.wp-admin [id^=siren-] button[class*=bg-primary]:hover,body.wp-admin [id^=siren-] button[class*=bg-primary]:active,body.wp-admin [id^=siren-] button[class*=bg-primary]:focus,body.wp-admin [id^=siren-] button[class*=bg-primary]:focus-visible,body.wp-admin [id^=siren-] a[class*=bg-primary]:hover,body.wp-admin [id^=siren-] a[class*=bg-primary]:active,body.wp-admin [id^=siren-] a[class*=bg-primary]:focus,body.wp-admin [id^=siren-] a[class*=bg-primary]:focus-visible{color:#fff!important}body.wp-admin [id^=siren-] table{background-color:#fff;border-collapse:collapse;width:100%}body.wp-admin [id^=siren-] table thead tr{background-color:#fff}body.wp-admin [id^=siren-] table tbody tr:nth-child(odd){background-color:#f6f7f7}body.wp-admin [id^=siren-] table tbody tr:nth-child(2n){background-color:#fff}body.wp-admin [id^=siren-] table tbody tr:hover{background-color:#f0f0f1}body.wp-admin [id^=siren-] table th,body.wp-admin [id^=siren-] table td{border-bottom:1px solid #c3c4c7;padding:8px 10px}body.wp-admin [id^=siren-] table th{font-weight:600;text-align:left}body.wp-admin [id^=siren-] .status-green{background-color:#d6efc7;color:#1e4620;border-color:#a4d494}body.wp-admin [id^=siren-] .status-yellow{background-color:#fcf0c3;color:#614200;border-color:#dba617}body.wp-admin [id^=siren-] .status-red{background-color:#facfd2;color:#8a0f0f;border-color:#d63638}body.wp-admin [id^=siren-] .status-gray{background-color:#f0f0f1;color:#50575e;border-color:#c3c4c7}body.wp-admin [id^=siren-] .status-blue{background-color:#e7f2fa;color:#135e96;border-color:#2271b1}body.wp-admin [id^=siren-] .siren-tabs{margin-bottom:-1px}body.wp-admin [id^=siren-] .siren-tab{position:relative;display:inline-flex;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;white-space:nowrap;border-bottom:2px solid transparent;color:#50575e;text-decoration:none;background:transparent;outline:none;transition:color .12s ease,border-color .12s ease;margin-bottom:-1px}body.wp-admin [id^=siren-] .siren-tab:hover{color:#1d2327;border-bottom-color:#87888c4d}body.wp-admin [id^=siren-] .siren-tab--active{color:#1d2327;border-bottom-color:#2271b1}body.wp-admin [id^=siren-] .siren-tab:focus{outline:none;box-shadow:none}body.wp-admin [id^=siren-] .siren-tab:focus-visible{outline:2px solid #2271b1;outline-offset:2px;border-radius:2px}
     1*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 100%;--foreground: 220 20% 15%;--card: 0 0% 100%;--card-foreground: 220 20% 15%;--popover: 0 0% 100%;--popover-foreground: 220 20% 15%;--primary: 164 84% 27%;--primary-foreground: 0 0% 100%;--secondary: 210 20% 96%;--secondary-foreground: 220 20% 15%;--muted: 210 20% 96%;--muted-foreground: 220 10% 45%;--accent: 164 100% 95%;--accent-foreground: 164 100% 25%;--destructive: 0 84% 60%;--destructive-foreground: 0 0% 100%;--border: 220 13% 90%;--input: 220 13% 90%;--ring: 164 84% 27%;--radius: .5rem}.dark{--background: 236 100% 5%;--foreground: 210 20% 95%;--card: 236 80% 8%;--card-foreground: 210 20% 95%;--popover: 236 80% 8%;--popover-foreground: 210 20% 95%;--primary: 164 100% 50%;--primary-foreground: 236 100% 5%;--secondary: 235 58% 17%;--secondary-foreground: 210 20% 95%;--muted: 235 58% 17%;--muted-foreground: 215 15% 60%;--accent: 180 30% 20%;--accent-foreground: 164 100% 50%;--destructive: 0 70% 45%;--destructive-foreground: 210 20% 95%;--border: 235 58% 17%;--input: 235 58% 17%;--ring: 164 100% 50%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.status-badge{display:inline-flex;align-items:center;border-radius:9999px;border-width:1px;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;font-weight:500}.status-green{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.dark .status-green{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1));background-color:#052e1680;--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.status-yellow{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(133 77 14 / var(--tw-text-opacity, 1))}.dark .status-yellow{--tw-border-opacity: 1;border-color:rgb(234 179 8 / var(--tw-border-opacity, 1));background-color:#42200680;--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.status-gray{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.dark .status-gray{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1));background-color:#03071280;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.status-red{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.dark .status-red{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));background-color:#450a0a80;--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.status-blue{border-color:transparent;--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.dark .status-blue{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1));background-color:#2e106580;--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.left-0{left:0}.left-2{left:.5rem}.left-2\.5{left:.625rem}.left-3{left:.75rem}.left-\[50\%\]{left:50%}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-1\.5{top:.375rem}.top-1\/2{top:50%}.top-2{top:.5rem}.top-4{top:1rem}.top-\[50\%\]{top:50%}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[999999\]{z-index:999999}.col-span-2{grid-column:span 2 / span 2}.col-span-3{grid-column:span 3 / span 3}.col-span-4{grid-column:span 4 / span 4}.col-span-6{grid-column:span 6 / span 6}.m-0{margin:0}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-2{margin-left:.5rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-2\.5{margin-top:.625rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.mt-px{margin-top:1px}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[280px\]{height:280px}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-fit{height:-moz-fit-content;height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-96{max-height:24rem}.max-h-\[360px\]{max-height:360px}.max-h-\[88vh\]{max-height:88vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.min-h-0{min-height:0px}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-4{width:1rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-\[100cqw\]{width:100cqw}.w-\[10rem\]{width:10rem}.w-\[11rem\]{width:11rem}.w-\[120px\]{width:120px}.w-\[140px\]{width:140px}.w-\[150px\]{width:150px}.w-\[160px\]{width:160px}.w-\[180px\]{width:180px}.w-\[190px\]{width:190px}.w-\[1px\]{width:1px}.w-\[240px\]{width:240px}.w-\[40px\]{width:40px}.w-\[80px\]{width:80px}.w-\[9rem\]{width:9rem}.w-\[calc\(100\%-2rem\)\]{width:calc(100% - 2rem)}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\[1\.25rem\]{min-width:1.25rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[16rem\]{min-width:16rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[min\(100\%\,14rem\)\]{min-width:min(100%,14rem)}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[16rem\]{max-width:16rem}.max-w-\[640px\]{max-width:640px}.max-w-\[68ch\]{max-width:68ch}.max-w-\[85vw\]{max-width:85vw}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-\[-50\%\]{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-50\%\]{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes glow{0%{box-shadow:0 0 hsl(var(--primary) / .7)}50%{box-shadow:0 0 20px 4px hsl(var(--primary) / .5)}to{box-shadow:0 0 hsl(var(--primary) / 0)}}.animate-glow{animation:glow 1s ease-out}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.scroll-mt-4{scroll-margin-top:1rem}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-\[60px_1fr_1fr_120px_100px_100px_40px\]{grid-template-columns:60px 1fr 1fr 120px 100px 100px 40px}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0px}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-16{-moz-column-gap:4rem;column-gap:4rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-1\.5{row-gap:.375rem}.gap-y-14{row-gap:3.5rem}.gap-y-2{row-gap:.5rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(3rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3rem * var(--tw-space-y-reverse))}.space-y-14>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(3.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.625rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.space-y-px>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1px * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.justify-self-end{justify-self:end}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-t-lg{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-amber-400\/40{border-color:#fbbf2466}.border-amber-400\/50{border-color:#fbbf2480}.border-amber-500\/30{border-color:#f59e0b4d}.border-border{border-color:hsl(var(--border))}.border-border\/60{border-color:hsl(var(--border) / .6)}.border-destructive{border-color:hsl(var(--destructive))}.border-destructive\/30{border-color:hsl(var(--destructive) / .3)}.border-emerald-400\/50{border-color:#34d39980}.border-emerald-500\/30{border-color:#10b9814d}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-green-500\/30{border-color:#22c55e4d}.border-input{border-color:hsl(var(--input))}.border-muted-foreground\/25{border-color:hsl(var(--muted-foreground) / .25)}.border-primary{border-color:hsl(var(--primary))}.border-primary\/20{border-color:hsl(var(--primary) / .2)}.border-primary\/25{border-color:hsl(var(--primary) / .25)}.border-primary\/30{border-color:hsl(var(--primary) / .3)}.border-primary\/40{border-color:hsl(var(--primary) / .4)}.border-primary\/50{border-color:hsl(var(--primary) / .5)}.border-purple-400\/50{border-color:#c084fc80}.border-sky-400\/50{border-color:#38bdf880}.border-transparent{border-color:transparent}.bg-accent{background-color:hsl(var(--accent))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-400\/10{background-color:#fbbf241a}.bg-amber-400\/\[0\.07\]{background-color:#fbbf2412}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/15{background-color:#f59e0b26}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-background{background-color:hsl(var(--background))}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-card\/50{background-color:hsl(var(--card) / .5)}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-destructive\/5{background-color:hsl(var(--destructive) / .05)}.bg-emerald-400\/10{background-color:#34d3991a}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/15{background-color:#10b98126}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-50\/50{background-color:#f0fdf480}.bg-green-500\/5{background-color:#22c55e0d}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted-foreground{background-color:hsl(var(--muted-foreground))}.bg-muted-foreground\/40{background-color:hsl(var(--muted-foreground) / .4)}.bg-muted\/20{background-color:hsl(var(--muted) / .2)}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/40{background-color:hsl(var(--muted) / .4)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-primary\/5{background-color:hsl(var(--primary) / .05)}.bg-purple-400\/10{background-color:#c084fc1a}.bg-rose-100{--tw-bg-opacity: 1;background-color:rgb(255 228 230 / var(--tw-bg-opacity, 1))}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sky-400\/10{background-color:#38bdf81a}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-primary\/10{--tw-gradient-from: hsl(var(--primary) / .1) var(--tw-gradient-from-position);--tw-gradient-to: hsl(var(--primary) / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-primary\/5{--tw-gradient-to: hsl(var(--primary) / .05) var(--tw-gradient-to-position)}.fill-current{fill:currentColor}.object-contain{-o-object-fit:contain;object-fit:contain}.p-0{padding:0}.p-1{padding:.25rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-\[50vh\]{padding-bottom:50vh}.pl-0{padding-left:0}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-1\.5{padding-right:.375rem}.pr-10{padding-right:2.5rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pr-8{padding-right:2rem}.pr-9{padding-right:2.25rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-10{padding-top:2.5rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.ordinal{--tw-ordinal: ordinal;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-widest{letter-spacing:.1em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-current{color:currentColor}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-destructive\/70{color:hsl(var(--destructive) / .7)}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/80{color:hsl(var(--foreground) / .8)}.text-foreground\/90{color:hsl(var(--foreground) / .9)}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-primary\/60{color:hsl(var(--primary) / .6)}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-rose-800{--tw-text-opacity: 1;color:rgb(159 18 57 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-sky-600{--tw-text-opacity: 1;color:rgb(2 132 199 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/25{--tw-shadow-color: rgb(0 0 0 / .25);--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-primary{--tw-ring-color: hsl(var(--primary))}.ring-primary\/40{--tw-ring-color: hsl(var(--primary) / .4)}.ring-primary\/50{--tw-ring-color: hsl(var(--primary) / .5)}.ring-offset-2{--tw-ring-offset-width: 2px}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[transform\,visibility\,width\]{transition-property:transform,visibility,width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.\[container-type\:inline-size\]{container-type:inline-size}.\[grid-template-columns\:repeat\(auto-fill\,minmax\(260px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}.code-token{color:var(--code-light, inherit)}.dark .code-token{color:var(--code-dark, inherit)}.dark [data-color-mode=dark] .w-tc-editor-text,.dark [data-color-mode=dark] textarea{caret-color:#e2e8f0!important}.dark [data-color-mode=dark] .w-tc-editor{--color-prettylights-syntax-entity: #93c5fd;--color-prettylights-syntax-string: #86efac;--color-prettylights-syntax-constant: #c4b5fd;--color-prettylights-syntax-keyword: #f9a8d4}body.admin-bar [data-radix-portal] [role=dialog]{top:32px!important;height:calc(100vh - 32px)!important}body.admin-bar [data-radix-portal] [data-state][class*=inset-0]{top:32px!important}@media screen and (max-width:782px){body.admin-bar [data-radix-portal] [role=dialog]{top:46px!important;height:calc(100vh - 46px)!important}body.admin-bar [data-radix-portal] [data-state][class*=inset-0]{top:46px!important}}.siren-tabs .siren-tab{position:relative;display:inline-flex;align-items:center;padding:.5rem 1rem;margin-bottom:-1px;font-size:.875rem;font-weight:500;white-space:nowrap;border-bottom:2px solid transparent;color:hsl(var(--muted-foreground));transition:color .12s,border-color .12s;text-decoration:none;outline:none;box-shadow:none}.siren-tabs .siren-tab:hover{color:hsl(var(--foreground));border-bottom-color:hsl(var(--muted-foreground) / .3);text-decoration:none}.siren-tabs .siren-tab:focus,.siren-tabs .siren-tab:active{outline:none;box-shadow:none}.siren-tabs .siren-tab:focus-visible{outline:2px dotted hsl(var(--ring));outline-offset:2px;border-radius:2px}.siren-tabs .siren-tab--active{color:hsl(var(--foreground));border-bottom-color:hsl(var(--primary))}.siren-tabs .siren-tab--active:hover{border-bottom-color:hsl(var(--primary))}.siren-notification-body p{margin:0 0 .75rem}.siren-notification-body ul{list-style:disc;padding-left:1.25rem;margin:0 0 .75rem}.siren-notification-body ol{list-style:decimal;padding-left:1.25rem;margin:0 0 .75rem}.siren-notification-body a{color:hsl(var(--primary));text-decoration:underline}.siren-notification-body p.is-editor-empty:first-child:before{content:attr(data-placeholder);float:left;height:0;pointer-events:none;color:hsl(var(--muted-foreground))}.siren-merge-tag{border-radius:.25rem;padding:0 .25rem;background:hsl(var(--primary) / .1);color:hsl(var(--primary));font-weight:500;white-space:nowrap}[data-tour-sample=true]+div{display:none}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:text-foreground::file-selector-button{color:hsl(var(--foreground))}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:bottom-1:before{content:var(--tw-content);bottom:.25rem}.before\:left-\[1\.05rem\]:before{content:var(--tw-content);left:1.05rem}.before\:top-1:before{content:var(--tw-content);top:.25rem}.before\:w-px:before{content:var(--tw-content);width:1px}.before\:bg-border:before{content:var(--tw-content);background-color:hsl(var(--border))}.last\:mb-0:last-child{margin-bottom:0}.last\:border-0:last-child{border-width:0px}.last\:border-b-0:last-child{border-bottom-width:0px}.last\:pb-0:last-child{padding-bottom:0}.hover\:-translate-y-0\.5:hover{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border:hover{border-width:1px}.hover\:border-current:hover{border-color:currentColor}.hover\:border-destructive:hover{border-color:hsl(var(--destructive))}.hover\:border-muted-foreground\/50:hover{border-color:hsl(var(--muted-foreground) / .5)}.hover\:border-primary\/30:hover{border-color:hsl(var(--primary) / .3)}.hover\:border-primary\/40:hover{border-color:hsl(var(--primary) / .4)}.hover\:border-primary\/50:hover{border-color:hsl(var(--primary) / .5)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/30:hover{background-color:hsl(var(--muted) / .3)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-muted\/60:hover{background-color:hsl(var(--muted) / .6)}.hover\:bg-primary\/10:hover{background-color:hsl(var(--primary) / .1)}.hover\:bg-primary\/5:hover{background-color:hsl(var(--primary) / .05)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:bg-transparent:hover{background-color:transparent}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:text-primary:hover{color:hsl(var(--primary))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:fixed:focus{position:fixed}.focus\:left-4:focus{left:1rem}.focus\:top-4:focus{top:1rem}.focus\:z-\[100\]:focus{z-index:100}.focus\:rounded-md:focus{border-radius:calc(var(--radius) - 2px)}.focus\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\:bg-primary:focus{background-color:hsl(var(--primary))}.focus\:px-4:focus{padding-left:1rem;padding-right:1rem}.focus\:py-2:focus{padding-top:.5rem;padding-bottom:.5rem}.focus\:text-sm:focus{font-size:.875rem;line-height:1.25rem}.focus\:font-medium:focus{font-weight:500}.focus\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\:text-destructive:focus{color:hsl(var(--destructive))}.focus\:text-primary-foreground:focus{color:hsl(var(--primary-foreground))}.focus\:opacity-100:focus{opacity:1}.focus\:shadow-lg:focus{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group.toaster .group-\[\.toaster\]\:border-border{border-color:hsl(var(--border))}.group.toaster .group-\[\.toaster\]\:border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.group.toaster .group-\[\.toaster\]\:border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.group.toast .group-\[\.toast\]\:bg-muted{background-color:hsl(var(--muted))}.group.toast .group-\[\.toast\]\:bg-primary{background-color:hsl(var(--primary))}.group.toaster .group-\[\.toaster\]\:bg-background{background-color:hsl(var(--background))}.group.toaster .group-\[\.toaster\]\:bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.group.toaster .group-\[\.toaster\]\:bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.group.toast .group-\[\.toast\]\:text-muted-foreground{color:hsl(var(--muted-foreground))}.group.toast .group-\[\.toast\]\:text-primary-foreground{color:hsl(var(--primary-foreground))}.group.toaster .group-\[\.toaster\]\:text-foreground{color:hsl(var(--foreground))}.group.toaster .group-\[\.toaster\]\:text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.group.toaster .group-\[\.toaster\]\:text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.group.toaster .group-\[\.toaster\]\:shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\[state\=open\]\:bg-secondary[data-state=open]{background-color:hsl(var(--secondary))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:hsl(var(--primary-foreground))}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\[state\=closed\]\:duration-300[data-state=closed]{transition-duration:.3s}.data-\[state\=open\]\:duration-500[data-state=open]{transition-duration:.5s}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-amber-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:bg-amber-900\/30:is(.dark *){background-color:#78350f4d}.dark\:bg-amber-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(69 26 3 / var(--tw-bg-opacity, 1))}.dark\:bg-amber-950\/30:is(.dark *){background-color:#451a034d}.dark\:bg-amber-950\/40:is(.dark *){background-color:#451a0366}.dark\:bg-background:is(.dark *){background-color:hsl(var(--background))}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-blue-950\/30:is(.dark *){background-color:#1725544d}.dark\:bg-green-500:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-rose-900\/30:is(.dark *){background-color:#8813374d}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:text-amber-100:is(.dark *){--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity, 1))}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-amber-500:is(.dark *){--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.dark\:text-blue-200:is(.dark *){--tw-text-opacity: 1;color:rgb(191 219 254 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-emerald-400:is(.dark *){--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-green-500:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-purple-300:is(.dark *){--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.dark\:text-rose-300:is(.dark *){--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.dark\:text-sky-300:is(.dark *){--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:shadow-black\/50:is(.dark *){--tw-shadow-color: rgb(0 0 0 / .5);--tw-shadow: var(--tw-shadow-colored)}.dark\:ring-1:is(.dark *){--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.dark\:ring-white\/10:is(.dark *){--tw-ring-color: rgb(255 255 255 / .1)}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:hidden{display:none}.sm\:w-40{width:10rem}.sm\:w-\[160px\]{width:160px}.sm\:w-\[200px\]{width:200px}.sm\:w-\[220px\]{width:220px}.sm\:w-full{width:100%}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-lg{max-width:32rem}.sm\:max-w-md{max-width:28rem}.sm\:max-w-sm{max-width:24rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,14rem\)\]{grid-template-columns:minmax(0,1fr) minmax(0,14rem)}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-start{align-items:flex-start}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-between{justify-content:space-between}.sm\:gap-8{gap:2rem}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:p-6{padding:1.5rem}.sm\:pl-11{padding-left:2.75rem}.sm\:text-left{text-align:left}.sm\:opacity-0{opacity:0}.group:focus-within .sm\:group-focus-within\:opacity-100{opacity:1}.group:hover .sm\:group-hover\:opacity-100{opacity:1}}@media(min-width:768px){.md\:visible{visibility:visible}.md\:sticky{position:sticky}.md\:top-0{top:0}.md\:z-auto{z-index:auto}.md\:col-span-2{grid-column:span 2 / span 2}.md\:inline-flex{display:inline-flex}.md\:table-cell{display:table-cell}.md\:hidden{display:none}.md\:h-screen{height:100vh}.md\:w-16{width:4rem}.md\:w-56{width:14rem}.md\:max-w-none{max-width:none}.md\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}@media(min-width:1024px){.lg\:sticky{position:sticky}.lg\:top-6{top:1.5rem}.lg\:col-span-1{grid-column:span 1 / span 1}.lg\:col-span-3{grid-column:span 3 / span 3}.lg\:block{display:block}.lg\:grid{display:grid}.lg\:w-60{width:15rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-\[60px_1fr_1fr_120px_100px_100px_40px\]{grid-template-columns:60px 1fr 1fr 120px 100px 100px 40px}.lg\:grid-cols-\[minmax\(0\,1fr\)_344px\]{grid-template-columns:minmax(0,1fr) 344px}.lg\:flex-row{flex-direction:row}.lg\:self-start{align-self:flex-start}.lg\:rounded-none{border-radius:0}.lg\:border-0{border-width:0px}.lg\:p-0{padding:0}}@media(min-width:1280px){.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>\*\]\:min-w-0>*{min-width:0px}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>span\]\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\[\&\>svg\]\:size-4>svg{width:1rem;height:1rem}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:1rem;height:1rem}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}body.wp-admin{--background: 0 0% 94.1%;--foreground: 210 14% 14%;--card: 0 0% 100%;--card-foreground: 210 14% 14%;--popover: 0 0% 100%;--popover-foreground: 210 14% 14%;--primary: 206 69% 41%;--primary-foreground: 0 0% 100%;--secondary: 220 4% 96%;--secondary-foreground: 210 14% 14%;--muted: 220 4% 96%;--muted-foreground: 210 7% 46%;--accent: 206 69% 95%;--accent-foreground: 206 69% 30%;--destructive: 359 74% 52%;--destructive-foreground: 0 0% 100%;--border: 225 4% 77%;--input: 225 4% 77%;--ring: 206 69% 41%;--radius: 4px}body.wp-admin [id^=siren-]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:1.4}body.wp-admin [id^=siren-]{padding-top:32px}@media screen and (max-width:782px){body.wp-admin [id^=siren-]{padding-top:46px}}body.wp-admin [id^=siren-] input[type=text],body.wp-admin [id^=siren-] input[type=email],body.wp-admin [id^=siren-] input[type=number],body.wp-admin [id^=siren-] input[type=password],body.wp-admin [id^=siren-] input[type=search],body.wp-admin [id^=siren-] input[type=url],body.wp-admin [id^=siren-] input:not([type]),body.wp-admin [id^=siren-] select,body.wp-admin [id^=siren-] textarea,body.wp-admin [id^=siren-] [role=combobox],body.wp-admin [id^=siren-] button[data-slot=trigger]{background-color:#fff!important;border:1px solid #8c8f94!important;border-radius:4px!important;color:#1d2327!important}body.wp-admin [id^=siren-] [data-radix-select-trigger],body.wp-admin [id^=siren-] [cmdk-input]{background-color:#fff!important;border:1px solid #8c8f94!important}body.wp-admin [id^=siren-] input:focus,body.wp-admin [id^=siren-] select:focus,body.wp-admin [id^=siren-] textarea:focus{border-color:#2271b1!important;box-shadow:0 0 0 1px #2271b1!important;outline:none!important}body.wp-admin [id^=siren-] button[class*=bg-primary]:hover,body.wp-admin [id^=siren-] button[class*=bg-primary]:active,body.wp-admin [id^=siren-] button[class*=bg-primary]:focus,body.wp-admin [id^=siren-] button[class*=bg-primary]:focus-visible,body.wp-admin [id^=siren-] a[class*=bg-primary]:hover,body.wp-admin [id^=siren-] a[class*=bg-primary]:active,body.wp-admin [id^=siren-] a[class*=bg-primary]:focus,body.wp-admin [id^=siren-] a[class*=bg-primary]:focus-visible{color:#fff!important}body.wp-admin [id^=siren-] table{background-color:#fff;border-collapse:collapse;width:100%}body.wp-admin [id^=siren-] table thead tr{background-color:#fff}body.wp-admin [id^=siren-] table tbody tr:nth-child(odd){background-color:#f6f7f7}body.wp-admin [id^=siren-] table tbody tr:nth-child(2n){background-color:#fff}body.wp-admin [id^=siren-] table tbody tr:hover{background-color:#f0f0f1}body.wp-admin [id^=siren-] table th,body.wp-admin [id^=siren-] table td{border-bottom:1px solid #c3c4c7;padding:8px 10px}body.wp-admin [id^=siren-] table th{font-weight:600;text-align:left}body.wp-admin [id^=siren-] .status-green{background-color:#d6efc7;color:#1e4620;border-color:#a4d494}body.wp-admin [id^=siren-] .status-yellow{background-color:#fcf0c3;color:#614200;border-color:#dba617}body.wp-admin [id^=siren-] .status-red{background-color:#facfd2;color:#8a0f0f;border-color:#d63638}body.wp-admin [id^=siren-] .status-gray{background-color:#f0f0f1;color:#50575e;border-color:#c3c4c7}body.wp-admin [id^=siren-] .status-blue{background-color:#e7f2fa;color:#135e96;border-color:#2271b1}body.wp-admin [id^=siren-] .siren-tabs{margin-bottom:-1px}body.wp-admin [id^=siren-] .siren-tab{position:relative;display:inline-flex;align-items:center;padding:.5rem 1rem;font-size:.875rem;font-weight:500;white-space:nowrap;border-bottom:2px solid transparent;color:#50575e;text-decoration:none;background:transparent;outline:none;transition:color .12s ease,border-color .12s ease;margin-bottom:-1px}body.wp-admin [id^=siren-] .siren-tab:hover{color:#1d2327;border-bottom-color:#87888c4d}body.wp-admin [id^=siren-] .siren-tab--active{color:#1d2327;border-bottom-color:#2271b1}body.wp-admin [id^=siren-] .siren-tab:focus{outline:none;box-shadow:none}body.wp-admin [id^=siren-] .siren-tab:focus-visible{outline:2px solid #2271b1;outline-offset:2px;border-radius:2px}
Note: See TracChangeset for help on using the changeset viewer.