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.
- package/.ci/staging.yml +191 -0
- package/.dockerignore +117 -0
- package/.env +40 -0
- package/.env.staging +38 -0
- package/.gitlab-ci.yml +16 -0
- package/DEMO_STATUS.md +579 -0
- package/Dockerfile +61 -0
- package/Influence-MW-AdServer-12-02-2026/client/index.html +17 -0
- package/Influence-MW-AdServer-12-02-2026/client/public/favicon.png +0 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/App.tsx +91 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/advanced-map-drawer.tsx +1131 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ai-recommendation-panel.tsx +379 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/app-sidebar.tsx +183 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/auto-optimize-button.tsx +184 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/availability-drawer.tsx +385 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/brand-insights-panel.tsx +87 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/create-agency-drawer.tsx +198 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/create-brand-drawer.tsx +275 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/creative-assignment.tsx +526 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table-toolbar.tsx +148 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table.tsx +158 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/filter-drawer.tsx +356 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/form-insights-panel.tsx +82 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/geography-selector.tsx +699 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/header-user-menu.tsx +178 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/history-drawer.tsx +313 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-availability-section.tsx +176 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-format-drawer.tsx +173 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-selector.tsx +401 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/manual-inventory-drawer.tsx +368 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/mapbox-map.tsx +368 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/market-insights-panel.tsx +202 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/media-owner-drawer.tsx +217 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/metric-card.tsx +58 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/page-header.tsx +27 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/player-status-indicator.tsx +137 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/poi-targeting-drawer.tsx +298 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/recommendation-score-badge.tsx +102 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/recommended-inventories-panel.tsx +248 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/searchable-combobox.tsx +134 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/signal-visualizations.tsx +407 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/status-badge.tsx +35 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-provider.tsx +73 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-toggle.tsx +37 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/traffic-slider.tsx +75 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/accordion.tsx +56 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert-dialog.tsx +139 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert.tsx +59 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/aspect-ratio.tsx +5 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/avatar.tsx +51 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/badge.tsx +38 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/breadcrumb.tsx +115 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/button.tsx +62 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/calendar.tsx +68 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/card.tsx +85 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/carousel.tsx +260 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/chart.tsx +365 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/checkbox.tsx +28 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/collapsible.tsx +11 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/command.tsx +151 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/context-menu.tsx +198 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dialog.tsx +122 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/drawer.tsx +118 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dropdown-menu.tsx +198 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/form.tsx +178 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/hover-card.tsx +29 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input-otp.tsx +69 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input.tsx +23 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/label.tsx +24 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/menubar.tsx +256 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/navigation-menu.tsx +128 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/pagination.tsx +117 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/popover.tsx +29 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/progress.tsx +28 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/radio-group.tsx +42 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/resizable.tsx +45 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/scroll-area.tsx +46 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/select.tsx +160 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/separator.tsx +29 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sheet.tsx +140 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sidebar.tsx +727 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/skeleton.tsx +15 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/slider.tsx +26 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/switch.tsx +27 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/table.tsx +117 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tabs.tsx +53 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/textarea.tsx +22 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toast.tsx +127 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toaster.tsx +33 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle-group.tsx +61 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle.tsx +43 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tooltip.tsx +30 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/vendor-stores-modal.tsx +336 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-drawer.tsx +359 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-selector.tsx +436 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-mobile.tsx +19 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-toast.ts +191 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/index.css +244 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/lib/queryClient.ts +57 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/lib/utils.ts +39 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/lib/venue-taxonomy.ts +532 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/main.tsx +5 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/assign-creative.tsx +781 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/content-hub.tsx +995 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/custom-pois.tsx +431 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/dashboard.tsx +620 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-detail.tsx +1062 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-form.tsx +1570 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/deals.tsx +716 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/edit-creative-assignment.tsx +1051 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/geotargeting.tsx +675 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/integrations.tsx +425 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-creatives.tsx +622 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-form.tsx +3132 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-items.tsx +530 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/not-found.tsx +21 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play-upload.tsx +479 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play.tsx +880 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/reports.tsx +235 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/settings.tsx +652 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/signal-form.tsx +1117 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/signals.tsx +366 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/tags.tsx +332 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/pages/venues.tsx +381 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/types/mapbox-gl-draw.d.ts +37 -0
- package/Influence-MW-AdServer-12-02-2026/client/src/types/react-simple-maps.d.ts +57 -0
- package/Influence-MW-AdServer-12-02-2026/components.json +20 -0
- package/Influence-MW-AdServer-12-02-2026/docs/PRD.md +3373 -0
- package/Influence-MW-AdServer-12-02-2026/docs/influence-feature-mapping.csv +498 -0
- package/Influence-MW-AdServer-12-02-2026/drizzle.config.ts +14 -0
- package/Influence-MW-AdServer-12-02-2026/package-lock.json +9672 -0
- package/Influence-MW-AdServer-12-02-2026/package.json +118 -0
- package/Influence-MW-AdServer-12-02-2026/postcss.config.js +6 -0
- package/Influence-MW-AdServer-12-02-2026/replit.md +91 -0
- package/Influence-MW-AdServer-12-02-2026/script/build.ts +67 -0
- package/Influence-MW-AdServer-12-02-2026/scripts/create-miro-diagrams.cjs +318 -0
- package/Influence-MW-AdServer-12-02-2026/scripts/create-remaining-diagrams.cjs +270 -0
- package/Influence-MW-AdServer-12-02-2026/server/index.ts +103 -0
- package/Influence-MW-AdServer-12-02-2026/server/recommendation-service.ts +319 -0
- package/Influence-MW-AdServer-12-02-2026/server/routes.ts +1890 -0
- package/Influence-MW-AdServer-12-02-2026/server/static.ts +19 -0
- package/Influence-MW-AdServer-12-02-2026/server/storage.ts +2058 -0
- package/Influence-MW-AdServer-12-02-2026/server/vite.ts +58 -0
- package/Influence-MW-AdServer-12-02-2026/shared/schema.ts +1595 -0
- package/Influence-MW-AdServer-12-02-2026/tailwind.config.ts +107 -0
- package/Influence-MW-AdServer-12-02-2026/tsconfig.json +23 -0
- package/Influence-MW-AdServer-12-02-2026/vite.config.ts +40 -0
- package/LINE_ITEM_BUDGET_FIELD_MAPPING.md +178 -0
- package/PCM/.env.example +92 -0
- package/PCM/README.md +558 -0
- package/PCM/docs/TEST_CASES.md +422 -0
- package/PCM/index.js +106 -0
- package/PCM/package-lock.json +3282 -0
- package/PCM/package.json +32 -0
- package/PCM/replit.md +64 -0
- package/PCM/schema.sql +495 -0
- package/PCM/scripts/export-schema.js +183 -0
- package/PCM/scripts/seed-comprehensive.js +631 -0
- package/PCM/scripts/seed-production.js +477 -0
- package/PCM/src/config/db.js +56 -0
- package/PCM/src/config/swagger.js +5975 -0
- package/PCM/src/dto/EmailRequestDTO.js +166 -0
- package/PCM/src/middleware/errorHandler.js +52 -0
- package/PCM/src/middleware/logger.js +26 -0
- package/PCM/src/migrations/001_add_campaign_mode_fields.sql +36 -0
- package/PCM/src/migrations/002_create_deal_id_counters.sql +22 -0
- package/PCM/src/migrations/003_update_publishers_column.sql +15 -0
- package/PCM/src/migrations/004_add_direct_dealtype_and_advertiser.sql +5 -0
- package/PCM/src/migrations/005_add_programmatic_fields_and_update_enums.sql +31 -0
- package/PCM/src/migrations/006_add_line_item_programmatic_fields.sql +12 -0
- package/PCM/src/migrations/007_add_line_item_direct_fields.sql +15 -0
- package/PCM/src/migrations/008_add_inventory_fields.sql +45 -0
- package/PCM/src/migrations/009_move_inventory_fields_to_metadata.sql +32 -0
- package/PCM/src/migrations/010_add_draft_status_and_line_items_count.sql +23 -0
- package/PCM/src/migrations/011_add_planning_field.sql +21 -0
- package/PCM/src/migrations/012_fix_inventory_composite_pk.sql +17 -0
- package/PCM/src/migrations/013_make_external_id_optional.sql +3 -0
- package/PCM/src/migrations/014_create_change_history.sql +38 -0
- package/PCM/src/migrations/016_create_publisher_insertion_orders.sql +33 -0
- package/PCM/src/migrations/017_fix_line_item_id_fk_reference.sql +86 -0
- package/PCM/src/migrations/018_create_approval_tables.sql +44 -0
- package/PCM/src/migrations/019_add_encrypted_token_column.sql +2 -0
- package/PCM/src/migrations/020_add_rejection_reason_to_deals.sql +10 -0
- package/PCM/src/migrations/021_add_publisher_external_id_to_inventories.sql +12 -0
- package/PCM/src/migrations/022_add_line_item_extended_fields.sql +24 -0
- package/PCM/src/migrations/023_add_base_price_fields.sql +8 -0
- package/PCM/src/migrations/run-migrations.js +46 -0
- package/PCM/src/models/ApprovalOTP.js +51 -0
- package/PCM/src/models/ApprovalToken.js +79 -0
- package/PCM/src/models/ChangeHistory.js +107 -0
- package/PCM/src/models/Deal.js +186 -0
- package/PCM/src/models/DealIdCounter.js +28 -0
- package/PCM/src/models/LineItem.js +227 -0
- package/PCM/src/models/LineItemCreative.js +89 -0
- package/PCM/src/models/LineItemInventory.js +115 -0
- package/PCM/src/models/PublisherInsertionOrder.js +93 -0
- package/PCM/src/models/TransactionHistory.js +34 -0
- package/PCM/src/models/associations.js +81 -0
- package/PCM/src/routes/approval.js +321 -0
- package/PCM/src/routes/creatives.js +437 -0
- package/PCM/src/routes/deals.js +1638 -0
- package/PCM/src/routes/digitalSignage.js +242 -0
- package/PCM/src/routes/insertionOrders.js +380 -0
- package/PCM/src/routes/lineItems.js +926 -0
- package/PCM/src/routes/system.js +384 -0
- package/PCM/src/services/ApprovalService.js +885 -0
- package/PCM/src/services/CampaignImportConverter.js +631 -0
- package/PCM/src/services/CampaignModeService.js +273 -0
- package/PCM/src/services/CampaignStatusService.js +395 -0
- package/PCM/src/services/ChangeHistoryService.js +316 -0
- package/PCM/src/services/DealIdService.js +94 -0
- package/PCM/src/services/DealResponseFormatter.js +90 -0
- package/PCM/src/services/EmailNotificationService.js +315 -0
- package/PCM/src/services/LineItemResponseFormatter.js +122 -0
- package/PCM/src/services/LineItemStatusService.js +380 -0
- package/PCM/src/tests/comprehensiveTestRunner.js +360 -0
- package/PCM/src/tests/comprehensiveTests.js +1277 -0
- package/PCM/src/tests/dealTypeUnitTests.js +1058 -0
- package/PCM/src/tests/testRunner.js +248 -0
- package/PCM/src/utils/caseConverter.js +92 -0
- package/PCM/src/utils/dealCalculations.js +206 -0
- package/PCM/src/utils/lineItemPayloadNormalizer.js +41 -0
- package/PCM/src/utils/payloadNormalizer.js +34 -0
- package/PCM/src/utils/sourceNormalizer.js +56 -0
- package/PCM/src/validators/creativeValidator.js +27 -0
- package/PCM/src/validators/dealValidator.js +203 -0
- package/PCM/src/validators/lineItemValidator.js +489 -0
- package/PCM/tests/approval-flows.test.js +238 -0
- package/PCM/tests/approval-workflow.test.js +291 -0
- package/PCM/tests/campaign-import-converter.test.js +543 -0
- package/PCM/tests/campaign-import-e2e.test.js +520 -0
- package/PCM/tests/campaign-status.test.js +539 -0
- package/PCM/tests/direct-publisher-split-reimport.test.js +460 -0
- package/PCM/tests/e2e/digital-signage.test.js +145 -0
- package/PCM/tests/e2e/search-filter-pagination.test.js +399 -0
- package/PCM/tests/e2e-comprehensive.test.js +3446 -0
- package/PCM/tests/edge-cases.test.js +340 -0
- package/PCM/tests/line-item-status.test.js +340 -0
- package/PCM/tests/seller-account-external-ids.test.js +877 -0
- package/PCM/tests/source-validation.test.js +324 -0
- package/PRD.md +3373 -0
- package/README.md +186 -0
- package/client/index.html +35 -0
- package/client/public/DEMO_STATUS.md +579 -0
- package/client/public/img/MW-logo-trans_1754045676555.png +0 -0
- package/client/public/locales/ar/approval.json +144 -0
- package/client/public/locales/ar/buyer.json +61 -0
- package/client/public/locales/ar/campaigns.json +1 -0
- package/client/public/locales/ar/common.json +218 -0
- package/client/public/locales/ar/contentHub.json +266 -0
- package/client/public/locales/ar/creatives.json +79 -0
- package/client/public/locales/ar/dashboard.json +57 -0
- package/client/public/locales/ar/deals.json +886 -0
- package/client/public/locales/ar/dsp.json +131 -0
- package/client/public/locales/ar/inventory.json +201 -0
- package/client/public/locales/ar/lineItems.json +553 -0
- package/client/public/locales/ar/navigation.json +48 -0
- package/client/public/locales/ar/wizard.json +1 -0
- package/client/public/locales/en/approval.json +144 -0
- package/client/public/locales/en/buyer.json +65 -0
- package/client/public/locales/en/campaigns.json +1 -0
- package/client/public/locales/en/common.json +218 -0
- package/client/public/locales/en/contentHub.json +266 -0
- package/client/public/locales/en/creatives.json +79 -0
- package/client/public/locales/en/dashboard.json +57 -0
- package/client/public/locales/en/deals.json +886 -0
- package/client/public/locales/en/dsp.json +131 -0
- package/client/public/locales/en/inventory.json +201 -0
- package/client/public/locales/en/lineItems.json +659 -0
- package/client/public/locales/en/navigation.json +48 -0
- package/client/public/locales/en/wizard.json +1 -0
- package/client/public/locales/ja/approval.json +144 -0
- package/client/public/locales/ja/buyer.json +61 -0
- package/client/public/locales/ja/campaigns.json +1 -0
- package/client/public/locales/ja/common.json +218 -0
- package/client/public/locales/ja/contentHub.json +266 -0
- package/client/public/locales/ja/creatives.json +79 -0
- package/client/public/locales/ja/dashboard.json +57 -0
- package/client/public/locales/ja/deals.json +886 -0
- package/client/public/locales/ja/dsp.json +131 -0
- package/client/public/locales/ja/inventory.json +201 -0
- package/client/public/locales/ja/lineItems.json +553 -0
- package/client/public/locales/ja/navigation.json +48 -0
- package/client/public/locales/ja/wizard.json +1 -0
- package/client/public/locales/zh/approval.json +144 -0
- package/client/public/locales/zh/buyer.json +61 -0
- package/client/public/locales/zh/campaigns.json +1 -0
- package/client/public/locales/zh/common.json +218 -0
- package/client/public/locales/zh/contentHub.json +266 -0
- package/client/public/locales/zh/creatives.json +79 -0
- package/client/public/locales/zh/dashboard.json +57 -0
- package/client/public/locales/zh/deals.json +886 -0
- package/client/public/locales/zh/dsp.json +131 -0
- package/client/public/locales/zh/inventory.json +201 -0
- package/client/public/locales/zh/lineItems.json +553 -0
- package/client/public/locales/zh/navigation.json +48 -0
- package/client/public/locales/zh/wizard.json +1 -0
- package/client/public/manifest.json +36 -0
- package/client/src/App.tsx +464 -0
- package/client/src/components/app-sidebar.tsx +312 -0
- package/client/src/components/approval/approval-decision-form.test.tsx +294 -0
- package/client/src/components/approval/approval-decision-form.tsx +326 -0
- package/client/src/components/approval/approval-sheet.tsx +631 -0
- package/client/src/components/approval/line-item-details-sheet.tsx +371 -0
- package/client/src/components/approval/otp-verification.test.tsx +337 -0
- package/client/src/components/approval/otp-verification.tsx +180 -0
- package/client/src/components/content-hub/bulk-transcode-dialog.tsx +379 -0
- package/client/src/components/content-hub/content-hub-manager-v2.tsx +574 -0
- package/client/src/components/content-hub/content-hub-manager.tsx +330 -0
- package/client/src/components/content-hub/creative-card.tsx +456 -0
- package/client/src/components/content-hub/creative-detail-sheet.tsx +685 -0
- package/client/src/components/content-hub/creative-filters.tsx +457 -0
- package/client/src/components/content-hub/creative-grid.tsx +329 -0
- package/client/src/components/content-hub/creative-selector.tsx +415 -0
- package/client/src/components/content-hub/creative-upload.tsx +547 -0
- package/client/src/components/content-hub/folder-dialogs.tsx +445 -0
- package/client/src/components/content-hub/folder-list.tsx +280 -0
- package/client/src/components/content-hub/review-dialogs.tsx +268 -0
- package/client/src/components/content-hub/transcode-dialog.tsx +226 -0
- package/client/src/components/creative-library/creative-details-view.tsx +446 -0
- package/client/src/components/creative-library/creative-filters-panel.tsx +203 -0
- package/client/src/components/creative-library/creative-list.tsx +360 -0
- package/client/src/components/creative-library/creative-status-badge.tsx +71 -0
- package/client/src/components/creative-library/folder-card.tsx +78 -0
- package/client/src/components/creative-library/index.ts +27 -0
- package/client/src/components/creative-library/new-creative-card.tsx +211 -0
- package/client/src/components/creative-library/upload-creative-dialog.tsx +261 -0
- package/client/src/components/dashboard-overview.tsx +109 -0
- package/client/src/components/deals/approval-history-panel.test.tsx +240 -0
- package/client/src/components/deals/approval-history-panel.tsx +156 -0
- package/client/src/components/deals/deal-status-badge.tsx +92 -0
- package/client/src/components/deals/import-from-planner-dialog.tsx +399 -0
- package/client/src/components/deals/market-insights-panel.tsx +237 -0
- package/client/src/components/deals/reopen-deal-sheet.tsx +191 -0
- package/client/src/components/deals/request-approval-sheet.test.tsx +323 -0
- package/client/src/components/deals/request-approval-sheet.tsx +136 -0
- package/client/src/components/deals/resend-approval-sheet.tsx +201 -0
- package/client/src/components/direct-campaigns/campaign-card.tsx +283 -0
- package/client/src/components/direct-campaigns/deal-filter-panel.tsx +325 -0
- package/client/src/components/inventory/advanced-filters-panel.tsx +273 -0
- package/client/src/components/inventory/csv-upload-modal.tsx +639 -0
- package/client/src/components/inventory/inventory-availability-view.tsx +486 -0
- package/client/src/components/inventory/inventory-details-sheet.tsx +376 -0
- package/client/src/components/inventory/inventory-map-view.tsx +596 -0
- package/client/src/components/inventory/inventory-settings-menu.tsx +52 -0
- package/client/src/components/language-switcher.tsx +53 -0
- package/client/src/components/line-items/campaign-forecast-panel.tsx +138 -0
- package/client/src/components/line-items/form-insights.tsx +89 -0
- package/client/src/components/line-items/geofencing/LocationCsvUploadDrawer.tsx +100 -0
- package/client/src/components/line-items/geofencing/POIDropdown.tsx +379 -0
- package/client/src/components/line-items/geofencing/SelectedLocationsSidebar.tsx +436 -0
- package/client/src/components/line-items/geofencing/ViewFileLocationDrawer.tsx +199 -0
- package/client/src/components/line-items/geofencing/components/ExistingFilesTab.tsx +268 -0
- package/client/src/components/line-items/geofencing/components/TemplateDownloadSection.tsx +59 -0
- package/client/src/components/line-items/geofencing/components/UploadTab.tsx +215 -0
- package/client/src/components/line-items/geofencing-map.tsx +1270 -0
- package/client/src/components/line-items/inventory-availability-section.tsx +178 -0
- package/client/src/components/line-items/line-item-schedule-manager.tsx +313 -0
- package/client/src/components/line-items/manual-inventory-drawer.tsx +346 -0
- package/client/src/components/line-items/planner-inventory-card.tsx +495 -0
- package/client/src/components/line-items/planner-schedule-grid.tsx +495 -0
- package/client/src/components/line-items/schedule-rule-editor.tsx +649 -0
- package/client/src/components/line-items/schedule-rule-types.ts +122 -0
- package/client/src/components/line-items/steps/creatives-step.tsx +681 -0
- package/client/src/components/line-items/steps/inventory-schedule-step.tsx +1596 -0
- package/client/src/components/line-items/steps/inventory-step.tsx +1533 -0
- package/client/src/components/line-items/steps/line-item-details-step.tsx +916 -0
- package/client/src/components/line-items/steps/schedule-step.tsx +273 -0
- package/client/src/components/line-items/steps/summary-step.tsx +680 -0
- package/client/src/components/line-items/steps/targeting-step.tsx +1708 -0
- package/client/src/components/product-switcher.tsx +105 -0
- package/client/src/components/protected-route.tsx +49 -0
- package/client/src/components/skip-link.tsx +22 -0
- package/client/src/components/stat-card.tsx +53 -0
- package/client/src/components/status-badge.tsx +96 -0
- package/client/src/components/ui/hierarchical-venue-selector.tsx +389 -0
- package/client/src/components/ui/toaster.tsx +111 -0
- package/client/src/contexts/auth-context.tsx +181 -0
- package/client/src/contexts/sidebar-state.tsx +50 -0
- package/client/src/contexts/theme-context.tsx +66 -0
- package/client/src/data/campaign-data.json +107 -0
- package/client/src/data/countries.json +22 -0
- package/client/src/hooks/use-approval.ts +366 -0
- package/client/src/hooks/use-keyboard-shortcuts.ts +74 -0
- package/client/src/hooks/use-media-query.ts +46 -0
- package/client/src/hooks/use-mobile.tsx +19 -0
- package/client/src/hooks/use-page-title.ts +21 -0
- package/client/src/hooks/use-toast.ts +195 -0
- package/client/src/index.css +694 -0
- package/client/src/lib/__tests__/accessibility.test.ts +104 -0
- package/client/src/lib/__tests__/date-utils.test.ts +199 -0
- package/client/src/lib/__tests__/dsp-buyer-api.test.ts +127 -0
- package/client/src/lib/__tests__/dsp-buyer-integration.test.ts +247 -0
- package/client/src/lib/__tests__/storage-utils.test.ts +167 -0
- package/client/src/lib/__tests__/utils.test.ts +57 -0
- package/client/src/lib/accessibility.ts +141 -0
- package/client/src/lib/api-config.ts +9 -0
- package/client/src/lib/auth-service.ts +209 -0
- package/client/src/lib/campaign-creative-api.ts +82 -0
- package/client/src/lib/company-api.ts +61 -0
- package/client/src/lib/content-hub-api.ts +407 -0
- package/client/src/lib/creative-mapper.ts +61 -0
- package/client/src/lib/date-utils.ts +119 -0
- package/client/src/lib/deal-helpers.ts +220 -0
- package/client/src/lib/dsp-buyer-api.ts +196 -0
- package/client/src/lib/geo-import-api.ts +151 -0
- package/client/src/lib/google-poi-api.ts +305 -0
- package/client/src/lib/i18n/__tests__/formatting.test.ts +202 -0
- package/client/src/lib/i18n/formatting.ts +130 -0
- package/client/src/lib/i18n/index.ts +8 -0
- package/client/src/lib/i18n-compat.ts +76 -0
- package/client/src/lib/influence-deals-api.ts +896 -0
- package/client/src/lib/inventory-api.ts +399 -0
- package/client/src/lib/oauth-service.ts +678 -0
- package/client/src/lib/poi-types.ts +75 -0
- package/client/src/lib/queryClient.ts +144 -0
- package/client/src/lib/recommendation-api.ts +380 -0
- package/client/src/lib/storage-utils.ts +104 -0
- package/client/src/lib/tolgee.ts +85 -0
- package/client/src/lib/utils.ts +0 -0
- package/client/src/main.tsx +67 -0
- package/client/src/mapbox-draw-modes.d.ts +32 -0
- package/client/src/pages/all-folders.tsx +203 -0
- package/client/src/pages/auth-callback.tsx +115 -0
- package/client/src/pages/buyer-form.tsx +339 -0
- package/client/src/pages/buyer-list.tsx +622 -0
- package/client/src/pages/content-hub.tsx +1358 -0
- package/client/src/pages/create-deal.tsx +2093 -0
- package/client/src/pages/creative-assignment-page.tsx +548 -0
- package/client/src/pages/creatives.tsx +5 -0
- package/client/src/pages/custom-pois.tsx +425 -0
- package/client/src/pages/dashboard.tsx +615 -0
- package/client/src/pages/deal-history.tsx +434 -0
- package/client/src/pages/deal-line-items.tsx +1703 -0
- package/client/src/pages/demo-status.tsx +113 -0
- package/client/src/pages/direct-campaign-details.tsx +361 -0
- package/client/src/pages/direct-campaigns-new.tsx +824 -0
- package/client/src/pages/dsp-form.tsx +803 -0
- package/client/src/pages/dsp-list.tsx +239 -0
- package/client/src/pages/folder-content.tsx +336 -0
- package/client/src/pages/integrations.tsx +429 -0
- package/client/src/pages/line-item-creatives.tsx +789 -0
- package/client/src/pages/line-item-detail-page.tsx +684 -0
- package/client/src/pages/line-item-form-page.tsx +3261 -0
- package/client/src/pages/line-item-wizard.tsx +1207 -0
- package/client/src/pages/login.tsx +154 -0
- package/client/src/pages/not-found.tsx +23 -0
- package/client/src/pages/proof-of-play.tsx +397 -0
- package/client/src/pages/public-approval.tsx +551 -0
- package/client/src/pages/reports.tsx +231 -0
- package/client/src/pages/settings.tsx +760 -0
- package/client/src/pages/signals.tsx +389 -0
- package/client/src/pages/tags.tsx +318 -0
- package/client/src/pages/test-results.tsx +328 -0
- package/client/src/store/hooks.ts +5 -0
- package/client/src/store/index.ts +15 -0
- package/client/src/store/mapMarkerLocationsSlice.ts +241 -0
- package/client/src/styles/design-tokens.css +324 -0
- package/client/src/test/setup.ts +261 -0
- package/client/src/test/test-utils.tsx +40 -0
- package/client/src/types/approval.ts +221 -0
- package/client/src/types/content-hub.ts +209 -0
- package/client/src/types/geofencing.ts +67 -0
- package/client/src/types/transcoding.ts +140 -0
- package/client/src/vite-env.d.ts +18 -0
- package/components.json +20 -0
- package/creative-api.json +1 -0
- package/docs/AI_REFERENCE.md +459 -0
- package/docs/MWDesign-Prompt.md +132 -0
- package/docs/MWDesign-System.md +344 -0
- package/docs/test-plan.md +277 -0
- package/e2e/AUTONOMOUS-TESTING.md +406 -0
- package/e2e/README.md +219 -0
- package/e2e/autonomous-flow.spec.ts +308 -0
- package/e2e/debug-sso.spec.ts +163 -0
- package/e2e/direct-campaigns.spec.ts +219 -0
- package/e2e/explore-sso.spec.ts +149 -0
- package/e2e/fixtures/auth.ts +26 -0
- package/e2e/fixtures/enhanced-test.ts +331 -0
- package/e2e/pagination.spec.ts +280 -0
- package/e2e/view-toggle.spec.ts +312 -0
- package/generated-icon.png +0 -0
- package/i18next-scanner.config.cjs +46 -0
- package/package.json +141 -0
- package/playwright.config.ts +93 -0
- package/postcss.config.js +6 -0
- package/replit.md +196 -0
- package/screenshot-after-login.png +0 -0
- package/screenshot-contenthub-grid.png +0 -0
- package/screenshot-contenthub-list-fixed.png +0 -0
- package/screenshot-contenthub-list.png +0 -0
- package/screenshot-create-deal.png +0 -0
- package/screenshot-dashboard.png +0 -0
- package/screenshot-deals.png +0 -0
- package/screenshot-login-filled.png +0 -0
- package/screenshot-login.png +0 -0
- package/screenshot.mjs +24 -0
- package/scripts/deploy-stg.sh +185 -0
- package/shared/direct-io-schema.ts +383 -0
- package/shared/schema.ts +439 -0
- package/shared/screen-types.ts +149 -0
- package/springdocDefault.json +1 -0
- package/swagger-ui-bundle.js +2 -0
- package/swagger-ui-init.js +10316 -0
- package/tailwind.config.ts +282 -0
- package/terraform/README.md +306 -0
- package/terraform/cloudfront.tf +289 -0
- package/terraform/ecs.tf +727 -0
- package/terraform/environments/dev.tfvars +59 -0
- package/terraform/environments/production.tfvars +60 -0
- package/terraform/main.tf +47 -0
- package/terraform/outputs.tf +145 -0
- package/terraform/s3.tf +192 -0
- package/terraform/variables.tf +226 -0
- package/terraform/waf.tf +165 -0
- package/terraform-frontend/.terraform.lock.hcl +25 -0
- package/terraform-frontend/README.md +85 -0
- package/terraform-frontend/cloudfront.tf +125 -0
- package/terraform-frontend/main.tf +31 -0
- package/terraform-frontend/outputs.tf +24 -0
- package/terraform-frontend/terraform.tfvars +12 -0
- package/terraform-frontend/variables.tf +53 -0
- package/tsconfig.json +23 -0
- package/vite.config.ts +226 -0
- 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
|
+
}
|