Detailed documentation for each module in the Amazon Ad Console Training Simulator.
Component: Dashboard.tsx (133 lines)
View: dashboard
The aggregate metrics view showing totals across all enabled campaigns.
- Total Impressions — sum of all enabled campaign impressions
- Total Clicks — sum of all enabled campaign clicks
- Total Spend — sum of all enabled campaign spend
- Total Sales — sum of all enabled campaign sales
- Total Orders — sum of all enabled campaign orders
- Average ACoS — spend / sales × 100
- Average ROAS — sales / spend
- Average CTR — clicks / impressions × 100
Metrics flow bottom-up:
- Targets (per-keyword) have individual metrics
- Ad Groups sum their child targets' metrics
- Campaigns sum their child ad groups' metrics
- Dashboard sums all enabled campaigns' metrics
The totalMetrics() function in core/engine.ts handles the campaign → dashboard aggregation. The simulateDays() function handles the target → ad group → campaign cascade.
Component: CampaignManager.tsx (300 lines)
View: campaigns
List view of all campaigns with filtering and bulk actions.
- Filter by type: All / SP / SB / SD
- Filter by status: All / Enabled / Paused / Archived
- Filter by portfolio: All / any portfolio name
- Search: Free-text across name, type, targeting mode, portfolio, ad format
- Per-campaign actions: Toggle status, archive, duplicate, view details
- Inline metrics: Impressions, clicks, spend, sales, ACoS, ROAS
- Click a campaign row → navigates to
CampaignDetail - Toggle button → calls
toggleCampaignStatus - Archive button → calls
archiveCampaign - Duplicate button → calls
duplicateCampaign
Component: CampaignDetail.tsx (550+ lines)
View: detail
Deep-dive view for a single campaign with tabbed sub-views.
-
Overview — campaign settings, metrics, creative status
-
Ad Groups — list of ad groups with CRUD actions and drill-down
CRUD operations (inline in the table):
- Create: Enter a name in the "New ad group name" field and click "+ Add ad group"
- Rename: Click the inline edit icon next to the ad group name
- Status: Toggle via inline dropdown (Enabled / Paused / Archived); cascades to all targets in the group
- Default bid: Set via inline numeric input; clamped to ≥ $0.02
- Delete: Click the "Remove" button (disabled if it's the only ad group); removes the group and all its targets
Drill-down: Click an ad group row to see its child targets in a focused sub-view with a "← All ad groups" back button. The drill-down shows:
- Ad group name, status dropdown, default bid editor with Save button
- Full targets table filtered to that ad group
-
Targets — keyword/product targets with bid management
-
Search Terms — customer search terms with harvest/negate actions
-
Negatives — negative keyword list
-
Placements — placement bid adjustments
-
Budget Rules — schedule/performance-based rules with full CRUD
- Add rule: Form with name, type (Schedule/Performance), budget increase multiplier, condition text
- Edit rule: Inline editable name, type dropdown, increase amount, condition text
- Remove rule: Delete button with confirmation dialog
- Validation: Type must be Schedule or Performance, increase must be positive, name and condition required
-
Change History — chronological log of all changes
- Add keyword: Opens form for keyword text, match type, bid
- Remove target: Removes target from campaign
- Set bid: Set exact CPC bid on a target
- Adjust bid: Multiply current bid by a factor
- Pause target: Sets target status to Paused
- Harvest: Promotes a converting search term to an Exact keyword target and adds a Phrase negative to prevent duplicate matching
- Negate: Adds the search term as a Negative exact keyword
Three placement types with percentage bid modifiers:
- Top of Search — premium placement at top of results
- Product Pages — ads on product detail pages
- Rest of Search — all other placements
Component: CreateCampaignWizard.tsx (280+ lines)
View: create
Multi-step campaign creation wizard mimicking the Amazon Ads Console flow.
- Ad type: Select SP, SB, or SD
- Basics: Campaign name, portfolio, status, daily budget, start date, ad format
- Products & creative: Select ASINs from a checkable product catalog table; enter brand name and headline for SB/SD campaigns
- Targeting: Choose targeting mode with auto-targeting context panel; enter keywords (one per line) for manual modes, or ASIN/audience targets for product/contextual targeting
- Bidding & budget: Bid strategy, default bid, and placement adjustments (Top of Search / Product pages / Rest of Search)
- Review & launch: Full settings summary; keywords and product counts shown; launch creates the campaign with parsed keywords as targets
- Campaign name is required
- Daily budget must be ≥ $1
- Default bid must be ≥ $0.02
- Keywords are parsed one-per-line from the text area
Creates a normalized campaign via normalizeCampaign() and prepends it to the campaigns array. Immediately navigates to the detail view.
Component: PortfolioOverview.tsx (136 lines)
View: portfolio
Campaigns grouped by portfolio with aggregate metrics per group.
- Each unique portfolio name becomes a group
- Campaigns without a portfolio go into "Training Portfolio" (default)
- Each group shows aggregate metrics and campaign count
- Click a campaign within a group → navigates to detail view
Component: DrillsPage.tsx (126 lines)
Engine: features/drills/engine.ts
View: drills
Reachable from: topbar Training section (lands here by default) and the Training left rail
Click-by-click navigation coaching through real Amazon Ads Console workflows.
| ID | Title | Ad Type | Difficulty | Steps |
|---|---|---|---|---|
nav-sp-search-term-negative |
Find and block waste from Search terms | SP | Beginner | 5 |
nav-sp-placement-controls |
Adjust SP placement settings | SP | Beginner | 5 |
nav-sb-creative-review |
Review SB creative before launch | SB | Intermediate | 4 |
nav-report-request |
Request and copy a performance report | SP | Beginner | 3 |
nav-sd-audience-path |
Find Sponsored Display audience targeting | SD | Intermediate | 4 |
- User selects a drill from the list
- Sidebar shows step-by-step instructions
- User clicks the target action in the simulator
- Engine evaluates: correct → advance; incorrect → record mistake
- Skippable steps allow skipping without penalty
- Score calculated:
100 - (mistakes × 15) - (skips × 5), min 0 - Results stored in
drillResultshistory
Component: MissionsPage.tsx (68 lines)
View: missions
Reachable from: topbar Training section and the Training left rail
Engine: features/missions/engine.ts
View: missions
Scenario-based challenges that test real campaign management skills.
| ID | Title | Difficulty | Steps |
|---|---|---|---|
mission-optimize-acos |
Optimize Campaign ACoS Below Target | Advanced | 6 |
mission-launch-manual |
Launch a Manual SP Campaign from Scratch | Intermediate | 5 |
mission-cleanup-waste |
Clean Up Wasted Spend | Beginner | 4 |
- Starts at 100 points
- Each hint used: -10 points
- Complete all steps to finish
- Final score reflects efficiency (fewer hints = higher score)
Component: ReportsPage.tsx (89 lines)
View: reports
Reachable from: topbar Training section and the Training left rail
Engine: features/reports/engine.ts
View: reports
Generate and export performance reports matching Amazon Ads Console report types.
| Type | Description |
|---|---|
campaign |
Campaign-level performance summary |
adGroup |
Ad group breakdown |
target |
Keyword/target performance |
searchTerm |
Customer search term data |
placement |
Placement-level breakdown |
- Select report type
- Click "Request report"
- Report generates immediately (simulated)
- View report data in table format
- Click "Export CSV" to download
Component: BulkOpsPage.tsx (85 lines)
View: bulk
Reachable from: topbar Training section and the Training left rail
Engine: features/bulk/engine.ts
View: bulk
Import and validate Amazon Ads bulk CSV operations.
Entity,Operation,Id,Campaign Name,Field,Value
campaign,update,C-SP-001,,DailyBudget,50
target,pause,,C-SP-001,Status,Paused
negative,create,,C-SP-001,Keyword,irrelevant term
- campaign: update, pause, enable, archive
- adGroup: update, pause, enable
- target: update, pause, enable, delete
- negative: create, delete
- budgetRule: create, delete
The validateBulkRows() function checks:
- Required fields per entity type
- Valid operation names
- Valid field names
- Value format matching (e.g., bid must be numeric)
Returns row-level error messages with specific field and reason.
Component: IntegrityPage.tsx (76 lines)
View: integrity
Reachable from: topbar Training section and the Training left rail
Engine: features/integrity/engine.ts
View: integrity
Automated data-quality auditing of campaign setup.
| Check | Severity | Description |
|---|---|---|
| Archived campaign has active children | Error | Targets in archived campaigns should also be archived |
| Duplicate target IDs | Error | Each target must have a unique ID |
| Orphaned search terms | Warning | Search terms should link to a target (except SD) |
| SD with search terms | Warning | SD campaigns use audience reports, not search terms |
| SB rejected creative | Error | Creative must be approved before campaign can run |
| Low-inventory product | Warning | Campaigns promoting low-stock items may waste spend |
- Score starts at 100
- Each error: -15 points
- Each warning: -5 points
- Passes at ≥70
Each issue includes a recommendation string explaining how to fix the problem.
Component: TrainerPage.tsx (124 lines)
View: trainer
Reachable from: topbar Training section and the Training left rail
Engine: features/trainer/engine.ts
View: trainer
Supervisor view for monitoring trainee progress.
9-item checklist tracking trainee competency:
- Names ad type before making changes
- Checks campaign status before editing
- Checks date range before reading performance
- Reads spend, sales, orders, ACoS, CPC, CVR
- Explains why a target gets increased, decreased, paused, harvested, or negated
- Uses exact negatives for precise waste, phrase only when safe
- Validates SB creative fields before launch
- Understands SD audience/contextual targeting vs keyword targeting
- Checks change history after major edits
Each simulator action is automatically graded:
- Good (green): Creating campaigns, adding keywords, harvesting terms, pausing waste
- Bad (red): Deleting without reason, ignoring metrics, wrong match type
- Warn (yellow): Pausing broadly, adjusting bids without analysis
Trainer can add timestamped notes for each trainee session.
Engine: features/profiles/engine.ts
View: Integrated into sidebar
Separate training state per trainee.
- Default profile: "Trainee" (
p-default) - Create new profiles with custom names
- Switch between profiles (updates
lastActiveAt) - Rename profiles
- Delete profiles (falls back to first available)
Engine: store.ts — Zustand persist middleware
View: Automatic (no user-facing component)
The Zustand store uses persist middleware from zustand/middleware to save and restore state across page refreshes.
Storage key: ad-console-storage (localStorage)
Persisted data:
- All campaigns, ad groups, targets, search terms, negatives, budget rules
- Portfolio assignments and portfolio name list
- Filter preferences, simulation days, action log
- State version string
Not persisted (UI-only transient state):
- Draft/campaign creation wizard state
- Current view, selected tab, selected campaign ID
- Mobile menu status
- Feature engine state (drills, missions, profiles, etc.)
The store exposes exportState() and importState(json) for manual backup/restore:
exportState()serializes all core state to a JSON stringimportState()deserializes and validates the JSON (rejects empty strings and non-object values)- Returns
trueon success,falseon parse failure
Left-rail sidebar items now map to campaign detail tabs:
- Campaigns → campaign list view
- Ad groups →
adgroupstab in campaign detail - Targeting →
targetstab - Search terms →
searchTermstab - Negative keywords →
negativestab - Budget rules (Portfolios section) →
budgetRulestab
When clicking a tab-mapped item:
- If user is already viewing a campaign detail → switches the active tab
- If user is in the campaign list → navigates to detail view and switches tab
- Items without a tab → plain view navigation (unchanged behaviour)
Component: MobileNav.tsx (133 lines)
Hook: useBreakpoint.ts (52 lines)
Engine: core/engine.ts — resolveBreakpoint, mobileMenuReducer, isTouchViewport
View: Integrated into all views via topbar
| Range | Label | Behavior |
|---|---|---|
| < 768px | Mobile | Desktop sidebar hidden; hamburger toggle + slide-out drawer |
| 768–1100px | Tablet | Same as mobile — desktop sidebar hidden, hamburger drawer takes over (both are isMobileOrTablet in useBreakpoint) |
| > 1100px | Desktop | Full Amazon Console layout with the persistent left sidebar |
- Hamburger button in the global nav toggles a slide-out drawer
- Drawer contains all sidebar groups for the active section: Campaign Manager, Portfolios, Measurement, or Training (Drills/Missions/Reports/Bulk ops/Trainer/Integrity)
- Backdrop overlay with click-to-close
- Escape key closes the drawer
- Animation state machine: closed → open ↔ closing → closed
- Touch-friendly
44pxminimum tap targets on all interactive elements
isTouchViewport()in the engine detects devices with coarse pointer at ≤ 1100px- Touch-action: manipulation on interactive elements prevents tap delay
- -webkit-overflow-scrolling: touch on scrollable panels
- Nav: Brand text truncates, nav account text truncates, section text hidden
- Tables: Horizontal scroll, smaller padding, smaller pill badges
- Forms: Full-width input stacking, 44px min-height on inputs
- Tabs: Horizontal overflow scroll with hidden scrollbar
- Toolbar: Wrap on multiple lines, flex-grow on filter controls
- Page titles: Stack vertically on mobile
Auth Provider: NextAuth v5
Database: Prisma + Postgres (via @prisma/adapter-neon)
Components: SessionProvider.tsx, UserMenu.tsx, SyncButton.tsx
Pages: /auth/login, /auth/register, /landing
Multi-user access system allowing multiple trainees to have isolated campaign data with cloud synchronization.
- Registration: User creates account with email/password
- Login: User signs in with credentials
- Session: JWT token stored in HTTP-only cookie
- Logout: Session destroyed, redirect to home
- User: id, email, name, passwordHash, timestamps
- Campaign: All campaign data linked to userId
- Simulation: Simulation history linked to userId
POST /api/auth/register— Create new userGET/POST /api/campaigns— List/create campaignsGET/PUT/DELETE /api/campaigns/[id]— Single campaign CRUDGET/POST /api/sync— Bulk sync campaigns to/from database
- SessionProvider: Wraps app for client-side session access
- UserMenu: Shows avatar, name, dropdown with sign out
- SyncButton: "Save" and "Load" buttons for cloud sync
- Visit
/auth/registerto create account - Sign in at
/auth/login - Use simulator normally
- Click "Save" to persist campaigns to database
- Click "Load" to restore campaigns from any device
- Password hashing with bcrypt (10 rounds)
- JWT sessions with secure HTTP-only cookies
- User data isolation via userId foreign key
- API route protection via session checks
Component: landing/page.tsx
Route: /landing
- Public landing page with auth links
- Feature showcase with animations
- Stats display
- CTA to simulator
- Responsive design
- Dark theme with zinc-950 background
- Emerald accent color
- Motion animations via
motion/react - Mobile-optimized layout
File: globals.css
- Typography: Geist font stack with refined type scale
- Colors: Amazon-faithful palette with improved contrast
- Shadows: Subtle, depth-aware shadow system
- Borders: Refined hairlines with light/strong variants
- Radius: Consistent corner radius scale
- Buttons: Better hover/active/disabled states
- Cards: Subtle border + shadow, hover elevation
- Tables: Sticky headers, better row hover
- Forms: Teal focus ring, proper select arrows
- Pills: Refined color system
- 48px minimum touch targets
- Better drawer animation with blur backdrop
- Safe area padding for iPhone notch
- Improved responsive breakpoints
- Visible focus ring on all interactive elements
- Reduced motion support
- Better color contrast ratios