adserver-dashboard 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. package/.ci/staging.yml +191 -0
  2. package/.dockerignore +117 -0
  3. package/.env +40 -0
  4. package/.env.staging +38 -0
  5. package/.gitlab-ci.yml +16 -0
  6. package/DEMO_STATUS.md +579 -0
  7. package/Dockerfile +61 -0
  8. package/Influence-MW-AdServer-12-02-2026/client/index.html +17 -0
  9. package/Influence-MW-AdServer-12-02-2026/client/public/favicon.png +0 -0
  10. package/Influence-MW-AdServer-12-02-2026/client/src/App.tsx +91 -0
  11. package/Influence-MW-AdServer-12-02-2026/client/src/components/advanced-map-drawer.tsx +1131 -0
  12. package/Influence-MW-AdServer-12-02-2026/client/src/components/ai-recommendation-panel.tsx +379 -0
  13. package/Influence-MW-AdServer-12-02-2026/client/src/components/app-sidebar.tsx +183 -0
  14. package/Influence-MW-AdServer-12-02-2026/client/src/components/auto-optimize-button.tsx +184 -0
  15. package/Influence-MW-AdServer-12-02-2026/client/src/components/availability-drawer.tsx +385 -0
  16. package/Influence-MW-AdServer-12-02-2026/client/src/components/brand-insights-panel.tsx +87 -0
  17. package/Influence-MW-AdServer-12-02-2026/client/src/components/create-agency-drawer.tsx +198 -0
  18. package/Influence-MW-AdServer-12-02-2026/client/src/components/create-brand-drawer.tsx +275 -0
  19. package/Influence-MW-AdServer-12-02-2026/client/src/components/creative-assignment.tsx +526 -0
  20. package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table-toolbar.tsx +148 -0
  21. package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table.tsx +158 -0
  22. package/Influence-MW-AdServer-12-02-2026/client/src/components/filter-drawer.tsx +356 -0
  23. package/Influence-MW-AdServer-12-02-2026/client/src/components/form-insights-panel.tsx +82 -0
  24. package/Influence-MW-AdServer-12-02-2026/client/src/components/geography-selector.tsx +699 -0
  25. package/Influence-MW-AdServer-12-02-2026/client/src/components/header-user-menu.tsx +178 -0
  26. package/Influence-MW-AdServer-12-02-2026/client/src/components/history-drawer.tsx +313 -0
  27. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-availability-section.tsx +176 -0
  28. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-format-drawer.tsx +173 -0
  29. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-selector.tsx +401 -0
  30. package/Influence-MW-AdServer-12-02-2026/client/src/components/manual-inventory-drawer.tsx +368 -0
  31. package/Influence-MW-AdServer-12-02-2026/client/src/components/mapbox-map.tsx +368 -0
  32. package/Influence-MW-AdServer-12-02-2026/client/src/components/market-insights-panel.tsx +202 -0
  33. package/Influence-MW-AdServer-12-02-2026/client/src/components/media-owner-drawer.tsx +217 -0
  34. package/Influence-MW-AdServer-12-02-2026/client/src/components/metric-card.tsx +58 -0
  35. package/Influence-MW-AdServer-12-02-2026/client/src/components/page-header.tsx +27 -0
  36. package/Influence-MW-AdServer-12-02-2026/client/src/components/player-status-indicator.tsx +137 -0
  37. package/Influence-MW-AdServer-12-02-2026/client/src/components/poi-targeting-drawer.tsx +298 -0
  38. package/Influence-MW-AdServer-12-02-2026/client/src/components/recommendation-score-badge.tsx +102 -0
  39. package/Influence-MW-AdServer-12-02-2026/client/src/components/recommended-inventories-panel.tsx +248 -0
  40. package/Influence-MW-AdServer-12-02-2026/client/src/components/searchable-combobox.tsx +134 -0
  41. package/Influence-MW-AdServer-12-02-2026/client/src/components/signal-visualizations.tsx +407 -0
  42. package/Influence-MW-AdServer-12-02-2026/client/src/components/status-badge.tsx +35 -0
  43. package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-provider.tsx +73 -0
  44. package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-toggle.tsx +37 -0
  45. package/Influence-MW-AdServer-12-02-2026/client/src/components/traffic-slider.tsx +75 -0
  46. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/accordion.tsx +56 -0
  47. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert-dialog.tsx +139 -0
  48. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert.tsx +59 -0
  49. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/aspect-ratio.tsx +5 -0
  50. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/avatar.tsx +51 -0
  51. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/badge.tsx +38 -0
  52. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/breadcrumb.tsx +115 -0
  53. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/button.tsx +62 -0
  54. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/calendar.tsx +68 -0
  55. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/card.tsx +85 -0
  56. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/carousel.tsx +260 -0
  57. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/chart.tsx +365 -0
  58. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/checkbox.tsx +28 -0
  59. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/collapsible.tsx +11 -0
  60. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/command.tsx +151 -0
  61. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/context-menu.tsx +198 -0
  62. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dialog.tsx +122 -0
  63. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/drawer.tsx +118 -0
  64. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dropdown-menu.tsx +198 -0
  65. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/form.tsx +178 -0
  66. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/hover-card.tsx +29 -0
  67. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input-otp.tsx +69 -0
  68. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input.tsx +23 -0
  69. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/label.tsx +24 -0
  70. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/menubar.tsx +256 -0
  71. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/navigation-menu.tsx +128 -0
  72. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/pagination.tsx +117 -0
  73. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/popover.tsx +29 -0
  74. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/progress.tsx +28 -0
  75. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/radio-group.tsx +42 -0
  76. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/resizable.tsx +45 -0
  77. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/scroll-area.tsx +46 -0
  78. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/select.tsx +160 -0
  79. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/separator.tsx +29 -0
  80. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sheet.tsx +140 -0
  81. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sidebar.tsx +727 -0
  82. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/skeleton.tsx +15 -0
  83. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/slider.tsx +26 -0
  84. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/switch.tsx +27 -0
  85. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/table.tsx +117 -0
  86. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tabs.tsx +53 -0
  87. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/textarea.tsx +22 -0
  88. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toast.tsx +127 -0
  89. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toaster.tsx +33 -0
  90. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle-group.tsx +61 -0
  91. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle.tsx +43 -0
  92. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tooltip.tsx +30 -0
  93. package/Influence-MW-AdServer-12-02-2026/client/src/components/vendor-stores-modal.tsx +336 -0
  94. package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-drawer.tsx +359 -0
  95. package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-selector.tsx +436 -0
  96. package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-mobile.tsx +19 -0
  97. package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-toast.ts +191 -0
  98. package/Influence-MW-AdServer-12-02-2026/client/src/index.css +244 -0
  99. package/Influence-MW-AdServer-12-02-2026/client/src/lib/queryClient.ts +57 -0
  100. package/Influence-MW-AdServer-12-02-2026/client/src/lib/utils.ts +39 -0
  101. package/Influence-MW-AdServer-12-02-2026/client/src/lib/venue-taxonomy.ts +532 -0
  102. package/Influence-MW-AdServer-12-02-2026/client/src/main.tsx +5 -0
  103. package/Influence-MW-AdServer-12-02-2026/client/src/pages/assign-creative.tsx +781 -0
  104. package/Influence-MW-AdServer-12-02-2026/client/src/pages/content-hub.tsx +995 -0
  105. package/Influence-MW-AdServer-12-02-2026/client/src/pages/custom-pois.tsx +431 -0
  106. package/Influence-MW-AdServer-12-02-2026/client/src/pages/dashboard.tsx +620 -0
  107. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-detail.tsx +1062 -0
  108. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-form.tsx +1570 -0
  109. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deals.tsx +716 -0
  110. package/Influence-MW-AdServer-12-02-2026/client/src/pages/edit-creative-assignment.tsx +1051 -0
  111. package/Influence-MW-AdServer-12-02-2026/client/src/pages/geotargeting.tsx +675 -0
  112. package/Influence-MW-AdServer-12-02-2026/client/src/pages/integrations.tsx +425 -0
  113. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-creatives.tsx +622 -0
  114. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-form.tsx +3132 -0
  115. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-items.tsx +530 -0
  116. package/Influence-MW-AdServer-12-02-2026/client/src/pages/not-found.tsx +21 -0
  117. package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play-upload.tsx +479 -0
  118. package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play.tsx +880 -0
  119. package/Influence-MW-AdServer-12-02-2026/client/src/pages/reports.tsx +235 -0
  120. package/Influence-MW-AdServer-12-02-2026/client/src/pages/settings.tsx +652 -0
  121. package/Influence-MW-AdServer-12-02-2026/client/src/pages/signal-form.tsx +1117 -0
  122. package/Influence-MW-AdServer-12-02-2026/client/src/pages/signals.tsx +366 -0
  123. package/Influence-MW-AdServer-12-02-2026/client/src/pages/tags.tsx +332 -0
  124. package/Influence-MW-AdServer-12-02-2026/client/src/pages/venues.tsx +381 -0
  125. package/Influence-MW-AdServer-12-02-2026/client/src/types/mapbox-gl-draw.d.ts +37 -0
  126. package/Influence-MW-AdServer-12-02-2026/client/src/types/react-simple-maps.d.ts +57 -0
  127. package/Influence-MW-AdServer-12-02-2026/components.json +20 -0
  128. package/Influence-MW-AdServer-12-02-2026/docs/PRD.md +3373 -0
  129. package/Influence-MW-AdServer-12-02-2026/docs/influence-feature-mapping.csv +498 -0
  130. package/Influence-MW-AdServer-12-02-2026/drizzle.config.ts +14 -0
  131. package/Influence-MW-AdServer-12-02-2026/package-lock.json +9672 -0
  132. package/Influence-MW-AdServer-12-02-2026/package.json +118 -0
  133. package/Influence-MW-AdServer-12-02-2026/postcss.config.js +6 -0
  134. package/Influence-MW-AdServer-12-02-2026/replit.md +91 -0
  135. package/Influence-MW-AdServer-12-02-2026/script/build.ts +67 -0
  136. package/Influence-MW-AdServer-12-02-2026/scripts/create-miro-diagrams.cjs +318 -0
  137. package/Influence-MW-AdServer-12-02-2026/scripts/create-remaining-diagrams.cjs +270 -0
  138. package/Influence-MW-AdServer-12-02-2026/server/index.ts +103 -0
  139. package/Influence-MW-AdServer-12-02-2026/server/recommendation-service.ts +319 -0
  140. package/Influence-MW-AdServer-12-02-2026/server/routes.ts +1890 -0
  141. package/Influence-MW-AdServer-12-02-2026/server/static.ts +19 -0
  142. package/Influence-MW-AdServer-12-02-2026/server/storage.ts +2058 -0
  143. package/Influence-MW-AdServer-12-02-2026/server/vite.ts +58 -0
  144. package/Influence-MW-AdServer-12-02-2026/shared/schema.ts +1595 -0
  145. package/Influence-MW-AdServer-12-02-2026/tailwind.config.ts +107 -0
  146. package/Influence-MW-AdServer-12-02-2026/tsconfig.json +23 -0
  147. package/Influence-MW-AdServer-12-02-2026/vite.config.ts +40 -0
  148. package/LINE_ITEM_BUDGET_FIELD_MAPPING.md +178 -0
  149. package/PCM/.env.example +92 -0
  150. package/PCM/README.md +558 -0
  151. package/PCM/docs/TEST_CASES.md +422 -0
  152. package/PCM/index.js +106 -0
  153. package/PCM/package-lock.json +3282 -0
  154. package/PCM/package.json +32 -0
  155. package/PCM/replit.md +64 -0
  156. package/PCM/schema.sql +495 -0
  157. package/PCM/scripts/export-schema.js +183 -0
  158. package/PCM/scripts/seed-comprehensive.js +631 -0
  159. package/PCM/scripts/seed-production.js +477 -0
  160. package/PCM/src/config/db.js +56 -0
  161. package/PCM/src/config/swagger.js +5975 -0
  162. package/PCM/src/dto/EmailRequestDTO.js +166 -0
  163. package/PCM/src/middleware/errorHandler.js +52 -0
  164. package/PCM/src/middleware/logger.js +26 -0
  165. package/PCM/src/migrations/001_add_campaign_mode_fields.sql +36 -0
  166. package/PCM/src/migrations/002_create_deal_id_counters.sql +22 -0
  167. package/PCM/src/migrations/003_update_publishers_column.sql +15 -0
  168. package/PCM/src/migrations/004_add_direct_dealtype_and_advertiser.sql +5 -0
  169. package/PCM/src/migrations/005_add_programmatic_fields_and_update_enums.sql +31 -0
  170. package/PCM/src/migrations/006_add_line_item_programmatic_fields.sql +12 -0
  171. package/PCM/src/migrations/007_add_line_item_direct_fields.sql +15 -0
  172. package/PCM/src/migrations/008_add_inventory_fields.sql +45 -0
  173. package/PCM/src/migrations/009_move_inventory_fields_to_metadata.sql +32 -0
  174. package/PCM/src/migrations/010_add_draft_status_and_line_items_count.sql +23 -0
  175. package/PCM/src/migrations/011_add_planning_field.sql +21 -0
  176. package/PCM/src/migrations/012_fix_inventory_composite_pk.sql +17 -0
  177. package/PCM/src/migrations/013_make_external_id_optional.sql +3 -0
  178. package/PCM/src/migrations/014_create_change_history.sql +38 -0
  179. package/PCM/src/migrations/016_create_publisher_insertion_orders.sql +33 -0
  180. package/PCM/src/migrations/017_fix_line_item_id_fk_reference.sql +86 -0
  181. package/PCM/src/migrations/018_create_approval_tables.sql +44 -0
  182. package/PCM/src/migrations/019_add_encrypted_token_column.sql +2 -0
  183. package/PCM/src/migrations/020_add_rejection_reason_to_deals.sql +10 -0
  184. package/PCM/src/migrations/021_add_publisher_external_id_to_inventories.sql +12 -0
  185. package/PCM/src/migrations/022_add_line_item_extended_fields.sql +24 -0
  186. package/PCM/src/migrations/023_add_base_price_fields.sql +8 -0
  187. package/PCM/src/migrations/run-migrations.js +46 -0
  188. package/PCM/src/models/ApprovalOTP.js +51 -0
  189. package/PCM/src/models/ApprovalToken.js +79 -0
  190. package/PCM/src/models/ChangeHistory.js +107 -0
  191. package/PCM/src/models/Deal.js +186 -0
  192. package/PCM/src/models/DealIdCounter.js +28 -0
  193. package/PCM/src/models/LineItem.js +227 -0
  194. package/PCM/src/models/LineItemCreative.js +89 -0
  195. package/PCM/src/models/LineItemInventory.js +115 -0
  196. package/PCM/src/models/PublisherInsertionOrder.js +93 -0
  197. package/PCM/src/models/TransactionHistory.js +34 -0
  198. package/PCM/src/models/associations.js +81 -0
  199. package/PCM/src/routes/approval.js +321 -0
  200. package/PCM/src/routes/creatives.js +437 -0
  201. package/PCM/src/routes/deals.js +1638 -0
  202. package/PCM/src/routes/digitalSignage.js +242 -0
  203. package/PCM/src/routes/insertionOrders.js +380 -0
  204. package/PCM/src/routes/lineItems.js +926 -0
  205. package/PCM/src/routes/system.js +384 -0
  206. package/PCM/src/services/ApprovalService.js +885 -0
  207. package/PCM/src/services/CampaignImportConverter.js +631 -0
  208. package/PCM/src/services/CampaignModeService.js +273 -0
  209. package/PCM/src/services/CampaignStatusService.js +395 -0
  210. package/PCM/src/services/ChangeHistoryService.js +316 -0
  211. package/PCM/src/services/DealIdService.js +94 -0
  212. package/PCM/src/services/DealResponseFormatter.js +90 -0
  213. package/PCM/src/services/EmailNotificationService.js +315 -0
  214. package/PCM/src/services/LineItemResponseFormatter.js +122 -0
  215. package/PCM/src/services/LineItemStatusService.js +380 -0
  216. package/PCM/src/tests/comprehensiveTestRunner.js +360 -0
  217. package/PCM/src/tests/comprehensiveTests.js +1277 -0
  218. package/PCM/src/tests/dealTypeUnitTests.js +1058 -0
  219. package/PCM/src/tests/testRunner.js +248 -0
  220. package/PCM/src/utils/caseConverter.js +92 -0
  221. package/PCM/src/utils/dealCalculations.js +206 -0
  222. package/PCM/src/utils/lineItemPayloadNormalizer.js +41 -0
  223. package/PCM/src/utils/payloadNormalizer.js +34 -0
  224. package/PCM/src/utils/sourceNormalizer.js +56 -0
  225. package/PCM/src/validators/creativeValidator.js +27 -0
  226. package/PCM/src/validators/dealValidator.js +203 -0
  227. package/PCM/src/validators/lineItemValidator.js +489 -0
  228. package/PCM/tests/approval-flows.test.js +238 -0
  229. package/PCM/tests/approval-workflow.test.js +291 -0
  230. package/PCM/tests/campaign-import-converter.test.js +543 -0
  231. package/PCM/tests/campaign-import-e2e.test.js +520 -0
  232. package/PCM/tests/campaign-status.test.js +539 -0
  233. package/PCM/tests/direct-publisher-split-reimport.test.js +460 -0
  234. package/PCM/tests/e2e/digital-signage.test.js +145 -0
  235. package/PCM/tests/e2e/search-filter-pagination.test.js +399 -0
  236. package/PCM/tests/e2e-comprehensive.test.js +3446 -0
  237. package/PCM/tests/edge-cases.test.js +340 -0
  238. package/PCM/tests/line-item-status.test.js +340 -0
  239. package/PCM/tests/seller-account-external-ids.test.js +877 -0
  240. package/PCM/tests/source-validation.test.js +324 -0
  241. package/PRD.md +3373 -0
  242. package/README.md +186 -0
  243. package/client/index.html +35 -0
  244. package/client/public/DEMO_STATUS.md +579 -0
  245. package/client/public/img/MW-logo-trans_1754045676555.png +0 -0
  246. package/client/public/locales/ar/approval.json +144 -0
  247. package/client/public/locales/ar/buyer.json +61 -0
  248. package/client/public/locales/ar/campaigns.json +1 -0
  249. package/client/public/locales/ar/common.json +218 -0
  250. package/client/public/locales/ar/contentHub.json +266 -0
  251. package/client/public/locales/ar/creatives.json +79 -0
  252. package/client/public/locales/ar/dashboard.json +57 -0
  253. package/client/public/locales/ar/deals.json +886 -0
  254. package/client/public/locales/ar/dsp.json +131 -0
  255. package/client/public/locales/ar/inventory.json +201 -0
  256. package/client/public/locales/ar/lineItems.json +553 -0
  257. package/client/public/locales/ar/navigation.json +48 -0
  258. package/client/public/locales/ar/wizard.json +1 -0
  259. package/client/public/locales/en/approval.json +144 -0
  260. package/client/public/locales/en/buyer.json +65 -0
  261. package/client/public/locales/en/campaigns.json +1 -0
  262. package/client/public/locales/en/common.json +218 -0
  263. package/client/public/locales/en/contentHub.json +266 -0
  264. package/client/public/locales/en/creatives.json +79 -0
  265. package/client/public/locales/en/dashboard.json +57 -0
  266. package/client/public/locales/en/deals.json +886 -0
  267. package/client/public/locales/en/dsp.json +131 -0
  268. package/client/public/locales/en/inventory.json +201 -0
  269. package/client/public/locales/en/lineItems.json +659 -0
  270. package/client/public/locales/en/navigation.json +48 -0
  271. package/client/public/locales/en/wizard.json +1 -0
  272. package/client/public/locales/ja/approval.json +144 -0
  273. package/client/public/locales/ja/buyer.json +61 -0
  274. package/client/public/locales/ja/campaigns.json +1 -0
  275. package/client/public/locales/ja/common.json +218 -0
  276. package/client/public/locales/ja/contentHub.json +266 -0
  277. package/client/public/locales/ja/creatives.json +79 -0
  278. package/client/public/locales/ja/dashboard.json +57 -0
  279. package/client/public/locales/ja/deals.json +886 -0
  280. package/client/public/locales/ja/dsp.json +131 -0
  281. package/client/public/locales/ja/inventory.json +201 -0
  282. package/client/public/locales/ja/lineItems.json +553 -0
  283. package/client/public/locales/ja/navigation.json +48 -0
  284. package/client/public/locales/ja/wizard.json +1 -0
  285. package/client/public/locales/zh/approval.json +144 -0
  286. package/client/public/locales/zh/buyer.json +61 -0
  287. package/client/public/locales/zh/campaigns.json +1 -0
  288. package/client/public/locales/zh/common.json +218 -0
  289. package/client/public/locales/zh/contentHub.json +266 -0
  290. package/client/public/locales/zh/creatives.json +79 -0
  291. package/client/public/locales/zh/dashboard.json +57 -0
  292. package/client/public/locales/zh/deals.json +886 -0
  293. package/client/public/locales/zh/dsp.json +131 -0
  294. package/client/public/locales/zh/inventory.json +201 -0
  295. package/client/public/locales/zh/lineItems.json +553 -0
  296. package/client/public/locales/zh/navigation.json +48 -0
  297. package/client/public/locales/zh/wizard.json +1 -0
  298. package/client/public/manifest.json +36 -0
  299. package/client/src/App.tsx +464 -0
  300. package/client/src/components/app-sidebar.tsx +312 -0
  301. package/client/src/components/approval/approval-decision-form.test.tsx +294 -0
  302. package/client/src/components/approval/approval-decision-form.tsx +326 -0
  303. package/client/src/components/approval/approval-sheet.tsx +631 -0
  304. package/client/src/components/approval/line-item-details-sheet.tsx +371 -0
  305. package/client/src/components/approval/otp-verification.test.tsx +337 -0
  306. package/client/src/components/approval/otp-verification.tsx +180 -0
  307. package/client/src/components/content-hub/bulk-transcode-dialog.tsx +379 -0
  308. package/client/src/components/content-hub/content-hub-manager-v2.tsx +574 -0
  309. package/client/src/components/content-hub/content-hub-manager.tsx +330 -0
  310. package/client/src/components/content-hub/creative-card.tsx +456 -0
  311. package/client/src/components/content-hub/creative-detail-sheet.tsx +685 -0
  312. package/client/src/components/content-hub/creative-filters.tsx +457 -0
  313. package/client/src/components/content-hub/creative-grid.tsx +329 -0
  314. package/client/src/components/content-hub/creative-selector.tsx +415 -0
  315. package/client/src/components/content-hub/creative-upload.tsx +547 -0
  316. package/client/src/components/content-hub/folder-dialogs.tsx +445 -0
  317. package/client/src/components/content-hub/folder-list.tsx +280 -0
  318. package/client/src/components/content-hub/review-dialogs.tsx +268 -0
  319. package/client/src/components/content-hub/transcode-dialog.tsx +226 -0
  320. package/client/src/components/creative-library/creative-details-view.tsx +446 -0
  321. package/client/src/components/creative-library/creative-filters-panel.tsx +203 -0
  322. package/client/src/components/creative-library/creative-list.tsx +360 -0
  323. package/client/src/components/creative-library/creative-status-badge.tsx +71 -0
  324. package/client/src/components/creative-library/folder-card.tsx +78 -0
  325. package/client/src/components/creative-library/index.ts +27 -0
  326. package/client/src/components/creative-library/new-creative-card.tsx +211 -0
  327. package/client/src/components/creative-library/upload-creative-dialog.tsx +261 -0
  328. package/client/src/components/dashboard-overview.tsx +109 -0
  329. package/client/src/components/deals/approval-history-panel.test.tsx +240 -0
  330. package/client/src/components/deals/approval-history-panel.tsx +156 -0
  331. package/client/src/components/deals/deal-status-badge.tsx +92 -0
  332. package/client/src/components/deals/import-from-planner-dialog.tsx +399 -0
  333. package/client/src/components/deals/market-insights-panel.tsx +237 -0
  334. package/client/src/components/deals/reopen-deal-sheet.tsx +191 -0
  335. package/client/src/components/deals/request-approval-sheet.test.tsx +323 -0
  336. package/client/src/components/deals/request-approval-sheet.tsx +136 -0
  337. package/client/src/components/deals/resend-approval-sheet.tsx +201 -0
  338. package/client/src/components/direct-campaigns/campaign-card.tsx +283 -0
  339. package/client/src/components/direct-campaigns/deal-filter-panel.tsx +325 -0
  340. package/client/src/components/inventory/advanced-filters-panel.tsx +273 -0
  341. package/client/src/components/inventory/csv-upload-modal.tsx +639 -0
  342. package/client/src/components/inventory/inventory-availability-view.tsx +486 -0
  343. package/client/src/components/inventory/inventory-details-sheet.tsx +376 -0
  344. package/client/src/components/inventory/inventory-map-view.tsx +596 -0
  345. package/client/src/components/inventory/inventory-settings-menu.tsx +52 -0
  346. package/client/src/components/language-switcher.tsx +53 -0
  347. package/client/src/components/line-items/campaign-forecast-panel.tsx +138 -0
  348. package/client/src/components/line-items/form-insights.tsx +89 -0
  349. package/client/src/components/line-items/geofencing/LocationCsvUploadDrawer.tsx +100 -0
  350. package/client/src/components/line-items/geofencing/POIDropdown.tsx +379 -0
  351. package/client/src/components/line-items/geofencing/SelectedLocationsSidebar.tsx +436 -0
  352. package/client/src/components/line-items/geofencing/ViewFileLocationDrawer.tsx +199 -0
  353. package/client/src/components/line-items/geofencing/components/ExistingFilesTab.tsx +268 -0
  354. package/client/src/components/line-items/geofencing/components/TemplateDownloadSection.tsx +59 -0
  355. package/client/src/components/line-items/geofencing/components/UploadTab.tsx +215 -0
  356. package/client/src/components/line-items/geofencing-map.tsx +1270 -0
  357. package/client/src/components/line-items/inventory-availability-section.tsx +178 -0
  358. package/client/src/components/line-items/line-item-schedule-manager.tsx +313 -0
  359. package/client/src/components/line-items/manual-inventory-drawer.tsx +346 -0
  360. package/client/src/components/line-items/planner-inventory-card.tsx +495 -0
  361. package/client/src/components/line-items/planner-schedule-grid.tsx +495 -0
  362. package/client/src/components/line-items/schedule-rule-editor.tsx +649 -0
  363. package/client/src/components/line-items/schedule-rule-types.ts +122 -0
  364. package/client/src/components/line-items/steps/creatives-step.tsx +681 -0
  365. package/client/src/components/line-items/steps/inventory-schedule-step.tsx +1596 -0
  366. package/client/src/components/line-items/steps/inventory-step.tsx +1533 -0
  367. package/client/src/components/line-items/steps/line-item-details-step.tsx +916 -0
  368. package/client/src/components/line-items/steps/schedule-step.tsx +273 -0
  369. package/client/src/components/line-items/steps/summary-step.tsx +680 -0
  370. package/client/src/components/line-items/steps/targeting-step.tsx +1708 -0
  371. package/client/src/components/product-switcher.tsx +105 -0
  372. package/client/src/components/protected-route.tsx +49 -0
  373. package/client/src/components/skip-link.tsx +22 -0
  374. package/client/src/components/stat-card.tsx +53 -0
  375. package/client/src/components/status-badge.tsx +96 -0
  376. package/client/src/components/ui/hierarchical-venue-selector.tsx +389 -0
  377. package/client/src/components/ui/toaster.tsx +111 -0
  378. package/client/src/contexts/auth-context.tsx +181 -0
  379. package/client/src/contexts/sidebar-state.tsx +50 -0
  380. package/client/src/contexts/theme-context.tsx +66 -0
  381. package/client/src/data/campaign-data.json +107 -0
  382. package/client/src/data/countries.json +22 -0
  383. package/client/src/hooks/use-approval.ts +366 -0
  384. package/client/src/hooks/use-keyboard-shortcuts.ts +74 -0
  385. package/client/src/hooks/use-media-query.ts +46 -0
  386. package/client/src/hooks/use-mobile.tsx +19 -0
  387. package/client/src/hooks/use-page-title.ts +21 -0
  388. package/client/src/hooks/use-toast.ts +195 -0
  389. package/client/src/index.css +694 -0
  390. package/client/src/lib/__tests__/accessibility.test.ts +104 -0
  391. package/client/src/lib/__tests__/date-utils.test.ts +199 -0
  392. package/client/src/lib/__tests__/dsp-buyer-api.test.ts +127 -0
  393. package/client/src/lib/__tests__/dsp-buyer-integration.test.ts +247 -0
  394. package/client/src/lib/__tests__/storage-utils.test.ts +167 -0
  395. package/client/src/lib/__tests__/utils.test.ts +57 -0
  396. package/client/src/lib/accessibility.ts +141 -0
  397. package/client/src/lib/api-config.ts +9 -0
  398. package/client/src/lib/auth-service.ts +209 -0
  399. package/client/src/lib/campaign-creative-api.ts +82 -0
  400. package/client/src/lib/company-api.ts +61 -0
  401. package/client/src/lib/content-hub-api.ts +407 -0
  402. package/client/src/lib/creative-mapper.ts +61 -0
  403. package/client/src/lib/date-utils.ts +119 -0
  404. package/client/src/lib/deal-helpers.ts +220 -0
  405. package/client/src/lib/dsp-buyer-api.ts +196 -0
  406. package/client/src/lib/geo-import-api.ts +151 -0
  407. package/client/src/lib/google-poi-api.ts +305 -0
  408. package/client/src/lib/i18n/__tests__/formatting.test.ts +202 -0
  409. package/client/src/lib/i18n/formatting.ts +130 -0
  410. package/client/src/lib/i18n/index.ts +8 -0
  411. package/client/src/lib/i18n-compat.ts +76 -0
  412. package/client/src/lib/influence-deals-api.ts +896 -0
  413. package/client/src/lib/inventory-api.ts +399 -0
  414. package/client/src/lib/oauth-service.ts +678 -0
  415. package/client/src/lib/poi-types.ts +75 -0
  416. package/client/src/lib/queryClient.ts +144 -0
  417. package/client/src/lib/recommendation-api.ts +380 -0
  418. package/client/src/lib/storage-utils.ts +104 -0
  419. package/client/src/lib/tolgee.ts +85 -0
  420. package/client/src/lib/utils.ts +0 -0
  421. package/client/src/main.tsx +67 -0
  422. package/client/src/mapbox-draw-modes.d.ts +32 -0
  423. package/client/src/pages/all-folders.tsx +203 -0
  424. package/client/src/pages/auth-callback.tsx +115 -0
  425. package/client/src/pages/buyer-form.tsx +339 -0
  426. package/client/src/pages/buyer-list.tsx +622 -0
  427. package/client/src/pages/content-hub.tsx +1358 -0
  428. package/client/src/pages/create-deal.tsx +2093 -0
  429. package/client/src/pages/creative-assignment-page.tsx +548 -0
  430. package/client/src/pages/creatives.tsx +5 -0
  431. package/client/src/pages/custom-pois.tsx +425 -0
  432. package/client/src/pages/dashboard.tsx +615 -0
  433. package/client/src/pages/deal-history.tsx +434 -0
  434. package/client/src/pages/deal-line-items.tsx +1703 -0
  435. package/client/src/pages/demo-status.tsx +113 -0
  436. package/client/src/pages/direct-campaign-details.tsx +361 -0
  437. package/client/src/pages/direct-campaigns-new.tsx +824 -0
  438. package/client/src/pages/dsp-form.tsx +803 -0
  439. package/client/src/pages/dsp-list.tsx +239 -0
  440. package/client/src/pages/folder-content.tsx +336 -0
  441. package/client/src/pages/integrations.tsx +429 -0
  442. package/client/src/pages/line-item-creatives.tsx +789 -0
  443. package/client/src/pages/line-item-detail-page.tsx +684 -0
  444. package/client/src/pages/line-item-form-page.tsx +3261 -0
  445. package/client/src/pages/line-item-wizard.tsx +1207 -0
  446. package/client/src/pages/login.tsx +154 -0
  447. package/client/src/pages/not-found.tsx +23 -0
  448. package/client/src/pages/proof-of-play.tsx +397 -0
  449. package/client/src/pages/public-approval.tsx +551 -0
  450. package/client/src/pages/reports.tsx +231 -0
  451. package/client/src/pages/settings.tsx +760 -0
  452. package/client/src/pages/signals.tsx +389 -0
  453. package/client/src/pages/tags.tsx +318 -0
  454. package/client/src/pages/test-results.tsx +328 -0
  455. package/client/src/store/hooks.ts +5 -0
  456. package/client/src/store/index.ts +15 -0
  457. package/client/src/store/mapMarkerLocationsSlice.ts +241 -0
  458. package/client/src/styles/design-tokens.css +324 -0
  459. package/client/src/test/setup.ts +261 -0
  460. package/client/src/test/test-utils.tsx +40 -0
  461. package/client/src/types/approval.ts +221 -0
  462. package/client/src/types/content-hub.ts +209 -0
  463. package/client/src/types/geofencing.ts +67 -0
  464. package/client/src/types/transcoding.ts +140 -0
  465. package/client/src/vite-env.d.ts +18 -0
  466. package/components.json +20 -0
  467. package/creative-api.json +1 -0
  468. package/docs/AI_REFERENCE.md +459 -0
  469. package/docs/MWDesign-Prompt.md +132 -0
  470. package/docs/MWDesign-System.md +344 -0
  471. package/docs/test-plan.md +277 -0
  472. package/e2e/AUTONOMOUS-TESTING.md +406 -0
  473. package/e2e/README.md +219 -0
  474. package/e2e/autonomous-flow.spec.ts +308 -0
  475. package/e2e/debug-sso.spec.ts +163 -0
  476. package/e2e/direct-campaigns.spec.ts +219 -0
  477. package/e2e/explore-sso.spec.ts +149 -0
  478. package/e2e/fixtures/auth.ts +26 -0
  479. package/e2e/fixtures/enhanced-test.ts +331 -0
  480. package/e2e/pagination.spec.ts +280 -0
  481. package/e2e/view-toggle.spec.ts +312 -0
  482. package/generated-icon.png +0 -0
  483. package/i18next-scanner.config.cjs +46 -0
  484. package/package.json +141 -0
  485. package/playwright.config.ts +93 -0
  486. package/postcss.config.js +6 -0
  487. package/replit.md +196 -0
  488. package/screenshot-after-login.png +0 -0
  489. package/screenshot-contenthub-grid.png +0 -0
  490. package/screenshot-contenthub-list-fixed.png +0 -0
  491. package/screenshot-contenthub-list.png +0 -0
  492. package/screenshot-create-deal.png +0 -0
  493. package/screenshot-dashboard.png +0 -0
  494. package/screenshot-deals.png +0 -0
  495. package/screenshot-login-filled.png +0 -0
  496. package/screenshot-login.png +0 -0
  497. package/screenshot.mjs +24 -0
  498. package/scripts/deploy-stg.sh +185 -0
  499. package/shared/direct-io-schema.ts +383 -0
  500. package/shared/schema.ts +439 -0
  501. package/shared/screen-types.ts +149 -0
  502. package/springdocDefault.json +1 -0
  503. package/swagger-ui-bundle.js +2 -0
  504. package/swagger-ui-init.js +10316 -0
  505. package/tailwind.config.ts +282 -0
  506. package/terraform/README.md +306 -0
  507. package/terraform/cloudfront.tf +289 -0
  508. package/terraform/ecs.tf +727 -0
  509. package/terraform/environments/dev.tfvars +59 -0
  510. package/terraform/environments/production.tfvars +60 -0
  511. package/terraform/main.tf +47 -0
  512. package/terraform/outputs.tf +145 -0
  513. package/terraform/s3.tf +192 -0
  514. package/terraform/variables.tf +226 -0
  515. package/terraform/waf.tf +165 -0
  516. package/terraform-frontend/.terraform.lock.hcl +25 -0
  517. package/terraform-frontend/README.md +85 -0
  518. package/terraform-frontend/cloudfront.tf +125 -0
  519. package/terraform-frontend/main.tf +31 -0
  520. package/terraform-frontend/outputs.tf +24 -0
  521. package/terraform-frontend/terraform.tfvars +12 -0
  522. package/terraform-frontend/variables.tf +53 -0
  523. package/tsconfig.json +23 -0
  524. package/vite.config.ts +226 -0
  525. package/vitest.config.ts +56 -0
