diff --git a/docs/plans/PHASE-6-BACKUP-CLEANUP-GUIDE.md b/docs/plans/PHASE-6-BACKUP-CLEANUP-GUIDE.md new file mode 100644 index 00000000..889fe767 --- /dev/null +++ b/docs/plans/PHASE-6-BACKUP-CLEANUP-GUIDE.md @@ -0,0 +1,662 @@ +# Phase 6: Data Backup & Cleanup Guide + +**Version:** 1.0 +**Created:** January 9, 2026 +**Purpose:** Pre-V1.0 Launch Database Preparation + +--- + +## 📋 Table of Contents + +1. [Overview](#overview) +2. [What Was Created](#what-was-created) +3. [When to Use](#when-to-use) +4. [Pre-Execution Checklist](#pre-execution-checklist) +5. [Command 1: Export System Config](#command-1-export-system-config) +6. [Command 2: Cleanup User Data](#command-2-cleanup-user-data) +7. [Complete Workflow](#complete-workflow) +8. [Safety Measures](#safety-measures) +9. [Rollback Procedures](#rollback-procedures) +10. [FAQ](#faq) + +--- + +## 📖 Overview + +Phase 6 provides two Django management commands to safely prepare your IGNY8 database for V1.0 production launch: + +1. **Export System Configuration** - Backs up all system settings to JSON files +2. **Cleanup User Data** - Removes all test/development user data while preserving system configuration + +### Why These Commands? + +- **Clean Start**: Launch V1.0 with a pristine database +- **Configuration Preservation**: Keep all your carefully configured settings +- **Safety First**: Multiple safety checks and dry-run options +- **Audit Trail**: Complete metadata and logging + +--- + +## 🛠️ What Was Created + +### File Locations + +``` +backend/igny8_core/management/commands/ +├── export_system_config.py # System configuration backup +└── cleanup_user_data.py # User data cleanup +``` + +### Command 1: `export_system_config.py` + +**Purpose**: Exports all system configuration to JSON files for backup and version control. + +**What it exports:** +- ✅ Subscription Plans (Starter, Growth, Scale) +- ✅ Credit Cost Configurations +- ✅ AI Model Settings (OpenAI, Anthropic, etc.) +- ✅ Global Integration Settings +- ✅ Industries and Sectors +- ✅ Seed Keywords (reference data) +- ✅ Author Profiles +- ✅ AI Prompts and Variables + +**What it creates:** +- Individual JSON files for each data type +- `export_metadata.json` with timestamp and statistics +- Organized folder structure in `backups/config/` + +### Command 2: `cleanup_user_data.py` + +**Purpose**: Safely removes all user-generated test data before production launch. + +**What it deletes:** +- 🗑️ Sites and Site Settings +- 🗑️ Keywords, Clusters, Ideas +- 🗑️ Tasks, Content, Images +- 🗑️ Publishing Records +- 🗑️ WordPress Sync Events +- 🗑️ Credit Transactions and Usage Logs +- 🗑️ Automation Runs +- 🗑️ Notifications +- 🗑️ Orders + +**What it preserves:** +- ✅ User Accounts (admin users) +- ✅ System Configuration (all settings from export) +- ✅ Plans and Pricing +- ✅ AI Models and Prompts +- ✅ Industries and Sectors + +--- + +## ⏰ When to Use + +### Correct Timing + +✅ **Use these commands when:** +- You're preparing for V1.0 production launch +- You've completed all testing and configuration +- You want to start production with clean data +- All system settings (Plans, AI models, prompts) are finalized + +❌ **Do NOT use these commands when:** +- You're still in active development +- You haven't backed up your configurations +- You're unsure about your system settings +- You're in production with live users + +### Recommended Timeline + +``` +Day -7: Final configuration review +Day -5: Export system config (first backup) +Day -3: Test commands in staging +Day -2: Export system config (final backup) +Day -1: Cleanup user data in staging +Day 0: Launch day - cleanup in production +``` + +--- + +## ✅ Pre-Execution Checklist + +Before running ANY Phase 6 command, complete this checklist: + +### Environment Verification + +- [ ] Confirm you're in the correct environment (staging vs production) +- [ ] Check `ENVIRONMENT` setting in Django settings +- [ ] Verify database connection is correct +- [ ] Ensure you have full database backup + +### System State + +- [ ] All Plans configured and tested +- [ ] All AI prompts finalized +- [ ] All credit costs verified +- [ ] All industries/sectors populated +- [ ] Seed keywords imported + +### Safety Backups + +- [ ] Full database dump exists +- [ ] Previous export exists (if available) +- [ ] Media files backed up +- [ ] Environment variables documented + +### Access & Permissions + +- [ ] You have Django shell access +- [ ] You have database backup access +- [ ] You have rollback permissions +- [ ] Stakeholders notified + +--- + +## 📤 Command 1: Export System Config + +### Basic Usage + +```bash +cd /data/app/igny8/backend +python manage.py export_system_config +``` + +### With Custom Output Directory + +```bash +python manage.py export_system_config --output-dir=/path/to/backup +``` + +### Step-by-Step Execution + +#### Step 1: Navigate to Backend + +```bash +cd /data/app/igny8/backend +``` + +#### Step 2: Run Export + +```bash +python manage.py export_system_config --output-dir=../backups/config/$(date +%Y%m%d) +``` + +#### Step 3: Verify Output + +```bash +ls -la ../backups/config/$(date +%Y%m%d)/ +``` + +Expected output: +``` +plans.json # Subscription plans +credit_costs.json # Credit cost configurations +ai_models.json # AI model settings +global_integrations.json # Integration settings +industries.json # Industry master data +sectors.json # Sector master data +seed_keywords.json # Reference keywords +author_profiles.json # Writing style profiles +prompts.json # AI prompts +prompt_variables.json # Prompt variables +export_metadata.json # Export timestamp & stats +``` + +#### Step 4: Verify Data + +Check one of the exports: +```bash +cat ../backups/config/$(date +%Y%m%d)/plans.json | head -20 +``` + +#### Step 5: Commit to Version Control + +```bash +cd /data/app/igny8 +git add backups/config/ +git commit -m "Backup: V1.0 system configuration export" +git push +``` + +### What The Output Looks Like + +``` +Exporting system configuration to: /data/app/igny8/backups/config/20260109 + +✓ Exported 3 Subscription Plans → plans.json +✓ Exported 12 Credit Cost Configurations → credit_costs.json +✓ Exported 4 AI Model Configurations → ai_models.json +✓ Exported 1 Global Integration Settings → global_integrations.json +✓ Exported 15 Industries → industries.json +✓ Exported 47 Sectors → sectors.json +✓ Exported 523 Seed Keywords → seed_keywords.json +✓ Exported 3 Author Profiles → author_profiles.json +✓ Exported 8 AI Prompts → prompts.json +✓ Exported 12 Prompt Variables → prompt_variables.json + +✓ Metadata saved to export_metadata.json + +====================================================================== +System Configuration Export Complete! + + Successful: 10 exports + Failed: 0 exports + Location: /data/app/igny8/backups/config/20260109 +====================================================================== +``` + +### Troubleshooting + +**Problem**: "No module named 'django'" +```bash +# Solution: Activate virtual environment or use Docker +docker-compose exec backend python manage.py export_system_config +``` + +**Problem**: "Permission denied" when writing files +```bash +# Solution: Check directory permissions +mkdir -p ../backups/config +chmod 755 ../backups/config +``` + +**Problem**: Empty JSON files +```bash +# Solution: Verify data exists in database +python manage.py shell +>>> from igny8_core.modules.billing.models import Plan +>>> Plan.objects.count() +``` + +--- + +## 🗑️ Command 2: Cleanup User Data + +### ⚠️ CRITICAL WARNING + +**THIS COMMAND PERMANENTLY DELETES DATA** + +- Cannot be undone without database restore +- Removes ALL user-generated content +- Should ONLY be run before production launch +- ALWAYS run `--dry-run` first + +### Safety Features + +1. **Dry-Run Mode**: Preview deletions without actually deleting +2. **Confirmation Prompt**: Must type "DELETE ALL DATA" to proceed +3. **Production Protection**: Blocked in production environment (unless explicitly allowed) +4. **Transaction Safety**: All deletions in atomic transaction +5. **Detailed Logging**: Shows exactly what was deleted + +### Usage: Dry Run (Always First!) + +```bash +cd /data/app/igny8/backend +python manage.py cleanup_user_data --dry-run +``` + +### Dry Run Output Example + +``` +====================================================================== +DRY RUN - No data will be deleted +====================================================================== + + ✓ Would delete 1,234 Notifications + ✓ Would delete 5,678 Credit Usage Logs + ✓ Would delete 456 Credit Transactions + ✓ Would delete 23 Orders + ✓ Would delete 8,901 WordPress Sync Events + ✓ Would delete 234 Publishing Records + ✓ Would delete 45 Automation Runs + ✓ Would delete 3,456 Images + ✓ Would delete 2,345 Content + ✓ Would delete 4,567 Tasks + ✓ Would delete 5,678 Content Ideas + ✓ Would delete 1,234 Clusters + ✓ Would delete 9,876 Keywords + ✓ Would delete 12 Sites + + → Keeping 3 Users (not deleted) + + Total records to delete: 43,739 + +====================================================================== +To proceed with actual deletion, run: + python manage.py cleanup_user_data --confirm +====================================================================== +``` + +### Usage: Actual Cleanup + +```bash +python manage.py cleanup_user_data --confirm +``` + +**You will be prompted:** +``` +====================================================================== +⚠️ DELETING ALL USER DATA - THIS CANNOT BE UNDONE! +====================================================================== + +Type "DELETE ALL DATA" to proceed: +``` + +**Type exactly:** `DELETE ALL DATA` + +### Actual Cleanup Output + +``` +Proceeding with deletion... + +✓ Deleted 1,234 Notifications +✓ Deleted 5,678 Credit Usage Logs +✓ Deleted 456 Credit Transactions +✓ Deleted 23 Orders +✓ Deleted 8,901 WordPress Sync Events +✓ Deleted 234 Publishing Records +✓ Deleted 45 Automation Runs +✓ Deleted 3,456 Images +✓ Deleted 2,345 Content +✓ Deleted 4,567 Tasks +✓ Deleted 5,678 Content Ideas +✓ Deleted 1,234 Clusters +✓ Deleted 9,876 Keywords +✓ Deleted 12 Sites + +====================================================================== +User Data Cleanup Complete! + + Total records deleted: 43,739 + Failed deletions: 0 +====================================================================== +``` + +### Production Environment Protection + +If you try to run cleanup in production: + +``` +⚠️ BLOCKED: Cannot run cleanup in PRODUCTION environment! + +To allow this, temporarily set ENVIRONMENT to "staging" in settings. +``` + +To override (ONLY if absolutely necessary): + +```python +# In settings.py - TEMPORARY +ENVIRONMENT = 'staging' # Change back after cleanup! +``` + +--- + +## 🔄 Complete Workflow + +### Full Pre-Launch Procedure + +```bash +# ======================================== +# STEP 1: FULL DATABASE BACKUP +# ======================================== +cd /data/app/igny8/backend +pg_dump -h localhost -U postgres igny8_db > ../backups/$(date +%Y%m%d)_pre_v1_full_backup.sql + +# Verify backup exists and has content +ls -lh ../backups/$(date +%Y%m%d)_pre_v1_full_backup.sql +head -50 ../backups/$(date +%Y%m%d)_pre_v1_full_backup.sql + + +# ======================================== +# STEP 2: EXPORT SYSTEM CONFIGURATION +# ======================================== +python manage.py export_system_config --output-dir=../backups/config/$(date +%Y%m%d) + +# Verify exports +ls -la ../backups/config/$(date +%Y%m%d)/ + +# Review critical configs +cat ../backups/config/$(date +%Y%m%d)/plans.json | python -m json.tool | head -30 +cat ../backups/config/$(date +%Y%m%d)/credit_costs.json | python -m json.tool | head -30 + + +# ======================================== +# STEP 3: COMMIT CONFIGS TO GIT +# ======================================== +cd /data/app/igny8 +git add backups/config/ +git commit -m "Pre-V1.0: System configuration backup $(date +%Y%m%d)" +git push + + +# ======================================== +# STEP 4: BACKUP MEDIA FILES +# ======================================== +cd /data/app/igny8 +tar -czf backups/$(date +%Y%m%d)_media_backup.tar.gz backend/media/ + + +# ======================================== +# STEP 5: DRY RUN CLEANUP (REVIEW CAREFULLY) +# ======================================== +cd backend +python manage.py cleanup_user_data --dry-run + +# Review the counts - make sure they're expected + + +# ======================================== +# STEP 6: ACTUAL CLEANUP (POINT OF NO RETURN) +# ======================================== +python manage.py cleanup_user_data --confirm +# Type: DELETE ALL DATA + + +# ======================================== +# STEP 7: VERIFY CLEANUP +# ======================================== +python manage.py shell << 'EOF' +from igny8_core.auth.models import Site, CustomUser +from igny8_core.business.planning.models import Keywords +from igny8_core.modules.billing.models import Plan + +print(f"Sites: {Site.objects.count()} (should be 0)") +print(f"Keywords: {Keywords.objects.count()} (should be 0)") +print(f"Users: {CustomUser.objects.count()} (admins preserved)") +print(f"Plans: {Plan.objects.count()} (should have your plans)") +EOF + + +# ======================================== +# STEP 8: TEST APPLICATION +# ======================================== +python manage.py runserver 0.0.0.0:8000 & +# Visit app and verify: +# - Can login as admin +# - Dashboard loads (empty state) +# - Plans visible in settings +# - Can create new user account + + +# ======================================== +# STEP 9: TAG RELEASE +# ======================================== +cd /data/app/igny8 +git tag -a v1.0.0-clean -m "V1.0.0 - Clean database ready for launch" +git push origin v1.0.0-clean +``` + +--- + +## 🛡️ Safety Measures + +### Built-in Protections + +1. **Atomic Transactions**: All deletions in single transaction - all or nothing +2. **Production Check**: Requires explicit override in production +3. **Confirmation Prompt**: Must type exact phrase +4. **Dry Run**: See exactly what will be deleted +5. **Detailed Logging**: Know what was deleted and any failures + +### Manual Safety Checklist + +Before running cleanup: + +- [ ] **Full database backup** exists and verified +- [ ] **System config export** completed and committed to git +- [ ] **Media files** backed up +- [ ] **Dry run reviewed** and counts are expected +- [ ] **Stakeholders notified** of pending cleanup +- [ ] **Rollback plan** documented and tested +- [ ] **Off-hours execution** scheduled (if production) +- [ ] **Monitoring ready** to catch any issues + +### Additional Recommendations + +1. **Staging First**: Always test in staging environment first +2. **Screenshot Evidence**: Take screenshots of dry-run output +3. **Communication**: Notify team before and after +4. **Timing**: Run during low-traffic hours +5. **Verification**: Test application immediately after + +--- + +## 🔙 Rollback Procedures + +### If Something Goes Wrong + +#### During Cleanup (Transaction Failed) + +No action needed - atomic transaction will automatically rollback. + +#### After Cleanup (Need to Restore) + +```bash +# OPTION 1: Restore from PostgreSQL backup +cd /data/app/igny8 +psql -U postgres -d igny8_db < backups/20260109_pre_v1_full_backup.sql + +# OPTION 2: Restore specific tables (if partial restore needed) +pg_restore -U postgres -d igny8_db -t "specific_table" backups/20260109_pre_v1_full_backup.sql + +# OPTION 3: Restore from Docker backup (if using Docker) +docker-compose exec -T db psql -U postgres igny8_db < backups/20260109_pre_v1_full_backup.sql +``` + +#### Restore Media Files + +```bash +cd /data/app/igny8 +tar -xzf backups/20260109_media_backup.tar.gz -C backend/ +``` + +#### Verify Restore + +```bash +cd backend +python manage.py shell << 'EOF' +from igny8_core.auth.models import Site +from igny8_core.business.planning.models import Keywords +print(f"Sites restored: {Site.objects.count()}") +print(f"Keywords restored: {Keywords.objects.count()}") +EOF +``` + +--- + +## ❓ FAQ + +### Q: Can I run these commands multiple times? + +**A:** +- **Export Config**: Yes, safe to run multiple times. Creates timestamped backups. +- **Cleanup**: Yes, but after first cleanup there's nothing left to delete (idempotent). + +### Q: What if I only want to delete some data? + +**A:** These commands are all-or-nothing by design for safety. To delete specific data, use Django admin or write a custom management command. + +### Q: Can I restore individual items from the export? + +**A:** Yes! The JSON files use Django's standard serialization format. Use `python manage.py loaddata .json` to restore. + +### Q: Will this affect my development environment? + +**A:** Only if you run it there. These commands work on whatever database your Django settings point to. + +### Q: How long does cleanup take? + +**A:** Depends on data volume. Typical ranges: +- Small (< 10k records): 1-5 seconds +- Medium (10k-100k): 5-30 seconds +- Large (> 100k): 30-120 seconds + +### Q: What if cleanup fails halfway? + +**A:** Can't happen - it's wrapped in an atomic transaction. Either everything deletes or nothing does. + +### Q: Do I need to stop the application? + +**A:** Recommended but not required. Stopping the app prevents race conditions during cleanup. + +### Q: Can I schedule these as cron jobs? + +**A:** +- **Export**: Yes, great for automated backups +- **Cleanup**: No, should only be run manually with explicit confirmation + +### Q: What about Django migrations? + +**A:** Cleanup only deletes data, not schema. All tables and migrations remain intact. + +### Q: How do I know if my system config is complete? + +**A:** Run the export and review the counts in `export_metadata.json`. Compare with your documentation. + +--- + +## 📞 Support + +### If You Need Help + +1. **Check this guide** thoroughly first +2. **Review error messages** carefully +3. **Test in staging** before production +4. **Contact team** if unsure about any step + +### Emergency Contacts + +- **Database Issues**: DBA team +- **Application Issues**: Backend team +- **Configuration Questions**: System admin +- **Rollback Needed**: All hands on deck! + +--- + +## ✅ Success Criteria + +After completing Phase 6, you should have: + +- ✅ Multiple timestamped config exports in `backups/config/` +- ✅ Full database SQL backup in `backups/` +- ✅ Media files backup in `backups/` +- ✅ Zero user-generated data in database +- ✅ All system configurations intact +- ✅ Application starts and loads empty state +- ✅ Admin can log in +- ✅ New users can sign up +- ✅ Plans visible and functional +- ✅ Git tag created for v1.0.0-clean + +--- + +**Document Version:** 1.0 +**Last Updated:** January 9, 2026 +**Next Review:** After V1.0 Launch + +--- + +*This guide is part of the IGNY8 Pre-Launch Preparation (Phase 6)* diff --git a/frontend/src/components/common/SearchModal.tsx b/frontend/src/components/common/SearchModal.tsx index 787ef55d..f9581a77 100644 --- a/frontend/src/components/common/SearchModal.tsx +++ b/frontend/src/components/common/SearchModal.tsx @@ -7,17 +7,60 @@ import { useNavigate } from 'react-router-dom'; import { Modal } from '../ui/modal'; import Button from '../ui/button/Button'; +// Add styles for highlighted search terms +const searchHighlightStyles = ` + .search-result mark { + background-color: rgb(252 211 77); /* amber-300 */ + color: rgb(17 24 39); /* gray-900 */ + padding: 0 0.25rem; + border-radius: 0.25rem; + font-weight: 500; + transition: all 0.2s; + } + .dark .search-result mark { + background-color: rgb(180 83 9); /* amber-700 */ + color: rgb(255 255 255); + } + .search-result:hover mark { + background-color: rgb(245 158 11); /* amber-500 */ + color: rgb(255 255 255); + box-shadow: 0 0 0 2px rgb(245 158 11 / 0.3); + } + .dark .search-result:hover mark { + background-color: rgb(217 119 6); /* amber-600 */ + box-shadow: 0 0 0 2px rgb(217 119 6 / 0.3); + } +`; + interface SearchModalProps { isOpen: boolean; onClose: () => void; } +interface QuickAction { + label: string; + path?: string; + action?: () => void; +} + interface SearchResult { title: string; path: string; type: 'workflow' | 'setup' | 'account' | 'help'; category: string; + description?: string; icon?: string; + quickActions?: QuickAction[]; + keywords?: string[]; // Additional searchable terms + content?: string; // Page content hints for better search + contextSnippet?: string; // Context around matched text +} + +interface SuggestedQuestion { + question: string; + answer: string; + helpSection: string; + path: string; } type FilterType = 'all' | 'workflow' | 'setup' | 'account' | 'help'; @@ -25,32 +68,378 @@ type FilterType = 'all' | 'workflow' | 'setup' | 'account' | 'help'; const RECENT_SEARCHES_KEY = 'igny8_recent_searches'; const MAX_RECENT_SEARCHES = 5; +// Knowledge base for suggested questions and answers +// Keys include main terms + common aliases for better search matching +const HELP_KNOWLEDGE_BASE: Record = { + 'keyword': [ + { question: 'How do I import keywords?', answer: 'Go to Add Keywords page and either select your industry/sector for seed keywords or upload a CSV file with your own keywords.', helpSection: 'Importing Keywords', path: '/help#importing-keywords' }, + { question: 'How do I organize keywords into clusters?', answer: 'Navigate to Clusters page and run the AI clustering algorithm. It will automatically group similar keywords by topic.', helpSection: 'Keyword Clustering', path: '/help#keyword-clustering' }, + { question: 'Can I bulk delete keywords?', answer: 'Yes, on the Keywords page select multiple keywords using checkboxes and click the bulk delete action button.', helpSection: 'Managing Keywords', path: '/help#managing-keywords' }, + ], + 'cluster': [ // Added alias for clustering + { question: 'How do I organize keywords into clusters?', answer: 'Navigate to Clusters page and run the AI clustering algorithm. It will automatically group similar keywords by topic.', helpSection: 'Keyword Clustering', path: '/help#keyword-clustering' }, + { question: 'Can I bulk delete keywords?', answer: 'Yes, on the Keywords page select multiple keywords using checkboxes and click the bulk delete action button.', helpSection: 'Managing Keywords', path: '/help#managing-keywords' }, + ], + 'task': [ // Added for tasks + { question: 'How do I generate content?', answer: 'Convert content ideas to tasks in the Queue, or create tasks manually. The AI will generate content based on your keywords and settings.', helpSection: 'Content Generation', path: '/help#content-generation' }, + { question: 'What is the difference between Tasks and Content?', answer: 'Tasks are content ideas converted into actionable writing assignments with status tracking. Content is the actual generated articles created from tasks.', helpSection: 'Content Workflow', path: '/help#content-workflow' }, + ], + 'content': [ + { question: 'How do I generate content?', answer: 'Convert content ideas to tasks in the Queue, or create tasks manually. The AI will generate content based on your keywords and settings.', helpSection: 'Content Generation', path: '/help#content-generation' }, + { question: 'How do I edit generated content?', answer: 'Go to Drafts page, click on any content to open the editor. You can edit text, title, and metadata before approving.', helpSection: 'Editing Content', path: '/help#editing-content' }, + { question: 'What content settings can I configure?', answer: 'In Content Settings you can set default length, tone, style, SEO preferences, and image generation settings.', helpSection: 'Content Settings', path: '/help#content-settings' }, + { question: 'How do I approve content for publishing?', answer: 'Review content in the Review page, then click approve to move it to the Approved queue ready for publishing.', helpSection: 'Content Workflow', path: '/help#content-workflow' }, + ], + 'writing': [ // Added alias + { question: 'How do I generate content?', answer: 'Convert content ideas to tasks in the Queue, or create tasks manually. The AI will generate content based on your keywords and settings.', helpSection: 'Content Generation', path: '/help#content-generation' }, + { question: 'How do I edit generated content?', answer: 'Go to Drafts page, click on any content to open the editor. You can edit text, title, and metadata before approving.', helpSection: 'Editing Content', path: '/help#editing-content' }, + ], + 'publish': [ + { question: 'How do I publish to WordPress?', answer: 'Connect your WordPress site in Sites page, then use Content Calendar to schedule or immediately publish approved content.', helpSection: 'Publishing', path: '/help#publishing-wordpress' }, + { question: 'Can I schedule posts in advance?', answer: 'Yes, in the Content Calendar you can drag and drop content to specific dates and times for automatic publishing.', helpSection: 'Scheduling', path: '/help#scheduling-posts' }, + { question: 'How do I connect a WordPress site?', answer: 'Go to Sites page, click Add Site, enter your WordPress URL and credentials. Test the connection before saving.', helpSection: 'WordPress Integration', path: '/help#wordpress-integration' }, + ], + 'wordpress': [ // Added alias + { question: 'How do I publish to WordPress?', answer: 'Connect your WordPress site in Sites page, then use Content Calendar to schedule or immediately publish approved content.', helpSection: 'Publishing', path: '/help#publishing-wordpress' }, + { question: 'How do I connect a WordPress site?', answer: 'Go to Sites page, click Add Site, enter your WordPress URL and credentials. Test the connection before saving.', helpSection: 'WordPress Integration', path: '/help#wordpress-integration' }, + ], + 'schedule': [ // Added alias + { question: 'Can I schedule posts in advance?', answer: 'Yes, in the Content Calendar you can drag and drop content to specific dates and times for automatic publishing.', helpSection: 'Scheduling', path: '/help#scheduling-posts' }, + ], + 'image': [ + { question: 'How do I generate images?', answer: 'Images are auto-generated with content. You can also regenerate specific images from the Images page with custom prompts.', helpSection: 'Image Generation', path: '/help#image-generation' }, + { question: 'Can I use different AI image models?', answer: 'Yes, configure your preferred AI image model (DALL-E, Midjourney, Stable Diffusion) in Content Settings under Images.', helpSection: 'Image Settings', path: '/help#image-settings' }, + { question: 'How do I assign images to content?', answer: 'From the Images page, click on an image and select which content to assign it as featured image.', helpSection: 'Managing Images', path: '/help#managing-images' }, + ], + 'picture': [ // Added alias + { question: 'How do I generate images?', answer: 'Images are auto-generated with content. You can also regenerate specific images from the Images page with custom prompts.', helpSection: 'Image Generation', path: '/help#image-generation' }, + ], + 'credit': [ + { question: 'How do credits work?', answer: 'Credits are consumed for AI operations: keyword clustering, content generation, and image creation. Check Usage Analytics for detailed breakdown.', helpSection: 'Credit System', path: '/help#credit-system' }, + { question: 'How do I buy more credits?', answer: 'Go to Plans & Billing page to purchase credit packs or upgrade your subscription plan for more monthly credits.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + { question: 'Where can I see credit usage?', answer: 'Usage Analytics page shows detailed charts and logs of credit consumption by action type and date.', helpSection: 'Usage Tracking', path: '/help#usage-tracking' }, + ], + 'billing': [ // Added for billing + { question: 'How do I buy more credits?', answer: 'Go to Plans & Billing page to purchase credit packs or upgrade your subscription plan for more monthly credits.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + { question: 'What payment methods are supported?', answer: 'IGNY8 supports Stripe (credit/debit cards), PayPal, and Bank Transfer (for annual plans). Available methods vary by country.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + ], + 'payment': [ // Added alias + { question: 'How do I buy more credits?', answer: 'Go to Plans & Billing page to purchase credit packs or upgrade your subscription plan for more monthly credits.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + { question: 'What payment methods are supported?', answer: 'IGNY8 supports Stripe (credit/debit cards), PayPal, and Bank Transfer (for annual plans). Available methods vary by country.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + ], + 'invoice': [ // Added for invoice + { question: 'How do I buy more credits?', answer: 'Go to Plans & Billing page to purchase credit packs or upgrade your subscription plan for more monthly credits.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + { question: 'Where can I see billing history?', answer: 'Go to Plans & Billing page to view your invoices, payment history, and download receipts for your records.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + ], + 'plan': [ // Added for subscription plans + { question: 'How do I buy more credits?', answer: 'Go to Plans & Billing page to purchase credit packs or upgrade your subscription plan for more monthly credits.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + { question: 'Can I upgrade my plan?', answer: 'Yes, go to Plans & Billing to upgrade or downgrade your subscription. Changes take effect immediately with prorated billing.', helpSection: 'Purchasing Credits', path: '/help#purchasing-credits' }, + ], + 'usage': [ // Added for usage + { question: 'Where can I see credit usage?', answer: 'Usage Analytics page shows detailed charts and logs of credit consumption by action type and date.', helpSection: 'Usage Tracking', path: '/help#usage-tracking' }, + { question: 'How do credits work?', answer: 'Credits are consumed for AI operations: keyword clustering, content generation, and image creation. Check Usage Analytics for detailed breakdown.', helpSection: 'Credit System', path: '/help#credit-system' }, + ], + 'automation': [ + { question: 'How do I set up automation?', answer: 'Go to Automation page to configure recurring tasks: auto-clustering, scheduled content generation, and auto-publishing rules.', helpSection: 'Automation Setup', path: '/help#automation-setup' }, + { question: 'Can content be auto-published?', answer: 'Yes, enable auto-approval rules in Automation and set publishing schedules in Content Calendar for fully automated workflows.', helpSection: 'Auto-Publishing', path: '/help#auto-publishing' }, + ], + 'team': [ + { question: 'How do I invite team members?', answer: 'Go to Team Management, click Invite User, enter their email and assign a role. They will receive an invitation email.', helpSection: 'Team Collaboration', path: '/help#team-collaboration' }, + { question: 'What are the different user roles?', answer: 'Admin has full access, Editor can manage content, and Viewer can only view data. Configure in Team Management.', helpSection: 'User Roles', path: '/help#user-roles' }, + ], + 'user': [ // Added alias + { question: 'How do I invite team members?', answer: 'Go to Team Management, click Invite User, enter their email and assign a role. They will receive an invitation email.', helpSection: 'Team Collaboration', path: '/help#team-collaboration' }, + { question: 'What are the different user roles?', answer: 'Admin has full access, Editor can manage content, and Viewer can only view data. Configure in Team Management.', helpSection: 'User Roles', path: '/help#user-roles' }, + ], + 'prompt': [ + { question: 'How do I customize AI prompts?', answer: 'Admins can edit AI prompt templates in Prompts page to control how content is generated.', helpSection: 'Prompt Management', path: '/help#prompt-management' }, + { question: 'What are author profiles?', answer: 'Author profiles define writing styles (tone, vocabulary, structure) that you can assign to content for consistent brand voice.', helpSection: 'Author Profiles', path: '/help#author-profiles' }, + ], + 'ai': [ // Added alias + { question: 'How do I customize AI prompts?', answer: 'Admins can edit AI prompt templates in Prompts page to control how content is generated.', helpSection: 'Prompt Management', path: '/help#prompt-management' }, + { question: 'Can I use different AI image models?', answer: 'Yes, configure your preferred AI image model (DALL-E, Midjourney, Stable Diffusion) in Content Settings under Images.', helpSection: 'Image Settings', path: '/help#image-settings' }, + ], +}; + const SEARCH_ITEMS: SearchResult[] = [ - // Workflow - { title: 'Keywords', path: '/planner/keywords', type: 'workflow', category: 'Planner' }, - { title: 'Clusters', path: '/planner/clusters', type: 'workflow', category: 'Planner' }, - { title: 'Ideas', path: '/planner/ideas', type: 'workflow', category: 'Planner' }, - { title: 'Queue', path: '/writer/tasks', type: 'workflow', category: 'Writer' }, - { title: 'Drafts', path: '/writer/content', type: 'workflow', category: 'Writer' }, - { title: 'Images', path: '/writer/images', type: 'workflow', category: 'Writer' }, - { title: 'Review', path: '/writer/review', type: 'workflow', category: 'Writer' }, - { title: 'Approved', path: '/writer/approved', type: 'workflow', category: 'Writer' }, - { title: 'Automation', path: '/automation', type: 'workflow', category: 'Automation' }, - { title: 'Content Calendar', path: '/publisher/content-calendar', type: 'workflow', category: 'Publisher' }, + // Workflow - Planner + { + title: 'Keywords', + path: '/planner/keywords', + type: 'workflow', + category: 'Planner', + description: 'Manage and organize your keywords', + keywords: ['keyword', 'search terms', 'seo', 'target', 'focus', 'research', 'phrases', 'queries'], + content: 'View and manage all your target keywords. Filter by cluster, search volume, or status. Bulk actions: delete, assign to cluster, export to CSV. Table shows keyword text, search volume, cluster assignment, and status.', + quickActions: [ + { label: 'Import Keywords', path: '/setup/add-keywords' }, + { label: 'View Clusters', path: '/planner/clusters' }, + ] + }, + { + title: 'Clusters', + path: '/planner/clusters', + type: 'workflow', + category: 'Planner', + description: 'AI-grouped keyword clusters', + keywords: ['cluster', 'groups', 'topics', 'themes', 'organize', 'categorize', 'ai grouping'], + content: 'View AI-generated keyword clusters grouped by topic similarity. Each cluster shows assigned keywords count and suggested content topics. Run clustering algorithm, view cluster details, generate content ideas from clusters.', + quickActions: [ + { label: 'Generate Ideas', path: '/planner/ideas' }, + { label: 'View Keywords', path: '/planner/keywords' }, + ] + }, + { + title: 'Ideas', + path: '/planner/ideas', + type: 'workflow', + category: 'Planner', + description: 'Content ideas from clusters', + keywords: ['ideas', 'suggestions', 'topics', 'content planning', 'brainstorm', 'article ideas'], + content: 'AI-generated content ideas based on keyword clusters. Review suggested titles, topics, and angles. Convert ideas to writing tasks with one click. Filter by cluster, status, or keyword.', + quickActions: [ + { label: 'Convert to Tasks', path: '/writer/tasks' }, + { label: 'View Clusters', path: '/planner/clusters' }, + ] + }, + // Workflow - Writer + { + title: 'Queue', + path: '/writer/tasks', + type: 'workflow', + category: 'Writer', + description: 'Content generation queue', + keywords: ['queue', 'tasks', 'writing', 'generation', 'pending', 'in progress', 'batch', 'jobs'], + content: 'Content generation task queue. View pending, in-progress, and completed tasks. Monitor AI writing progress, cancel tasks, regenerate content. Shows task title, status, keywords, and generation progress.', + quickActions: [ + { label: 'View Drafts', path: '/writer/content' }, + { label: 'Check Images', path: '/writer/images' }, + ] + }, + { + title: 'Drafts', + path: '/writer/content', + type: 'workflow', + category: 'Writer', + description: 'Generated content drafts', + keywords: ['drafts', 'content', 'articles', 'posts', 'generated', 'ai writing', 'edit', 'review'], + content: 'All AI-generated content drafts. Edit content in rich text editor, adjust title and metadata, assign featured images. Filter by keyword, status, or generation date. Bulk approve or delete drafts.', + quickActions: [ + { label: 'Move to Review', path: '/writer/review' }, + { label: 'View Images', path: '/writer/images' }, + ] + }, + { + title: 'Images', + path: '/writer/images', + type: 'workflow', + category: 'Writer', + description: 'AI-generated images', + keywords: ['images', 'pictures', 'graphics', 'featured image', 'midjourney', 'dall-e', 'stable diffusion', 'ai art'], + content: 'AI-generated images library. View all generated images with prompts, assign to content, regenerate images. Filter by status, generation date, or content assignment. Supports multiple AI image models.', + quickActions: [ + { label: 'View Content', path: '/writer/content' }, + { label: 'Image Settings', path: '/account/content-settings/images' }, + ] + }, + { + title: 'Review', + path: '/writer/review', + type: 'workflow', + category: 'Writer', + description: 'Content pending review', + keywords: ['review', 'approve', 'quality check', 'editorial', 'pending approval'], + content: 'Review AI-generated content before publishing. Check quality, accuracy, and brand alignment. Approve for publishing or send back to drafts for revisions.', + quickActions: [ + { label: 'Approve Content', path: '/writer/approved' }, + { label: 'View Drafts', path: '/writer/content' }, + ] + }, + { + title: 'Approved', + path: '/writer/approved', + type: 'workflow', + category: 'Writer', + description: 'Ready to publish', + keywords: ['approved', 'ready', 'final', 'publish ready', 'scheduled'], + content: 'Approved content ready for publishing. Schedule for auto-publish or manually publish to WordPress sites. View publishing status and scheduled dates.', + quickActions: [ + { label: 'Schedule Publishing', path: '/publisher/content-calendar' }, + { label: 'View Sites', path: '/sites' }, + ] + }, + // Workflow - Automation + { + title: 'Automation', + path: '/automation', + type: 'workflow', + category: 'Automation', + description: 'Pipeline automation settings', + keywords: ['automation', 'pipeline', 'workflow', 'auto', 'schedule', 'recurring', 'batch processing'], + content: 'Configure automated content pipeline. Set up recurring keyword clustering, content generation schedules, auto-approval rules, and publishing automation. Monitor automation runs and logs.', + quickActions: [ + { label: 'View Keywords', path: '/planner/keywords' }, + { label: 'Check Queue', path: '/writer/tasks' }, + ] + }, + // Workflow - Publisher + { + title: 'Content Calendar', + path: '/publisher/content-calendar', + type: 'workflow', + category: 'Publisher', + description: 'Schedule and publish content', + keywords: ['calendar', 'schedule', 'publish', 'wordpress', 'posting', 'timeline', 'planning'], + content: 'Visual content calendar showing scheduled posts. Drag-and-drop to reschedule, bulk publish, view publishing history. Connect to WordPress sites for direct publishing.', + quickActions: [ + { label: 'View Approved', path: '/writer/approved' }, + { label: 'Manage Sites', path: '/sites' }, + ] + }, // Setup - { title: 'Sites', path: '/sites', type: 'setup', category: 'Sites' }, - { title: 'Add Keywords', path: '/setup/add-keywords', type: 'setup', category: 'Setup' }, - { title: 'Content Settings', path: '/account/content-settings', type: 'setup', category: 'Settings' }, - { title: 'Prompts', path: '/thinker/prompts', type: 'setup', category: 'AI' }, - { title: 'Author Profiles', path: '/thinker/author-profiles', type: 'setup', category: 'AI' }, + { + title: 'Sites', + path: '/sites', + type: 'setup', + category: 'Sites', + description: 'WordPress site management', + keywords: ['sites', 'wordpress', 'blog', 'website', 'connection', 'integration', 'wp', 'domain'], + content: 'Manage WordPress site connections. Add new sites, configure API credentials, test connections. View site details, publishing settings, and connection status. Supports multiple WordPress sites.', + quickActions: [ + { label: 'Add Keywords', path: '/setup/add-keywords' }, + { label: 'Content Settings', path: '/account/content-settings' }, + ] + }, + { + title: 'Add Keywords', + path: '/setup/add-keywords', + type: 'setup', + category: 'Setup', + description: 'Import keywords by industry/sector', + keywords: ['import', 'add', 'bulk upload', 'csv', 'industry', 'sector', 'seed keywords', 'niche'], + content: 'Quick-start keyword import wizard. Select your industry and sector to import pre-researched seed keywords. Or upload your own CSV file with custom keywords. Bulk import thousands of keywords at once.', + quickActions: [ + { label: 'View Keywords', path: '/planner/keywords' }, + { label: 'Run Clustering', path: '/planner/clusters' }, + ] + }, + { + title: 'Content Settings', + path: '/account/content-settings', + type: 'setup', + category: 'Settings', + description: 'Configure content generation', + keywords: ['settings', 'configuration', 'content length', 'tone', 'style', 'formatting', 'seo', 'meta'], + content: 'Configure AI content generation settings. Set default content length, tone of voice, writing style, SEO settings. Configure image generation, meta descriptions, and content structure preferences.', + quickActions: [ + { label: 'Edit Prompts', path: '/thinker/prompts' }, + { label: 'Author Profiles', path: '/thinker/author-profiles' }, + ] + }, + { + title: 'Prompts', + path: '/thinker/prompts', + type: 'setup', + category: 'AI', + description: 'AI prompt templates (Admin)', + keywords: ['prompts', 'templates', 'ai instructions', 'system prompts', 'gpt', 'claude', 'llm'], + content: 'Manage AI prompt templates for content generation. Edit system prompts, user prompts, and prompt variables. Configure different prompts for articles, social posts, meta descriptions. Admin only.', + quickActions: [ + { label: 'Author Profiles', path: '/thinker/author-profiles' }, + { label: 'Content Settings', path: '/account/content-settings' }, + ] + }, + { + title: 'Author Profiles', + path: '/thinker/author-profiles', + type: 'setup', + category: 'AI', + description: 'Writing style profiles (Admin)', + keywords: ['author', 'voice', 'style', 'tone', 'personality', 'writing profile', 'brand voice'], + content: 'Create author personas for different writing styles. Configure tone, vocabulary level, sentence structure preferences. Assign author profiles to content for consistent brand voice. Admin only.', + quickActions: [ + { label: 'View Prompts', path: '/thinker/prompts' }, + { label: 'Content Settings', path: '/account/content-settings' }, + ] + }, // Account - { title: 'Account Settings', path: '/account/settings', type: 'account', category: 'Account' }, - { title: 'Plans & Billing', path: '/account/plans', type: 'account', category: 'Account' }, - { title: 'Usage Analytics', path: '/account/usage', type: 'account', category: 'Account' }, - { title: 'Team Management', path: '/account/settings/team', type: 'account', category: 'Account' }, - { title: 'Notifications', path: '/account/notifications', type: 'account', category: 'Account' }, + { + title: 'Account Settings', + path: '/account/settings', + type: 'account', + category: 'Account', + description: 'Profile and preferences', + keywords: ['account', 'profile', 'user', 'preferences', 'settings', 'password', 'email', 'name'], + content: 'Manage your account profile and preferences. Update name, email, password. Configure notification preferences, timezone, language. View account status and subscription details.', + quickActions: [ + { label: 'Team Management', path: '/account/settings/team' }, + { label: 'Notifications', path: '/account/notifications' }, + ] + }, + { + title: 'Plans & Billing', + path: '/account/plans', + type: 'account', + category: 'Account', + description: 'Subscription and credits', + keywords: ['billing', 'subscription', 'plan', 'credits', 'payment', 'upgrade', 'pricing', 'invoice'], + content: 'Manage subscription plan and credits. View current plan details, upgrade or downgrade. Purchase credit packs, view billing history and invoices. Configure payment methods.', + quickActions: [ + { label: 'Usage Analytics', path: '/account/usage' }, + { label: 'Purchase Credits', path: '/account/plans' }, + ] + }, + { + title: 'Usage Analytics', + path: '/account/usage', + type: 'account', + category: 'Account', + description: 'Credit usage and insights', + keywords: ['usage', 'analytics', 'stats', 'consumption', 'credits spent', 'reports', 'metrics'], + content: 'View detailed credit usage analytics. Charts and graphs showing daily/weekly/monthly consumption. Filter by action type (content generation, images, clustering). Export usage reports.', + quickActions: [ + { label: 'View Logs', path: '/account/usage/logs' }, + { label: 'Plans & Billing', path: '/account/plans' }, + ] + }, + { + title: 'Team Management', + path: '/account/settings/team', + type: 'account', + category: 'Account', + description: 'Invite and manage team members', + keywords: ['team', 'users', 'members', 'invite', 'permissions', 'roles', 'collaboration', 'access'], + content: 'Invite team members to your workspace. Manage user roles and permissions. View team activity, remove users, resend invitations. Configure collaboration settings and access controls.', + quickActions: [ + { label: 'Account Settings', path: '/account/settings' }, + { label: 'View Usage', path: '/account/usage' }, + ] + }, + { + title: 'Notifications', + path: '/account/notifications', + type: 'account', + category: 'Account', + description: 'System and content notifications', + keywords: ['notifications', 'alerts', 'updates', 'email notifications', 'bell', 'messages'], + content: 'View all system notifications and content updates. Mark as read, filter by type. Configure notification preferences for email and in-app alerts. See content generation completions, publishing status, credit warnings.', + quickActions: [ + { label: 'Account Settings', path: '/account/settings' }, + ] + }, // Help - { title: 'Help & Support', path: '/help', type: 'help', category: 'Help' }, + { + title: 'Help & Support', + path: '/help', + type: 'help', + category: 'Help', + description: 'Documentation and support', + keywords: ['help', 'support', 'docs', 'documentation', 'guide', 'tutorial', 'faq', 'assistance'], + content: 'Access help documentation, user guides, and tutorials. Search knowledge base, view FAQs, contact support. Getting started guides, video tutorials, API documentation, and troubleshooting tips.', + quickActions: [ + { label: 'Get Started', path: '/setup/wizard' }, + ] + }, ]; export default function SearchModal({ isOpen, onClose }: SearchModalProps) { @@ -86,15 +475,140 @@ export default function SearchModal({ isOpen, onClose }: SearchModalProps) { .filter((item): item is SearchResult => item !== undefined); }; + // Enhanced search: title, category, description, keywords, and content + const searchItems = (searchQuery: string): SearchResult[] => { + const lowerQuery = searchQuery.toLowerCase().trim(); + if (!lowerQuery) return []; + + return SEARCH_ITEMS.filter(item => { + const matchesFilter = activeFilter === 'all' || item.type === activeFilter; + if (!matchesFilter) return false; + + // Search in title, category, description + const matchesBasic = + item.title.toLowerCase().includes(lowerQuery) || + item.category.toLowerCase().includes(lowerQuery) || + item.description?.toLowerCase().includes(lowerQuery); + + // Search in keywords array + const matchesKeywords = item.keywords?.some(kw => kw.toLowerCase().includes(lowerQuery)); + + // Search in content text + const matchesContent = item.content?.toLowerCase().includes(lowerQuery); + + return matchesBasic || matchesKeywords || matchesContent; + }).map(item => { + // Add context snippet around matched text + let contextSnippet = ''; + + // Try to find context in keywords first + const matchedKeyword = item.keywords?.find(kw => kw.toLowerCase().includes(lowerQuery)); + if (matchedKeyword) { + contextSnippet = `Related: ${matchedKeyword}`; + } + // Otherwise look for context in content + else if (item.content && item.content.toLowerCase().includes(lowerQuery)) { + contextSnippet = getContextSnippet(item.content, lowerQuery); + } + + return { ...item, contextSnippet }; + }); + }; + + // Get context snippet with words before and after the match + const getContextSnippet = (text: string, query: string): string => { + const lowerText = text.toLowerCase(); + const index = lowerText.indexOf(query.toLowerCase()); + if (index === -1) return ''; + + // Get ~50 chars before and after the match + const start = Math.max(0, index - 50); + const end = Math.min(text.length, index + query.length + 50); + let snippet = text.substring(start, end); + + // Add ellipsis if truncated + if (start > 0) snippet = '...' + snippet; + if (end < text.length) snippet = snippet + '...'; + + return snippet; + }; + +// Normalize search query by removing common filler words + const normalizeQuery = (query: string): string[] => { + const fillerWords = ['how', 'to', 'do', 'i', 'can', 'what', 'is', 'are', 'the', 'a', 'an', 'where', 'when', 'why', 'which', 'who', 'does', 'my', 'your', 'for', 'in', 'on', 'at', 'from']; + const words = query.toLowerCase().trim().split(/\s+/); + + // Filter out filler words and keep meaningful terms + const meaningfulWords = words.filter(word => !fillerWords.includes(word)); + + // Also handle plurals -> singular (basic stemming) + return meaningfulWords.map(word => { + if (word.endsWith('s') && word.length > 3) { + return word.slice(0, -1); // Remove 's' from end + } + return word; + }); + }; + + // Get suggested questions based on search query + const getSuggestedQuestions = (searchQuery: string): SuggestedQuestion[] => { + if (!searchQuery || searchQuery.length < 3) return []; + + const lowerQuery = searchQuery.toLowerCase().trim(); + const suggestions: SuggestedQuestion[] = []; + const seenQuestions = new Set(); // Prevent duplicates + + // Get normalized search terms + const searchTerms = normalizeQuery(searchQuery); + + // Find relevant questions from knowledge base + Object.entries(HELP_KNOWLEDGE_BASE).forEach(([keyword, questions]) => { + // Check if query matches keyword directly + const directMatch = lowerQuery.includes(keyword) || keyword.includes(lowerQuery); + + // Check if any normalized search term matches + const termMatch = searchTerms.some(term => + keyword.includes(term) || term.includes(keyword) + ); + + // Also check if any term appears in the question text itself + const questionTextMatch = questions.some(q => + searchTerms.some(term => q.question.toLowerCase().includes(term)) + ); + + if (directMatch || termMatch || questionTextMatch) { + questions.forEach(q => { + // Avoid duplicates + if (!seenQuestions.has(q.question)) { + suggestions.push(q); + seenQuestions.add(q.question); + } + }); + } + }); + + // Limit to top 4 most relevant questions + return suggestions.slice(0, 4); + }; + + // Highlight matched text in string + const highlightMatch = (text: string, query: string) => { + if (!query) return text; + + const parts = text.split(new RegExp(`(${query})`, 'gi')); + return parts.map((part, index) => + part.toLowerCase() === query.toLowerCase() + ? `${part}` + : part + ).join(''); + }; + const filteredResults = query.length > 0 - ? SEARCH_ITEMS.filter(item => { - const matchesQuery = item.title.toLowerCase().includes(query.toLowerCase()) || - item.category.toLowerCase().includes(query.toLowerCase()); - const matchesFilter = activeFilter === 'all' || item.type === activeFilter; - return matchesQuery && matchesFilter; - }) + ? searchItems(query) : (activeFilter === 'all' ? getRecentSearchResults() : SEARCH_ITEMS.filter(item => item.type === activeFilter)); + const suggestedQuestions = getSuggestedQuestions(query); + useEffect(() => { if (isOpen) { setQuery(''); @@ -126,6 +640,23 @@ export default function SearchModal({ isOpen, onClose }: SearchModalProps) { onClose(); }; + const handleQuickAction = (action: QuickAction, e: React.MouseEvent) => { + e.stopPropagation(); + if (action.path) { + addRecentSearch(action.path); + navigate(action.path); + onClose(); + } else if (action.action) { + action.action(); + } + }; + + const handleClearSearch = () => { + setQuery(''); + setSelectedIndex(0); + inputRef.current?.focus(); + }; + const filterOptions: { value: FilterType; label: string }[] = [ { value: 'all', label: 'All' }, { value: 'workflow', label: 'Workflow' }, @@ -136,31 +667,65 @@ export default function SearchModal({ isOpen, onClose }: SearchModalProps) { return ( +
- {/* Search Input */} -
- - - - - - {/* Using native input for ref and onKeyDown support - styled to match design system */} - setQuery(e.target.value)} - onKeyDown={handleKeyDown} - placeholder="Search pages..." - className="h-9 w-full rounded-lg border appearance-none px-3 py-2 text-sm shadow-theme-xs placeholder:text-gray-400 focus:outline-hidden focus:ring-3 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 bg-transparent text-gray-800 border-gray-300 focus:border-brand-300 focus:ring-brand-500/20 dark:border-gray-700 dark:focus:border-brand-800 pl-12 pr-4 py-4 text-lg border-b border-gray-200 dark:border-gray-700 rounded-none border-x-0 border-t-0" - /> - - ESC to close - + {/* Header */} +
+
+
+

