Changeset 3788740
- Timestamp:
- 11/06/2026 09:26:47 PM (less than one hour ago)
- Location:
- siren-affiliates/trunk
- Files:
-
- 115 added
- 40 deleted
- 94 edited
-
frontend-source/lite-paid-sources.json (modified) (5 diffs)
-
frontend-source/package-lock.json (modified) (7 diffs)
-
frontend-source/package.json (modified) (2 diffs)
-
frontend-source/src/core/constants/recordImports.ts (added)
-
frontend-source/src/core/schemas/collaborator.schema.ts (modified) (2 diffs)
-
frontend-source/src/core/schemas/transaction.schema.ts (modified) (1 diff)
-
frontend-source/src/core/types/api.ts (modified) (1 diff)
-
frontend-source/src/core/types/collaborator-dashboard.ts (modified) (1 diff)
-
frontend-source/src/core/types/collaborator.ts (modified) (2 diffs)
-
frontend-source/src/core/types/inbound.ts (modified) (1 diff)
-
frontend-source/src/core/types/property-kind.ts (added)
-
frontend-source/src/core/types/transaction.ts (modified) (1 diff)
-
frontend-source/src/core/utils/collaboratorDisplayName.ts (added)
-
frontend-source/src/core/utils/customFieldKey.ts (added)
-
frontend-source/src/index.css (modified) (2 diffs)
-
frontend-source/src/platform/wordpress/entries/collaborators.tsx (modified) (2 diffs)
-
frontend-source/src/platform/wordpress/entries/programs.tsx (modified) (1 diff)
-
frontend-source/src/service/api/client.ts (modified) (3 diffs)
-
frontend-source/src/service/api/collaborators.ts (modified) (5 diffs)
-
frontend-source/src/service/api/connection-health.ts (added)
-
frontend-source/src/service/api/fulfillments.ts (modified) (1 diff)
-
frontend-source/src/service/api/inbound.ts (modified) (2 diffs)
-
frontend-source/src/service/api/products.ts (modified) (2 diffs)
-
frontend-source/src/service/api/properties.ts (modified) (5 diffs)
-
frontend-source/src/service/api/recipes.ts (modified) (13 diffs)
-
frontend-source/src/service/api/transactions.ts (modified) (3 diffs)
-
frontend-source/src/service/components/ActivityTimeline.tsx (modified) (2 diffs)
-
frontend-source/src/service/components/ConnectionHealthStatus.tsx (added)
-
frontend-source/src/service/components/RecordsEmptyState.tsx (added)
-
frontend-source/src/service/components/SirenWordmark.tsx (added)
-
frontend-source/src/service/components/collaborator-dashboard/ReferralUrlGenerator.tsx (modified) (2 diffs)
-
frontend-source/src/service/components/data-table/BulkActionBar.tsx (modified) (5 diffs)
-
frontend-source/src/service/components/data-table/DataTable.tsx (modified) (12 diffs)
-
frontend-source/src/service/components/help/ProgramFlowDiagram.tsx (modified) (1 diff)
-
frontend-source/src/service/components/help/help-content.ts (modified) (7 diffs)
-
frontend-source/src/service/components/sidebar/BrandLink.tsx (added)
-
frontend-source/src/service/components/sidebar/GroupNav.tsx (modified) (3 diffs)
-
frontend-source/src/service/components/sidebar/Sidebar.tsx (modified) (26 diffs)
-
frontend-source/src/service/components/sidebar/groups.ts (modified) (2 diffs)
-
frontend-source/src/service/components/sidebar/index.ts (modified) (1 diff)
-
frontend-source/src/service/components/tour-sample (added)
-
frontend-source/src/service/components/tour-sample/TourSample.tsx (added)
-
frontend-source/src/service/components/tour-sample/index.ts (added)
-
frontend-source/src/service/components/ui/code-block (added)
-
frontend-source/src/service/components/ui/code-block/code-block.tsx (added)
-
frontend-source/src/service/components/ui/code-block/highlight.ts (added)
-
frontend-source/src/service/components/ui/code-block/index.ts (added)
-
frontend-source/src/service/components/ui/code-block/siren-dark.json (added)
-
frontend-source/src/service/components/ui/code-block/siren-light.json (added)
-
frontend-source/src/service/components/ui/copy-button.tsx (added)
-
frontend-source/src/service/components/ui/index.ts (modified) (1 diff)
-
frontend-source/src/service/components/ui/sonner.tsx (modified) (1 diff)
-
frontend-source/src/service/contexts/platform.tsx (modified) (2 diffs)
-
frontend-source/src/service/contexts/tour-sample.ts (added)
-
frontend-source/src/service/hooks/useBoundedRefresh.ts (added)
-
frontend-source/src/service/lib/clipboard.ts (added)
-
frontend-source/src/service/recipes/describedValues.ts (added)
-
frontend-source/src/service/screens/collaborator-dashboard/CollaboratorCouponsScreen.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/collaborator-dashboard/CollaboratorDashboardScreen.tsx (modified) (1 diff)
-
frontend-source/src/service/screens/collaborators/CollaboratorViewScreen.tsx (modified) (9 diffs)
-
frontend-source/src/service/screens/collaborators/CollaboratorsEditScreen.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/collaborators/CollaboratorsListScreen.tsx (modified) (18 diffs)
-
frontend-source/src/service/screens/collaborators/CustomFieldsCard.tsx (added)
-
frontend-source/src/service/screens/collaborators/InvitedStatus.tsx (added)
-
frontend-source/src/service/screens/collaborators/import (added)
-
frontend-source/src/service/screens/collaborators/import/ChoicesStep.tsx (added)
-
frontend-source/src/service/screens/collaborators/import/CollaboratorImport.tsx (added)
-
frontend-source/src/service/screens/collaborators/import/CollaboratorImportScreen.tsx (added)
-
frontend-source/src/service/screens/collaborators/import/definition.ts (added)
-
frontend-source/src/service/screens/collaborators/import/index.ts (added)
-
frontend-source/src/service/screens/collaborators/import/plan.ts (added)
-
frontend-source/src/service/screens/collaborators/import/recipe.ts (added)
-
frontend-source/src/service/screens/conversions/ConversionDetailScreen.tsx (modified) (5 diffs)
-
frontend-source/src/service/screens/conversions/ConversionsListScreen.tsx (modified) (7 diffs)
-
frontend-source/src/service/screens/coupons/CollaboratorCouponsCard.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/coupons/CollaboratorPicker.tsx (modified) (3 diffs)
-
frontend-source/src/service/screens/coupons/CouponCodesScreen.tsx (modified) (6 diffs)
-
frontend-source/src/service/screens/csv-import (added)
-
frontend-source/src/service/screens/csv-import/CsvImport.tsx (added)
-
frontend-source/src/service/screens/csv-import/MappingStep.tsx (added)
-
frontend-source/src/service/screens/csv-import/PreviewStep.tsx (added)
-
frontend-source/src/service/screens/csv-import/RecipePanel.tsx (added)
-
frontend-source/src/service/screens/csv-import/ResultStep.tsx (added)
-
frontend-source/src/service/screens/csv-import/TypeStep.tsx (added)
-
frontend-source/src/service/screens/csv-import/UploadStep.tsx (added)
-
frontend-source/src/service/screens/csv-import/csv.ts (added)
-
frontend-source/src/service/screens/csv-import/importTypes.ts (added)
-
frontend-source/src/service/screens/csv-import/index.ts (added)
-
frontend-source/src/service/screens/csv-import/mapping.ts (added)
-
frontend-source/src/service/screens/csv-import/preview.ts (added)
-
frontend-source/src/service/screens/csv-import/results.ts (added)
-
frontend-source/src/service/screens/csv-import/rows.ts (added)
-
frontend-source/src/service/screens/csv-import/types.ts (added)
-
frontend-source/src/service/screens/currencies/CustomCurrenciesManager.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/customers/CustomersBanner.tsx (modified) (1 diff)
-
frontend-source/src/service/screens/customers/CustomersListScreen.tsx (modified) (7 diffs)
-
frontend-source/src/service/screens/customers/LinkCollaboratorDialog.tsx (modified) (3 diffs)
-
frontend-source/src/service/screens/customers/helpers.ts (modified) (2 diffs)
-
frontend-source/src/service/screens/engagements/EngagementsListScreen.tsx (modified) (1 diff)
-
frontend-source/src/service/screens/fulfillments/FulfillmentDetailScreen.tsx (modified) (15 diffs)
-
frontend-source/src/service/screens/fulfillments/FulfillmentsAutoRefresh.tsx (added)
-
frontend-source/src/service/screens/fulfillments/FulfillmentsListScreen.tsx (modified) (5 diffs)
-
frontend-source/src/service/screens/main-menu/LogsTab.tsx (modified) (4 diffs)
-
frontend-source/src/service/screens/main-menu/UtilitiesTab.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/obligations/ObligationsListScreen.tsx (modified) (4 diffs)
-
frontend-source/src/service/screens/products/CollaboratorProductsCard.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/products/ProductViewScreen.tsx (modified) (6 diffs)
-
frontend-source/src/service/screens/products/ProductsListScreen.tsx (modified) (10 diffs)
-
frontend-source/src/service/screens/products/import (added)
-
frontend-source/src/service/screens/products/import/ChoicesStep.tsx (added)
-
frontend-source/src/service/screens/products/import/ProductImportScreen.tsx (added)
-
frontend-source/src/service/screens/products/import/definition.ts (added)
-
frontend-source/src/service/screens/products/import/index.ts (added)
-
frontend-source/src/service/screens/products/import/plan.ts (added)
-
frontend-source/src/service/screens/products/import/recipe.ts (added)
-
frontend-source/src/service/screens/programs/ProgramViewScreen.tsx (modified) (8 diffs)
-
frontend-source/src/service/screens/programs/ProgramsEditScreen.tsx (modified) (9 diffs)
-
frontend-source/src/service/screens/programs/ProgramsListScreen.tsx (modified) (8 diffs)
-
frontend-source/src/service/screens/recipes/CreateProgramChooser.tsx (modified) (2 diffs)
-
frontend-source/src/service/screens/recipes/ImportRecipeScreen.tsx (modified) (4 diffs)
-
frontend-source/src/service/screens/recipes/RecipeBrowserScreen.tsx (modified) (6 diffs)
-
frontend-source/src/service/screens/recipes/RecipeConstructs.tsx (modified) (8 diffs)
-
frontend-source/src/service/screens/recipes/RecipeDetailScreen.tsx (modified) (3 diffs)
-
frontend-source/src/service/screens/recipes/UploadView.tsx (modified) (7 diffs)
-
frontend-source/src/service/screens/recipes/UseRecipeModal.tsx (modified) (1 diff)
-
frontend-source/src/service/screens/recipes/catalog-taxonomy.ts (modified) (9 diffs)
-
frontend-source/src/service/screens/transactions/TransactionDetailScreen.tsx (modified) (8 diffs)
-
frontend-source/src/service/screens/transactions/TransactionsListScreen.tsx (modified) (15 diffs)
-
frontend-source/src/service/screens/transactions/order-link.ts (added)
-
frontend-source/src/service/stores/collaborators.ts (modified) (2 diffs)
-
frontend-source/src/service/stores/fulfillments.ts (modified) (3 diffs)
-
frontend-source/src/service/stores/inbound.ts (modified) (1 diff)
-
frontend-source/src/service/stores/recipeCatalog.ts (modified) (2 diffs)
-
frontend-source/src/service/utils/payout-refresh.ts (added)
-
frontend-source/src/vite-env.d.ts (modified) (1 diff)
-
frontend-source/tsconfig.json (modified) (1 diff)
-
frontend-source/vite.config.ts (modified) (4 diffs)
-
frontend/collaborator-coupons.js (modified) (1 diff)
-
frontend/collaborator-dashboard.js (modified) (1 diff)
-
frontend/collaborator-performance.js (modified) (1 diff)
-
frontend/collaborator-profile.js (modified) (1 diff)
-
frontend/collaborator-rewards.js (modified) (1 diff)
-
frontend/collaborators.js (modified) (1 diff)
-
frontend/conversions.js (modified) (1 diff)
-
frontend/coupon-codes.js (modified) (1 diff)
-
frontend/customers.js (modified) (1 diff)
-
frontend/engagements.js (modified) (1 diff)
-
frontend/fulfillments.js (modified) (1 diff)
-
frontend/main-menu.js (modified) (1 diff)
-
frontend/obligations.js (modified) (1 diff)
-
frontend/programs.js (modified) (1 diff)
-
frontend/shared/ActivityDrawer-BZxDAdLe.js (added)
-
frontend/shared/ActivityDrawer-iYDgZTH3.js (deleted)
-
frontend/shared/AreaChart-58TrxGu7.js (deleted)
-
frontend/shared/AreaChart-CUGMAtch.js (added)
-
frontend/shared/BulkPickerModal-DpL-mI_R.js (added)
-
frontend/shared/CollaboratorProfileScreen-BdTj_h9E.js (added)
-
frontend/shared/CollaboratorProfileScreen-DiVRzawG.js (deleted)
-
frontend/shared/CouponDialogs-BS2YEuir.js (added)
-
frontend/shared/CouponDialogs-Ci2bD_jZ.js (deleted)
-
frontend/shared/CsvImport-Dumku5_r.js (added)
-
frontend/shared/HelpDrawer-BOa5Le1J.js (added)
-
frontend/shared/HelpDrawer-CQSl1exo.js (deleted)
-
frontend/shared/HelpTooltip-DsFyDQG4.js (deleted)
-
frontend/shared/HelpTooltip-YN4U7Ym7.js (added)
-
frontend/shared/IntegrationPreview-BM-XjKI4.js (deleted)
-
frontend/shared/IntegrationPreview-VmIfRPju.js (added)
-
frontend/shared/ListPager-DKO5XR7M.js (deleted)
-
frontend/shared/RecipeDetailScreen-CEcAya7w.js (added)
-
frontend/shared/RecipeDetailScreen-DcUFdtvj.js (deleted)
-
frontend/shared/RecordsEmptyState-jrCUXFqo.js (added)
-
frontend/shared/TestSaleBadge--DG3xZwg.js (added)
-
frontend/shared/TestSaleBadge-DCBR_ipH.js (deleted)
-
frontend/shared/WordPressRouter-CAYzko7X.js (added)
-
frontend/shared/WordPressRouter-ifxiIFvs.js (deleted)
-
frontend/shared/arrow-left-W0B3m2vw.js (deleted)
-
frontend/shared/arrow-left-XvsxLAWy.js (added)
-
frontend/shared/bash-Yzrsuije.js (added)
-
frontend/shared/clipboard-Ch4rpUJU.js (added)
-
frontend/shared/clock-3iWagaOq.js (added)
-
frontend/shared/clock-MPHmQLgH.js (deleted)
-
frontend/shared/collaborator-dashboard-CmODHn95.js (deleted)
-
frontend/shared/collaborator-dashboard-o5ivsW6s.js (added)
-
frontend/shared/collaborator-groups-BP0hAJf8.js (added)
-
frontend/shared/collaboratorDisplayName-DvmzsaZc.js (added)
-
frontend/shared/collaborators-BvingK76.js (deleted)
-
frontend/shared/confirm-dialog-BdfYPOfc.js (added)
-
frontend/shared/confirm-dialog-DM12emMj.js (deleted)
-
frontend/shared/conversion.schema-BXGiWhtb.js (added)
-
frontend/shared/conversions-D67NHe2F.js (added)
-
frontend/shared/conversions-HMIw6T3R.js (deleted)
-
frontend/shared/copy-j7vAIT70.js (deleted)
-
frontend/shared/core-C0bywMpg.js (added)
-
frontend/shared/engagements-6JbMv8n_.js (added)
-
frontend/shared/engagements-BdjHp3Bf.js (deleted)
-
frontend/shared/engine-javascript-CCVFU3bj.js (added)
-
frontend/shared/form-field-CrfWqu5t.js (added)
-
frontend/shared/form-field-Dbux2jvw.js (deleted)
-
frontend/shared/fulfillments-DDk-ZIVs.js (deleted)
-
frontend/shared/fulfillments-PrFHoXSm.js (added)
-
frontend/shared/gift-Bbpi-vg_.js (deleted)
-
frontend/shared/gift-Bz0xaFMj.js (added)
-
frontend/shared/html-XDxVMB5l.js (added)
-
frontend/shared/javascript-wDzz0qaB.js (added)
-
frontend/shared/json-Cp-IABpG.js (added)
-
frontend/shared/link-2-C4uE2qWf.js (added)
-
frontend/shared/link-2-CR4ULk7z.js (deleted)
-
frontend/shared/markdown-renderer-1IfYWwRA.js (added)
-
frontend/shared/markdown-renderer-s6F8PPyM.js (deleted)
-
frontend/shared/obligations-1RIdX1q5.js (deleted)
-
frontend/shared/obligations-tU6cfrpO.js (added)
-
frontend/shared/php-BIU069ue.js (added)
-
frontend/shared/plus-8fF9_2v-.js (added)
-
frontend/shared/plus-xgV5QLEC.js (deleted)
-
frontend/shared/properties-ByxWotcN.js (added)
-
frontend/shared/properties-Cx8gxvGK.js (deleted)
-
frontend/shared/python-B6aJPvgy.js (added)
-
frontend/shared/react-Rq6nbqOn.js (added)
-
frontend/shared/react-zvEYxxW2.js (deleted)
-
frontend/shared/registries-CatPSk3G.js (added)
-
frontend/shared/registries-Ql2SZeKd.js (deleted)
-
frontend/shared/shopping-cart-BNnMkrGt.js (deleted)
-
frontend/shared/shopping-cart-wQHZa-fh.js (added)
-
frontend/shared/siren-dark-CoTtnrmf.js (added)
-
frontend/shared/siren-light-BpiCssA2.js (added)
-
frontend/shared/sparkles-Cs-c5bLd.js (added)
-
frontend/shared/sparkles-ZTBJ8zt0.js (deleted)
-
frontend/shared/tag-C-fbb3UJ.js (added)
-
frontend/shared/tag-DozXXg8T.js (deleted)
-
frontend/shared/trending-up-B12dlnRi.js (deleted)
-
frontend/shared/trending-up-Cg5-4LxH.js (added)
-
frontend/shared/triangle-alert-B1idIoet.js (deleted)
-
frontend/shared/triangle-alert-BXQaBsm-.js (added)
-
frontend/shared/typescript-BPQ3VLAy.js (added)
-
frontend/shared/upload-ZoYz9lGb.js (added)
-
frontend/shared/useListRequest-BAYNcD8F.js (added)
-
frontend/shared/useListRequest-CKMUCtxK.js (deleted)
-
frontend/shared/useMoneyFormatter-B6sdhxKB.js (added)
-
frontend/shared/useMoneyFormatter-BaBJUw_5.js (deleted)
-
frontend/shared/usePortalMoney-BvA6Y-hX.js (deleted)
-
frontend/shared/usePortalMoney-l-aykMsd.js (added)
-
frontend/shared/useStagedMembership-C1sNy_D6.js (deleted)
-
frontend/shared/useStagedMembership-pDKVh3Wd.js (added)
-
frontend/shared/validation-D6cKTXRt.js (added)
-
frontend/shared/validation-f7jbdrjp.js (deleted)
-
frontend/shared/wordpress-admin-DNnGQGoM.js (deleted)
-
frontend/shared/wordpress-admin-D_eccjaB.js (added)
-
frontend/transactions.js (modified) (1 diff)
-
frontend/wordpress-admin.css (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
siren-affiliates/trunk/frontend-source/lite-paid-sources.json
r3775642 r3788740 5 5 "src/core/schemas/custom-currency.schema.ts", 6 6 "src/core/schemas/distribution.schema.ts", 7 "src/core/schemas/metric.schema.ts", 7 8 "src/core/types/api-key.ts", 8 9 "src/core/types/autofulfiller.ts", … … 11 12 "src/core/types/distribution.ts", 12 13 "src/core/types/distributor.ts", 14 "src/core/types/metric.ts", 13 15 "src/core/types/program-group.ts", 14 16 "src/core/types/webhook.ts", … … 19 21 "src/service/api/distributions.ts", 20 22 "src/service/api/integrations.ts", 23 "src/service/api/metrics.ts", 21 24 "src/service/api/webhooks.ts", 22 25 "src/service/components/payouts/email.ts", … … 24 27 "src/service/screens/collaborator-groups", 25 28 "src/service/screens/integrations", 29 "src/service/screens/metrics", 26 30 "src/service/screens/main-menu/CutoverWarnings.tsx", 27 31 "src/service/screens/main-menu/DeleteLocalDataCard.tsx", … … 33 37 "src/service/stores/integrationCatalog.ts", 34 38 "src/service/stores/metric-calculations.ts", 39 "src/service/stores/metrics.ts", 35 40 "src/service/stores/program-groups.ts" 36 41 ], -
siren-affiliates/trunk/frontend-source/package-lock.json
r3775642 r3788740 22 22 "@radix-ui/react-tabs": "^1.1.2", 23 23 "@radix-ui/react-tooltip": "^1.2.8", 24 "@shikijs/langs": "4.5.0", 24 25 "@tiptap/core": "^3.32.0", 25 26 "@tiptap/extension-bold": "^3.32.0", … … 44 45 "react-router-dom": "^7.1.1", 45 46 "recharts": "^3.7.0", 47 "shiki": "4.5.0", 46 48 "sonner": "^2.0.7", 47 49 "tailwind-merge": "^2.6.0", … … 2374 2376 ] 2375 2377 }, 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 }, 2376 2478 "node_modules/@standard-schema/spec": { 2377 2479 "version": "1.1.0", … … 2785 2887 }, 2786 2888 "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==", 2790 2892 "license": "MIT", 2791 2893 "dependencies": { … … 4283 4385 } 4284 4386 }, 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 }, 4285 4404 "node_modules/orderedmap": { 4286 4405 "version": "2.1.1", … … 5022 5141 "url": "https://github.com/sponsors/wooorm" 5023 5142 } 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" 5024 5167 }, 5025 5168 "node_modules/rehype": { … … 5233 5376 "license": "MIT" 5234 5377 }, 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 }, 5235 5397 "node_modules/sonner": { 5236 5398 "version": "2.0.7", -
siren-affiliates/trunk/frontend-source/package.json
r3775642 r3788740 21 21 "@radix-ui/react-tabs": "^1.1.2", 22 22 "@radix-ui/react-tooltip": "^1.2.8", 23 "@shikijs/langs": "4.5.0", 23 24 "@tiptap/core": "^3.32.0", 24 25 "@tiptap/extension-bold": "^3.32.0", … … 43 44 "react-router-dom": "^7.1.1", 44 45 "recharts": "^3.7.0", 46 "shiki": "4.5.0", 45 47 "sonner": "^2.0.7", 46 48 "tailwind-merge": "^2.6.0", -
siren-affiliates/trunk/frontend-source/src/core/schemas/collaborator.schema.ts
r3775642 r3788740 2 2 3 3 /** 4 * Collaborator status values. 4 * Collaborator status values. An invited person has been sent an invitation 5 * and has not accepted it yet. 5 6 */ 6 export const CollaboratorStatusSchema = z.enum(['active', 'pending', 'inactive', 'rejected', 'deleted']) 7 export 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 */ 13 export 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 */ 23 export const CollaboratorCustomFieldsSchema = z.preprocess( 24 (value) => (Array.isArray(value) && value.length === 0 ? {} : value), 25 z.record(z.string(), z.string()), 26 ) 7 27 8 28 /** … … 41 61 distributorId: z.number().nullish(), 42 62 distributorName: z.string().nullish(), 63 invitation: CollaboratorInvitationStateSchema.nullish(), 64 fields: CollaboratorCustomFieldsSchema.nullish(), 43 65 }) 44 66 -
siren-affiliates/trunk/frontend-source/src/core/schemas/transaction.schema.ts
r3775642 r3788740 58 58 source: z.string().nullish(), 59 59 sourceId: z.string().nullish(), 60 sourcePropertyId: z.number().nullish(), 60 61 details: z.array(TransactionDetailSchema).nullish(), 61 62 totalValue: z.number().nullish(), -
siren-affiliates/trunk/frontend-source/src/core/types/api.ts
r3754739 r3788740 34 34 */ 35 35 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> 36 44 } -
siren-affiliates/trunk/frontend-source/src/core/types/collaborator-dashboard.ts
r3775642 r3788740 90 90 /** The site's base URL */ 91 91 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 92 98 } 93 99 -
siren-affiliates/trunk/frontend-source/src/core/types/collaborator.ts
r3775642 r3788740 1 1 /** 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. 3 4 */ 4 export type CollaboratorStatus = 'active' | 'pending' | 'inactive' | 'rejected' | 'deleted' 5 export 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 */ 16 export interface CollaboratorInvitationState { 17 state: 'held' | 'sending' | 'sent' | 'expired' | 'failed' 18 sentAt?: string | null 19 expiresAt?: string | null 20 } 5 21 6 22 /** … … 42 58 distributorId?: number 43 59 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 44 68 } 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 */ 75 export type CollaboratorCustomFields = Record<string, string> 45 76 46 77 /** -
siren-affiliates/trunk/frontend-source/src/core/types/inbound.ts
r3775642 r3788740 41 41 */ 42 42 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. */ 50 export 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. */ 61 export type InboundRefusalReason = 'no_key' | 'signature' 62 63 export 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 79 export 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. */ 87 export 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 43 96 } 44 97 -
siren-affiliates/trunk/frontend-source/src/core/types/transaction.ts
r3775642 r3788740 28 28 source?: string // e.g., 'woocommerce', 'edd', 'manual' 29 29 sourceId?: string // e.g., WooCommerce order ID 30 sourcePropertyId?: number | null // Property whose connected store supplied the order 30 31 31 32 // Extended fields - joined from TransactionDetail or computed -
siren-affiliates/trunk/frontend-source/src/index.css
r3775642 r3788740 113 113 } 114 114 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 115 123 /* Code editor (manifest editor) dark mode overrides */ 116 124 .dark [data-color-mode="dark"] .w-tc-editor-text, … … 244 252 white-space: nowrap; 245 253 } 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 4 4 import { configureApi } from '@service/api/client' 5 5 import { CollaboratorsListScreen, CollaboratorsEditScreen, CollaboratorViewScreen } from '@service/screens/collaborators' 6 import { CollaboratorImportScreen } from '@service/screens/collaborators/import' 6 7 import { Toaster } from '@service/components/ui' 7 8 import { WordPressRouter } from '../WordPressRouter' … … 28 29 <Route path="/collaborators" element={<CollaboratorsListScreen />} /> 29 30 <Route path="/collaborators/new" element={<CollaboratorsEditScreen />} /> 31 <Route path="/collaborators/import" element={<CollaboratorImportScreen />} /> 30 32 <Route path="/collaborators/:id" element={<CollaboratorViewScreen />} /> 31 33 <Route path="/collaborators/:id/view" element={<CollaboratorViewScreen />} /> -
siren-affiliates/trunk/frontend-source/src/platform/wordpress/entries/programs.tsx
r3590633 r3788740 23 23 createRoot(container).render( 24 24 <StrictMode> 25 <WordPressRouter defaultRoute="/programs" >25 <WordPressRouter defaultRoute="/programs" capabilities={window.sirenConfig?.capabilities}> 26 26 <Toaster position="top-right" richColors /> 27 27 <div className="p-4"> -
siren-affiliates/trunk/frontend-source/src/service/api/client.ts
r3775642 r3788740 104 104 105 105 /** 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 */ 109 export 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 /** 106 121 * Make an API request. 107 122 */ … … 163 178 164 179 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))) { 165 191 response = await send(apiConfig.token) 166 192 } … … 227 253 options?.onHeaders?.(response.headers) 228 254 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 } 230 265 } 231 266 -
siren-affiliates/trunk/frontend-source/src/service/api/collaborators.ts
r3775642 r3788740 2 2 import type { DeletionBlockers } from '@service/components/DeleteConfirmDialog' 3 3 import type { ApiListResponse } from '@core/types/api' 4 import type { Collaborator, Collaborator Input } from '@core/types/collaborator'5 import { Collaborator Schema } from '@core/schemas/collaborator.schema'4 import type { Collaborator, CollaboratorCustomFields, CollaboratorInput } from '@core/types/collaborator' 5 import { CollaboratorCustomFieldsSchema, CollaboratorSchema } from '@core/schemas/collaborator.schema' 6 6 import { createApiListResponseSchema } from '@core/schemas/api.schema' 7 7 … … 42 42 'engagementsCount', 43 43 'dateCreated', 44 // Where an invited person's invitation stands. Null for everyone else. 45 'invitation', 44 46 ] 45 47 … … 68 70 'dateCreated', 69 71 'dateModified', 72 // The custom fields the merchant keeps about them, by key. 73 'fields', 70 74 ] 71 75 … … 132 136 api.put<Collaborator>(`/collaborators/${id}`, transformInputForApi(input)) 133 137 .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), 134 147 135 148 /** … … 173 186 174 187 /** 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 /** 175 201 * Generate a random, unique referral code. 176 202 * The server validates the code is safe to use. -
siren-affiliates/trunk/frontend-source/src/service/api/fulfillments.ts
r3775642 r3788740 67 67 orderBy: params?.orderBy, 68 68 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', 70 70 }).then(response => fulfillmentListResponse.parse(response) as ApiListResponse<Fulfillment>) 71 71 }, -
siren-affiliates/trunk/frontend-source/src/service/api/inbound.ts
r3775642 r3788740 5 5 InboundMode, 6 6 InboundTestDelivery, 7 InboundStoreAddressResult, 7 8 } from '@core/types/inbound' 8 9 … … 61 62 clearTestDeliveries: (sourceSlug: string) => 62 63 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 }), 63 68 } -
siren-affiliates/trunk/frontend-source/src/service/api/products.ts
r3775642 r3788740 27 27 /** When a save, an import, a webhook or a sale last confirmed it. */ 28 28 lastSeenAt: string | null 29 parentPlatformId?: string | null 29 30 } 30 31 … … 38 39 name: string 39 40 mergedIntoId: number | null 41 /** The Siren product this variation belongs to. */ 42 parentId?: number | null 40 43 listings: ProductListing[] 41 44 owners: ProductOwnerRef[] -
siren-affiliates/trunk/frontend-source/src/service/api/properties.ts
r3775642 r3788740 1 import type { PropertyKind } from '@core/types/property-kind' 1 2 import { api } from './client' 2 3 … … 7 8 * platform. What it is connected to is its list of integrations: the WordPress 8 9 * 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. 10 12 */ 11 13 14 export type { PropertyKind } 15 12 16 /** One thing a Property is connected to. */ 17 /** A plugin a connected WordPress site runs, such as WooCommerce, as the site last reported it. */ 18 export 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 13 27 export interface PropertyIntegration { 14 28 /** What it connects to: `wordpress` for the connector, else an inbound source's slug such as `shopify`. */ … … 24 38 /** True when it's only shown for the integration preview. It's never connected. */ 25 39 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[] 26 45 } 27 46 … … 31 50 siteUrl: string 32 51 status: string 52 /** A website or a storefront. Older servers leave it out, and those are websites. */ 53 kind?: PropertyKind 33 54 /** Present where the server lists integrations. */ 34 55 integrations?: PropertyIntegration[] 35 56 } 36 57 37 /** What a Property's name, address and statusare changed to. */58 /** What a Property's name, address, status and kind are changed to. */ 38 59 export interface PropertyInput { 39 60 name: string 40 61 siteUrl: string 41 62 status: PropertyStatus 63 /** Left out, it keeps the kind it has. A storefront drops its address. */ 64 kind?: PropertyKind 42 65 } 43 66 … … 90 113 get: (id: number) => api.get<Property>(`/properties/${id}`), 91 114 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 }), 94 118 95 119 /** 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 53 53 } 54 54 55 /** A link from a collaborator to a program, distributor or collaborator group. */ 56 export 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. */ 65 export type CollaboratorOnExisting = 'merge' | 'update' | 'skip' 66 67 /** Emails the collaborator a link to set up their account. */ 68 export 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 55 75 export interface CollaboratorDefinition { 56 76 email: string 57 77 firstName?: string 58 78 lastName?: string 79 fullName?: string 59 80 status?: string 81 /** Set exactly as given. */ 82 referralCode?: string 60 83 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 65 90 [key: string]: unknown 91 } 92 93 /** Who owns a product: a collaborator by email, referral code, id, or recipe key. */ 94 export 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 */ 100 export 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' 66 112 } 67 113 … … 122 168 autofulfillers?: Record<string, AutofulfillerDefinition> 123 169 collaborators?: Record<string, CollaboratorDefinition> 170 products?: Record<string, ProductDefinition> 124 171 mappings?: RecipeMapping[] 125 172 tracking?: RecipeTrackingSettings … … 135 182 | 'autofulfillers' 136 183 | 'collaborators' 184 | 'products' 137 185 | 'mappings' 138 186 | 'tracking' … … 146 194 name: string 147 195 meta: string[] 196 } 197 198 /** One problem or notice the preview found on a collaborator entry. */ 199 export interface PreviewEntryMessage { 200 field: string 201 message: string 202 } 203 204 /** What the preview found for one collaborator entry, by its recipe key. */ 205 export 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. */ 219 export 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 148 226 } 149 227 … … 154 232 samples: PreviewSample[] 155 233 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 156 238 } 157 239 … … 163 245 version: number 164 246 sections: PreviewSection[] 247 invitations?: PreviewInvitations 165 248 } 249 invitations?: PreviewInvitations 166 250 } 167 251 … … 188 272 programGroups: CreatedEntity[] 189 273 distributors: CreatedEntity[] 274 collaboratorGroups?: CreatedEntity[] 190 275 collaborators?: CreatedEntity[] 191 276 currencies?: CreatedCurrency[] … … 196 281 197 282 export type ImportStanzaType = PreviewSectionType 283 284 /** Where an import came from. A CSV import keeps its file name and column mapping. */ 285 export 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. */ 293 export 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 304 export 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. */ 313 export 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 322 export interface ProductImportSummary { 323 added: number 324 updated: number 325 skipped: number 326 failed: number 327 } 198 328 199 329 export interface ImportJobSnapshot { … … 209 339 errorMessage: string | null 210 340 dateCreated: string | null 341 collaboratorResults?: CollaboratorImportResult[] 342 collaboratorSummary?: CollaboratorImportSummary 343 productResults?: ProductImportResult[] 344 productSummary?: ProductImportSummary 345 source?: RecipeImportSource | null 211 346 } 212 347 … … 222 357 completedDate: string | null 223 358 errorMessage: string | null 359 source?: RecipeImportSource | null 224 360 } 225 361 … … 237 373 autofulfillers: 'Autofulfillers', 238 374 collaborators: 'Collaborators', 375 products: 'Products', 239 376 mappings: 'External mappings', 240 377 tracking: 'Tracking settings', … … 280 417 281 418 /** 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 */ 430 export 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. */ 438 export 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 */ 445 export function previewRecipe(recipe: RecipeData, options: RecipeImportOptions = {}): Promise<PreviewResult> { 446 return api.post<PreviewResult>('/recipes/preview', { ...recipe, ...options }) 286 447 } 287 448 … … 294 455 * polls {@link getRecipeImport} until status reaches `complete` or `failed`. 295 456 */ 296 export function applyRecipe(recipe: RecipeData ): Promise<ImportJobSnapshot> {297 return api.post<ImportJobSnapshot>('/recipes/apply', recipe)457 export function applyRecipe(recipe: RecipeData, options: RecipeImportOptions = {}): Promise<ImportJobSnapshot> { 458 return api.post<ImportJobSnapshot>('/recipes/apply', { ...recipe, ...options }) 298 459 } 299 460 -
siren-affiliates/trunk/frontend-source/src/service/api/transactions.ts
r3775642 r3788740 18 18 search?: string 19 19 status?: string 20 /** True for sales a conversion credits to a collaborator, false for the rest. */ 21 credited?: boolean 20 22 orderBy?: string 21 23 order?: 'asc' | 'desc' … … 55 57 s: params?.search, 56 58 status: params?.status, 59 credited: params?.credited === undefined ? undefined : params.credited ? '1' : '0', 57 60 orderBy: params?.orderBy, 58 61 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', 60 63 }).then(response => transactionListResponse.parse(response) as ApiListResponse<Transaction>) 61 64 }, … … 65 68 */ 66 69 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', 68 71 }).then(response => transactionResponse.parse(response) as Transaction), 69 72 -
siren-affiliates/trunk/frontend-source/src/service/components/ActivityTimeline.tsx
r3775642 r3788740 207 207 ? (SOURCE_TYPE_PLURAL[sourceType] ?? `all ${sourceType}s`) 208 208 : (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' 209 212 const [notes, setNotes] = useState<Note[]>([]) 210 213 const [total, setTotal] = useState(0) … … 394 397 <> 395 398 <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> 397 400 </> 398 401 ) : ( 399 402 <> 400 403 <CardTitle>Activity for {subjectLabel}</CardTitle> 401 <CardDescription> Events that touched this record</CardDescription>404 <CardDescription>{description}</CardDescription> 402 405 </> 403 406 )} -
siren-affiliates/trunk/frontend-source/src/service/components/collaborator-dashboard/ReferralUrlGenerator.tsx
r3754739 r3788740 8 8 import type { ReferralConfig } from '@core/types/collaborator-dashboard' 9 9 import { buildReferralUrl } from '@service/utils/referral-url' 10 import { writeClipboard } from '@service/lib/clipboard' 10 11 11 12 interface ReferralUrlGeneratorProps { … … 66 67 67 68 try { 68 await navigator.clipboard.writeText(referralUrl)69 await writeClipboard(referralUrl) 69 70 setCopied(true) 70 71 toast.success(translate('Copied to clipboard!')) -
siren-affiliates/trunk/frontend-source/src/service/components/data-table/BulkActionBar.tsx
r3775642 r3788740 1 1 import * as React from 'react' 2 import { TourSampleBadge } from '@service/components/tour-sample' 2 3 import { X } from 'lucide-react' 3 4 import { useTranslation } from '@service/i18n' … … 32 33 onClear: () => void 33 34 isProcessing?: boolean 35 /** The product tour's example selection: shown, marked as an example, and not usable. */ 36 sample?: boolean 34 37 } 35 38 … … 39 42 onClear, 40 43 isProcessing = false, 44 sample = false, 41 45 }: BulkActionBarProps) { 42 46 const { translate } = useTranslation() … … 88 92 } 89 93 90 const busy = isProcessing || isExecuting 94 const busy = isProcessing || isExecuting || sample 91 95 92 96 return ( 93 97 <> 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 > 95 102 <div className="flex items-center gap-2"> 103 {sample && <TourSampleBadge />} 96 104 <span className="text-sm font-medium"> 97 105 {selectedCount} {translate('selected')} … … 122 130 ))} 123 131 </div> 124 {busy && (132 {busy && !sample && ( 125 133 <span className="ml-auto text-sm text-muted-foreground"> 126 134 {translate('Processing...')} -
siren-affiliates/trunk/frontend-source/src/service/components/data-table/DataTable.tsx
r3775642 r3788740 14 14 } from '@service/components/ui' 15 15 import { cn } from '@service/components/lib/utils' 16 import { useTourSample } from '@service/contexts/tour-sample' 17 import { TourSampleBadge, TourSampleBanner } from '@service/components/tour-sample' 16 18 17 19 export interface ColumnDef<T> { … … 36 38 data: T[] 37 39 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 39 42 40 43 // Selection … … 53 56 getRowLabel?: (item: T) => string 54 57 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 55 66 // Hover actions 56 67 getRowHref?: (item: T) => string … … 73 84 export function DataTable<T extends { id: number }>({ 74 85 columns, 75 data ,86 data: records, 76 87 isLoading = false, 77 88 emptyMessage = 'No items found.', … … 82 93 getRowLabel = defaultRowLabel, 83 94 getRowHref, 84 onEdit ,85 onDelete ,95 onEdit: editRecord, 96 onDelete: deleteRecord, 86 97 sortField, 87 98 sortOrder, 88 99 onSort, 89 100 renderExpanded, 101 sampleKey, 102 sample = false, 90 103 }: 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 91 111 const hasHoverActions = !!(onEdit || onDelete) 92 112 const selectableRows = isRowSelectable ? data.filter(isRowSelectable) : data … … 137 157 138 158 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" />} 140 167 <Table> 141 168 <TableHeader> … … 145 172 <Checkbox 146 173 checked={allSelected} 147 disabled={selectableRows.length === 0 }174 disabled={selectableRows.length === 0 || showsSample} 148 175 aria-label="Select all rows" 149 176 ref={(el) => { … … 224 251 onDelete={onDelete} 225 252 hasHoverActions={hasHoverActions} 253 isSample={showsSample} 226 254 /> 227 255 {expanded !== null && expanded !== undefined && ( … … 256 284 onDelete?: (item: T) => void 257 285 hasHoverActions?: boolean 286 /** An example record from the product tour: marked, shaded, and not interactive. */ 287 isSample?: boolean 258 288 } 259 289 … … 283 313 onDelete, 284 314 hasHoverActions, 315 isSample = false, 285 316 }: DataTableRowProps<T>) { 286 317 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 287 320 288 321 return ( 289 322 <TableRow 290 data-state={isSelected ? 'selected' : undefined}323 data-state={isSelected || sampleSelected ? 'selected' : undefined} 291 324 onMouseEnter={() => setIsHovered(true)} 292 325 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' } : {})} 294 329 > 295 330 {selectable && ( … … 297 332 {canSelect && ( 298 333 <Checkbox 299 checked={isSelected} 334 checked={isSelected || sampleSelected} 335 disabled={isSample} 300 336 aria-label={`Select ${rowLabel}`} 301 337 onCheckedChange={(checked) => onSelect(checked === true)} … … 306 342 {columns.map((column, index) => ( 307 343 <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 ? ( 309 350 <Link 310 351 to={getRowHref(item)} -
siren-affiliates/trunk/frontend-source/src/service/components/help/ProgramFlowDiagram.tsx
r3775642 r3788740 116 116 * Get commission display text based on incentive type and config 117 117 */ 118 function getCommissionText( 118 // eslint-disable-next-line react-refresh/only-export-components 119 export function getCommissionText( 119 120 incentiveType: string, 120 121 config?: ProgramFlowDiagramProps['commissionConfig'], -
siren-affiliates/trunk/frontend-source/src/service/components/help/help-content.ts
r3775642 r3788740 16 16 | 'what-is-fulfillment' 17 17 | 'what-is-distributor' 18 | 'what-is-metric' 18 19 | 'what-is-payout' 19 20 // Collaborator Dashboard … … 225 226 | 'lifetime-attribution' 226 227 // end of moved screen help (type) 228 // Siren Cloud usage 229 | 'engine-activity' 227 230 228 231 export interface HelpTooltipContent { … … 285 288 title: 'What is a Conversion?', 286 289 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.', 288 291 learnMoreTopic: 'what-is-conversion', 289 292 }, … … 299 302 title: 'What is a Transaction?', 300 303 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.', 302 305 learnMoreTopic: 'what-is-transaction', 303 306 }, … … 313 316 title: 'What is a Distributor?', 314 317 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.", 316 326 learnMoreTopic: 'what-is-distributor', 317 327 }, … … 1588 1598 title: 'Reply-to address', 1589 1599 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.', 1591 1601 }, 1592 1602 'notification-editor': { 1593 1603 title: 'Writing an email', 1594 1604 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.', 1596 1606 }, 1597 1607 'notification-new': { … … 1686 1696 // end of moved screen help 1687 1697 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 1688 1704 'siren-cloud-connector': { 1689 1705 title: 'What the connector does', 1690 1706 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.', 1692 1708 }, 1693 1709 -
siren-affiliates/trunk/frontend-source/src/service/components/sidebar/GroupNav.tsx
r3775642 r3788740 148 148 149 149 return ( 150 <li key={group.key} >150 <li key={group.key} data-tour={`nav-${group.key}`}> 151 151 <button 152 152 type="button" … … 184 184 to={page.to} 185 185 aria-current={isActive ? 'page' : undefined} 186 data-tour-page={page.to} 187 data-tour={`nav-link-${page.to.replace(/^\//, '').replace(/\//g, '-')}`} 186 188 className={cn( 187 189 'flex items-center gap-2 rounded-md pl-9 pr-2.5 transition-colors hover:bg-accent hover:text-accent-foreground', … … 327 329 <ul className="space-y-px px-2"> 328 330 {groups.map((group) => ( 329 <li key={group.key} >331 <li key={group.key} data-tour={`nav-${group.key}`}> 330 332 <GroupFlyout group={group} isCurrent={group.key === currentKey} navBadges={navBadges} /> 331 333 </li> -
siren-affiliates/trunk/frontend-source/src/service/components/sidebar/Sidebar.tsx
r3775642 r3788740 17 17 PanelLeftClose, 18 18 PanelLeftOpen, 19 Compass, 19 20 } from 'lucide-react' 20 21 import { useNavigate } from 'react-router-dom' … … 34 35 TooltipTrigger, 35 36 } from '@service/components/ui' 37 import { BrandLink } from './BrandLink' 36 38 import { SIDEBAR_ID } from './constants' 37 39 import { visibleGroups } from './groups' … … 107 109 export interface SidebarProps { 108 110 currentOrgName?: string 109 currentOrg Slug?: string111 currentOrgId?: number 110 112 userEmail?: string 111 113 memberships?: OrgMembership[] … … 138 140 * Show Products and Coupon codes under Track. They 139 141 * 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. 141 144 */ 142 145 showCouponCodes?: boolean 143 showProduct Owners?: boolean144 /** 145 * Show Customers under Track. The platform turns it on where an active146 * 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. 147 150 */ 148 151 showCustomers?: boolean … … 199 202 */ 200 203 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 201 208 } 202 209 … … 264 271 isCollapsed, 265 272 currentOrgName, 266 currentOrg Slug,273 currentOrgId, 267 274 userEmail, 268 275 memberships, … … 282 289 isDark, 283 290 setIsDark, 291 forceOpen = false, 292 onStartTour, 284 293 }: { 285 294 isCollapsed: boolean 286 295 currentOrgName?: string 287 currentOrg Slug?: string296 currentOrgId?: number 288 297 userEmail?: string 289 298 memberships?: OrgMembership[] … … 303 312 isDark: boolean 304 313 setIsDark: (value: boolean) => void 314 forceOpen?: boolean 315 onStartTour?: () => void 305 316 }) { 306 317 const navigate = useNavigate() 318 const [open, setOpen] = useState(false) 307 319 const { translate } = useTranslation() 308 320 // Developer holds API keys, Webhooks and Logs. It shows while the person may open one of them. 309 321 const showDeveloper = canManageApiKeys || canManageWebhooks || canUseSiteTools 310 const otherOrgs = (memberships ?? []).filter((m) => m.org Slug !== currentOrgSlug)322 const otherOrgs = (memberships ?? []).filter((m) => m.orgId !== currentOrgId) 311 323 const accountName = currentOrgName ?? translate('Account') 312 324 // Properties and Currencies are settings, so they sit here with the rest. … … 316 328 317 329 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}> 319 333 <RailTooltip label={accountName} show={isCollapsed}> 320 334 <DropdownMenuTrigger asChild> … … 323 337 size="sm" 324 338 aria-label={isCollapsed ? accountName : undefined} 339 data-tour="account-menu" 325 340 className={cn('h-9 w-full', isCollapsed ? 'justify-center px-0' : 'justify-between px-2.5')} 326 341 > … … 374 389 {choosePlanUrl ? ( 375 390 <> 376 <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" >391 <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" data-tour-account="/settings/integrations"> 377 392 <Plug className="h-4 w-4" /> 378 393 <span className="ml-2">{translate('Integrations')}</span> 379 394 </DropdownMenuItem> 380 395 {showProperties && ( 381 <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" >396 <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" data-tour-account="/properties"> 382 397 <Globe className="h-4 w-4" /> 383 398 <span className="ml-2">{translate('Properties')}</span> … … 385 400 )} 386 401 {canManageBilling && ( 387 <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" >402 <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" data-tour-account="/settings/billing"> 388 403 <CreditCard className="h-4 w-4" /> 389 404 <span className="ml-2">{translate('Billing & Usage')}</span> … … 399 414 ) : ( 400 415 <> 401 <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" >416 <DropdownMenuItem onClick={() => navigate('/settings/integrations')} className="cursor-pointer" data-tour-account="/settings/integrations"> 402 417 <Plug className="h-4 w-4" /> 403 418 <span className="ml-2">{translate('Integrations')}</span> 404 419 </DropdownMenuItem> 405 420 {showPropertiesLink && ( 406 <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" >421 <DropdownMenuItem onClick={() => navigate('/properties')} className="cursor-pointer" data-tour-account="/properties"> 407 422 <Globe className="h-4 w-4" /> 408 423 <span className="ml-2">{translate('Properties')}</span> … … 410 425 )} 411 426 {showCurrenciesLink && ( 412 <DropdownMenuItem onClick={() => navigate('/currencies')} className="cursor-pointer" >427 <DropdownMenuItem onClick={() => navigate('/currencies')} className="cursor-pointer" data-tour-account="/currencies"> 413 428 <Coins className="h-4 w-4" /> 414 429 <span className="ml-2">{translate('Currencies')}</span> … … 416 431 )} 417 432 {canManageOrganization && ( 418 <DropdownMenuItem onClick={() => navigate('/settings/organization')} className="cursor-pointer" >433 <DropdownMenuItem onClick={() => navigate('/settings/organization')} className="cursor-pointer" data-tour-account="/settings/organization"> 419 434 <Building2 className="h-4 w-4" /> 420 435 <span className="ml-2">{translate('Organization')}</span> … … 422 437 )} 423 438 {canManageMembers && ( 424 <DropdownMenuItem onClick={() => navigate('/settings/members')} className="cursor-pointer" >439 <DropdownMenuItem onClick={() => navigate('/settings/members')} className="cursor-pointer" data-tour-account="/settings/members"> 425 440 <UsersRound className="h-4 w-4" /> 426 441 <span className="ml-2">{translate('Members')}</span> … … 428 443 )} 429 444 {canManageNotifications && ( 430 <DropdownMenuItem onClick={() => navigate('/settings/notifications')} className="cursor-pointer" >445 <DropdownMenuItem onClick={() => navigate('/settings/notifications')} className="cursor-pointer" data-tour-account="/settings/notifications"> 431 446 <Bell className="h-4 w-4" /> 432 447 <span className="ml-2">{translate('Notifications')}</span> … … 434 449 )} 435 450 {canManageBilling && ( 436 <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" >451 <DropdownMenuItem onClick={() => navigate('/settings/billing')} className="cursor-pointer" data-tour-account="/settings/billing"> 437 452 <CreditCard className="h-4 w-4" /> 438 453 <span className="ml-2">{translate('Billing & Usage')}</span> … … 440 455 )} 441 456 {showDeveloper && ( 442 <DropdownMenuItem onClick={() => navigate('/settings/developer')} className="cursor-pointer" >457 <DropdownMenuItem onClick={() => navigate('/settings/developer')} className="cursor-pointer" data-tour-account="/settings/developer"> 443 458 <Code className="h-4 w-4" /> 444 459 <span className="ml-2">{translate('Developer')}</span> 445 460 </DropdownMenuItem> 446 461 )} 447 <DropdownMenuItem onClick={() => navigate('/import')} className="cursor-pointer" >462 <DropdownMenuItem onClick={() => navigate('/import')} className="cursor-pointer" data-tour-account="/import"> 448 463 <ArrowLeftRight className="h-4 w-4" /> 449 464 <span className="ml-2">{translate('Import & Export')}</span> 450 465 </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> 451 475 </> 452 476 )} … … 468 492 export function Sidebar({ 469 493 currentOrgName, 470 currentOrg Slug,494 currentOrgId, 471 495 userEmail, 472 496 memberships, … … 485 509 showProperties, 486 510 showCouponCodes, 487 showProduct Owners,511 showProducts, 488 512 showCustomers, 489 513 showApplicationForms, … … 494 518 mobileOpen = false, 495 519 onMobileClose, 520 accountMenuOpen = false, 521 onStartTour, 496 522 }: SidebarProps) { 497 523 const [collapsedPreference, setIsCollapsed] = useCollapsedPreference() … … 535 561 showProperties: showProperties === true, 536 562 showCouponCodes: showCouponCodes === true, 537 showProduct Owners: showProductOwners === true,563 showProducts: showProducts === true, 538 564 showCustomers: showCustomers === true, 539 565 showApplicationForms: showApplicationForms === true, … … 592 618 ) : ( 593 619 <> 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> 600 629 <Button 601 630 variant="ghost" … … 681 710 isCollapsed={isCollapsed} 682 711 currentOrgName={currentOrgName} 683 currentOrg Slug={currentOrgSlug}712 currentOrgId={currentOrgId} 684 713 userEmail={userEmail} 685 714 memberships={memberships} … … 699 728 isDark={isDark} 700 729 setIsDark={setIsDark} 730 forceOpen={accountMenuOpen} 731 onStartTour={onStartTour} 701 732 /> 702 733 )} -
siren-affiliates/trunk/frontend-source/src/service/components/sidebar/groups.ts
r3775642 r3788740 10 10 showProperties: boolean 11 11 showCouponCodes: boolean 12 showProduct Owners: boolean12 showProducts: boolean 13 13 showCustomers: boolean 14 14 showApplicationForms: boolean … … 68 68 icon: Target, 69 69 pages: [ 70 { to: '/engagements', label: 'Engagements', shows: () => !!supports.engagements }, 71 { to: '/metrics', label: 'Metrics', shows: () => !!supports.distributors }, 70 72 { to: '/conversions', label: 'Conversions', shows: () => !!supports.conversions }, 71 { to: '/engagements', label: 'Engagements', shows: () => !!supports.engagements },72 73 { to: '/transactions', label: 'Transactions', shows: () => !!supports.transactions }, 73 74 { to: '/customers', label: 'Customers', shows: (flags) => flags.showCustomers }, 74 { to: '/products', label: 'Products', shows: (flags) => flags.showProperties && flags.showProduct Owners },75 { to: '/products', label: 'Products', shows: (flags) => flags.showProperties && flags.showProducts }, 75 76 { to: '/coupon-codes', label: 'Coupon codes', shows: (flags) => flags.showProperties && flags.showCouponCodes }, 76 77 ], -
siren-affiliates/trunk/frontend-source/src/service/components/sidebar/index.ts
r3754739 r3788740 1 export { BrandLink } from './BrandLink' 1 2 export { Sidebar } from './Sidebar' 2 3 export { SIDEBAR_ID } from './constants' -
siren-affiliates/trunk/frontend-source/src/service/components/ui/index.ts
r3590633 r3788740 16 16 export * from './tabs' 17 17 export * from './tooltip' 18 export * from './code-block' 19 export * from './copy-button' -
siren-affiliates/trunk/frontend-source/src/service/components/ui/sonner.tsx
r3590633 r3788740 7 7 <Sonner 8 8 className="toaster group" 9 closeButton 9 10 toastOptions={{ 10 11 classNames: { -
siren-affiliates/trunk/frontend-source/src/service/contexts/platform.tsx
r3775642 r3788740 55 55 export type PlanCheck = (capability: string) => boolean 56 56 57 /** What the CSV import hands the platform's invitation message editor. */ 58 export 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 57 68 /** 58 69 * Screens a platform adds to the shared ones. The shared screens render a … … 65 76 /** Links in the header of the Programs list. */ 66 77 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> 67 90 /** 68 91 * 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 11 11 import { useTranslation } from '@service/i18n' 12 12 import type { CollaboratorCoupon } from '@core/types/collaborator-dashboard' 13 import { writeClipboard } from '@service/lib/clipboard' 13 14 14 15 // ============================================================================= … … 140 141 const copyToClipboard = async () => { 141 142 try { 142 await navigator.clipboard.writeText(coupon.code)143 await writeClipboard(coupon.code) 143 144 setCopied(true) 144 145 toast.success(translate('Coupon code copied!')) -
siren-affiliates/trunk/frontend-source/src/service/screens/collaborator-dashboard/CollaboratorDashboardScreen.tsx
r3775642 r3788740 282 282 283 283 {/* Referral URL Generator */} 284 {referralConfig && referralConfig.trackingId && (284 {referralConfig && referralConfig.trackingId && !referralConfig.inPersonOnly && ( 285 285 <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> 286 291 )} 287 292 -
siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorViewScreen.tsx
r3775642 r3788740 49 49 import { CollaboratorProductsCard } from '@service/screens/products/CollaboratorProductsCard' 50 50 import { LifetimeAttributionCard } from './LifetimeAttributionCard' 51 import { CustomFieldsCard } from './CustomFieldsCard' 52 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 51 53 52 54 const statusColors: Record<CollaboratorStatus, string> = { … … 56 58 rejected: 'status-badge status-red', 57 59 deleted: 'status-badge status-red', 60 invited: 'status-badge status-blue', 58 61 } 59 62 … … 83 86 rejected: translate('Rejected'), 84 87 deleted: translate('Trashed'), 88 invited: translate('Invited'), 85 89 } 86 90 const { id } = useParams<{ id: string }>() … … 169 173 // Conversions have no collaboratorId column. The API resolves this filter through 170 174 // 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' }) 173 177 if (supports.customerOwnership) { 174 178 fetchOwnedByCollaborator(collaboratorId) … … 309 313 </Button> 310 314 )} 311 <div className="flex-1 min-w-[min(100%,14rem)]" >315 <div className="flex-1 min-w-[min(100%,14rem)]" data-tour="collaborator-heading"> 312 316 <div className="flex flex-wrap items-center gap-3"> 313 <h1 className="text-2xl font-semibold">{c urrent.fullName}</h1>317 <h1 className="text-2xl font-semibold">{collaboratorDisplayName(current)}</h1> 314 318 <span className={statusColors[current.status]}> 315 319 {statusLabels[current.status]} … … 319 323 </div> 320 324 <div className="flex items-center gap-2"> 321 <ActivityDrawer sourceType="collaborator" sourceId={current.id} contextLabel={c urrent.fullName} />325 <ActivityDrawer sourceType="collaborator" sourceId={current.id} contextLabel={collaboratorDisplayName(current)} /> 322 326 <Button asChild> 323 327 <Link to={`/collaborators/${current.id}/edit`}> … … 334 338 collaboratorId={current.id} 335 339 status={current.status} 336 name={c urrent.fullName || current.email}340 name={collaboratorDisplayName(current)} 337 341 onChanged={() => fetchOne(current.id)} 338 342 /> 339 343 )} 340 344 {!isWordPress && <CollaboratorPropertiesCard collaboratorId={current.id} />} 341 <CollaboratorCouponsCard collaboratorId={current.id} name={c urrent.fullName || current.email} />345 <CollaboratorCouponsCard collaboratorId={current.id} name={collaboratorDisplayName(current)} /> 342 346 {!isWordPress && <CollaboratorProductsCard collaboratorId={current.id} />} 343 <Card >347 <Card data-tour="collaborator-profile"> 344 348 <CardHeader> 345 349 <CardTitle>{translate('Profile')}</CardTitle> … … 374 378 </Card> 375 379 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"> 377 386 <CardHeader> 378 387 <CardTitle>{translate('Rewards Statistics')}</CardTitle> … … 514 523 )} 515 524 516 <Card >525 <Card data-tour="collaborator-enrolled-programs"> 517 526 <CardHeader> 518 527 <CardTitle>{programsTitle}</CardTitle> -
siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorsEditScreen.tsx
r3775642 r3788740 56 56 rejected: translate('Rejected'), 57 57 deleted: translate('Trashed'), 58 invited: translate('Invited'), 58 59 } 59 60 61 // Only an invitation makes someone invited, and only accepting it moves 62 // them on, so neither is offered here. 60 63 const editableStatuses = (Object.entries(statusLabels) as [CollaboratorStatus, string][]) 61 .filter(([value]) => value !== 'deleted' )64 .filter(([value]) => value !== 'deleted' && value !== 'invited') 62 65 63 66 const { id } = useParams<{ id: string }>() … … 500 503 } 501 504 > 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 )} 517 526 </FormField> 518 527 </CardContent> -
siren-affiliates/trunk/frontend-source/src/service/screens/collaborators/CollaboratorsListScreen.tsx
r3775642 r3788740 2 2 import { useNavigate, useSearchParams } from 'react-router-dom' 3 3 import { Link } from '@service/components/Link' 4 import { Plus, Search } from 'lucide-react'4 import { Plus, Search, Upload } from 'lucide-react' 5 5 import { useCollaboratorsStore } from '@service/stores/collaborators' 6 6 import { useProgramsStore } from '@service/stores/programs' … … 29 29 import { ActivityDrawer } from '@service/components/ActivityDrawer' 30 30 import { useTranslation } from '@service/i18n' 31 import { usePlatform } from '@service/contexts/platform' 31 32 import { DeleteConfirmDialog } from '@service/components/DeleteConfirmDialog' 32 33 import { collaboratorsApi } from '@service/api/collaborators' 33 34 import { useListRequest } from '@service/hooks/useListRequest' 35 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 36 import { InvitedStatus } from './InvitedStatus' 34 37 35 38 // The columns GET /collaborators can order by. Keep in step with GetCollaborators::SORTABLE_COLUMNS. … … 43 46 rejected: 'status-badge status-red', 44 47 deleted: 'status-badge status-red', 48 invited: 'status-badge status-blue', 45 49 } 46 50 47 51 export function CollaboratorsListScreen() { 48 52 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 49 59 50 60 const statusLabels: Record<CollaboratorStatus, string> = { … … 54 64 rejected: translate('Rejected'), 55 65 deleted: translate('Trashed'), 66 invited: translate('Invited'), 56 67 } 57 68 const navigate = useNavigate() … … 81 92 bulkRestore, 82 93 bulkSendSignupEmail, 94 resendInvitation, 95 cancelInvitation, 83 96 update, 84 97 } = useCollaboratorsStore() … … 101 114 const [distributorIdFilter, setDistributorIdFilter] = useState<string>(initialDistributorId) 102 115 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) 103 118 const [localPerPage, setLocalPerPage] = useState(10) 104 119 const [sortField, setSortField] = useState<SortField>('fullName') … … 164 179 orderBy: sortField, 165 180 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, 167 183 programId: programIdFilter ? parseInt(programIdFilter) : undefined, 168 184 distributorId: distributorIdFilter ? parseInt(distributorIdFilter) : undefined, … … 228 244 const selectedNames = items 229 245 .filter((collaborator) => selectedIds.has(collaborator.id)) 230 .map((collaborator) => collaborator .fullName || collaborator.email)246 .map((collaborator) => collaboratorDisplayName(collaborator)) 231 247 232 248 const handleEdit = (collaborator: Collaborator) => { … … 319 335 header: translate('Name'), 320 336 sortable: true, 321 cell: (collaborator) => collaborator .fullName,337 cell: (collaborator) => collaboratorDisplayName(collaborator), 322 338 }, 323 339 { … … 366 382 header: translate('Programs'), 367 383 cell: (collaborator) => ( 368 <div className="flex flex-wrap gap-1" >384 <div className="flex flex-wrap gap-1" data-tour="collaborator-programs"> 369 385 {collaborator.programs?.map((program) => ( 370 386 <Link … … 448 464 sortable: true, 449 465 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 </> 455 482 ), 456 483 }, … … 593 620 <div className="flex flex-wrap items-center gap-2"> 594 621 <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"> 596 632 <Link to="/collaborators/new"> 597 633 <Plus className="h-4 w-4" /> … … 610 646 )} 611 647 612 <div className="flex gap-2 mb-4" >648 <div className="flex gap-2 mb-4" data-tour="collaborators-filters"> 613 649 <div className="relative flex-1 max-w-sm"> 614 650 <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /> … … 631 667 <SelectItem value="inactive">{translate('Inactive')}</SelectItem> 632 668 <SelectItem value="rejected">{translate('Rejected')}</SelectItem> 669 <SelectItem value="invited">{translate('Invited')}</SelectItem> 633 670 <SelectItem value="deleted">{translate('Trashed')}</SelectItem> 634 671 </SelectContent> … … 650 687 )} 651 688 689 {CollaboratorsListNotice && !isDeletedView && <CollaboratorsListNotice />} 690 652 691 <BulkActionBar 653 692 selectedCount={selectedIds.size} … … 660 699 columns={columns} 661 700 data={items} 701 sampleKey="collaborators" 662 702 isLoading={isLoading} 663 703 emptyMessage={translate('No collaborators found.')} … … 728 768 onClose={() => setDeleteTarget(null)} 729 769 noun={translate('collaborator')} 730 name={deleteTarget ?.fullName || deleteTarget?.email ||''}770 name={deleteTarget ? collaboratorDisplayName(deleteTarget) : ''} 731 771 permanent={isDeletedView} 732 772 title={isDeletedView ? translate('Delete Collaborator Permanently') : translate('Delete Collaborator')} … … 734 774 loadBlockers={deleteTarget ? () => collaboratorsApi.deletionBlockers(deleteTarget.id) : undefined} 735 775 /> 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> 736 807 737 808 {/* Program Selection Dialog */} -
siren-affiliates/trunk/frontend-source/src/service/screens/conversions/ConversionDetailScreen.tsx
r3775642 r3788740 223 223 </div> 224 224 <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"> 226 226 {statusLabels[current.status]} 227 227 </span> 228 228 {current.status === 'pending' && ( 229 229 <> 230 <Button size="sm" onClick={() => decide('approve')} disabled={deciding !== null} >230 <Button size="sm" onClick={() => decide('approve')} disabled={deciding !== null} data-tour="conversion-approve"> 231 231 <Check className="h-4 w-4 mr-1" /> 232 232 {deciding === 'approve' ? translate('Approving...') : translate('Approve')} … … 278 278 279 279 {/* Collaborator */} 280 <Card >280 <Card data-tour="conversion-collaborator"> 281 281 <CardHeader> 282 282 <CardTitle>{translate('Collaborator')}</CardTitle> … … 322 322 323 323 {/* Transaction Details */} 324 <Card >324 <Card data-tour="conversion-transaction"> 325 325 <CardHeader> 326 326 <CardTitle>{translate('Transaction')}</CardTitle> … … 373 373 374 374 {/* Engagement Details */} 375 <Card >375 <Card data-tour="conversion-attribution"> 376 376 <CardHeader> 377 377 <CardTitle>{translate('Engagement')}</CardTitle> … … 414 414 415 415 {/* Obligations Table */} 416 <Card >416 <Card data-tour="conversion-rewards"> 417 417 <CardHeader> 418 418 <CardTitle>{translate('Obligations')}</CardTitle> -
siren-affiliates/trunk/frontend-source/src/service/screens/conversions/ConversionsListScreen.tsx
r3775642 r3788740 23 23 type SortOrder = 'asc' | 'desc' 24 24 25 const normalizeStatusFilter = (status: string) => status === 'approved' ? 'complete' : status 26 25 27 const statusColors: Record<ConversionStatus, string> = { 26 28 pending: 'status-badge status-yellow', … … 43 45 pending: translate('Pending'), 44 46 approved: translate('Approved'), 45 complete: translate(' Complete'),47 complete: translate('Approved'), 46 48 rejected: translate('Rejected'), 47 49 deleted: translate('Trashed'), … … 68 70 69 71 // Initialize from URL params 70 const initialStatus = searchParams.get('status') || 'all'72 const initialStatus = normalizeStatusFilter(searchParams.get('status') || 'all') 71 73 const initialType = searchParams.get('type') || 'all' 72 74 const initialTransactionId = searchParams.get('transactionId') || '' … … 88 90 89 91 useEffect(() => { 90 const status = searchParams.get('status')92 const status = normalizeStatusFilter(searchParams.get('status') || '') 91 93 const type = searchParams.get('type') 92 94 const transactionId = searchParams.get('transactionId') … … 409 411 )} 410 412 411 <div className="flex gap-2 mb-4 flex-wrap" >413 <div className="flex gap-2 mb-4 flex-wrap" data-tour="conversions-filters"> 412 414 <Select value={statusFilter} onValueChange={handleStatusChange}> 413 415 <SelectTrigger aria-label={translate('Filter by status')} className="w-[140px]"> … … 417 419 <SelectItem value="all">{translate('All Statuses')}</SelectItem> 418 420 <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> 421 422 <SelectItem value="rejected">{translate('Rejected')}</SelectItem> 422 423 <SelectItem value="deleted">{translate('Trashed')}</SelectItem> … … 464 465 columns={columns} 465 466 data={items} 467 sampleKey="conversions" 466 468 isLoading={isLoading} 467 469 emptyMessage={translate('No conversions found.')} -
siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CollaboratorCouponsCard.tsx
r3775642 r3788740 45 45 const load = useCallback(async () => { 46 46 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) 48 59 setFailed(false) 49 60 } catch { … … 88 99 89 100 return ( 90 <Card data-testid="collaborator-coupon-codes" >101 <Card data-testid="collaborator-coupon-codes" data-tour="collaborator-coupons"> 91 102 <CardHeader className="flex flex-row flex-wrap items-start justify-between gap-2"> 92 103 <div> -
siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CollaboratorPicker.tsx
r3775642 r3788740 3 3 import { useTranslation } from '@service/i18n' 4 4 import { collaboratorsApi } from '@service/api/collaborators' 5 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 5 6 6 7 /** How many collaborators a search shows at once. */ … … 41 42 const timer = window.setTimeout(() => { 42 43 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'] }) 44 46 .then((list) => { 45 47 if (cancelled) return … … 47 49 (list.items ?? []).map((collaborator) => ({ 48 50 id: Number(collaborator.id), 49 name: collaborator .fullName || collaborator.nickname || collaborator.email || `#${collaborator.id}`,51 name: collaboratorDisplayName(collaborator), 50 52 email: collaborator.email ?? null, 51 53 status: collaborator.status ?? null, -
siren-affiliates/trunk/frontend-source/src/service/screens/coupons/CouponCodesScreen.tsx
r3775642 r3788740 24 24 import { ActivityDrawer } from '@service/components/ActivityDrawer' 25 25 import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview' 26 import { RecordsEmptyState } from '@service/components/RecordsEmptyState' 26 27 import { previewLabel } from '@service/hooks/useIntegrationPreview' 27 28 import { Link } from '@service/components/Link' … … 85 86 * The list can be narrowed by address: `?property=5&integration=wc`. On a 86 87 * 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. 87 93 */ 88 94 export function CouponCodesScreen({ … … 403 409 const total = data?.total ?? rows.length 404 410 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 406 414 const orphaned = capability !== undefined && !capability.available && capability.hasRecords 407 415 const filteredStore = propertyFilter !== undefined ? stores.find((store) => store.id === propertyFilter) : undefined … … 409 417 filteredStore !== undefined && filteredStore.integrations.length > 0 && filteredStore.integrations.every((integration) => integration.slug === 'shopify') 410 418 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 }429 419 430 420 return ( … … 576 566 columns={columns} 577 567 data={rows} 568 sampleKey="couponCodes" 578 569 isLoading={loading} 579 570 selectable={!credit} … … 581 572 onSelectionChange={setSelected} 582 573 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 ) 588 583 } 589 584 getRowLabel={(coupon) => coupon.code} -
siren-affiliates/trunk/frontend-source/src/service/screens/currencies/CustomCurrenciesManager.tsx
r3775642 r3788740 295 295 fields: ['id', 'name', 'status'], 296 296 units: code, 297 status: 'active', 297 298 perPage: 100, 298 299 }) 299 setAffectedPrograms(response.items .filter((p: Program) => p.status !== 'inactive'))300 setAffectedPrograms(response.items) 300 301 } catch { 301 302 setAffectedPrograms([]) … … 523 524 columns={columns} 524 525 data={rows} 526 sampleKey="currencies" 525 527 emptyMessage={translate('No custom currencies. Create one to get started.')} 526 528 getRowLabel={(currency) => currency.name} -
siren-affiliates/trunk/frontend-source/src/service/screens/customers/CustomersBanner.tsx
r3775642 r3788740 23 23 ) 24 24 } 25 26 /**27 * What the Customers screen says when no integration provides customers and28 * 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 19 19 import { ActivityDrawer } from '@service/components/ActivityDrawer' 20 20 import { Link } from '@service/components/Link' 21 import { RecordsEmptyState } from '@service/components/RecordsEmptyState' 21 22 import { useRecordCapability } from '@service/hooks/useRecordCapability' 22 23 import { useTranslation } from '@service/i18n' 23 24 import { customersApi, customerTitle, type Customer, type CustomerList, type SuggestionPair } from '@service/api/customers' 24 25 import { identityDescription, integrationName, knownIntegrations, useCollaboratorNames, usePropertyNames } from './helpers' 25 import { CustomersBanner , NoCustomersProvided} from './CustomersBanner'26 import { CustomersBanner } from './CustomersBanner' 26 27 import { MergeCustomersDialog } from './MergeCustomersDialog' 27 28 import { MergeWithDialog } from './MergeWithDialog' … … 43 44 * Rows can be selected for a bulk Merge, and each has "Merge with…". The 44 45 * 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. 46 52 */ 47 53 export function CustomersListScreen({ canConfirmCrossStore = false }: { canConfirmCrossStore?: boolean } = {}) { … … 70 76 const nameOf = useCollaboratorNames((data?.customers ?? []).flatMap((customer) => customer.collaboratorIds)) 71 77 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 73 81 74 82 useEffect(() => { 75 if (hidden) return76 83 let cancelled = false 77 84 setLoading(true) … … 107 114 cancelled = true 108 115 } 109 }, [ hidden,appliedSearch, property, integration, linked, matchesOnly, page, reload, translate])116 }, [appliedSearch, property, integration, linked, matchesOnly, page, reload, translate]) 110 117 111 118 const setParam = useCallback( … … 218 225 ) 219 226 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 229 227 const filterItems = [ 230 228 { … … 381 379 columns={columns} 382 380 data={data?.customers ?? []} 381 sampleKey="customers" 383 382 isLoading={loading} 384 383 selectable … … 386 385 onSelectionChange={setSelected} 387 386 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 ) 391 394 } 392 395 getRowLabel={(customer) => customerTitle(customer)} -
siren-affiliates/trunk/frontend-source/src/service/screens/customers/LinkCollaboratorDialog.tsx
r3775642 r3788740 5 5 import { useTranslation } from '@service/i18n' 6 6 import type { Collaborator } from '@core/types/collaborator' 7 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 7 8 8 9 /** … … 34 35 35 36 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' }) 37 39 .then((response) => { 38 40 if (cancelled) return … … 53 55 54 56 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) }, 56 58 { id: 'email', header: translate('Email'), cell: (collaborator) => collaborator.email }, 57 59 ] -
siren-affiliates/trunk/frontend-source/src/service/screens/customers/helpers.ts
r3775642 r3788740 4 4 import { usePlatform } from '@service/contexts/platform' 5 5 import type { CustomerIdentity } from '@service/api/customers' 6 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 6 7 7 8 const INTEGRATIONS: Record<string, string> = { … … 87 88 collaboratorsApi 88 89 .get(id) 89 .then((collaborator) => [id, collaborator .fullName || collaborator.email || `#${id}`] as const)90 .then((collaborator) => [id, collaboratorDisplayName(collaborator)] as const) 90 91 .catch(() => [id, `#${id}`] as const) 91 92 ) -
siren-affiliates/trunk/frontend-source/src/service/screens/engagements/EngagementsListScreen.tsx
r3754739 r3788740 271 271 columns={columns} 272 272 data={items} 273 sampleKey="engagements" 273 274 isLoading={isLoading} 274 275 emptyMessage={translate('No engagements found.')} -
siren-affiliates/trunk/frontend-source/src/service/screens/fulfillments/FulfillmentDetailScreen.tsx
r3775642 r3788740 6 6 import { useFulfillmentsStore } from '@service/stores/fulfillments' 7 7 import { useAutofulfillersStore } from '@service/stores/autofulfillers' 8 import type { AutofulfillResult, Payout, PayoutStatus } from '@core/types/fulfillment'8 import type { AutofulfillResult, Fulfillment, Payout, PayoutStatus } from '@core/types/fulfillment' 9 9 import type { FulfillmentMethod } from '@core/types/autofulfiller' 10 10 import { DataTable, BulkActionBar } from '@service/components/data-table' … … 14 14 import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter' 15 15 import { isWaitingOnCollaborator, waitingMethodName } from '@service/utils/payout-waiting' 16 import { automaticMethodFor, payoutMaySendSoon } from '@service/utils/payout-refresh' 17 import { useBoundedRefresh } from '@service/hooks/useBoundedRefresh' 16 18 import { 17 19 Button, … … 26 28 import { ActivityDrawer } from '@service/components/ActivityDrawer' 27 29 import { AutofulfillResultNotice } from './AutofulfillResultNotice' 30 import { useTourSample } from '@service/contexts/tour-sample' 31 import { TourSampleBanner } from '@service/components/tour-sample' 28 32 29 33 const statusColors: Record<PayoutStatus, string> = { … … 49 53 50 54 const { 51 current ,52 isLoading ,55 current: storedCurrent, 56 isLoading: storeLoading, 53 57 isSubmitting, 54 error ,58 error: storeError, 55 59 fetchOne, 60 refreshCurrent, 56 61 clearCurrent, 57 62 fulfillPayouts, … … 67 72 } = useAutofulfillersStore() 68 73 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 69 82 const [selectedPayoutIds, setSelectedPayoutIds] = useState<Set<number>>(new Set()) 70 83 const [showFulfillConfirm, setShowFulfillConfirm] = useState(false) … … 85 98 86 99 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)) { 88 102 fetchOne(parseInt(id)) 89 103 } … … 92 106 clearCurrent() 93 107 } 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)) 95 121 96 122 const formatDate = (dateString: string | undefined) => { … … 252 278 )} 253 279 {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"> 255 281 <p className="text-sm text-destructive break-words"> 256 282 {payout.failureReason || translate('No reason was recorded for this failure.')} … … 301 327 variant="outline" 302 328 size="sm" 303 disabled={isSubmitting }329 disabled={isSubmitting || isSample} 304 330 onClick={() => retryPayout(current.id, payout.id)} 305 331 > … … 311 337 } 312 338 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) 327 341 328 342 // The payouts the primary action would send: unpaid ones, and failed ones, … … 356 370 return ( 357 371 <div> 372 {isSample && <TourSampleBanner className="mb-4 rounded-lg border" />} 358 373 <div className="flex flex-wrap items-center gap-x-4 gap-y-2 mb-6"> 359 374 {!isWordPress && ( … … 366 381 <Button 367 382 onClick={() => setShowAutofulfillConfirm(true)} 368 disabled={isSubmitting} 383 disabled={isSubmitting || isSample} 384 data-tour="fulfillment-send-automatically" 369 385 > 370 386 <Send className="h-4 w-4 mr-2" /> … … 375 391 variant="outline" 376 392 onClick={() => setShowFulfillConfirm(true)} 377 disabled={isSubmitting} 393 disabled={isSubmitting || isSample} 394 data-tour="fulfill-payouts" 378 395 > 379 396 {isSubmitting … … 386 403 {payouts.length} item{payouts.length !== 1 ? 's' : ''} 387 404 </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 )} 393 412 </div> 394 413 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"> 396 415 <div className="rounded-lg border bg-muted/30 px-4 py-3"> 397 416 <div className="text-xs text-muted-foreground">Total Value</div> … … 444 463 columns={columns} 445 464 data={payouts} 465 sample={isSample} 446 466 isLoading={false} 447 467 emptyMessage={translate('No payouts in this fulfillment.')} -
siren-affiliates/trunk/frontend-source/src/service/screens/fulfillments/FulfillmentsListScreen.tsx
r3775642 r3788740 20 20 import { AutofulfillersModal } from './AutofulfillersModal' 21 21 import { AutofulfillResultNotice } from './AutofulfillResultNotice' 22 import { FulfillmentsAutoRefresh } from './FulfillmentsAutoRefresh' 22 23 23 24 type SortField = 'dateCreated' … … 207 208 <ActivityDrawer sourceType="fulfillment" contextLabel="all fulfillments" /> 208 209 {import.meta.env.FEATURE_AUTOFULFILLERS ? ( 209 <Button variant="outline" onClick={() => setShowAutofulfillers(true)} >210 <Button variant="outline" onClick={() => setShowAutofulfillers(true)} data-tour="autofulfillers"> 210 211 <Settings2 className="h-4 w-4 mr-2" /> 211 212 {translate('Manage Autofulfillers')} 212 213 </Button> 213 214 ) : ( 214 <Button variant="ghost" disabled className="opacity-60" >215 <Button variant="ghost" disabled className="opacity-60" data-tour="autofulfillers"> 215 216 <Sparkles className="h-4 w-4 mr-2" /> 216 217 {translate('Manage Autofulfillers')} … … 226 227 <AutofulfillersModal open={showAutofulfillers} onOpenChange={setShowAutofulfillers} /> 227 228 )} 229 {import.meta.env.FEATURE_AUTOFULFILLERS && <FulfillmentsAutoRefresh />} 228 230 229 231 {error && ( … … 233 235 )} 234 236 235 <div className="flex gap-2 mb-4 flex-wrap" >237 <div className="flex gap-2 mb-4 flex-wrap" data-tour="fulfillments-filters"> 236 238 <Select value={statusFilter} onValueChange={(value) => setStatusFilter(value as StatusFilter)}> 237 239 <SelectTrigger className="w-[190px]" aria-label={translate('Filter fulfillments')}> … … 274 276 columns={columns} 275 277 data={items} 278 sampleKey="fulfillments" 276 279 isLoading={isLoading} 277 280 selectable={import.meta.env.FEATURE_AUTOFULFILLERS} -
siren-affiliates/trunk/frontend-source/src/service/screens/main-menu/LogsTab.tsx
r3775642 r3788740 14 14 SelectTrigger, 15 15 SelectValue, 16 CodeBlock, 16 17 } from '@service/components/ui' 17 18 import { useTranslation } from '@service/i18n' … … 24 25 type LogResponse, 25 26 } from '@service/api/utilities' 27 import { toast } from 'sonner' 28 import { writeClipboard } from '@service/lib/clipboard' 26 29 27 30 const PAGE_SIZE = 100 … … 124 127 const payload = formatEntryForClipboard(entry) 125 128 try { 126 await navigator.clipboard.writeText(payload)129 await writeClipboard(payload) 127 130 } 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 141 133 } 142 134 setCopiedId(entry.id) … … 312 304 </button> 313 305 {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 /> 317 313 )} 318 314 </li> -
siren-affiliates/trunk/frontend-source/src/service/screens/main-menu/UtilitiesTab.tsx
r3775642 r3788740 32 32 type StatusSection, 33 33 } from '@service/api/utilities' 34 import { writeClipboard } from '@service/lib/clipboard' 34 35 35 36 /** … … 81 82 if (!status || !info) return 82 83 try { 83 await navigator.clipboard.writeText(formatDump(status, info))84 await writeClipboard(formatDump(status, info)) 84 85 setCopied(true) 85 86 setTimeout(() => setCopied(false), 2000) -
siren-affiliates/trunk/frontend-source/src/service/screens/obligations/ObligationsListScreen.tsx
r3775642 r3788740 24 24 import { TestSaleBadge } from '@service/components/TestSaleBadge' 25 25 import { useTranslation } from '@service/i18n' 26 import { useTourSample } from '@service/contexts/tour-sample' 26 27 import { linkedRecordName } from '@service/utils/linked-record' 27 28 import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter' … … 249 250 }) 250 251 } 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 251 257 252 258 const columns: ColumnDef<Obligation>[] = [ … … 447 453 )} 448 454 449 <div className="flex gap-2 mb-4 flex-wrap" >455 <div className="flex gap-2 mb-4 flex-wrap" data-tour="obligations-filters"> 450 456 <Select value={statusFilter} onValueChange={handleStatusChange}> 451 457 <SelectTrigger aria-label={translate('Filter by status')} className="w-[240px]"> … … 470 476 /> 471 477 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 472 488 <DataTable 473 489 columns={columns} 474 490 data={items} 491 sampleKey="obligations" 475 492 isLoading={isLoading} 476 493 emptyMessage={translate('No obligations found.')} -
siren-affiliates/trunk/frontend-source/src/service/screens/products/CollaboratorProductsCard.tsx
r3775642 r3788740 188 188 ] 189 189 190 const unavailableIds = new Set(excluded) 191 items.forEach((product) => { 192 if (product.owners.length >= MAX_PRODUCT_OWNERS) unavailableIds.add(product.id) 193 }) 194 190 195 return ( 191 196 <BulkPickerModal … … 194 199 title={translate('Link to a product')} 195 200 description={translate('This collaborator earns from the products you pick, on every store that sells them.')} 196 excludedIds={ excluded}201 excludedIds={unavailableIds} 197 202 items={items} 198 203 isLoading={loading} -
siren-affiliates/trunk/frontend-source/src/service/screens/products/ProductViewScreen.tsx
r3775642 r3788740 27 27 import { HelpTooltip } from '@service/components/help' 28 28 import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview' 29 import { PlanUpgradeNotice } from '@service/components/plan-upgrade-notice' 29 30 import { useTranslation } from '@service/i18n' 30 31 import { collaboratorsApi } from '@service/api/collaborators' … … 44 45 import { usePropertyNames } from './usePropertyNames' 45 46 import { formatDate } from '@service/utils/format-date' 47 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 46 48 47 49 /** Rows on one page of the owner picker. */ … … 62 64 * product with one the merchant finds, and "Split off" turns one listing 63 65 * 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. 64 69 */ 65 70 export function ProductViewScreen() { … … 81 86 const [unlinking, setUnlinking] = useState<ProductOwnerRef | null>(null) 82 87 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') 84 91 const properties = usePropertyNames() 85 92 … … 311 318 <HelpTooltip topic="product-owners" side="right" /> 312 319 </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} 317 326 </div> 318 327 </CardHeader> 319 328 <CardContent> 320 {product.owners.length === 0 ? ( 329 {!canOwn ? ( 330 <PlanUpgradeNotice feature={translate('product owners')} plan="essentials" /> 331 ) : product.owners.length === 0 ? ( 321 332 <p className="text-sm text-muted-foreground">{translate('No owners')}</p> 322 333 ) : ( … … 471 482 setLoading(true) 472 483 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' }) 474 486 const candidates = found.items.map((collaborator) => ({ 475 487 id: collaborator.id, 476 name: collaborator .fullName || collaborator.nickname || collaborator.email,488 name: collaboratorDisplayName(collaborator), 477 489 email: collaborator.email, 478 490 status: collaborator.status, -
siren-affiliates/trunk/frontend-source/src/service/screens/products/ProductsListScreen.tsx
r3775642 r3788740 2 2 import { useNavigate, useSearchParams } from 'react-router-dom' 3 3 import { toast } from 'sonner' 4 import { Plus, Search } from 'lucide-react'4 import { Plus, Search, Upload } from 'lucide-react' 5 5 import { 6 6 Button, … … 18 18 import { ActivityDrawer } from '@service/components/ActivityDrawer' 19 19 import { IntegrationPreviewNotice } from '@service/components/IntegrationPreview' 20 import { RecordsEmptyState } from '@service/components/RecordsEmptyState' 21 import { usePlatform } from '@service/contexts/platform' 20 22 import { useTranslation } from '@service/i18n' 23 import { Link } from '@service/components/Link' 21 24 import { MAX_MERGE_PRODUCTS, productsApi, liveListings, type Product, type ProductList } from '@service/api/products' 22 25 import { integrationName, knownIntegrations } from './integrationLabels' … … 25 28 import { MergeProductsDialog } from './MergeProductsDialog' 26 29 import { usePropertyNames } from './usePropertyNames' 30 31 /** The plan capability for choosing who owns a product. */ 32 const PRODUCT_OWNERSHIP = 'product-ownership' 27 33 28 34 /** Rows on one page of the list. */ … … 50 56 * merchant keeps. `propertyId` holds an embedded list to one store. 51 57 * 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. 54 63 */ 55 64 export function ProductsListScreen({ propertyId, embedded = false }: { propertyId?: number; embedded?: boolean } = {}) { 56 65 const { translate } = useTranslation() 57 66 const navigate = useNavigate() 67 const { planAllows } = usePlatform() 68 const showsOwners = planAllows(PRODUCT_OWNERSHIP) 58 69 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 59 72 60 73 const property = propertyId ?? wholeNumber(searchParams.get('property')) … … 109 122 110 123 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]) 111 144 112 145 /** Changes the query string. A new filter or search goes back to page one. */ … … 132 165 header: translate('Product'), 133 166 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' : ''}`}> 135 168 <span className="truncate font-medium">{product.name}</span> 169 {product.parentId != null && <span className="text-xs text-muted-foreground">{translate('Variation')}</span>} 136 170 {product.openSuggestions > 0 && ( 137 171 <span className="status-badge status-yellow shrink-0"> … … 159 193 }, 160 194 }, 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 : []), 171 209 ], 172 [properties, translate]210 [properties, showsOwners, translate] 173 211 ) 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 174 217 175 218 const filterItems = [ … … 214 257 <div className="flex flex-wrap items-center gap-2"> 215 258 {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 )} 216 267 <Button onClick={() => setAdding(true)}> 217 268 <Plus className="h-4 w-4" aria-hidden="true" /> … … 316 367 <DataTable 317 368 columns={columns} 318 data={data?.products ?? []} 369 data={displayedProducts} 370 sampleKey="products" 319 371 selectable 320 372 selectedIds={selected} … … 322 374 isLoading={loading} 323 375 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 ) 327 385 } 328 386 getRowLabel={(product) => product.name} -
siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramViewScreen.tsx
r3775642 r3788740 48 48 import { linkedRecordName } from '@service/utils/linked-record' 49 49 import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter' 50 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 50 51 51 52 const incentiveTypeLabels: Record<string, string> = { … … 117 118 const programId = parseInt(id) 118 119 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' }) 120 121 // 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' }) 122 123 fetchCollaborators({ programId, perPage: 10, status: 'active,pending,inactive,rejected' }) 123 124 } … … 219 220 cell: (collaborator) => ( 220 221 <Link to={`/collaborators/${collaborator.id}/view`} className="text-primary hover:underline"> 221 {collaborator .fullName}222 {collaboratorDisplayName(collaborator)} 222 223 </Link> 223 224 ), … … 271 272 </Button> 272 273 )} 273 <div className="flex-1 min-w-[min(100%,14rem)]" >274 <div className="flex-1 min-w-[min(100%,14rem)]" data-tour="program-heading"> 274 275 <div className="flex flex-wrap items-center gap-3"> 275 276 <h1 className="text-2xl font-semibold">{current.name}</h1> … … 280 281 <div className="flex items-center gap-2"> 281 282 <ActivityDrawer sourceType="program" sourceId={current.id} contextLabel={current.name} /> 282 <Button asChild >283 <Button asChild data-tour="program-edit"> 283 284 <Link to={`/programs/${current.id}`}> 284 285 <Pencil className="h-4 w-4 mr-2" /> … … 317 318 /> 318 319 319 <Card >320 <Card data-tour="program-rewards"> 320 321 <CardHeader> 321 322 <CardTitle>{translate('Configuration')}</CardTitle> … … 404 405 </Card> 405 406 406 <Card >407 <Card data-tour="program-stats"> 407 408 <CardHeader> 408 409 <CardTitle>{translate('Statistics')}</CardTitle> … … 512 513 {/* Collaborators Table */} 513 514 <div className="mt-6"> 514 <Card >515 <Card data-tour="program-collaborators"> 515 516 <CardHeader className="flex flex-row items-center justify-between"> 516 517 <div> -
siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramsEditScreen.tsx
r3775642 r3788740 79 79 import { useCategoryFilterSupport } from '@service/hooks/useCategoryFilterSupport' 80 80 import { CategoryFilterNotice } from '@service/components/CategoryFilterNotice' 81 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 81 82 82 83 // The backend may return registry values as plain strings OR as {id, name} objects. … … 1351 1352 <form onSubmit={handleSubmit} className="flex-1 min-w-0 max-w-2xl space-y-6 min-h-0 pb-[50vh]"> 1352 1353 {/* Basic Information */} 1353 <div className="space-y-4" >1354 <div className="space-y-4" data-tour="program-form-basics"> 1354 1355 <FormField 1355 1356 label={translate('Name')} … … 1583 1584 currentColumns={ 1584 1585 [ 1585 { id: 'fullName', header: translate('Name'), cell: (c) => c .fullName},1586 { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) }, 1586 1587 { id: 'email', header: translate('Email'), cell: (c) => c.email }, 1587 1588 { id: 'status', header: translate('Status'), cell: (c) => c.status }, … … 1593 1594 pendingAdditionColumns={ 1594 1595 [ 1595 { id: 'fullName', header: translate('Name'), cell: (c) => c .fullName},1596 { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) }, 1596 1597 { id: 'email', header: translate('Email'), cell: (c) => c.email }, 1597 1598 { id: 'status', header: translate('Status'), cell: (c) => c.status }, … … 1606 1607 pickerColumns={ 1607 1608 [ 1608 { id: 'fullName', header: translate('Name'), cell: (c) => c .fullName},1609 { id: 'fullName', header: translate('Name'), cell: (c) => collaboratorDisplayName(c) }, 1609 1610 { id: 'email', header: translate('Email'), cell: (c) => c.email }, 1610 1611 { id: 'status', header: translate('Status'), cell: (c) => c.status }, … … 1688 1689 <Card 1689 1690 id="engagement-tracking" 1691 data-tour="program-form-engagements" 1690 1692 className={cn( 1691 1693 'transition-all duration-300', … … 1773 1775 <Card 1774 1776 id="attribution-model" 1777 data-tour="program-form-attribution" 1775 1778 className={cn( 1776 1779 'transition-all duration-300', … … 1878 1881 <Card 1879 1882 id="incentive-structure" 1883 data-tour="program-form-rewards" 1880 1884 className={cn( 1881 1885 'transition-all duration-300', … … 2085 2089 /> 2086 2090 2087 <div className="flex gap-2" >2091 <div className="flex gap-2" data-tour="program-form-save"> 2088 2092 <Button 2089 2093 type="submit" -
siren-affiliates/trunk/frontend-source/src/service/screens/programs/ProgramsListScreen.tsx
r3775642 r3788740 21 21 import { ActivityDrawer } from '@service/components/ActivityDrawer' 22 22 import { useTranslation } from '@service/i18n' 23 import { useTourSample } from '@service/contexts/tour-sample' 23 24 import { DeleteConfirmDialog } from '@service/components/DeleteConfirmDialog' 24 25 import { programsApi } from '@service/api/programs' … … 571 572 const showColdStart = 572 573 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]) 573 598 574 599 return ( … … 582 607 <ActivityDrawer sourceType="program" contextLabel="all programs" /> 583 608 {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 ? ( 590 611 <Button variant="outline" onClick={() => setShowCurrencies(true)}> 591 612 <Coins className="h-4 w-4 mr-2" /> … … 601 622 </Button> 602 623 )} 603 <Button onClick={() => setShowSplash(true)} >624 <Button onClick={() => setShowSplash(true)} data-tour="add-program"> 604 625 <Plus className="h-4 w-4" /> 605 626 {translate('Add Program')} … … 616 637 /> 617 638 618 {show ColdStart ? (639 {showsColdStart ? ( 619 640 <div className="animate-in fade-in duration-300"> 620 641 <div className="mb-1.5 flex items-center gap-3"> … … 634 655 onBrowse={() => navigate('/recipes/browse')} 635 656 /> 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 )} 636 665 </div> 637 666 ) : ( … … 645 674 )} 646 675 647 <div className="flex gap-2 mb-4 flex-wrap" >676 <div className="flex gap-2 mb-4 flex-wrap" data-tour="programs-filters"> 648 677 <div className="relative flex-1 max-w-sm"> 649 678 <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /> … … 709 738 columns={columns} 710 739 data={items} 740 sampleKey="programs" 711 741 isLoading={isLoading} 712 742 emptyMessage={translate('No programs found.')} -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/CreateProgramChooser.tsx
r3754739 r3788740 26 26 const { translate } = useTranslation() 27 27 const { status, recipes, load } = useRecipeCatalogStore() 28 const { isWordPress } = usePlatform() 28 const { isWordPress, capabilities } = usePlatform() 29 const canBrowseRecipes = capabilities.recipeExport === true 29 30 30 31 // Pull the catalog so we can show how many recipes are on offer; cheap + cached. 31 32 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]) 34 35 35 36 const noun = kind === 'distributors' ? translate('distributor') : translate('program') … … 44 45 onClick={onBlank} 45 46 /> 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 )} 57 60 <ChooserCard 58 61 icon={Bot} -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/ImportRecipeScreen.tsx
r3754739 r3788740 15 15 import { useTranslation } from '@service/i18n' 16 16 import { UploadView } from './UploadView' 17 import { CsvImport, type LoadedFile } from '../csv-import' 17 18 import { SectionCard } from './SectionCard' 18 19 … … 22 23 * Entry points: 23 24 * 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. 27 32 * 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. 28 36 * 29 37 * On approve, the screen dispatches the apply task and navigates to … … 32 40 * users navigate away without losing the running import. 33 41 */ 34 export function ImportRecipeScreen({ payload: payloadProp }: { payload?: string | null }) { 42 export 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 }) { 35 50 const { translate } = useTranslation() 36 51 const navigate = useNavigate() 37 52 const search = typeof window !== 'undefined' ? new URLSearchParams(window.location.search) : null 38 53 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' 40 55 const autoApplied = useRef(false) 56 const [csvFile, setCsvFile] = useState<LoadedFile | null>(null) 41 57 42 58 const { … … 104 120 </div> 105 121 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} />} 107 125 108 126 {step === 'previewing' && ( -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeBrowserScreen.tsx
r3754739 r3788740 36 36 * on the left, grouped recipe cards on the right. Clicking a card opens the 37 37 * 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. 38 43 */ 39 export function RecipeBrowserScreen() { 44 export 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 } = {}) { 40 53 const { translate } = useTranslation() 41 54 const navigate = useNavigate() … … 59 72 } = store 60 73 61 const { tier: installTier, isWordPress } = usePlatform() 74 const { tier: installTier, isWordPress, capabilities } = usePlatform() 75 const canBrowseRecipes = capabilities.recipeExport === true 62 76 63 77 useEffect(() => { 64 if ( status === 'idle') {78 if (canBrowseRecipes && status === 'idle') { 65 79 void load({ isWordPress }) 66 80 } 67 }, [ status, load, isWordPress])81 }, [canBrowseRecipes, status, load, isWordPress]) 68 82 69 83 // The store defaults to the top tier (SaaS includes everything); once the … … 116 130 } 117 131 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 118 147 if (status === 'loading' || status === 'idle') { 119 148 return ( … … 140 169 } 141 170 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 142 187 return ( 143 188 <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 )} 157 204 158 205 <div className="relative max-w-md"> … … 224 271 {/* RIGHT main */} 225 272 <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 ? ( 227 281 <Card className="flex flex-col items-center gap-3 p-12 text-center"> 228 282 <p className="text-sm font-medium">{translate('No recipes match your filters')}</p> … … 247 301 key={recipe.id} 248 302 recipe={recipe} 249 onClick={() => navigate(`/recipes/browse/${recipe.slug}`)}303 onClick={() => (onPick ? onPick(recipe) : navigate(`/recipes/browse/${recipe.slug}`))} 250 304 /> 251 305 ))} -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeConstructs.tsx
r3775642 r3788740 4 4 import { cn } from '@service/components/lib/utils' 5 5 import { useTranslation } from '@service/i18n' 6 import { ProgramFlowDiagram } from '@service/components/help/ProgramFlowDiagram'6 import { getCommissionText, ProgramFlowDiagram } from '@service/components/help/ProgramFlowDiagram' 7 7 import { ProgramGroupFlowDiagram } from '@service/components/help/ProgramGroupFlowDiagram' 8 8 import { parseRecipeConstructs, type RecipeConstruct } from './catalog-taxonomy' … … 17 17 18 18 /** 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 */ 24 function 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 /** 19 40 * The expanded body of a construct drawer: the same Siren flow diagram the 20 41 * program / group view screens render for programs and groups, or a spec … … 24 45 function ConstructDetail({ construct }: { construct: RecipeConstruct }) { 25 46 const { translate } = useTranslation() 26 const { formatMoney, definitions } = useMoneyFormatter()47 const formatAmount = useConstructAmount(construct) 27 48 28 49 if (construct.kind === 'Program') { 29 const { units, unitsLabel } = construct.program30 // A currency the recipe brings with it is not in the org's registry until31 // the recipe is applied. Recipes create those as whole-unit currencies, so32 // 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 37 50 return ( 38 51 <ProgramFlowDiagram … … 77 90 * description, and the construct's flow diagram or spec summary. 78 91 */ 79 function ConstructDrawer({ construct }: { construct: RecipeConstruct}) {92 function ConstructDrawer({ construct, badge, savedSettings = false }: { construct: RecipeConstruct; badge?: string; savedSettings?: boolean }) { 80 93 const { translate } = useTranslation() 81 94 const [open, setOpen] = useState(false) 95 const formatAmount = useConstructAmount(construct) 82 96 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 || '' 84 104 85 105 return ( … … 100 120 {translate(construct.kind)} 101 121 </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 )} 102 127 </span> 103 128 {summary && !open && ( … … 122 147 )} 123 148 124 { construct.description && (149 {!savedSettings && construct.description && ( 125 150 <p className="text-sm leading-relaxed text-muted-foreground">{translate(construct.description)}</p> 126 151 )} … … 137 162 * drawer per program, group, and distributor the recipe creates. When `values` 138 163 * (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. 139 166 */ 140 167 export function RecipeConstructs({ 141 168 recipe, 142 169 values, 170 badges, 171 savedSettings = false, 143 172 }: { 144 173 recipe: CatalogRecipe 145 174 values?: Record<string, string | number> 175 badges?: Record<string, string> 176 savedSettings?: boolean 146 177 }) { 147 178 const constructs = parseRecipeConstructs(recipe, values) … … 151 182 <div className="space-y-2.5"> 152 183 {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 /> 154 190 ))} 155 191 </div> -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/RecipeDetailScreen.tsx
r3775642 r3788740 353 353 function useRecipeBySlug(slug: string | null | undefined) { 354 354 const { status, recipes, load, error } = useRecipeCatalogStore() 355 const { isWordPress } = usePlatform() 355 const { isWordPress, capabilities } = usePlatform() 356 const canBrowseRecipes = capabilities.recipeExport === true 356 357 const retry = () => void load({ isWordPress }) 357 358 358 359 useEffect(() => { 359 if ( slug && status === 'idle') {360 if (canBrowseRecipes && slug && status === 'idle') { 360 361 void load({ isWordPress }) 361 362 } 362 }, [ slug, status, load, isWordPress])363 }, [canBrowseRecipes, slug, status, load, isWordPress]) 363 364 364 365 const recipe = useMemo( … … 367 368 ) 368 369 369 return { recipe, status, error, retry }370 return { recipe, status, error, retry, canBrowseRecipes } 370 371 } 371 372 … … 666 667 const { translate } = useTranslation() 667 668 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 } 669 685 670 686 if (status === 'loading' || status === 'idle') { -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/UploadView.tsx
r3590633 r3788740 11 11 } from '@service/components/ui' 12 12 import { useTranslation } from '@service/i18n' 13 import { csvProblemMessage, parseCsv, type LoadedFile } from '../csv-import' 13 14 14 15 function readFileAsText(file: File): Promise<string> { … … 26 27 * forwards the decoded recipe to the store. 27 28 * 28 * CSV support is planned as the first migration integration — the component is29 * 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. 30 31 */ 31 32 export function UploadView({ 32 33 onRecipeLoaded, 34 onCsvLoaded, 33 35 }: { 34 36 onRecipeLoaded: (recipe: RecipeData) => void 37 /** A CSV file, read and parsed. Without it the view takes JSON only. */ 38 onCsvLoaded?: (file: LoadedFile) => void 35 39 }) { 36 40 const { translate } = useTranslation() … … 50 54 } 51 55 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 52 63 let recipe: RecipeData 53 64 try { 54 65 recipe = JSON.parse(text) as RecipeData 55 66 } 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 } 56 73 const detail = err instanceof Error ? err.message : translate('Unknown parse error.') 57 74 setParseError(translate(`That file is not valid JSON: ${detail}`)) … … 60 77 61 78 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 }) 62 88 } 63 89 … … 119 145 <div className="space-y-1"> 120 146 <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')} 125 148 </p> 126 149 </div> … … 128 151 ref={inputRef} 129 152 type="file" 130 accept= ".json,application/json"153 accept={onCsvLoaded ? '.json,application/json,.csv,text/csv,.tsv,.txt' : '.json,application/json'} 131 154 className="hidden" 132 155 onChange={handleChange} … … 155 178 </Button> 156 179 </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 )} 157 186 </CardContent> 158 187 </Card> -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/UseRecipeModal.tsx
r3775642 r3788740 455 455 } 456 456 457 function FieldInput({457 export function FieldInput({ 458 458 field, 459 459 value, -
siren-affiliates/trunk/frontend-source/src/service/screens/recipes/catalog-taxonomy.ts
r3775642 r3788740 23 23 import { incentiveConfigAsNumbers } from '@core/utils/money' 24 24 import { applyEnhancementPatch, type EnhancementKey } from '@service/recipes/enhancements' 25 import { rewriteDescribedValues } from '@service/recipes/describedValues' 25 26 26 27 /** … … 313 314 314 315 return entry[1]?.symbol?.trim() || units 316 } 317 318 /** Whether the recipe writes its own currency's symbol before the amount. */ 319 function 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') 315 323 } 316 324 … … 331 339 */ 332 340 unitsLabel?: string 341 /** Whether `unitsLabel` goes before the amount, as a currency symbol such as $ does. */ 342 unitsLabelLeads?: boolean 333 343 } 334 344 … … 374 384 units?: string 375 385 } 376 interface PayloadCurrency { code?: string; name?: string; symbol?: string }386 interface PayloadCurrency { code?: string; name?: string; symbol?: string; symbolPosition?: string } 377 387 interface PayloadGroup { name?: string; description?: string; sorter?: string; programs?: string[] } 378 388 interface PayloadDistributor { … … 455 465 units: p.units, 456 466 unitsLabel: recipeCurrencyLabel(p.units, recipeCurrencies), 467 unitsLabelLeads: recipeCurrencyLeads(p.units, recipeCurrencies), 457 468 }, 458 469 }) … … 532 543 } 533 544 cursor[keys[keys.length - 1]] = value 545 } 546 547 /** Read the value at a dot path inside a plain object, or undefined. */ 548 function 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. */ 558 const 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 */ 572 export 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 534 581 } 535 582 … … 584 631 continue 585 632 } 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) 588 638 589 639 return payload as unknown as RecipeData … … 617 667 const raw = baseValues[field.path] 618 668 if (raw === undefined || raw === '') continue 619 setAtPath(payload, field.path, resolveFieldValue( field, raw))669 setAtPath(payload, field.path, resolveFieldValue(withStoredMultiplier(field, payload), raw)) 620 670 } 621 671 … … 625 675 const raw = addonValues[field.path] 626 676 if (raw === undefined || raw === '') continue 627 setAtPath(payload, field.path, resolveFieldValue( field, raw))677 setAtPath(payload, field.path, resolveFieldValue(withStoredMultiplier(field, payload), raw)) 628 678 } 629 679 } 630 680 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 631 685 return payload as unknown as RecipeData 632 686 } -
siren-affiliates/trunk/frontend-source/src/service/screens/transactions/TransactionDetailScreen.tsx
r3775642 r3788740 1 import { useEffect, useMemo } from 'react'1 import { useEffect, useMemo, useState } from 'react' 2 2 import { useNavigate, useParams } from 'react-router-dom' 3 3 import { Link } from '@service/components/Link' … … 24 24 } from '@service/components/ui' 25 25 import { ActivityDrawer } from '@service/components/ActivityDrawer' 26 import { propertiesApi, type Property } from '@service/api/properties' 27 import { isOrderSource, orderAdminUrl } from './order-link' 26 28 27 29 const conversionStatusColors: Record<string, string> = { … … 48 50 const navigate = useNavigate() 49 51 const { isWordPress } = usePlatform() 52 const [properties, setProperties] = useState<Property[]>([]) 50 53 51 54 const { … … 71 74 const transactionId = parseInt(id) 72 75 fetchOne(transactionId) 73 fetchConversions({ transactionId, perPage: 20 })76 fetchConversions({ transactionId, perPage: 20, orderBy: 'dateCreated', order: 'desc' }) 74 77 } 75 78 … … 78 81 } 79 82 }, [id, fetchOne, clearCurrent, fetchConversions]) 83 84 useEffect(() => { 85 if (current?.sourcePropertyId) { 86 void propertiesApi.list().then(setProperties).catch(() => setProperties([])) 87 } 88 }, [current?.sourcePropertyId]) 80 89 81 90 const formatDate = (dateString: string) => { … … 163 172 return Array.from(totals.entries()) 164 173 } 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]] 166 175 const taxes = current.taxTotal === undefined ? detailTotals(['tax']) : [[current.currency || '', current.taxTotal] as [string, number]] 167 176 const shipping = current.shippingTotal === undefined ? detailTotals(['shipping']) : [[current.currency || '', current.shippingTotal] as [string, number]] 168 177 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]] 169 180 // Refund lines carry negative values, so the refunded amount is their 170 181 // total turned positive. … … 220 231 </div> 221 232 )} 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 ) : ( 223 243 <div> 224 244 <dt className="text-sm font-medium text-muted-foreground">{translate('Source ID')}</dt> 225 245 <dd className="text-sm mt-1 font-mono">{current.sourceId}</dd> 226 246 </div> 227 ) }247 ))} 228 248 </dl> 229 249 </CardContent> … … 280 300 </div> 281 301 ))} 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 ))} 282 308 {taxes.map(([currency, taxTotal]) => taxTotal > 0 && ( 283 309 <div key={'taxes-' + currency} className="flex justify-between text-sm"> -
siren-affiliates/trunk/frontend-source/src/service/screens/transactions/TransactionsListScreen.tsx
r3775642 r3788740 33 33 import { useTranslation } from '@service/i18n' 34 34 import { useMoneyFormatter } from '@service/hooks/useMoneyFormatter' 35 import { collaboratorDisplayName } from '@core/utils/collaboratorDisplayName' 36 import { propertiesApi, type Property } from '@service/api/properties' 37 import { isOrderSource, orderAdminUrl } from './order-link' 35 38 36 39 type SortField = 'dateCreated' | 'status' 37 40 type 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 */ 47 type CreditedFilter = 'all' | 'credited' | 'uncredited' 48 49 const CREDITED_PARAM: Record<Exclude<CreditedFilter, 'all'>, string> = { credited: '1', uncredited: '0' } 50 51 function creditedFromParam(value: string | null): CreditedFilter { 52 if (value === '1') return 'credited' 53 if (value === '0') return 'uncredited' 54 return 'all' 55 } 56 57 function creditedParam(filter: CreditedFilter): boolean | undefined { 58 return filter === 'all' ? undefined : filter === 'credited' 59 } 38 60 39 61 export function TransactionsListScreen() { … … 74 96 75 97 const [statusFilter, setStatusFilter] = useState<string>(initialStatus) 98 const [creditedFilter, setCreditedFilter] = useState<CreditedFilter>(creditedFromParam(searchParams.get('credited'))) 76 99 const [localPerPage, setLocalPerPage] = useState(10) 77 100 const [sortField, setSortField] = useState<SortField>('dateCreated') … … 80 103 const [showCreditDialog, setShowCreditDialog] = useState(false) 81 104 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]) 82 112 83 113 useEffect(() => { … … 92 122 }, [searchParams, statusFilter]) 93 123 124 useEffect(() => { 125 const credited = creditedFromParam(searchParams.get('credited')) 126 if (credited !== creditedFilter) { 127 setCreditedFilter(credited) 128 } 129 }, [searchParams, creditedFilter]) 130 94 131 // Clear selection when filters change 95 132 useEffect(() => { 96 133 setSelectedIds(new Set()) 97 }, [statusFilter ])134 }, [statusFilter, creditedFilter]) 98 135 99 136 // Fetch collaborators when credit dialog opens … … 111 148 order: sortOrder, 112 149 status: statusFilter !== 'all' ? statusFilter : undefined, 150 credited: creditedParam(creditedFilter), 113 151 }) 114 }, [fetchList, localPerPage, sortField, sortOrder, statusFilter ])152 }, [fetchList, localPerPage, sortField, sortOrder, statusFilter, creditedFilter]) 115 153 116 154 const buildParams = (overrides: Partial<{ … … 124 162 perPage: overrides.perPage ?? localPerPage, 125 163 status: (overrides.status ?? statusFilter) !== 'all' ? (overrides.status ?? statusFilter) : undefined, 164 credited: creditedParam(creditedFilter), 126 165 orderBy: overrides.orderBy ?? sortField, 127 166 order: overrides.order ?? sortOrder, … … 134 173 } else { 135 174 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') 136 186 } 137 187 setSearchParams(searchParams) … … 199 249 id: 'source', 200 250 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> 204 266 ) : ( 205 267 <span className="text-muted-foreground">—</span> 206 ), 268 ) 269 }, 207 270 }, 208 271 { … … 210 273 header: translate('Details'), 211 274 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)) 214 278 if (details.length === 0) { 215 279 return <span className="text-muted-foreground">—</span> … … 268 332 ] 269 333 334 const creditedLabels: Record<CreditedFilter, string> = { 335 all: translate('All Sales'), 336 credited: translate('Credited'), 337 uncredited: translate('Not Credited'), 338 } 339 270 340 const filterItems = [ 271 341 { … … 276 346 onRemove: () => handleStatusChange('all'), 277 347 }, 348 { 349 key: 'credited', 350 label: 'Credited', 351 value: creditedFilter, 352 displayValue: creditedLabels[creditedFilter], 353 onRemove: () => handleCreditedChange('all'), 354 }, 278 355 ] 279 356 280 357 const handleClearAllFilters = () => { 281 358 handleStatusChange('all') 359 handleCreditedChange('all') 282 360 } 283 361 … … 327 405 </SelectContent> 328 406 </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> 329 417 </div> 330 418 … … 339 427 columns={columns} 340 428 data={items} 429 sampleKey="transactions" 341 430 isLoading={isLoading} 342 431 emptyMessage={translate('No transactions found.')} … … 399 488 <DialogTitle>{translate('Credit Collaborator')}</DialogTitle> 400 489 <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. 402 492 </DialogDescription> 403 493 </DialogHeader> … … 412 502 {collaborators.map((collaborator) => ( 413 503 <SelectItem key={collaborator.id} value={collaborator.id.toString()}> 414 {collaborator .fullName || collaborator.email || `Collaborator #${collaborator.id}`}504 {collaboratorDisplayName(collaborator)} 415 505 </SelectItem> 416 506 ))} -
siren-affiliates/trunk/frontend-source/src/service/stores/collaborators.ts
r3754739 r3788740 44 44 bulkRestore: (ids: number[]) => Promise<void> 45 45 bulkSendSignupEmail: (ids: number[]) => Promise<void> 46 resendInvitation: (id: number) => Promise<void> 47 cancelInvitation: (id: number) => Promise<void> 46 48 clearCurrent: () => void 47 49 clearError: () => void … … 350 352 } 351 353 }, 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 }, 352 382 })) 353 383 -
siren-affiliates/trunk/frontend-source/src/service/stores/fulfillments.ts
r3775642 r3788740 27 27 fetchList: (params?: ListFulfillmentsParams) => Promise<void> 28 28 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> 29 36 update: (id: number, input: Partial<Fulfillment>) => Promise<Fulfillment> 30 37 bulkProcess: (ids: number[]) => Promise<void> … … 50 57 const listRequests = createRequestSequence() 51 58 59 /** The same for the open fulfillment, so a slow refresh cannot undo a newer load. */ 60 const detailRequests = createRequestSequence() 61 52 62 export const useFulfillmentsStore = create<FulfillmentsState>((set, get) => ({ 53 63 // Initial state … … 88 98 89 99 fetchOne: async (id) => { 100 const request = detailRequests.begin() 90 101 set({ isLoading: true, error: null, current: null }) 91 102 try { 92 103 const fulfillment = await fulfillmentsApi.get(id) 104 if (!detailRequests.isCurrent(request)) return 93 105 set({ current: fulfillment, isLoading: false }) 94 106 } catch (err) { 107 if (!detailRequests.isCurrent(request)) return 95 108 set({ 96 109 error: err instanceof Error ? err.message : 'Failed to fetch fulfillment', 97 110 isLoading: false, 98 111 }) 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. 99 144 } 100 145 }, -
siren-affiliates/trunk/frontend-source/src/service/stores/inbound.ts
r3775642 r3788740 33 33 status: InboundConnectionStatus, 34 34 ): 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 35 45 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 } } 38 48 } 39 49 -
siren-affiliates/trunk/frontend-source/src/service/stores/recipeCatalog.ts
r3775642 r3788740 173 173 resultCount: number 174 174 total: number 175 isEmptyCatalog: boolean 175 176 isNoResults: boolean 176 177 /** Curated "Popular starting points" for the cold-start empty state. */ … … 451 452 resultCount: filtered.length, 452 453 total: recipes.length, 454 isEmptyCatalog: recipes.length === 0, 453 455 isNoResults: recipes.length > 0 && filtered.length === 0, 454 456 popularFeatured, -
siren-affiliates/trunk/frontend-source/src/vite-env.d.ts
r3775642 r3788740 59 59 readonly env: ImportMetaEnv 60 60 } 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 */ 67 declare const __SIREN_SANDBOX__: boolean -
siren-affiliates/trunk/frontend-source/tsconfig.json
r3590633 r3788740 9 9 /* Bundler mode */ 10 10 "moduleResolution": "bundler", 11 "resolveJsonModule": true, 11 12 "allowImportingTsExtensions": true, 12 13 "isolatedModules": true, -
siren-affiliates/trunk/frontend-source/vite.config.ts
r3775642 r3788740 299 299 export default defineConfig(({ mode, command }) => { 300 300 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 302 306 const isDemo = mode === 'demo' 303 307 const isBuild = command === 'build' … … 312 316 // Modes: 'lite', 'essentials', 'wordpress-lite', 'wordpress-essentials' 313 317 const tier = process.env.SIREN_TIER 314 || mode.replace('wordpress-', '')318 || (isSandbox ? 'saas' : mode.replace('wordpress-', '')) 315 319 || 'essentials' // Default to essentials for dev mode (all features) 316 320 … … 389 393 define: { 390 394 ...featureDefines, 395 __SIREN_SANDBOX__: JSON.stringify(isSandbox), 391 396 }, 392 397 // Proxy API requests to PHP backend in SaaS dev mode … … 458 463 }, 459 464 } : isSaaS ? { 460 outDir: 'dist/saas',465 outDir: isSandbox ? 'dist/sandbox' : 'dist/saas', 461 466 // Vendor code changes far less often than app code, so splitting it into 462 467 // 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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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"}]]);/** 7 7 * @license lucide-react v0.469.0 - ISC 8 8 * 9 9 * This source code is licensed under the ISC license. 10 10 * 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"}]]);/** 12 12 * @license lucide-react v0.469.0 - ISC 13 13 * 14 14 * This source code is licensed under the ISC license. 15 15 * 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"}]]);/** 17 17 * @license lucide-react v0.469.0 - ISC 18 18 * 19 19 * This source code is licensed under the ISC license. 20 20 * 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"}]]);/** 22 22 * @license lucide-react v0.469.0 - ISC 23 23 * 24 24 * This source code is licensed under the ISC license. 25 25 * 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"}]]);/** 27 27 * @license lucide-react v0.469.0 - ISC 28 28 * 29 29 * This source code is licensed under the ISC license. 30 30 * 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"}]]);/** 32 32 * @license lucide-react v0.469.0 - ISC 33 33 * 34 34 * This source code is licensed under the ISC license. 35 35 * 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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * -
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-D NnGQGoM.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,{})]})}));1 import{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,{})]})}));1 import{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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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"}]]);/** 7 7 * @license lucide-react v0.469.0 - ISC 8 8 * 9 9 * This source code is licensed under the ISC license. 10 10 * 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,{})})]})})]})}));1 import{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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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"}]]);/** 7 7 * @license lucide-react v0.469.0 - ISC 8 8 * 9 9 * This source code is licensed under the ISC license. 10 10 * 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,{})})]})})]})}));1 import{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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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"}]]);/** 7 7 * @license lucide-react v0.469.0 - ISC 8 8 * 9 9 * This source code is licensed under the ISC license. 10 10 * 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"}]]);/** 12 12 * @license lucide-react v0.469.0 - ISC 13 13 * 14 14 * This source code is licensed under the ISC license. 15 15 * 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"}]]);/** 17 17 * @license lucide-react v0.469.0 - ISC 18 18 * 19 19 * This source code is licensed under the ISC license. 20 20 * 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"}]]);/** 22 22 * @license lucide-react v0.469.0 - ISC 23 23 * 24 24 * This source code is licensed under the ISC license. 25 25 * 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,{})})]})})]})}));1 import{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";/**1 import{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";/** 2 2 * @license lucide-react v0.469.0 - ISC 3 3 * 4 4 * This source code is licensed under the ISC license. 5 5 * 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"}]]);/** 7 7 * @license lucide-react v0.469.0 - ISC 8 8 * 9 9 * This source code is licensed under the ISC license. 10 10 * 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"}]]);/** 12 12 * @license lucide-react v0.469.0 - ISC 13 13 * 14 14 * This source code is licensed under the ISC license. 15 15 * 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,{})})]})})]})}));1 import{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.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)