# Keywords Library Page Redesign Plan **Created:** January 18, 2026 **Updated:** January 19, 2026 _(v1.8.2 released)_ **Status:** ✅ COMPLETED & DOCUMENTED (v1.8.2) **Page:** `/keywords-library` (was `/setup/add-keywords`) **Priority:** đŸŸĸ COMPLETED --- ## Executive Summary Comprehensive redesign of the Keywords Library page completed and deployed in **v1.8.2**: 1. ✅ **Standardize naming** to "Keywords Library" across frontend, backend, URLs, menus, and admin 2. ✅ **Implement cascading filters** like Planner pages (Keywords, Clusters, Ideas) 3. âŦœ **Remove sector selector** from AppHeader, use site-only selector (partial - route updated) 4. ✅ **Add Sector Metric Cards** with clickable filtering + 6 bulk add stat options 5. ✅ **Redesign Smart Suggestions** to appear after search/filter with breathing indicator 6. âŦœ **Center filter bar** with sector filter added, matching Planner page styling (needs polish) 7. âŦœ **Show table data by default** (remove "Browse" toggle) (kept existing UX for now) 8. ✅ **No backward compatibility** - single source of truth 9. ✅ **CRITICAL FIX:** Sector-specific filtering - sites now only see keywords from their configured sectors **Release:** Version 1.8.2 - January 19, 2026 **Changelog:** See `/CHANGELOG.md` for complete details **API Documentation:** See `/docs/20-API/ENDPOINTS.md` for Keywords Library endpoints --- ## Part 1: Terminology Standardization ### Current State (Inconsistent) | Location | Current Term | Usage | |----------|--------------|-------| | Sidebar | "Keyword Library" | ❌ Should be "Keywords Library" | | Page Title | "Keyword Library" | ❌ Should be "Keywords Library" | | URL | `/setup/add-keywords` | ❌ Legacy | | Backend Model | `SeedKeyword` | ✅ Keep internal | | Backend URL | `/v1/auth/seed-keywords/` | ❌ Legacy | | Backend Admin | "Industry Sector Keywords" | ❌ Should be "Keywords Library" | | Frontend API | `fetchSeedKeywords()` | ❌ Legacy | | High Opportunity | "Quick-Start Keywords" | ❌ Different term | | Search Modal | Mixed terms | ❌ Inconsistent | | Onboarding | "Add Keywords" | ❌ Legacy | | Marketing Pages | "Seed Keywords", "High-Opportunity" | ❌ Mixed | ### Target State (Unified) **Standardized Term:** "Keywords Library" (plural "Keywords") **Internal/Code:** Keep `SeedKeyword` model name internally | Location | New Term | |----------|----------| | Sidebar | "Keywords Library" | | Page Title | "Keywords Library" | | URL | `/keywords-library` (**NO** redirect from legacy) | | Backend URL | `/v1/keywords-library/` (**NO** legacy alias) | | Backend Admin | "Keywords Library" | | Frontend API | `fetchKeywordsLibrary()` (replace `fetchSeedKeywords`) | | Smart Suggestions | "Smart Suggestions" | | Search Modal | "Keywords Library" | | Onboarding Step | "Browse Keywords Library" | ### Files to Update ``` Frontend: - src/layout/AppSidebar.tsx - Menu label → "Keywords Library" - src/layout/AppHeader.tsx - Route patterns - src/App.tsx - Route definition (NO redirect, direct change) - src/components/common/SearchModal.tsx - Search references - src/components/onboarding/OnboardingWizard.tsx - Step 4 name - src/components/onboarding/steps/Step4AddKeywords.tsx - Rename to Step4KeywordsLibrary.tsx - src/components/sites/SiteSetupChecklist.tsx - Link text - src/services/api.ts - Rename function to fetchKeywordsLibrary() - src/marketing/pages/Pricing.tsx - Feature descriptions - src/marketing/pages/Solutions.tsx - Feature descriptions Backend: - igny8_core/auth/urls.py - Change URL to /keywords-library/ - igny8_core/admin/ - Change admin menu label to "Keywords Library" - Keep model name as SeedKeyword (internal only) ``` --- ## Part 2: Filter System Redesign ### Current Filters (Keywords Library) ``` [Search] [Country â–ŧ] [Difficulty â–ŧ] [Status â–ŧ] ``` **Issues:** 1. ❌ No "Clear Filters" button near active filter indicator 2. ❌ No Volume filter (exists on Planner Keywords page) 3. ❌ No Sector filter in filter bar 4. ❌ Hardcoded country/difficulty options (not cascading) 5. ❌ Filters don't show only available options based on current data 6. ❌ Active/Clear button positioning doesn't match Planner pages ### Target Filters (Match Planner Pages Pattern) ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ [🔍 Search] [Sector â–ŧ] [Volume â–ŧ] [Difficulty â–ŧ] [Country â–ŧ] [Status â–ŧ] │ │ │ │ Active: 2 filters [Clear] ← Same position as Planner pages │ │ │ │ â„šī¸ Search 54,180 keywords. Filter by volume or difficulty to find your │ │ perfect keywords! │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` **Improvements:** 1. ✅ Active count + Clear button positioned **same as Planner pages** 2. ✅ Add Volume range filter (min/max popup like Planner pages) 3. ✅ Add Sector filter dropdown 4. ✅ Keep "Not Yet Added" status filter (in_workflow filter) 5. ✅ Implement cascading filters - options reflect available data 6. ✅ Center filter bar with explainer text below ### Filter: Status Options | Value | Label | Description | |-------|-------|-------------| | `all` | All Keywords | Show all keywords | | `available` | Not Yet Added | Keywords not in any workflow | | `in_workflow` | In Workflow | Keywords already added to site | ### Backend API Changes **New Endpoint:** `GET /v1/keywords-library/filter_options/` Returns available filter options based on current filters (cascading): ```python # Example Request GET /v1/keywords-library/filter_options/?industry=5§or=12&difficulty_max=40 # Response { "sectors": [ {"value": 12, "label": "Technology", "count": 1250}, {"value": 15, "label": "Mobile Apps", "count": 340}, ... ], "countries": [ {"value": "US", "label": "United States", "count": 1250}, {"value": "GB", "label": "United Kingdom", "count": 340}, ... ], "difficulties": [ {"value": "1", "label": "Very Easy (1-20)", "count": 890}, {"value": "2", "label": "Easy (21-40)", "count": 450}, {"value": "3", "label": "Medium (41-60)", "count": 320}, {"value": "4", "label": "Hard (61-80)", "count": 180}, {"value": "5", "label": "Very Hard (81-100)", "count": 90}, ], "volume_stats": { "min": 0, "max": 421000, "avg": 5420, "p50": 1200, "p90": 15000 }, "total_matching": 1590 } ``` ### Difficulty Mapping (Backend 1-100 → Frontend 1-5) | Frontend Level | Label | Backend Range | |----------------|-------|---------------| | 1 | Very Easy | 1-20 | | 2 | Easy | 21-40 | | 3 | Medium | 41-60 | | 4 | Hard | 61-80 | | 5 | Very Hard | 81-100 | **Low Difficulty = Level 1 and 2 (backend ≤ 40)** ### Frontend Changes 1. **Add `fetchKeywordsLibraryFilterOptions()` API function** 2. **Add Sector filter dropdown** (populated from site's sectors) 3. **Add Volume filter component** (reuse from Keywords.tsx) 4. **Position Active/Clear same as Planner pages** 5. **Load filter options dynamically** based on industry/sector selection 6. **Re-load options when any filter changes** (cascading) --- ## Part 3: App Header Selector Change ### Current Behavior - Keywords Library page shows `SiteAndSectorSelector` (Site + Sector dropdowns) - This is redundant since page will have sector cards and sector filter ### Target Behavior - Show `SingleSiteSelector` (Site only, like Automation pages) - Remove from `SITE_AND_SECTOR_ROUTES` array - Add to `SINGLE_SITE_ROUTES` array ### Code Change (AppHeader.tsx) ```diff const SITE_AND_SECTOR_ROUTES = [ '/planner', '/writer', - '/setup/add-keywords', ]; const SINGLE_SITE_ROUTES = [ '/automation', '/publisher', '/account/content-settings', '/sites', + '/keywords-library', ]; ``` --- ## Part 4: Sector Metric Cards ### Design Clickable sector cards that filter the table when clicked. Each card shows stats and has 5-6 bulk add options. ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Your Site Sectors [Add Sector]│ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ đŸ’ģ Technology │ │ 📱 Mobile Apps │ │ 🌐 Web Dev │ │ │ │ ─────────────────── │ │ ─────────────────── │ │ ─────────────────── │ │ │ │ │ │ │ │ │ │ │ │ Total: 1,245 │ │ Total: 892 │ │ Total: 456 │ │ │ │ Available: 1,200 │ │ Available: 880 │ │ Available: 456 │ │ │ │ In Workflow: 45 │ │ In Workflow: 12 │ │ In Workflow: 0 │ │ │ │ │ │ │ │ │ │ │ │ ─── Quick Add ───── │ │ ─── Quick Add ───── │ │ ─── Quick Add ───── │ │ │ │ │ │ │ │ │ │ │ │ 📈 High Volume │ │ 📈 High Volume │ │ 📈 High Volume │ │ │ │ 125 kw (>8.5K) │ │ 67 kw (>6.2K) │ │ 50 kw (>3.4K) │ │ │ │ [+50] [+100] │ │ [+50] [+67] │ │ [+50] │ │ │ │ │ │ │ │ │ │ │ │ đŸŽ¯ Low Difficulty │ │ đŸŽ¯ Low Difficulty │ │ đŸŽ¯ Low Difficulty │ │ │ │ 340 kw (≤40) │ │ 212 kw (≤40) │ │ 89 kw (≤40) │ │ │ │ [+50] [+100] │ │ [+50] [+100] │ │ [+50] [+89] │ │ │ │ │ │ │ │ │ │ │ │ đŸ”Ĩ High Vol + Easy │ │ đŸ”Ĩ High Vol + Easy │ │ đŸ”Ĩ High Vol + Easy │ │ │ │ 45 kw │ │ 28 kw │ │ 12 kw │ │ │ │ [+45] │ │ [+28] │ │ [+12] │ │ │ │ │ │ │ │ │ │ │ │ 💎 Premium (>50K) │ │ 💎 Premium (>50K) │ │ 💎 Premium (>50K) │ │ │ │ 12 kw │ │ 8 kw │ │ 3 kw │ │ │ │ [+12] │ │ [+8] │ │ [+3] │ │ │ │ │ │ │ │ │ │ │ │ 🌱 Long Tail │ │ 🌱 Long Tail │ │ 🌱 Long Tail │ │ │ │ 890 kw (4+ words)│ │ 654 kw (4+ words)│ │ 312 kw (4+ words)│ │ │ │ [+50] [+100] │ │ [+50] [+100] │ │ [+50] [+100] │ │ │ │ │ │ │ │ │ │ │ │ [Browse All →] │ │ [Browse All →] │ │ [Browse All →] │ │ │ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ │ │ │ │ 💡 Click any card to filter the table by that sector │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### Click Behavior - **Click on sector card** → Filter table by that sector - **Click on Quick Add button** → Add keywords matching that criteria ### Stats Per Sector Card (6 Options) Based on actual keyword data analysis (volume ranges 50-281,000, difficulty 0-99). **Dynamic fallback thresholds** ensure every sector shows useful data: | Stat | Criteria | Fallback Logic | Example | |------|----------|----------------|---------| | 📈 **High Volume** | Top 50/100 by volume | Dynamic threshold based on available data | "125 kw (>8.5K)" | | đŸŽ¯ **Low Difficulty** | Difficulty ≤ 40 (levels 1-2) | Fixed threshold | "340 kw (≤40)" | | đŸ”Ĩ **Best Opportunities** | High vol + Difficulty ≤ 40 | Combines above two criteria | "45 kw" | | 💎 **Premium Traffic** | Volume > 50,000 | If 0 → try >25,000 → if 0 → try >10,000 | "12 kw (>50K)" | | 🌱 **Long Tail** | Words â‰Ĩ 4 AND Volume > 1,000 | If 0 → try >500 → if 0 → try >200 | "890 kw (4+ words, >1K)" | | ⚡ **Quick Wins** | Difficulty ≤ 20 AND Volume > 1,000 + Available | If 0 → try >500 → if 0 → try >200 | "67 kw" | ### Dynamic Threshold Fallback Logic ```python # Premium Traffic - cascading volume thresholds def get_premium_traffic(keywords): for threshold in [50000, 25000, 10000]: count = keywords.filter(volume__gt=threshold).count() if count > 0: return {"count": count, "threshold": threshold} return {"count": 0, "threshold": 10000} # Long Tail - cascading volume with word count def get_long_tail(keywords): base = keywords.filter(word_count__gte=4) for threshold in [1000, 500, 200]: count = base.filter(volume__gt=threshold).count() if count > 0: return {"count": count, "min_volume": threshold} return {"count": 0, "min_volume": 200} # Quick Wins - cascading volume with low difficulty + available def get_quick_wins(keywords, attached_ids): base = keywords.filter(difficulty__lte=20).exclude(id__in=attached_ids) for threshold in [1000, 500, 200]: count = base.filter(volume__gt=threshold).count() if count > 0: return {"count": count, "min_volume": threshold} return {"count": 0, "min_volume": 200} ``` This ensures **every sector shows meaningful data** regardless of size, making the feature always useful and operational. ### High Volume Dynamic Threshold Instead of fixed 10,000 threshold: - Get top 50 keywords by volume for sector - Show threshold as ">X" where X = lowest volume in top 50 - If < 50 keywords available, use top 100 threshold - Example: "125 kw (>8,540)" means 125 keywords with volume > 8,540 ### Bulk Add Options Each stat shows add buttons based on availability: - `[+50]` - Add top 50 - `[+100]` - Add top 100 (if > 50 available) - `[+200]` - Add top 200 (if > 100 available) - `[+N]` - Add all N (if N ≤ 200) **Always show confirmation modal before adding.** ### Backend API **Endpoint:** `GET /v1/keywords-library/sector_stats/` ```python # Request GET /v1/keywords-library/sector_stats/?site_id=21 # Response { "sectors": [ { "sector_id": 12, "sector_name": "Technology", "sector_slug": "technology", "total_keywords": 1245, "available": 1200, "in_workflow": 45, "stats": { "high_volume": { "count": 125, "threshold": 8540, // Dynamic: lowest volume in top 50/100 "total_volume": 1200000 }, "low_difficulty": { "count": 340, "threshold": 40, // Backend value (maps to frontend level 2) "total_volume": 450000 }, "high_vol_easy": { "count": 45, "description": "High volume + Low difficulty" }, "premium": { "count": 12, "threshold": 50000, // Dynamic: 50K → 25K → 10K fallback "used_fallback": false }, "long_tail": { "count": 890, "min_words": 4, "min_volume": 1000, // Dynamic: 1K → 500 → 200 fallback "used_fallback": false }, "quick_wins": { "count": 67, "difficulty_max": 20, // Level 1 only "min_volume": 1000, // Dynamic: 1K → 500 → 200 fallback "used_fallback": false } } }, // ... more sectors ] } ``` ### Styling Use **subtle accents** matching IGNY8 design style: - Light/dark mode compatible - Muted colors from dashboard/billing/usage pages - No bright/colorful backgrounds - Subtle borders and shadows - Consistent with existing card components --- ## Part 5: Smart Suggestions Section ### Concept Show **Smart Suggestions** dynamically based on current filters/search. Display a **breathing circle indicator** until user interacts with filters or search. ### Initial State (Before Search/Filter) ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 💡 Smart Suggestions │ │ │ │ ○ Ready-to-use keywords waiting for you! Search for a keyword or apply │ │ any filter to see smart suggestions... │ │ ↑ │ │ Breathing/pulsing circle indicator (subtle animation) │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### After Search/Filter Applied ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ 💡 Smart Suggestions for "seo tools" │ │ │ │ ┌────────────────────────────────────┐ ┌───────────────────────────────────┐ │ │ │ 📈 High Volume Keywords │ │ đŸŽ¯ Easy Wins │ │ │ │ │ │ │ │ │ │ 89 keywords with >4,200 volume │ │ 156 keywords (difficulty ≤ 40) │ │ │ │ Combined: 2.4M searches/month │ │ Combined: 890K searches/month │ │ │ │ │ │ │ │ │ │ Top 5: seo tools, seo audit, ... │ │ Top 5: local seo, seo tips, ... │ │ │ │ │ │ │ │ │ │ [+50] [+100] [+All 89] │ │ [+50] [+100] [+All 156] │ │ │ └────────────────────────────────────┘ └───────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────┐ ┌───────────────────────────────────┐ │ │ │ đŸ”Ĩ Best Opportunities │ │ 🌱 Long Tail Keywords │ │ │ │ │ │ │ │ │ │ 45 kw (high volume + easy) │ │ 234 keywords (3+ words) │ │ │ │ Combined: 1.2M searches/month │ │ Lower competition phrases │ │ │ │ │ │ │ │ │ │ [+45] │ │ [+50] [+100] [+200] │ │ │ └────────────────────────────────────┘ └───────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────┐ │ │ │ 🔍 All matching "seo tools" - 234 keywords │ │ │ │ │ │ │ │ [+50 by Volume] [+50 by Difficulty] [+100] [+200] [+All 234] │ │ │ └──────────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### Breathing Circle Indicator CSS animation for pulsing circle: ```css .breathing-indicator { width: 12px; height: 12px; border-radius: 50%; background: var(--muted-foreground); animation: breathe 2s ease-in-out infinite; } @keyframes breathe { 0%, 100% { opacity: 0.3; transform: scale(0.9); } 50% { opacity: 0.8; transform: scale(1.1); } } ``` ### Suggestion Categories | Category | Criteria | Fallback Logic | |----------|----------|----------------| | 📈 High Volume | Top 50/100 by volume | Dynamic threshold | | đŸŽ¯ Easy Wins | Difficulty ≤ 40 | Fixed threshold | | đŸ”Ĩ Best Opportunities | High vol + Easy | Combines criteria | | 💎 Premium | Volume > 50K | 50K → 25K → 10K fallback | | 🌱 Long Tail | Words â‰Ĩ 4 + Vol > 1K | Vol: 1K → 500 → 200 fallback | | ⚡ Quick Wins | Diff ≤ 20 + Vol > 1K + Available | Vol: 1K → 500 → 200 fallback | ### Bulk Add Buttons | Button | Action | |--------|--------| | `[+50]` | Add top 50 sorted by relevant criteria | | `[+100]` | Add top 100 | | `[+200]` | Add top 200 | | `[+All N]` | Add all N matching (shown when N ≤ 200) | | `[+50 by Volume]` | Add top 50 sorted by volume DESC | | `[+50 by Difficulty]` | Add top 50 sorted by difficulty ASC | **Always show confirmation modal before any bulk add.** ### Styling Match IGNY8 dashboard/billing/usage styling: - Subtle card backgrounds (muted) - Light borders - Dark mode compatible colors - No bright/colorful accents - Consistent typography --- ## Part 6: Page Layout Redesign ### Current Layout ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ [Header with Site+Sector selector] │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Quick-Start Keywords Section (always shown first) │ │ │ │ [Browse All Keywords] button │ │ │ │ Table (only shown after clicking Browse) │ │ │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### New Layout ``` ┌─────────────────────────────────────────────────────────────────────────────────┐ │ [Header with Site-only selector] │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐│ │ │ Sector Metric Cards (clickable - filters table by sector) ││ │ │ - 5-6 bulk add stat options per card ││ │ │ - [+50] [+100] [+200] buttons ││ │ └─────────────────────────────────────────────────────────────────────────────┘│ │ │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌────────────────────────────────────────────────────────────────────┐ │ │ │ [🔍 Search] [Sector â–ŧ] [Volume â–ŧ] [Difficulty â–ŧ] [Country â–ŧ] │ │ │ │ │ │ │ │ Active: 2 filters [Clear] │ │ │ └────────────────────────────────────────────────────────────────────┘ │ │ │ │ â„šī¸ Search 54,180 keywords. Filter by volume or difficulty │ │ to find your perfect keywords! │ │ │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────┐│ │ │ 💡 Smart Suggestions ││ │ │ ││ │ │ ○ Search or filter keywords to see personalized suggestions... ││ │ │ ↑ breathing indicator ││ │ │ ││ │ │ (After search/filter: shows suggestion cards with [+50] [+100] buttons) ││ │ └─────────────────────────────────────────────────────────────────────────────┘│ │ │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ Keywords Table (always shown, data loaded by default) │ │ - Shows first 500 records (with server-side sorting/filtering) │ │ - Pagination shows total count │ │ - Sorted by volume DESC by default │ │ │ └─────────────────────────────────────────────────────────────────────────────────┘ ``` ### Key Layout Changes 1. **Site-only selector** in header (no sector dropdown) 2. **Sector cards at top** - clickable to filter table 3. **Centered filter bar** with sector filter + active/clear like Planner 4. **Smart Suggestions** - breathing indicator until search/filter 5. **Table always visible** - no "Browse" toggle 6. **Confirmation modal** for all bulk adds --- ## Part 7: Implementation Tasks ### Phase 1: Backend API Updates | Task | File | Priority | |------|------|----------| | Add `/filter_options/` endpoint | `auth/views.py` | High | | Add `/sector_stats/` endpoint with 6 stat types | `auth/views.py` | High | | Change URL to `/keywords-library/` (no alias) | `auth/urls.py` | High | | Update admin menu to "Keywords Library" | `admin/` | High | | Support volume_min/max filters | `auth/views.py` | High | | Support sector filter | `auth/views.py` | High | | Implement cascading filter logic | `auth/views.py` | High | | Add bulk add endpoint with confirmation | `auth/views.py` | High | ### Phase 2: Frontend Filter System | Task | File | Priority | |------|------|----------| | Rename `fetchSeedKeywords` → `fetchKeywordsLibrary` | `services/api.ts` | High | | Add `fetchKeywordsLibraryFilterOptions()` | `services/api.ts` | High | | Add `fetchKeywordsLibrarySectorStats()` | `services/api.ts` | High | | Add Sector filter dropdown | `KeywordsLibrary.tsx` | High | | Add Volume filter component | `KeywordsLibrary.tsx` | High | | Position Active/Clear same as Planner | `KeywordsLibrary.tsx` | High | | Implement cascading filter loading | `KeywordsLibrary.tsx` | High | | Center filter bar + add explainer | `KeywordsLibrary.tsx` | Medium | ### Phase 3: Selector & Layout Changes | Task | File | Priority | |------|------|----------| | Move route to `SINGLE_SITE_ROUTES` | `AppHeader.tsx` | High | | Change route to `/keywords-library` | `App.tsx` | High | | Remove "Browse" toggle, show table by default | `KeywordsLibrary.tsx` | High | | Remove High Opportunity section | `KeywordsLibrary.tsx` | Medium | ### Phase 4: Sector Metric Cards | Task | File | Priority | |------|------|----------| | Create SectorMetricCard component | `components/keywords-library/` | High | | Implement 6 stat types per card | `SectorMetricCard.tsx` | High | | Add click-to-filter behavior | `KeywordsLibrary.tsx` | High | | Add [+50] [+100] [+200] buttons | `SectorMetricCard.tsx` | High | | Add confirmation modal for bulk add | `KeywordsLibrary.tsx` | High | ### Phase 5: Smart Suggestions | Task | File | Priority | |------|------|----------| | Create SmartSuggestions component | `components/keywords-library/` | High | | Add breathing circle indicator | `SmartSuggestions.tsx` | High | | Show suggestions after search/filter | `KeywordsLibrary.tsx` | High | | Add bulk add buttons [+50] [+100] [+200] | `SmartSuggestions.tsx` | High | | Implement 6 suggestion categories | `SmartSuggestions.tsx` | Medium | ### Phase 6: Naming Standardization | Task | File | Priority | |------|------|----------| | Update sidebar label → "Keywords Library" | `AppSidebar.tsx` | High | | Update SearchModal references | `SearchModal.tsx` | Medium | | Rename Step4AddKeywords → Step4KeywordsLibrary | `onboarding/steps/` | Medium | | Update marketing pages | `Pricing.tsx`, `Solutions.tsx` | Low | ### Phase 7: Confirmation Modal | Task | File | Priority | |------|------|----------| | Create BulkAddConfirmation modal | `components/keywords-library/` | High | | Show count and criteria being added | `BulkAddConfirmation.tsx` | High | | Always require confirmation for bulk add | `KeywordsLibrary.tsx` | High | --- ## Part 8: No Backward Compatibility ### Single Source of Truth **No legacy URLs, no aliases, no fallbacks.** | Item | Action | |------|--------| | `/setup/add-keywords` URL | **REMOVE** - change to `/keywords-library` | | `/v1/auth/seed-keywords/` API | **REMOVE** - change to `/v1/keywords-library/` | | `fetchSeedKeywords()` function | **RENAME** to `fetchKeywordsLibrary()` | | Backend admin "Industry Sector Keywords" | **RENAME** to "Keywords Library" | | All references to old terms | **UPDATE** to new terms | ### Route Change (App.tsx) ```tsx // BEFORE } /> // AFTER (no redirect, direct change) } /> ``` ### API Change (auth/urls.py) ```python # BEFORE path('seed-keywords/', SeedKeywordViewSet.as_view({'get': 'list'}), name='seed-keyword-list'), # AFTER (no alias) urlpatterns = [ path('keywords-library/', include([ path('', SeedKeywordViewSet.as_view({'get': 'list'}), name='keywords-library-list'), path('filter_options/', SeedKeywordViewSet.as_view({'get': 'filter_options'}), name='keywords-library-filter-options'), path('sector_stats/', SeedKeywordViewSet.as_view({'get': 'sector_stats'}), name='keywords-library-sector-stats'), path('bulk_add/', SeedKeywordViewSet.as_view({'post': 'bulk_add'}), name='keywords-library-bulk-add'), ])), ] ``` ### File Renames | From | To | |------|-----| | `IndustriesSectorsKeywords.tsx` | `KeywordsLibrary.tsx` | | `Step4AddKeywords.tsx` | `Step4KeywordsLibrary.tsx` | --- ## Part 9: Success Metrics | Metric | Current | Target | |--------|---------|--------| | Filter usage rate | Low (no volume/sector filter) | High (all filters used) | | Keywords added per session | ~50 (quick-start only) | 100+ (smart bulk adds) | | Bulk add usage | N/A | Track [+50], [+100], [+200] clicks | | Sector card clicks | N/A | Track filtering by sector | | Smart suggestions engagement | N/A | Track after search/filter | | Time to first keyword add | Unknown | < 30 seconds | --- ## Part 10: Design Decisions Summary | Decision | Choice | Rationale | |----------|--------|-----------| | **URL** | `/keywords-library` | Clean, no legacy compat | | **Naming** | "Keywords Library" (plural) | Consistent across all surfaces | | **Backward Compat** | None | Single source of truth | | **Sector cards click** | Filters table | Intuitive UX | | **High Volume threshold** | Dynamic (top 50/100 lowest) | Adapts to actual data | | **Low Difficulty** | ≤ 40 (levels 1-2 mapped) | "Easy" keywords | | **Bulk add options** | 50, 100, 200, All | Flexible choices | | **Confirmation modal** | Always | Prevent accidental adds | | **Smart suggestions** | Breathing indicator until search | Encourages interaction | | **Filter styling** | Match Planner pages | Consistency | --- ## Files Summary ### Files to Modify | File | Changes | |------|---------| | `frontend/src/pages/Setup/IndustriesSectorsKeywords.tsx` | Major rewrite → rename to KeywordsLibrary.tsx | | `frontend/src/services/api.ts` | Rename + add new API functions | | `frontend/src/layout/AppHeader.tsx` | Move route category | | `frontend/src/layout/AppSidebar.tsx` | Update label to "Keywords Library" | | `frontend/src/App.tsx` | Change route (no redirect) | | `frontend/src/components/common/SearchModal.tsx` | Update references | | `backend/igny8_core/auth/views.py` | Add new endpoints, update existing | | `backend/igny8_core/auth/urls.py` | Change URL (no alias) | | `backend/igny8_core/admin/` | Update menu label | ### Files to Create | File | Purpose | |------|---------| | `frontend/src/components/keywords-library/SectorMetricCard.tsx` | Sector stats card with 6 stat options | | `frontend/src/components/keywords-library/SmartSuggestions.tsx` | Smart suggestions with breathing indicator | | `frontend/src/components/keywords-library/BulkAddConfirmation.tsx` | Confirmation modal for bulk adds | ### Files to Rename | From | To | |------|-----| | `IndustriesSectorsKeywords.tsx` | `KeywordsLibrary.tsx` | | `Step4AddKeywords.tsx` | `Step4KeywordsLibrary.tsx` | --- ## Approval Checklist - [x] Review by Product Owner - **APPROVED** - [x] Design decisions finalized - [x] Backend API design approved - [x] Frontend component design approved - [x] No backward compatibility confirmed - [ ] Implementation started --- ## Appendix A: Complete List of Files to Refactor ### Frontend Source Files (Must Change) | File | Changes Required | |------|------------------| | `frontend/src/App.tsx` | Change route `/setup/add-keywords` → `/keywords-library`, remove `IndustriesSectorsKeywords` import | | `frontend/src/layout/AppHeader.tsx` | Remove `/setup/add-keywords` from `SITE_AND_SECTOR_ROUTES`, add `/keywords-library` to `SINGLE_SITE_ROUTES` | | `frontend/src/layout/AppSidebar.tsx` | Change label "Keyword Library" → "Keywords Library", path `/setup/add-keywords` → `/keywords-library` | | `frontend/src/services/api.ts` | Rename `fetchSeedKeywords()` → `fetchKeywordsLibrary()`, rename `SeedKeyword` interface (user-facing), update API URL | | `frontend/src/components/common/SearchModal.tsx` | Change all `/setup/add-keywords` → `/keywords-library`, "Keyword Library" → "Keywords Library" | | `frontend/src/components/sites/SiteSetupChecklist.tsx` | Change href `/setup/add-keywords` → `/keywords-library` | | `frontend/src/components/dashboard/QuickActionsWidget.tsx` | Change "Keyword Library" → "Keywords Library" | | `frontend/src/components/onboarding/steps/Step4AddKeywords.tsx` | **RENAME FILE** → `Step4KeywordsLibrary.tsx`, update imports | | `frontend/src/components/onboarding/WorkflowGuide.tsx` | Update comment reference to `IndustriesSectorsKeywords` | | `frontend/src/pages/Setup/IndustriesSectorsKeywords.tsx` | **RENAME FILE** → `KeywordsLibrary.tsx`, **MAJOR REWRITE** | | `frontend/src/pages/Reference/SeedKeywords.tsx` | Update if needed for consistency | ### Backend Files (Must Change) | File | Changes Required | |------|------------------| | `backend/igny8_core/auth/urls.py` | Change route `seed-keywords/` → `keywords-library/` | | `backend/igny8_core/auth/views.py` | Keep `SeedKeywordViewSet` class name (internal), add new endpoints | | `backend/igny8_core/auth/serializers.py` | Keep `SeedKeywordSerializer` name (internal) | | `backend/igny8_core/auth/admin.py` | Update admin label to "Keywords Library" | | `backend/igny8_core/settings.py` | Change sidebar menu "Seed Keywords" → "Keywords Library" | | `backend/igny8_core/urls.py` | Update `seedkeyword_csv_template` and `seedkeyword_csv_import` URL paths | ### Backend Files (Keep Internal - SeedKeyword Model) | File | Status | |------|--------| | `backend/igny8_core/auth/models.py` | **KEEP** `SeedKeyword` class name (internal) | | `backend/igny8_core/business/planning/models.py` | **KEEP** `seed_keyword` field reference (internal) | | `backend/scripts/import_seed_keywords_single.py` | **KEEP** internal script name | | `backend/scripts/import_all_seed_keywords.py` | **KEEP** internal script name | ### Documentation Files (Must Update) | File | Changes Required | |------|------------------| | `docs/INDEX.md` | Update route `/setup/add-keywords` → `/keywords-library` | | `docs/20-API/ENDPOINTS.md` | Update endpoint `/seed-keywords/` → `/keywords-library/` | | `docs/90-REFERENCE/SEED-KEYWORDS-IMPORT-GUIDE.md` | Update user-facing terminology, keep internal references | | `docs/90-REFERENCE/MODELS.md` | Keep `SeedKeyword` model reference (internal) | | `docs/plans/NAVIGATION_REFACOTR/NAVIGATION_FINAL_COMPLETION_SUMMARY.md` | Update "Keyword Library" → "Keywords Library" | | `docs/plans/NAVIGATION_REFACOTR/NAVIGATION_REFACTOR_PLAN.md` | Update "Keyword Library" → "Keywords Library" | ### Other Files (May Need Review) | File | Notes | |------|-------| | `CHANGELOG.md` | Historical references - may keep as-is | | `.rules` | Keep `SeedKeyword` (internal model reference) | | `frontend/dist/` | **REBUILD** after changes | | `frontend/audit-results/` | Re-run audits after changes | --- **Status:** READY FOR IMPLEMENTATION **Next Steps:** Begin Phase 1 - Backend API Updates