+ Quick Navigation +

+

+ Navigate to any page in your IGNY8 workspace +

+
+ +
+ + {/* Search Input */} +
+ + + + + + setQuery(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Type to search pages..." + className="h-11 w-full rounded-lg border appearance-none px-3 py-2 text-sm shadow-sm placeholder:text-gray-400 focus:outline-hidden focus:ring-2 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 bg-white text-gray-900 border-gray-300 focus:border-brand-500 focus:ring-brand-500/30 dark:border-gray-700 dark:focus:border-brand-500 pl-10 pr-20" + /> + {query && ( + + )} + + ESC + +
{/* Filters */} -
+
{filterOptions.map((filter) => ( + ))} +
+ )} +
+ + {/* Enter hint */} + {index === selectedIndex && ( +
+ ↵ +
+ )} +
- - )) + ))} + + )} + + {/* Suggested Questions Section */} + {query.length >= 3 && suggestedQuestions.length > 0 && ( +
+
+ + + +

+ Suggested Questions +

+
+ +
+ {suggestedQuestions.map((item, idx) => ( +
{ + navigate(item.path); + onClose(); + }} + > +
+ + + +
+

+ {item.question} +

+

+ {item.answer} +

+
+ + 📖 {item.helpSection} + + + Read detailed guide → + +
+
+
+
+ ))} +
+
)} diff --git a/frontend/src/components/ui/accordion/Accordion.tsx b/frontend/src/components/ui/accordion/Accordion.tsx index e563207f..c5c2b1ca 100644 --- a/frontend/src/components/ui/accordion/Accordion.tsx +++ b/frontend/src/components/ui/accordion/Accordion.tsx @@ -1,10 +1,11 @@ -import React, { useState, ReactNode } from 'react'; +import React, { useState, useEffect, ReactNode } from 'react'; import { ChevronDownIcon } from '../../../icons'; interface AccordionItemProps { title: string; children: ReactNode; defaultOpen?: boolean; + forceOpen?: boolean; // External control to force open (for deep linking) className?: string; } @@ -12,10 +13,18 @@ export const AccordionItem: React.FC = ({ title, children, defaultOpen = false, + forceOpen = false, className = '', }) => { const [isOpen, setIsOpen] = useState(defaultOpen); + // Force open when forceOpen prop changes + useEffect(() => { + if (forceOpen) { + setIsOpen(true); + } + }, [forceOpen]); + return (
- -
+ +
(sectionRefs.current["importing-keywords"] = el)} className="space-y-4 scroll-mt-24">