@@ -0,0 +1,652 @@
1
+ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
2
+ import { Button } from "@/components/ui/button";
3
+ import { Input } from "@/components/ui/input";
4
+ import { Label } from "@/components/ui/label";
5
+ import { Switch } from "@/components/ui/switch";
6
+ import { Separator } from "@/components/ui/separator";
7
+ import { PageHeader } from "@/components/page-header";
8
+ import { Settings as SettingsIcon, Bell, Shield, Globe, Palette, Save, Workflow, Languages, Package, ListFilter, Sparkles, Target, TrendingUp, Sliders } from "lucide-react";
9
+ import {
10
+ Select,
11
+ SelectContent,
12
+ SelectItem,
13
+ SelectTrigger,
14
+ SelectValue,
15
+ } from "@/components/ui/select";
16
+ import { Textarea } from "@/components/ui/textarea";
17
+ import { useToast } from "@/hooks/use-toast";
18
+
19
+ export default function Settings() {
20
+ const { toast } = useToast();
21
+
22
+ const handleSave = () => {
23
+ toast({
24
+ title: "Settings saved",
25
+ description: "Your settings have been updated successfully.",
26
+ });
27
+ };
28
+
29
+ return (
30
+ <div className="flex flex-col gap-6 p-6">
31
+ <PageHeader
32
+ title="Settings"
33
+ description="Configure your ad server preferences"
34
+ />
35
+
36
+ <div className="grid gap-6">
37
+ <Card>
38
+ <CardHeader>
39
+ <CardTitle className="flex items-center gap-2">
40
+ <SettingsIcon className="h-5 w-5" />
41
+ General Settings
42
+ </CardTitle>
43
+ <CardDescription>Basic configuration for your ad server</CardDescription>
44
+ </CardHeader>
45
+ <CardContent className="space-y-6">
46
+ <div className="grid gap-4 sm:grid-cols-2">
47
+ <div className="space-y-2">
48
+ <Label htmlFor="company-name">Company Name</Label>
49
+ <Input id="company-name" defaultValue="Influence Media" data-testid="input-company-name" />
50
+ </div>
51
+ <div className="space-y-2">
52
+ <Label htmlFor="timezone">Timezone</Label>
53
+ <Select defaultValue="utc">
54
+ <SelectTrigger data-testid="select-timezone">
55
+ <SelectValue placeholder="Select timezone" />
56
+ </SelectTrigger>
57
+ <SelectContent>
58
+ <SelectItem value="utc">UTC</SelectItem>
59
+ <SelectItem value="est">Eastern Time (EST)</SelectItem>
60
+ <SelectItem value="pst">Pacific Time (PST)</SelectItem>
61
+ <SelectItem value="cet">Central European Time (CET)</SelectItem>
62
+ <SelectItem value="ist">India Standard Time (IST)</SelectItem>
63
+ </SelectContent>
64
+ </Select>
65
+ </div>
66
+ </div>
67
+ <div className="grid gap-4 sm:grid-cols-2">
68
+ <div className="space-y-2">
69
+ <Label htmlFor="currency">Default Currency</Label>
70
+ <Select defaultValue="usd">
71
+ <SelectTrigger data-testid="select-currency">
72
+ <SelectValue placeholder="Select currency" />
73
+ </SelectTrigger>
74
+ <SelectContent>
75
+ <SelectItem value="usd">USD ($)</SelectItem>
76
+ <SelectItem value="eur">EUR (€)</SelectItem>
77
+ <SelectItem value="gbp">GBP (£)</SelectItem>
78
+ <SelectItem value="inr">INR (₹)</SelectItem>
79
+ </SelectContent>
80
+ </Select>
81
+ </div>
82
+ <div className="space-y-2">
83
+ <Label htmlFor="date-format">Date Format</Label>
84
+ <Select defaultValue="mdy">
85
+ <SelectTrigger data-testid="select-date-format">
86
+ <SelectValue placeholder="Select format" />
87
+ </SelectTrigger>
88
+ <SelectContent>
89
+ <SelectItem value="mdy">MM/DD/YYYY</SelectItem>
90
+ <SelectItem value="dmy">DD/MM/YYYY</SelectItem>
91
+ <SelectItem value="ymd">YYYY-MM-DD</SelectItem>
92
+ </SelectContent>
93
+ </Select>
94
+ </div>
95
+ </div>
96
+ </CardContent>
97
+ </Card>
98
+
99
+ <Card>
100
+ <CardHeader>
101
+ <CardTitle className="flex items-center gap-2">
102
+ <Bell className="h-5 w-5" />
103
+ Notifications
104
+ </CardTitle>
105
+ <CardDescription>Configure alert and notification preferences</CardDescription>
106
+ </CardHeader>
107
+ <CardContent className="space-y-4">
108
+ <div className="flex items-center justify-between">
109
+ <div className="space-y-0.5">
110
+ <Label>Deal Alerts</Label>
111
+ <p className="text-sm text-muted-foreground">
112
+ Get notified when deals reach budget thresholds
113
+ </p>
114
+ </div>
115
+ <Switch defaultChecked data-testid="switch-deal-alerts" />
116
+ </div>
117
+ <Separator />
118
+ <div className="flex items-center justify-between">
119
+ <div className="space-y-0.5">
120
+ <Label>Screen Status Updates</Label>
121
+ <p className="text-sm text-muted-foreground">
122
+ Alert when screens go offline or require maintenance
123
+ </p>
124
+ </div>
125
+ <Switch defaultChecked data-testid="switch-screen-alerts" />
126
+ </div>
127
+ <Separator />
128
+ <div className="flex items-center justify-between">
129
+ <div className="space-y-0.5">
130
+ <Label>Daily Performance Reports</Label>
131
+ <p className="text-sm text-muted-foreground">
132
+ Receive daily email summaries of deal performance
133
+ </p>
134
+ </div>
135
+ <Switch data-testid="switch-daily-reports" />
136
+ </div>
137
+ <Separator />
138
+ <div className="flex items-center justify-between">
139
+ <div className="space-y-0.5">
140
+ <Label>Integration Status</Label>
141
+ <p className="text-sm text-muted-foreground">
142
+ Notify when SSP/DSP integrations have connectivity issues
143
+ </p>
144
+ </div>
145
+ <Switch defaultChecked data-testid="switch-integration-alerts" />
146
+ </div>
147
+ </CardContent>
148
+ </Card>
149
+
150
+ <Card>
151
+ <CardHeader>
152
+ <CardTitle className="flex items-center gap-2">
153
+ <Shield className="h-5 w-5" />
154
+ Traffic Control
155
+ </CardTitle>
156
+ <CardDescription>Default settings for traffic allocation and delivery</CardDescription>
157
+ </CardHeader>
158
+ <CardContent className="space-y-6">
159
+ <div className="grid gap-4 sm:grid-cols-2">
160
+ <div className="space-y-2">
161
+ <Label htmlFor="default-allocation">Default Traffic Allocation</Label>
162
+ <Select defaultValue="100">
163
+ <SelectTrigger data-testid="select-default-allocation">
164
+ <SelectValue placeholder="Select percentage" />
165
+ </SelectTrigger>
166
+ <SelectContent>
167
+ <SelectItem value="25">25%</SelectItem>
168
+ <SelectItem value="50">50%</SelectItem>
169
+ <SelectItem value="75">75%</SelectItem>
170
+ <SelectItem value="100">100%</SelectItem>
171
+ </SelectContent>
172
+ </Select>
173
+ </div>
174
+ <div className="space-y-2">
175
+ <Label htmlFor="delivery-pacing">Delivery Pacing</Label>
176
+ <Select defaultValue="even">
177
+ <SelectTrigger data-testid="select-pacing">
178
+ <SelectValue placeholder="Select pacing" />
179
+ </SelectTrigger>
180
+ <SelectContent>
181
+ <SelectItem value="even">Even (Spread evenly)</SelectItem>
182
+ <SelectItem value="asap">ASAP (As fast as possible)</SelectItem>
183
+ <SelectItem value="frontloaded">Frontloaded (Heavy at start)</SelectItem>
184
+ </SelectContent>
185
+ </Select>
186
+ </div>
187
+ </div>
188
+ <div className="flex items-center justify-between">
189
+ <div className="space-y-0.5">
190
+ <Label>Enable Programmatic Fallback</Label>
191
+ <p className="text-sm text-muted-foreground">
192
+ Fill unfilled inventory with programmatic demand
193
+ </p>
194
+ </div>
195
+ <Switch defaultChecked data-testid="switch-programmatic-fallback" />
196
+ </div>
197
+ </CardContent>
198
+ </Card>
199
+
200
+ <Card>
201
+ <CardHeader>
202
+ <CardTitle className="flex items-center gap-2">
203
+ <Target className="h-5 w-5" />
204
+ Forecasting Defaults
205
+ </CardTitle>
206
+ <CardDescription>Configure default settings for line item forecasting</CardDescription>
207
+ </CardHeader>
208
+ <CardContent className="space-y-6">
209
+ <div className="grid gap-4 sm:grid-cols-2">
210
+ <div className="space-y-2">
211
+ <Label htmlFor="forecast-goal-type">Default Goal Type</Label>
212
+ <Select defaultValue="impressions">
213
+ <SelectTrigger data-testid="select-forecast-goal-type">
214
+ <SelectValue placeholder="Select goal type" />
215
+ </SelectTrigger>
216
+ <SelectContent>
217
+ <SelectItem value="impressions">Impressions</SelectItem>
218
+ <SelectItem value="reach">Reach</SelectItem>
219
+ <SelectItem value="sov">Share of Voice</SelectItem>
220
+ <SelectItem value="ad-plays">Ad Plays</SelectItem>
221
+ <SelectItem value="carbon">Carbon Emission</SelectItem>
222
+ </SelectContent>
223
+ </Select>
224
+ </div>
225
+ <div className="space-y-2">
226
+ <Label htmlFor="forecast-confidence">Confidence Level</Label>
227
+ <Select defaultValue="medium">
228
+ <SelectTrigger data-testid="select-forecast-confidence">
229
+ <SelectValue placeholder="Select confidence" />
230
+ </SelectTrigger>
231
+ <SelectContent>
232
+ <SelectItem value="low">Low (70%)</SelectItem>
233
+ <SelectItem value="medium">Medium (85%)</SelectItem>
234
+ <SelectItem value="high">High (95%)</SelectItem>
235
+ </SelectContent>
236
+ </Select>
237
+ </div>
238
+ </div>
239
+ <div className="grid gap-4 sm:grid-cols-2">
240
+ <div className="space-y-2">
241
+ <Label htmlFor="default-budget-buffer">Budget Buffer (%)</Label>
242
+ <Input id="default-budget-buffer" type="number" defaultValue="10" data-testid="input-budget-buffer" />
243
+ <p className="text-xs text-muted-foreground">
244
+ Extra budget allowance for forecast variance
245
+ </p>
246
+ </div>
247
+ <div className="space-y-2">
248
+ <Label htmlFor="forecast-refresh-interval">Forecast Refresh Interval</Label>
249
+ <Select defaultValue="daily">
250
+ <SelectTrigger data-testid="select-forecast-refresh">
251
+ <SelectValue placeholder="Select interval" />
252
+ </SelectTrigger>
253
+ <SelectContent>
254
+ <SelectItem value="realtime">Real-time</SelectItem>
255
+ <SelectItem value="hourly">Hourly</SelectItem>
256
+ <SelectItem value="daily">Daily</SelectItem>
257
+ <SelectItem value="weekly">Weekly</SelectItem>
258
+ </SelectContent>
259
+ </Select>
260
+ </div>
261
+ </div>
262
+ <div className="flex items-center justify-between">
263
+ <div className="space-y-0.5">
264
+ <Label>Include Historical Performance</Label>
265
+ <p className="text-sm text-muted-foreground">
266
+ Use historical data to improve forecast accuracy
267
+ </p>
268
+ </div>
269
+ <Switch defaultChecked data-testid="switch-historical-forecast" />
270
+ </div>
271
+ </CardContent>
272
+ </Card>
273
+
274
+ <Card>
275
+ <CardHeader>
276
+ <CardTitle className="flex items-center gap-2">
277
+ <TrendingUp className="h-5 w-5" />
278
+ Optimization Preferences
279
+ </CardTitle>
280
+ <CardDescription>Configure AI-powered optimization behavior</CardDescription>
281
+ </CardHeader>
282
+ <CardContent className="space-y-6">
283
+ <div className="grid gap-4 sm:grid-cols-2">
284
+ <div className="space-y-2">
285
+ <Label htmlFor="optimization-mode">Optimization Mode</Label>
286
+ <Select defaultValue="balanced">
287
+ <SelectTrigger data-testid="select-optimization-mode">
288
+ <SelectValue placeholder="Select mode" />
289
+ </SelectTrigger>
290
+ <SelectContent>
291
+ <SelectItem value="aggressive">Aggressive (Maximize performance)</SelectItem>
292
+ <SelectItem value="balanced">Balanced (Performance + stability)</SelectItem>
293
+ <SelectItem value="conservative">Conservative (Minimal changes)</SelectItem>
294
+ </SelectContent>
295
+ </Select>
296
+ </div>
297
+ <div className="space-y-2">
298
+ <Label htmlFor="reoptimize-frequency">Re-optimization Frequency</Label>
299
+ <Select defaultValue="weekly">
300
+ <SelectTrigger data-testid="select-reoptimize-frequency">
301
+ <SelectValue placeholder="Select frequency" />
302
+ </SelectTrigger>
303
+ <SelectContent>
304
+ <SelectItem value="never">Never (Manual only)</SelectItem>
305
+ <SelectItem value="daily">Daily</SelectItem>
306
+ <SelectItem value="weekly">Weekly</SelectItem>
307
+ <SelectItem value="monthly">Monthly</SelectItem>
308
+ </SelectContent>
309
+ </Select>
310
+ </div>
311
+ </div>
312
+ <div className="flex items-center justify-between">
313
+ <div className="space-y-0.5">
314
+ <Label>Auto-Optimize New Line Items</Label>
315
+ <p className="text-sm text-muted-foreground">
316
+ Automatically apply AI recommendations to new line items
317
+ </p>
318
+ </div>
319
+ <Switch defaultChecked data-testid="switch-auto-optimize" />
320
+ </div>
321
+ <Separator />
322
+ <div className="flex items-center justify-between">
323
+ <div className="space-y-0.5">
324
+ <Label>Enable A/B Testing</Label>
325
+ <p className="text-sm text-muted-foreground">
326
+ Allow AI to run A/B tests on inventory selection
327
+ </p>
328
+ </div>
329
+ <Switch data-testid="switch-ab-testing" />
330
+ </div>
331
+ <Separator />
332
+ <div className="flex items-center justify-between">
333
+ <div className="space-y-0.5">
334
+ <Label>Show Optimization Insights</Label>
335
+ <p className="text-sm text-muted-foreground">
336
+ Display AI reasoning and recommendations in the UI
337
+ </p>
338
+ </div>
339
+ <Switch defaultChecked data-testid="switch-optimization-insights" />
340
+ </div>
341
+ </CardContent>
342
+ </Card>
343
+
344
+ <Card>
345
+ <CardHeader>
346
+ <CardTitle className="flex items-center gap-2">
347
+ <Sliders className="h-5 w-5" />
348
+ Recommendation Weights
349
+ </CardTitle>
350
+ <CardDescription>Adjust the importance of each factor in AI recommendations</CardDescription>
351
+ </CardHeader>
352
+ <CardContent className="space-y-4">
353
+ <p className="text-sm text-muted-foreground">
354
+ Configure how the 8-factor scoring system weights each component. Values should sum to 100%.
355
+ </p>
356
+ <div className="grid gap-4 sm:grid-cols-2">
357
+ <div className="space-y-2">
358
+ <div className="flex items-center justify-between">
359
+ <Label htmlFor="weight-measure-fit">Measure Fit</Label>
360
+ <span className="text-sm text-muted-foreground">15%</span>
361
+ </div>
362
+ <Input id="weight-measure-fit" type="range" min="0" max="30" defaultValue="15" className="w-full" data-testid="input-weight-measure-fit" />
363
+ </div>
364
+ <div className="space-y-2">
365
+ <div className="flex items-center justify-between">
366
+ <Label htmlFor="weight-geo-fit">Geo Fit</Label>
367
+ <span className="text-sm text-muted-foreground">15%</span>
368
+ </div>
369
+ <Input id="weight-geo-fit" type="range" min="0" max="30" defaultValue="15" className="w-full" data-testid="input-weight-geo-fit" />
370
+ </div>
371
+ </div>
372
+ <div className="grid gap-4 sm:grid-cols-2">
373
+ <div className="space-y-2">
374
+ <div className="flex items-center justify-between">
375
+ <Label htmlFor="weight-availability">Availability</Label>
376
+ <span className="text-sm text-muted-foreground">15%</span>
377
+ </div>
378
+ <Input id="weight-availability" type="range" min="0" max="30" defaultValue="15" className="w-full" data-testid="input-weight-availability" />
379
+ </div>
380
+ <div className="space-y-2">
381
+ <div className="flex items-center justify-between">
382
+ <Label htmlFor="weight-budget-fit">Budget Fit</Label>
383
+ <span className="text-sm text-muted-foreground">10%</span>
384
+ </div>
385
+ <Input id="weight-budget-fit" type="range" min="0" max="30" defaultValue="10" className="w-full" data-testid="input-weight-budget-fit" />
386
+ </div>
387
+ </div>
388
+ <div className="grid gap-4 sm:grid-cols-2">
389
+ <div className="space-y-2">
390
+ <div className="flex items-center justify-between">
391
+ <Label htmlFor="weight-audience-fit">Audience Fit</Label>
392
+ <span className="text-sm text-muted-foreground">15%</span>
393
+ </div>
394
+ <Input id="weight-audience-fit" type="range" min="0" max="30" defaultValue="15" className="w-full" data-testid="input-weight-audience-fit" />
395
+ </div>
396
+ <div className="space-y-2">
397
+ <div className="flex items-center justify-between">
398
+ <Label htmlFor="weight-brand-fit">Brand Fit</Label>
399
+ <span className="text-sm text-muted-foreground">10%</span>
400
+ </div>
401
+ <Input id="weight-brand-fit" type="range" min="0" max="30" defaultValue="10" className="w-full" data-testid="input-weight-brand-fit" />
402
+ </div>
403
+ </div>
404
+ <div className="grid gap-4 sm:grid-cols-2">
405
+ <div className="space-y-2">
406
+ <div className="flex items-center justify-between">
407
+ <Label htmlFor="weight-quality-fit">Quality Fit</Label>
408
+ <span className="text-sm text-muted-foreground">10%</span>
409
+ </div>
410
+ <Input id="weight-quality-fit" type="range" min="0" max="30" defaultValue="10" className="w-full" data-testid="input-weight-quality-fit" />
411
+ </div>
412
+ <div className="space-y-2">
413
+ <div className="flex items-center justify-between">
414
+ <Label htmlFor="weight-time-fit">Time Fit</Label>
415
+ <span className="text-sm text-muted-foreground">10%</span>
416
+ </div>
417
+ <Input id="weight-time-fit" type="range" min="0" max="30" defaultValue="10" className="w-full" data-testid="input-weight-time-fit" />
418
+ </div>
419
+ </div>
420
+ <Button variant="outline" size="sm" className="mt-2" data-testid="button-reset-weights">
421
+ Reset to Defaults
422
+ </Button>
423
+ </CardContent>
424
+ </Card>
425
+
426
+ <Card>
427
+ <CardHeader>
428
+ <CardTitle className="flex items-center gap-2">
429
+ <Workflow className="h-5 w-5" />
430
+ Workflow Settings
431
+ </CardTitle>
432
+ <CardDescription>Configure approval workflows and automation</CardDescription>
433
+ </CardHeader>
434
+ <CardContent className="space-y-4">
435
+ <div className="flex items-center justify-between">
436
+ <div className="space-y-0.5">
437
+ <Label>Require Creative Approval</Label>
438
+ <p className="text-sm text-muted-foreground">
439
+ All creatives must be approved before going live
440
+ </p>
441
+ </div>
442
+ <Switch defaultChecked data-testid="switch-creative-approval" />
443
+ </div>
444
+ <Separator />
445
+ <div className="flex items-center justify-between">
446
+ <div className="space-y-0.5">
447
+ <Label>Two-Tier Creative Approval</Label>
448
+ <p className="text-sm text-muted-foreground">
449
+ Enable Tier 2 (Media Owner) approval after Tier 1 (Content Hub)
450
+ </p>
451
+ </div>
452
+ <Switch defaultChecked data-testid="switch-two-tier-approval" />
453
+ </div>
454
+ <Separator />
455
+ <div className="flex items-center justify-between">
456
+ <div className="space-y-0.5">
457
+ <Label>Auto-Accept Deals</Label>
458
+ <p className="text-sm text-muted-foreground">
459
+ Automatically accept deals from trusted partners
460
+ </p>
461
+ </div>
462
+ <Switch data-testid="switch-auto-accept" />
463
+ </div>
464
+ <Separator />
465
+ <div className="flex items-center justify-between">
466
+ <div className="space-y-0.5">
467
+ <Label>Deal Locking</Label>
468
+ <p className="text-sm text-muted-foreground">
469
+ Lock deals after acceptance to prevent modifications
470
+ </p>
471
+ </div>
472
+ <Switch defaultChecked data-testid="switch-deal-locking" />
473
+ </div>
474
+ </CardContent>
475
+ </Card>
476
+
477
+ <Card>
478
+ <CardHeader>
479
+ <CardTitle className="flex items-center gap-2">
480
+ <Languages className="h-5 w-5" />
481
+ Terminology
482
+ </CardTitle>
483
+ <CardDescription>Customize labels and terminology used throughout the platform</CardDescription>
484
+ </CardHeader>
485
+ <CardContent className="space-y-4">
486
+ <div className="grid gap-4 sm:grid-cols-2">
487
+ <div className="space-y-2">
488
+ <Label htmlFor="term-deal">Deal</Label>
489
+ <Input id="term-deal" defaultValue="Deal" data-testid="input-term-deal" />
490
+ </div>
491
+ <div className="space-y-2">
492
+ <Label htmlFor="term-line-item">Line Item</Label>
493
+ <Input id="term-line-item" defaultValue="Line Item" data-testid="input-term-line-item" />
494
+ </div>
495
+ </div>
496
+ <div className="grid gap-4 sm:grid-cols-2">
497
+ <div className="space-y-2">
498
+ <Label htmlFor="term-creative">Creative</Label>
499
+ <Input id="term-creative" defaultValue="Creative" data-testid="input-term-creative" />
500
+ </div>
501
+ <div className="space-y-2">
502
+ <Label htmlFor="term-inventory">Inventory</Label>
503
+ <Input id="term-inventory" defaultValue="Inventory" data-testid="input-term-inventory" />
504
+ </div>
505
+ </div>
506
+ <div className="grid gap-4 sm:grid-cols-2">
507
+ <div className="space-y-2">
508
+ <Label htmlFor="term-advertiser">Advertiser</Label>
509
+ <Input id="term-advertiser" defaultValue="Advertiser" data-testid="input-term-advertiser" />
510
+ </div>
511
+ <div className="space-y-2">
512
+ <Label htmlFor="term-campaign">Campaign</Label>
513
+ <Input id="term-campaign" defaultValue="Campaign" data-testid="input-term-campaign" />
514
+ </div>
515
+ </div>
516
+ </CardContent>
517
+ </Card>
518
+
519
+ <Card>
520
+ <CardHeader>
521
+ <CardTitle className="flex items-center gap-2">
522
+ <Palette className="h-5 w-5" />
523
+ Themes & Branding
524
+ </CardTitle>
525
+ <CardDescription>Customize the look and feel of your platform</CardDescription>
526
+ </CardHeader>
527
+ <CardContent className="space-y-4">
528
+ <div className="grid gap-4 sm:grid-cols-2">
529
+ <div className="space-y-2">
530
+ <Label htmlFor="theme-mode">Theme Mode</Label>
531
+ <Select defaultValue="light">
532
+ <SelectTrigger data-testid="select-theme-mode">
533
+ <SelectValue placeholder="Select theme" />
534
+ </SelectTrigger>
535
+ <SelectContent>
536
+ <SelectItem value="light">Light</SelectItem>
537
+ <SelectItem value="dark">Dark</SelectItem>
538
+ <SelectItem value="system">System</SelectItem>
539
+ </SelectContent>
540
+ </Select>
541
+ </div>
542
+ <div className="space-y-2">
543
+ <Label htmlFor="primary-color">Primary Color</Label>
544
+ <div className="flex gap-2">
545
+ <Input id="primary-color" type="color" defaultValue="#3B82F6" className="w-14 h-9 p-1" data-testid="input-primary-color" />
546
+ <Input defaultValue="#3B82F6" className="flex-1 font-mono" readOnly />
547
+ </div>
548
+ </div>
549
+ </div>
550
+ <div className="space-y-2">
551
+ <Label htmlFor="logo-url">Logo URL</Label>
552
+ <Input id="logo-url" placeholder="https://example.com/logo.png" data-testid="input-logo-url" />
553
+ </div>
554
+ <div className="flex items-center justify-between">
555
+ <div className="space-y-0.5">
556
+ <Label>Compact Mode</Label>
557
+ <p className="text-sm text-muted-foreground">
558
+ Use a more compact UI with smaller spacing
559
+ </p>
560
+ </div>
561
+ <Switch data-testid="switch-compact-mode" />
562
+ </div>
563
+ </CardContent>
564
+ </Card>
565
+
566
+ <Card>
567
+ <CardHeader>
568
+ <CardTitle className="flex items-center gap-2">
569
+ <ListFilter className="h-5 w-5" />
570
+ Inventory Whitelisting
571
+ </CardTitle>
572
+ <CardDescription>Control which inventory is available for deals</CardDescription>
573
+ </CardHeader>
574
+ <CardContent className="space-y-4">
575
+ <div className="flex items-center justify-between">
576
+ <div className="space-y-0.5">
577
+ <Label>Enable Inventory Whitelisting</Label>
578
+ <p className="text-sm text-muted-foreground">
579
+ Only show whitelisted inventory to advertisers and agencies
580
+ </p>
581
+ </div>
582
+ <Switch data-testid="switch-inventory-whitelist" />
583
+ </div>
584
+ <Separator />
585
+ <div className="space-y-2">
586
+ <Label htmlFor="whitelist-ids">Whitelisted Inventory IDs</Label>
587
+ <Textarea
588
+ id="whitelist-ids"
589
+ placeholder="Enter inventory IDs separated by commas or new lines"
590
+ className="min-h-[100px] font-mono text-sm"
591
+ data-testid="input-whitelist-ids"
592
+ />
593
+ <p className="text-xs text-muted-foreground">
594
+ Leave empty to allow all inventory. Enter specific IDs to restrict availability.
595
+ </p>
596
+ </div>
597
+ <div className="flex items-center justify-between">
598
+ <div className="space-y-0.5">
599
+ <Label>Exclude Adult Content Venues</Label>
600
+ <p className="text-sm text-muted-foreground">
601
+ Automatically exclude venues with adult content classification
602
+ </p>
603
+ </div>
604
+ <Switch defaultChecked data-testid="switch-exclude-adult" />
605
+ </div>
606
+ </CardContent>
607
+ </Card>
608
+
609
+ <Card>
610
+ <CardHeader>
611
+ <CardTitle className="flex items-center gap-2">
612
+ <Globe className="h-5 w-5" />
613
+ API Settings
614
+ </CardTitle>
615
+ <CardDescription>Configure API access and rate limits</CardDescription>
616
+ </CardHeader>
617
+ <CardContent className="space-y-4">
618
+ <div className="space-y-2">
619
+ <Label>API Endpoint</Label>
620
+ <div className="flex items-center gap-2">
621
+ <Input
622
+ value="https://api.influence.io/v1"
623
+ readOnly
624
+ className="font-mono text-sm"
625
+ data-testid="input-api-endpoint"
626
+ />
627
+ <Button variant="outline" size="sm">Copy</Button>
628
+ </div>
629
+ </div>
630
+ <div className="grid gap-4 sm:grid-cols-2">
631
+ <div className="space-y-2">
632
+ <Label htmlFor="rate-limit">Rate Limit (requests/min)</Label>
633
+ <Input id="rate-limit" type="number" defaultValue="1000" data-testid="input-rate-limit" />
634
+ </div>
635
+ <div className="space-y-2">
636
+ <Label htmlFor="timeout">Request Timeout (ms)</Label>
637
+ <Input id="timeout" type="number" defaultValue="5000" data-testid="input-timeout" />
638
+ </div>
639
+ </div>
640
+ </CardContent>
641
+ </Card>
642
+
643
+ <div className="flex justify-end">
644
+ <Button onClick={handleSave} data-testid="button-save-settings">
645
+ <Save className="h-4 w-4 mr-2" />
646
+ Save Changes
647
+ </Button>
648
+ </div>
649
+ </div>
650
+ </div>
651
+ );
652
+ }