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,760 @@
1
+ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@moving-walls/design-system";
2
+ import { Button } from "@moving-walls/design-system";
3
+ import { Input } from "@moving-walls/design-system";
4
+ import { Label } from "@moving-walls/design-system";
5
+ import { Switch } from "@moving-walls/design-system";
6
+ import { Separator } from "@moving-walls/design-system";
7
+ import { Slider } from "@moving-walls/design-system";
8
+ import {
9
+ Select,
10
+ SelectContent,
11
+ SelectItem,
12
+ SelectTrigger,
13
+ SelectValue,
14
+ } from "@moving-walls/design-system";
15
+ import { Textarea } from "@moving-walls/design-system";
16
+ import { Settings as SettingsIcon, Bell, Shield, Globe, Palette, Save, Workflow, Languages, Package, ListFilter, Sparkles, Target, TrendingUp, Sliders } from "lucide-react";
17
+ import { usePageTitle } from "@/hooks/use-page-title";
18
+ import { useToast } from "@/hooks/use-toast";
19
+ import { useState } from "react";
20
+
21
+ export default function SettingsPage() {
22
+ usePageTitle("Settings");
23
+ const { toast } = useToast();
24
+
25
+ const [weights, setWeights] = useState({
26
+ measureFit: 15,
27
+ geoFit: 15,
28
+ availability: 15,
29
+ budgetFit: 10,
30
+ audienceFit: 15,
31
+ brandFit: 10,
32
+ qualityFit: 10,
33
+ timeFit: 10,
34
+ });
35
+
36
+ const handleSave = () => {
37
+ toast({
38
+ title: "Settings saved",
39
+ description: "Your settings have been updated successfully.",
40
+ });
41
+ };
42
+
43
+ const updateWeight = (key: keyof typeof weights, value: number[]) => {
44
+ setWeights(prev => ({ ...prev, [key]: value[0] }));
45
+ };
46
+
47
+ return (
48
+ <div className="h-[calc(100vh-72px)] w-full flex flex-col bg-mw-neutral-50 dark:bg-mw-neutral-900 overflow-hidden">
49
+ <div className="flex-shrink-0 px-6 py-4 border-b border-mw-neutral-200 bg-white dark:bg-mw-neutral-800">
50
+ <h1 className="text-xl font-semibold text-mw-neutral-900 dark:text-white">Settings</h1>
51
+ <p className="text-sm text-mw-neutral-500 dark:text-mw-neutral-400">Configure your ad server preferences</p>
52
+ </div>
53
+ <div className="flex-1 overflow-auto px-6 py-6">
54
+ <div className="grid gap-6 max-w-4xl">
55
+
56
+ <Card>
57
+ <CardHeader>
58
+ <CardTitle className="flex items-center gap-2">
59
+ <SettingsIcon className="h-5 w-5" />
60
+ General Settings
61
+ </CardTitle>
62
+ <CardDescription>Basic configuration for your ad server</CardDescription>
63
+ </CardHeader>
64
+ <CardContent className="pt-0 space-y-6">
65
+ <div className="grid gap-4 sm:grid-cols-2">
66
+ <div className="space-y-2">
67
+ <Label htmlFor="company-name">Company Name</Label>
68
+ <Input id="company-name" defaultValue="Influence Media" />
69
+ </div>
70
+ <div className="space-y-2">
71
+ <Label htmlFor="timezone">Timezone</Label>
72
+ <Select
73
+ defaultValue="utc"
74
+ options={[
75
+ { value: "utc-8", label: "UTC-8" },
76
+ { value: "utc+0", label: "UTC+0" },
77
+ { value: "utc+5:30", label: "UTC+5:30" },
78
+ { value: "utc+8", label: "UTC+8" },
79
+ { value: "utc+9", label: "UTC+9" },
80
+ ]}
81
+ >
82
+ <SelectTrigger>
83
+ <SelectValue placeholder="Select timezone" />
84
+ </SelectTrigger>
85
+ <SelectContent>
86
+ <SelectItem value="utc-8">UTC-8</SelectItem>
87
+ <SelectItem value="utc+0">UTC+0</SelectItem>
88
+ <SelectItem value="utc+5:30">UTC+5:30</SelectItem>
89
+ <SelectItem value="utc+8">UTC+8</SelectItem>
90
+ <SelectItem value="utc+9">UTC+9</SelectItem>
91
+ </SelectContent>
92
+ </Select>
93
+ </div>
94
+ </div>
95
+ <div className="grid gap-4 sm:grid-cols-2">
96
+ <div className="space-y-2">
97
+ <Label htmlFor="currency">Default Currency</Label>
98
+ <Select
99
+ defaultValue="usd"
100
+ options={[
101
+ { value: "usd", label: "USD" },
102
+ { value: "myr", label: "MYR" },
103
+ { value: "sgd", label: "SGD" },
104
+ { value: "thb", label: "THB" },
105
+ { value: "jpy", label: "JPY" },
106
+ ]}
107
+ >
108
+ <SelectTrigger>
109
+ <SelectValue placeholder="Select currency" />
110
+ </SelectTrigger>
111
+ <SelectContent>
112
+ <SelectItem value="usd">USD</SelectItem>
113
+ <SelectItem value="myr">MYR</SelectItem>
114
+ <SelectItem value="sgd">SGD</SelectItem>
115
+ <SelectItem value="thb">THB</SelectItem>
116
+ <SelectItem value="jpy">JPY</SelectItem>
117
+ </SelectContent>
118
+ </Select>
119
+ </div>
120
+ <div className="space-y-2">
121
+ <Label htmlFor="date-format">Date Format</Label>
122
+ <Select
123
+ defaultValue="mdy"
124
+ options={[
125
+ { value: "dmy", label: "DD/MM/YYYY" },
126
+ { value: "mdy", label: "MM/DD/YYYY" },
127
+ { value: "ymd", label: "YYYY-MM-DD" },
128
+ ]}
129
+ >
130
+ <SelectTrigger>
131
+ <SelectValue placeholder="Select format" />
132
+ </SelectTrigger>
133
+ <SelectContent>
134
+ <SelectItem value="dmy">DD/MM/YYYY</SelectItem>
135
+ <SelectItem value="mdy">MM/DD/YYYY</SelectItem>
136
+ <SelectItem value="ymd">YYYY-MM-DD</SelectItem>
137
+ </SelectContent>
138
+ </Select>
139
+ </div>
140
+ </div>
141
+ </CardContent>
142
+ </Card>
143
+
144
+ <Card>
145
+ <CardHeader>
146
+ <CardTitle className="flex items-center gap-2">
147
+ <Bell className="h-5 w-5" />
148
+ Notifications
149
+ </CardTitle>
150
+ <CardDescription>Configure alert and notification preferences</CardDescription>
151
+ </CardHeader>
152
+ <CardContent className="pt-0 space-y-4">
153
+ <div className="flex items-center justify-between">
154
+ <div className="space-y-0.5">
155
+ <Label>Deal Alerts</Label>
156
+ <p className="text-sm text-muted-foreground">
157
+ Get notified when deals reach budget thresholds
158
+ </p>
159
+ </div>
160
+ <Switch defaultChecked />
161
+ </div>
162
+ <Separator />
163
+ <div className="flex items-center justify-between">
164
+ <div className="space-y-0.5">
165
+ <Label>Screen Status Updates</Label>
166
+ <p className="text-sm text-muted-foreground">
167
+ Alert when screens go offline or require maintenance
168
+ </p>
169
+ </div>
170
+ <Switch defaultChecked />
171
+ </div>
172
+ <Separator />
173
+ <div className="flex items-center justify-between">
174
+ <div className="space-y-0.5">
175
+ <Label>Daily Performance Reports</Label>
176
+ <p className="text-sm text-muted-foreground">
177
+ Receive daily email summaries of deal performance
178
+ </p>
179
+ </div>
180
+ <Switch />
181
+ </div>
182
+ <Separator />
183
+ <div className="flex items-center justify-between">
184
+ <div className="space-y-0.5">
185
+ <Label>Integration Status</Label>
186
+ <p className="text-sm text-muted-foreground">
187
+ Notify when SSP/DSP integrations have connectivity issues
188
+ </p>
189
+ </div>
190
+ <Switch defaultChecked />
191
+ </div>
192
+ </CardContent>
193
+ </Card>
194
+
195
+ <Card>
196
+ <CardHeader>
197
+ <CardTitle className="flex items-center gap-2">
198
+ <Shield className="h-5 w-5" />
199
+ Traffic Control
200
+ </CardTitle>
201
+ <CardDescription>Default settings for traffic allocation and delivery</CardDescription>
202
+ </CardHeader>
203
+ <CardContent className="pt-0 space-y-6">
204
+ <div className="grid gap-4 sm:grid-cols-2">
205
+ <div className="space-y-2">
206
+ <Label htmlFor="default-allocation">Default Traffic Allocation</Label>
207
+ <Select
208
+ defaultValue="100"
209
+ options={[
210
+ { value: "25", label: "25%" },
211
+ { value: "50", label: "50%" },
212
+ { value: "75", label: "75%" },
213
+ { value: "100", label: "100%" },
214
+ ]}
215
+ >
216
+ <SelectTrigger>
217
+ <SelectValue placeholder="Select percentage" />
218
+ </SelectTrigger>
219
+ <SelectContent>
220
+ <SelectItem value="25">25%</SelectItem>
221
+ <SelectItem value="50">50%</SelectItem>
222
+ <SelectItem value="75">75%</SelectItem>
223
+ <SelectItem value="100">100%</SelectItem>
224
+ </SelectContent>
225
+ </Select>
226
+ </div>
227
+ <div className="space-y-2">
228
+ <Label htmlFor="delivery-pacing">Delivery Pacing</Label>
229
+ <Select
230
+ defaultValue="even"
231
+ options={[
232
+ { value: "even", label: "Even" },
233
+ { value: "asap", label: "ASAP" },
234
+ { value: "frontloaded", label: "Frontloaded" },
235
+ ]}
236
+ >
237
+ <SelectTrigger>
238
+ <SelectValue placeholder="Select pacing" />
239
+ </SelectTrigger>
240
+ <SelectContent>
241
+ <SelectItem value="even">Even (Spread evenly)</SelectItem>
242
+ <SelectItem value="asap">ASAP (As fast as possible)</SelectItem>
243
+ <SelectItem value="frontloaded">Frontloaded (Heavy at start)</SelectItem>
244
+ </SelectContent>
245
+ </Select>
246
+ </div>
247
+ </div>
248
+ <div className="flex items-center justify-between">
249
+ <div className="space-y-0.5">
250
+ <Label>Enable Programmatic Fallback</Label>
251
+ <p className="text-sm text-muted-foreground">
252
+ Fill unfilled inventory with programmatic demand
253
+ </p>
254
+ </div>
255
+ <Switch defaultChecked />
256
+ </div>
257
+ </CardContent>
258
+ </Card>
259
+
260
+ <Card>
261
+ <CardHeader>
262
+ <CardTitle className="flex items-center gap-2">
263
+ <Target className="h-5 w-5" />
264
+ Forecasting Defaults
265
+ </CardTitle>
266
+ <CardDescription>Configure default settings for line item forecasting</CardDescription>
267
+ </CardHeader>
268
+ <CardContent className="pt-0 space-y-6">
269
+ <div className="grid gap-4 sm:grid-cols-2">
270
+ <div className="space-y-2">
271
+ <Label htmlFor="forecast-goal-type">Default Goal Type</Label>
272
+ <Select
273
+ defaultValue="impressions"
274
+ options={[
275
+ { value: "impressions", label: "Impressions" },
276
+ { value: "reach", label: "Reach" },
277
+ { value: "sov", label: "Share of Voice" },
278
+ { value: "ad-plays", label: "Ad Plays" },
279
+ { value: "carbon", label: "Carbon Emission" },
280
+ ]}
281
+ >
282
+ <SelectTrigger>
283
+ <SelectValue placeholder="Select goal type" />
284
+ </SelectTrigger>
285
+ <SelectContent>
286
+ <SelectItem value="impressions">Impressions</SelectItem>
287
+ <SelectItem value="reach">Reach</SelectItem>
288
+ <SelectItem value="sov">Share of Voice</SelectItem>
289
+ <SelectItem value="ad-plays">Ad Plays</SelectItem>
290
+ <SelectItem value="carbon">Carbon Emission</SelectItem>
291
+ </SelectContent>
292
+ </Select>
293
+ </div>
294
+ <div className="space-y-2">
295
+ <Label htmlFor="forecast-confidence">Confidence Level</Label>
296
+ <Select
297
+ defaultValue="medium"
298
+ options={[
299
+ { value: "low", label: "Low 70%" },
300
+ { value: "medium", label: "Medium 85%" },
301
+ { value: "high", label: "High 95%" },
302
+ ]}
303
+ >
304
+ <SelectTrigger>
305
+ <SelectValue placeholder="Select confidence" />
306
+ </SelectTrigger>
307
+ <SelectContent>
308
+ <SelectItem value="low">Low (70%)</SelectItem>
309
+ <SelectItem value="medium">Medium (85%)</SelectItem>
310
+ <SelectItem value="high">High (95%)</SelectItem>
311
+ </SelectContent>
312
+ </Select>
313
+ </div>
314
+ </div>
315
+ <div className="grid gap-4 sm:grid-cols-2">
316
+ <div className="space-y-2">
317
+ <Label htmlFor="default-budget-buffer">Budget Buffer (%)</Label>
318
+ <Input id="default-budget-buffer" type="number" defaultValue="10" />
319
+ <p className="text-xs text-muted-foreground">
320
+ Extra budget allowance for forecast variance
321
+ </p>
322
+ </div>
323
+ <div className="space-y-2">
324
+ <Label htmlFor="forecast-refresh-interval">Forecast Refresh Interval</Label>
325
+ <Select
326
+ defaultValue="daily"
327
+ options={[
328
+ { value: "realtime", label: "Real-time" },
329
+ { value: "hourly", label: "Hourly" },
330
+ { value: "daily", label: "Daily" },
331
+ { value: "weekly", label: "Weekly" },
332
+ ]}
333
+ >
334
+ <SelectTrigger>
335
+ <SelectValue placeholder="Select interval" />
336
+ </SelectTrigger>
337
+ <SelectContent>
338
+ <SelectItem value="realtime">Real-time</SelectItem>
339
+ <SelectItem value="hourly">Hourly</SelectItem>
340
+ <SelectItem value="daily">Daily</SelectItem>
341
+ <SelectItem value="weekly">Weekly</SelectItem>
342
+ </SelectContent>
343
+ </Select>
344
+ </div>
345
+ </div>
346
+ <div className="flex items-center justify-between">
347
+ <div className="space-y-0.5">
348
+ <Label>Include Historical Performance</Label>
349
+ <p className="text-sm text-muted-foreground">
350
+ Use historical data to improve forecast accuracy
351
+ </p>
352
+ </div>
353
+ <Switch defaultChecked />
354
+ </div>
355
+ </CardContent>
356
+ </Card>
357
+
358
+ <Card>
359
+ <CardHeader>
360
+ <CardTitle className="flex items-center gap-2">
361
+ <TrendingUp className="h-5 w-5" />
362
+ Optimization Preferences
363
+ </CardTitle>
364
+ <CardDescription>Configure AI-powered optimization behavior</CardDescription>
365
+ </CardHeader>
366
+ <CardContent className="pt-0 space-y-6">
367
+ <div className="grid gap-4 sm:grid-cols-2">
368
+ <div className="space-y-2">
369
+ <Label htmlFor="optimization-mode">Optimization Mode</Label>
370
+ <Select
371
+ defaultValue="balanced"
372
+ options={[
373
+ { value: "aggressive", label: "Aggressive" },
374
+ { value: "balanced", label: "Balanced" },
375
+ { value: "conservative", label: "Conservative" },
376
+ ]}
377
+ >
378
+ <SelectTrigger>
379
+ <SelectValue placeholder="Select mode" />
380
+ </SelectTrigger>
381
+ <SelectContent>
382
+ <SelectItem value="aggressive">Aggressive (Maximize performance)</SelectItem>
383
+ <SelectItem value="balanced">Balanced (Performance + stability)</SelectItem>
384
+ <SelectItem value="conservative">Conservative (Minimal changes)</SelectItem>
385
+ </SelectContent>
386
+ </Select>
387
+ </div>
388
+ <div className="space-y-2">
389
+ <Label htmlFor="reoptimize-frequency">Re-optimization Frequency</Label>
390
+ <Select
391
+ defaultValue="weekly"
392
+ options={[
393
+ { value: "never", label: "Never" },
394
+ { value: "daily", label: "Daily" },
395
+ { value: "weekly", label: "Weekly" },
396
+ { value: "monthly", label: "Monthly" },
397
+ ]}
398
+ >
399
+ <SelectTrigger>
400
+ <SelectValue placeholder="Select frequency" />
401
+ </SelectTrigger>
402
+ <SelectContent>
403
+ <SelectItem value="never">Never (Manual only)</SelectItem>
404
+ <SelectItem value="daily">Daily</SelectItem>
405
+ <SelectItem value="weekly">Weekly</SelectItem>
406
+ <SelectItem value="monthly">Monthly</SelectItem>
407
+ </SelectContent>
408
+ </Select>
409
+ </div>
410
+ </div>
411
+ <div className="flex items-center justify-between">
412
+ <div className="space-y-0.5">
413
+ <Label>Auto-Optimize New Line Items</Label>
414
+ <p className="text-sm text-muted-foreground">
415
+ Automatically apply AI recommendations to new line items
416
+ </p>
417
+ </div>
418
+ <Switch defaultChecked />
419
+ </div>
420
+ <Separator />
421
+ <div className="flex items-center justify-between">
422
+ <div className="space-y-0.5">
423
+ <Label>Enable A/B Testing</Label>
424
+ <p className="text-sm text-muted-foreground">
425
+ Allow AI to run A/B tests on inventory selection
426
+ </p>
427
+ </div>
428
+ <Switch />
429
+ </div>
430
+ <Separator />
431
+ <div className="flex items-center justify-between">
432
+ <div className="space-y-0.5">
433
+ <Label>Show Optimization Insights</Label>
434
+ <p className="text-sm text-muted-foreground">
435
+ Display AI reasoning and recommendations in the UI
436
+ </p>
437
+ </div>
438
+ <Switch defaultChecked />
439
+ </div>
440
+ </CardContent>
441
+ </Card>
442
+
443
+ <Card>
444
+ <CardHeader>
445
+ <CardTitle className="flex items-center gap-2">
446
+ <Sliders className="h-5 w-5" />
447
+ Recommendation Weights
448
+ </CardTitle>
449
+ <CardDescription>Adjust the importance of each factor in AI recommendations</CardDescription>
450
+ </CardHeader>
451
+ <CardContent className="pt-0 space-y-4">
452
+ <p className="text-sm text-muted-foreground">
453
+ Configure how the 8-factor scoring system weights each component. Values should sum to 100%.
454
+ </p>
455
+ <div className="grid gap-6 sm:grid-cols-2">
456
+ <div className="space-y-3">
457
+ <div className="flex items-center justify-between">
458
+ <Label htmlFor="weight-measure-fit">Measure Fit</Label>
459
+ <span className="text-sm text-muted-foreground">{weights.measureFit}%</span>
460
+ </div>
461
+ <Slider value={[weights.measureFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('measureFit', v)} />
462
+ </div>
463
+ <div className="space-y-3">
464
+ <div className="flex items-center justify-between">
465
+ <Label htmlFor="weight-geo-fit">Geo Fit</Label>
466
+ <span className="text-sm text-muted-foreground">{weights.geoFit}%</span>
467
+ </div>
468
+ <Slider value={[weights.geoFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('geoFit', v)} />
469
+ </div>
470
+ <div className="space-y-3">
471
+ <div className="flex items-center justify-between">
472
+ <Label htmlFor="weight-availability">Availability</Label>
473
+ <span className="text-sm text-muted-foreground">{weights.availability}%</span>
474
+ </div>
475
+ <Slider value={[weights.availability]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('availability', v)} />
476
+ </div>
477
+ <div className="space-y-3">
478
+ <div className="flex items-center justify-between">
479
+ <Label htmlFor="weight-budget-fit">Budget Fit</Label>
480
+ <span className="text-sm text-muted-foreground">{weights.budgetFit}%</span>
481
+ </div>
482
+ <Slider value={[weights.budgetFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('budgetFit', v)} />
483
+ </div>
484
+ <div className="space-y-3">
485
+ <div className="flex items-center justify-between">
486
+ <Label htmlFor="weight-audience-fit">Audience Fit</Label>
487
+ <span className="text-sm text-muted-foreground">{weights.audienceFit}%</span>
488
+ </div>
489
+ <Slider value={[weights.audienceFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('audienceFit', v)} />
490
+ </div>
491
+ <div className="space-y-3">
492
+ <div className="flex items-center justify-between">
493
+ <Label htmlFor="weight-brand-fit">Brand Fit</Label>
494
+ <span className="text-sm text-muted-foreground">{weights.brandFit}%</span>
495
+ </div>
496
+ <Slider value={[weights.brandFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('brandFit', v)} />
497
+ </div>
498
+ <div className="space-y-3">
499
+ <div className="flex items-center justify-between">
500
+ <Label htmlFor="weight-quality-fit">Quality Fit</Label>
501
+ <span className="text-sm text-muted-foreground">{weights.qualityFit}%</span>
502
+ </div>
503
+ <Slider value={[weights.qualityFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('qualityFit', v)} />
504
+ </div>
505
+ <div className="space-y-3">
506
+ <div className="flex items-center justify-between">
507
+ <Label htmlFor="weight-time-fit">Time Fit</Label>
508
+ <span className="text-sm text-muted-foreground">{weights.timeFit}%</span>
509
+ </div>
510
+ <Slider value={[weights.timeFit]} min={0} max={30} step={1} onValueChange={(v) => updateWeight('timeFit', v)} />
511
+ </div>
512
+ </div>
513
+ <Button
514
+ variant="outline"
515
+ size="sm"
516
+ className="mt-2"
517
+ onClick={() => setWeights({
518
+ measureFit: 15, geoFit: 15, availability: 15, budgetFit: 10,
519
+ audienceFit: 15, brandFit: 10, qualityFit: 10, timeFit: 10,
520
+ })}
521
+ >
522
+ Reset to Defaults
523
+ </Button>
524
+ </CardContent>
525
+ </Card>
526
+
527
+ <Card>
528
+ <CardHeader>
529
+ <CardTitle className="flex items-center gap-2">
530
+ <Workflow className="h-5 w-5" />
531
+ Workflow Settings
532
+ </CardTitle>
533
+ <CardDescription>Configure approval workflows and automation</CardDescription>
534
+ </CardHeader>
535
+ <CardContent className="pt-0 space-y-4">
536
+ <div className="flex items-center justify-between">
537
+ <div className="space-y-0.5">
538
+ <Label>Require Creative Approval</Label>
539
+ <p className="text-sm text-muted-foreground">
540
+ All creatives must be approved before going live
541
+ </p>
542
+ </div>
543
+ <Switch defaultChecked />
544
+ </div>
545
+ <Separator />
546
+ <div className="flex items-center justify-between">
547
+ <div className="space-y-0.5">
548
+ <Label>Two-Tier Creative Approval</Label>
549
+ <p className="text-sm text-muted-foreground">
550
+ Enable Tier 2 (Media Owner) approval after Tier 1 (Content Hub)
551
+ </p>
552
+ </div>
553
+ <Switch defaultChecked />
554
+ </div>
555
+ <Separator />
556
+ <div className="flex items-center justify-between">
557
+ <div className="space-y-0.5">
558
+ <Label>Auto-Accept Deals</Label>
559
+ <p className="text-sm text-muted-foreground">
560
+ Automatically accept deals from trusted partners
561
+ </p>
562
+ </div>
563
+ <Switch />
564
+ </div>
565
+ <Separator />
566
+ <div className="flex items-center justify-between">
567
+ <div className="space-y-0.5">
568
+ <Label>Deal Locking</Label>
569
+ <p className="text-sm text-muted-foreground">
570
+ Lock deals after acceptance to prevent modifications
571
+ </p>
572
+ </div>
573
+ <Switch defaultChecked />
574
+ </div>
575
+ </CardContent>
576
+ </Card>
577
+
578
+ <Card>
579
+ <CardHeader>
580
+ <CardTitle className="flex items-center gap-2">
581
+ <Languages className="h-5 w-5" />
582
+ Terminology
583
+ </CardTitle>
584
+ <CardDescription>Customize labels and terminology used throughout the platform</CardDescription>
585
+ </CardHeader>
586
+ <CardContent className="pt-0 space-y-4">
587
+ <div className="grid gap-4 sm:grid-cols-2">
588
+ <div className="space-y-2">
589
+ <Label htmlFor="term-deal">Deal</Label>
590
+ <Input id="term-deal" defaultValue="Deal" />
591
+ </div>
592
+ <div className="space-y-2">
593
+ <Label htmlFor="term-line-item">Line Item</Label>
594
+ <Input id="term-line-item" defaultValue="Line Item" />
595
+ </div>
596
+ </div>
597
+ <div className="grid gap-4 sm:grid-cols-2">
598
+ <div className="space-y-2">
599
+ <Label htmlFor="term-creative">Creative</Label>
600
+ <Input id="term-creative" defaultValue="Creative" />
601
+ </div>
602
+ <div className="space-y-2">
603
+ <Label htmlFor="term-inventory">Inventory</Label>
604
+ <Input id="term-inventory" defaultValue="Inventory" />
605
+ </div>
606
+ </div>
607
+ <div className="grid gap-4 sm:grid-cols-2">
608
+ <div className="space-y-2">
609
+ <Label htmlFor="term-advertiser">Advertiser</Label>
610
+ <Input id="term-advertiser" defaultValue="Advertiser" />
611
+ </div>
612
+ <div className="space-y-2">
613
+ <Label htmlFor="term-campaign">Campaign</Label>
614
+ <Input id="term-campaign" defaultValue="Campaign" />
615
+ </div>
616
+ </div>
617
+ </CardContent>
618
+ </Card>
619
+
620
+ <Card>
621
+ <CardHeader>
622
+ <CardTitle className="flex items-center gap-2">
623
+ <Palette className="h-5 w-5" />
624
+ Themes & Branding
625
+ </CardTitle>
626
+ <CardDescription>Customize the look and feel of your platform</CardDescription>
627
+ </CardHeader>
628
+ <CardContent className="pt-0 space-y-4">
629
+ <div className="grid gap-4 sm:grid-cols-2">
630
+ <div className="space-y-2">
631
+ <Label htmlFor="theme-mode">Theme Mode</Label>
632
+ <Select
633
+ defaultValue="light"
634
+ options={[
635
+ { value: "light", label: "Light" },
636
+ { value: "dark", label: "Dark" },
637
+ { value: "system", label: "System" },
638
+ ]}
639
+ >
640
+ <SelectTrigger>
641
+ <SelectValue placeholder="Select theme" />
642
+ </SelectTrigger>
643
+ <SelectContent>
644
+ <SelectItem value="light">Light</SelectItem>
645
+ <SelectItem value="dark">Dark</SelectItem>
646
+ <SelectItem value="system">System</SelectItem>
647
+ </SelectContent>
648
+ </Select>
649
+ </div>
650
+ <div className="space-y-2">
651
+ <Label htmlFor="primary-color">Primary Color</Label>
652
+ <div className="flex gap-2">
653
+ <Input id="primary-color" type="color" defaultValue="#3B82F6" className="w-14 h-9 p-1" />
654
+ <Input defaultValue="#3B82F6" className="flex-1 font-mono" readOnly />
655
+ </div>
656
+ </div>
657
+ </div>
658
+ <div className="space-y-2">
659
+ <Label htmlFor="logo-url">Logo URL</Label>
660
+ <Input id="logo-url" placeholder="https://example.com/logo.png" />
661
+ </div>
662
+ <div className="flex items-center justify-between">
663
+ <div className="space-y-0.5">
664
+ <Label>Compact Mode</Label>
665
+ <p className="text-sm text-muted-foreground">
666
+ Use a more compact UI with smaller spacing
667
+ </p>
668
+ </div>
669
+ <Switch />
670
+ </div>
671
+ </CardContent>
672
+ </Card>
673
+
674
+ <Card>
675
+ <CardHeader>
676
+ <CardTitle className="flex items-center gap-2">
677
+ <ListFilter className="h-5 w-5" />
678
+ Inventory Whitelisting
679
+ </CardTitle>
680
+ <CardDescription>Control which inventory is available for deals</CardDescription>
681
+ </CardHeader>
682
+ <CardContent className="pt-0 space-y-4">
683
+ <div className="flex items-center justify-between">
684
+ <div className="space-y-0.5">
685
+ <Label>Enable Inventory Whitelisting</Label>
686
+ <p className="text-sm text-muted-foreground">
687
+ Only show whitelisted inventory to advertisers and agencies
688
+ </p>
689
+ </div>
690
+ <Switch />
691
+ </div>
692
+ <Separator />
693
+ <div className="space-y-2">
694
+ <Label htmlFor="whitelist-ids">Whitelisted Inventory IDs</Label>
695
+ <Textarea
696
+ id="whitelist-ids"
697
+ placeholder="Enter inventory IDs separated by commas or new lines"
698
+ className="min-h-[100px] font-mono text-sm"
699
+ />
700
+ <p className="text-xs text-muted-foreground">
701
+ Leave empty to allow all inventory. Enter specific IDs to restrict availability.
702
+ </p>
703
+ </div>
704
+ <div className="flex items-center justify-between">
705
+ <div className="space-y-0.5">
706
+ <Label>Exclude Adult Content Venues</Label>
707
+ <p className="text-sm text-muted-foreground">
708
+ Automatically exclude venues with adult content classification
709
+ </p>
710
+ </div>
711
+ <Switch defaultChecked />
712
+ </div>
713
+ </CardContent>
714
+ </Card>
715
+
716
+ <Card>
717
+ <CardHeader>
718
+ <CardTitle className="flex items-center gap-2">
719
+ <Globe className="h-5 w-5" />
720
+ API Settings
721
+ </CardTitle>
722
+ <CardDescription>Configure API access and rate limits</CardDescription>
723
+ </CardHeader>
724
+ <CardContent className="pt-0 space-y-4">
725
+ <div className="space-y-2">
726
+ <Label>API Endpoint</Label>
727
+ <div className="flex items-center gap-2">
728
+ <Input
729
+ value="https://api.influence.io/v1"
730
+ readOnly
731
+ className="font-mono text-sm"
732
+ />
733
+ <Button variant="outline" size="sm">Copy</Button>
734
+ </div>
735
+ </div>
736
+ <div className="grid gap-4 sm:grid-cols-2">
737
+ <div className="space-y-2">
738
+ <Label htmlFor="rate-limit">Rate Limit (requests/min)</Label>
739
+ <Input id="rate-limit" type="number" defaultValue="1000" />
740
+ </div>
741
+ <div className="space-y-2">
742
+ <Label htmlFor="timeout">Request Timeout (ms)</Label>
743
+ <Input id="timeout" type="number" defaultValue="5000" />
744
+ </div>
745
+ </div>
746
+ </CardContent>
747
+ </Card>
748
+
749
+ <div className="flex justify-end pb-6">
750
+ <Button onClick={handleSave}>
751
+ <Save className="h-4 w-4 mr-2" />
752
+ Save Changes
753
+ </Button>
754
+ </div>
755
+
756
+ </div>
757
+ </div>
758
+ </div>
759
+ );
760
+ }