Browse and add keywords from our curated database organized by 100+ industry sectors.

@@ -578,8 +597,8 @@ export default function Help() {
- -
+ +
(sectionRefs.current["content-settings"] = el)} className="space-y-4 scroll-mt-24">

Configure how AI generates and publishes your content.

@@ -669,8 +688,8 @@ export default function Help() { - -
+ +
(sectionRefs.current["managing-keywords"] = el)} className="space-y-4 scroll-mt-24">

Keywords are the foundation of your content strategy. Manage, filter, and organize your keywords here.

@@ -709,8 +728,8 @@ export default function Help() {
- -
+ +
(sectionRefs.current["keyword-clustering"] = el)} className="space-y-4 scroll-mt-24">

Clusters group related keywords for comprehensive content planning and topical authority building.

@@ -779,8 +798,8 @@ export default function Help() { - -
+ +
(sectionRefs.current["editing-content"] = el)} className="space-y-4 scroll-mt-24">

Tasks are content ideas converted into actionable writing assignments with status tracking.

@@ -808,8 +827,8 @@ export default function Help() {
- -
+ +
(sectionRefs.current["content-generation"] = el)} className="space-y-4 scroll-mt-24">

Generate, edit, and manage your AI-created content.

@@ -858,8 +877,10 @@ export default function Help() {
- -
+ +
(sectionRefs.current["image-generation"] = el)} className="space-y-4 scroll-mt-24"> +
(sectionRefs.current["image-settings"] = el)}>
+
(sectionRefs.current["managing-images"] = el)}>

Generate AI images for your content using DALL-E 3 (premium) or Runware (basic).

@@ -892,8 +913,8 @@ export default function Help() {
- -
+ +
(sectionRefs.current["content-workflow"] = el)} className="space-y-4 scroll-mt-24">

Final review stage before publishing to WordPress.

@@ -932,6 +953,8 @@ export default function Help() { {/* Automation Section */}
(sectionRefs.current["automation"] = el)} className="mb-12 scroll-mt-24"> +
(sectionRefs.current["automation-setup"] = el)}>
+
(sectionRefs.current["auto-publishing"] = el)}>

Automation Pipeline @@ -1022,8 +1045,9 @@ export default function Help() {

- -
+ +
(sectionRefs.current["publishing-wordpress"] = el)} className="space-y-4 scroll-mt-24"> +
(sectionRefs.current["wordpress-integration"] = el)}>

Connect your WordPress site for seamless content publishing.

@@ -1063,8 +1087,9 @@ export default function Help() {
- -
+ +
(sectionRefs.current["prompt-management"] = el)} className="space-y-4 scroll-mt-24"> +
(sectionRefs.current["author-profiles"] = el)}>

IGNY8 integrates with multiple AI providers for content and image generation.

@@ -1100,8 +1125,10 @@ export default function Help() { - -
+ +
(sectionRefs.current["credit-system"] = el)} className="space-y-4 scroll-mt-24"> +
(sectionRefs.current["purchasing-credits"] = el)}>
+
(sectionRefs.current["usage-tracking"] = el)}>

Credits are your currency for AI operations. Understand how credits work:

@@ -1212,8 +1239,9 @@ export default function Help() {
- -
+ +
(sectionRefs.current["team-collaboration"] = el)} className="space-y-4 scroll-mt-24"> +
(sectionRefs.current["user-roles"] = el)}>

Invite team members and manage roles in Account → Settings → Team.