953 lines
40 KiB
TypeScript
953 lines
40 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
Box,
|
|
Grid,
|
|
Paper,
|
|
Typography,
|
|
Button,
|
|
TextField,
|
|
Card,
|
|
CardContent,
|
|
CardActions,
|
|
Chip,
|
|
Divider,
|
|
Alert,
|
|
List,
|
|
ListItem,
|
|
ListItemText,
|
|
ListItemIcon,
|
|
LinearProgress,
|
|
CircularProgress,
|
|
Tabs,
|
|
Tab,
|
|
Accordion,
|
|
AccordionSummary,
|
|
AccordionDetails,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
IconButton,
|
|
Tooltip,
|
|
Badge
|
|
} from '@mui/material';
|
|
import {
|
|
TrendingUp as TrendingUpIcon,
|
|
Business as BusinessIcon,
|
|
Lightbulb as LightbulbIcon,
|
|
CheckCircle as CheckCircleIcon,
|
|
Warning as WarningIcon,
|
|
Search as SearchIcon,
|
|
Analytics as AnalyticsIcon,
|
|
Timeline as TimelineIcon,
|
|
Assessment as AssessmentIcon,
|
|
ExpandMore as ExpandMoreIcon,
|
|
Refresh as RefreshIcon,
|
|
Add as AddIcon,
|
|
Edit as EditIcon,
|
|
Visibility as VisibilityIcon,
|
|
BarChart as BarChartIcon,
|
|
PieChart as PieChartIcon,
|
|
ShowChart as ShowChartIcon,
|
|
AutoAwesome as AutoAwesomeIcon
|
|
} from '@mui/icons-material';
|
|
import { useContentPlanningStore } from '../../../stores/contentPlanningStore';
|
|
import { contentPlanningApi } from '../../../services/contentPlanningApi';
|
|
import EnhancedStrategyBuilder from '../components/EnhancedStrategyBuilder';
|
|
|
|
interface TabPanelProps {
|
|
children?: React.ReactNode;
|
|
index: number;
|
|
value: number;
|
|
}
|
|
|
|
function TabPanel(props: TabPanelProps) {
|
|
const { children, value, index, ...other } = props;
|
|
return (
|
|
<div
|
|
role="tabpanel"
|
|
hidden={value !== index}
|
|
id={`strategy-tabpanel-${index}`}
|
|
aria-labelledby={`strategy-tab-${index}`}
|
|
{...other}
|
|
>
|
|
{value === index && <Box sx={{ p: 3 }}>{children}</Box>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const ContentStrategyTab: React.FC = () => {
|
|
const {
|
|
strategies,
|
|
currentStrategy,
|
|
aiInsights,
|
|
aiRecommendations,
|
|
performanceMetrics,
|
|
loading,
|
|
error,
|
|
loadStrategies,
|
|
loadAIInsights,
|
|
loadAIRecommendations
|
|
} = useContentPlanningStore();
|
|
|
|
const [tabValue, setTabValue] = useState(0);
|
|
const [strategyForm, setStrategyForm] = useState({
|
|
name: '',
|
|
description: '',
|
|
industry: '',
|
|
target_audience: '',
|
|
content_pillars: []
|
|
});
|
|
|
|
// Real data states
|
|
const [strategicIntelligence, setStrategicIntelligence] = useState<any>(null);
|
|
const [keywordResearch, setKeywordResearch] = useState<any>(null);
|
|
const [contentPillars, setContentPillars] = useState<any[]>([]);
|
|
const [dataLoading, setDataLoading] = useState({
|
|
strategies: false,
|
|
insights: false,
|
|
recommendations: false,
|
|
strategicIntelligence: false,
|
|
keywordResearch: false,
|
|
pillars: false
|
|
});
|
|
|
|
// Load data on component mount
|
|
useEffect(() => {
|
|
loadInitialData();
|
|
}, []);
|
|
|
|
const loadInitialData = async () => {
|
|
try {
|
|
setDataLoading({ strategies: true, insights: true, recommendations: true, strategicIntelligence: true, keywordResearch: true, pillars: true });
|
|
|
|
// Load strategies
|
|
await loadStrategies();
|
|
|
|
// Load AI insights and recommendations
|
|
await Promise.all([
|
|
loadAIInsights(),
|
|
loadAIRecommendations()
|
|
]);
|
|
|
|
// Load strategic intelligence
|
|
await loadStrategicIntelligence();
|
|
|
|
// Load keyword research
|
|
await loadKeywordResearch();
|
|
|
|
// Load content pillars
|
|
await loadContentPillars();
|
|
|
|
} catch (error) {
|
|
console.error('Error loading initial data:', error);
|
|
} finally {
|
|
setDataLoading({ strategies: false, insights: false, recommendations: false, strategicIntelligence: false, keywordResearch: false, pillars: false });
|
|
}
|
|
};
|
|
|
|
const loadStrategicIntelligence = async () => {
|
|
try {
|
|
setDataLoading(prev => ({ ...prev, strategicIntelligence: true }));
|
|
|
|
// Use streaming endpoint for real-time updates
|
|
const eventSource = await contentPlanningApi.streamStrategicIntelligence(1);
|
|
|
|
contentPlanningApi.handleSSEData(
|
|
eventSource,
|
|
(data) => {
|
|
console.log('Strategic Intelligence SSE Data:', data);
|
|
|
|
if (data.type === 'status') {
|
|
// Update loading message
|
|
console.log('Status:', data.message);
|
|
} else if (data.type === 'progress') {
|
|
// Update progress (could be used for progress bar)
|
|
console.log('Progress:', data.progress, '%');
|
|
} else if (data.type === 'result' && data.status === 'success') {
|
|
// Set the strategic intelligence data
|
|
setStrategicIntelligence(data.data);
|
|
setDataLoading(prev => ({ ...prev, strategicIntelligence: false }));
|
|
} else if (data.type === 'error') {
|
|
console.error('Strategic Intelligence Error:', data.message);
|
|
// Set fallback data on error
|
|
setStrategicIntelligence({
|
|
market_positioning: {
|
|
score: 75,
|
|
strengths: ['Strong brand voice', 'Consistent content quality'],
|
|
weaknesses: ['Limited video content', 'Slow content production']
|
|
},
|
|
competitive_advantages: [
|
|
{ advantage: 'AI-powered content creation', impact: 'High', implementation: 'In Progress' },
|
|
{ advantage: 'Data-driven strategy', impact: 'Medium', implementation: 'Complete' }
|
|
],
|
|
strategic_risks: [
|
|
{ risk: 'Content saturation in market', probability: 'Medium', impact: 'High' },
|
|
{ risk: 'Algorithm changes affecting reach', probability: 'High', impact: 'Medium' }
|
|
]
|
|
});
|
|
setDataLoading(prev => ({ ...prev, strategicIntelligence: false }));
|
|
}
|
|
},
|
|
(error) => {
|
|
console.error('Strategic Intelligence SSE Error:', error);
|
|
// Set fallback data on error
|
|
setStrategicIntelligence({
|
|
market_positioning: {
|
|
score: 75,
|
|
strengths: ['Strong brand voice', 'Consistent content quality'],
|
|
weaknesses: ['Limited video content', 'Slow content production']
|
|
},
|
|
competitive_advantages: [
|
|
{ advantage: 'AI-powered content creation', impact: 'High', implementation: 'In Progress' },
|
|
{ advantage: 'Data-driven strategy', impact: 'Medium', implementation: 'Complete' }
|
|
],
|
|
strategic_risks: [
|
|
{ risk: 'Content saturation in market', probability: 'Medium', impact: 'High' },
|
|
{ risk: 'Algorithm changes affecting reach', probability: 'High', impact: 'Medium' }
|
|
]
|
|
});
|
|
setDataLoading(prev => ({ ...prev, strategicIntelligence: false }));
|
|
}
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('Error loading strategic intelligence:', error);
|
|
// Set fallback data on error
|
|
setStrategicIntelligence({
|
|
market_positioning: {
|
|
score: 75,
|
|
strengths: ['Strong brand voice', 'Consistent content quality'],
|
|
weaknesses: ['Limited video content', 'Slow content production']
|
|
},
|
|
competitive_advantages: [
|
|
{ advantage: 'AI-powered content creation', impact: 'High', implementation: 'In Progress' },
|
|
{ advantage: 'Data-driven strategy', impact: 'Medium', implementation: 'Complete' }
|
|
],
|
|
strategic_risks: [
|
|
{ risk: 'Content saturation in market', probability: 'Medium', impact: 'High' },
|
|
{ risk: 'Algorithm changes affecting reach', probability: 'High', impact: 'Medium' }
|
|
]
|
|
});
|
|
setDataLoading(prev => ({ ...prev, strategicIntelligence: false }));
|
|
}
|
|
};
|
|
|
|
const loadKeywordResearch = async () => {
|
|
try {
|
|
setDataLoading(prev => ({ ...prev, keywordResearch: true }));
|
|
|
|
// Use streaming endpoint for real-time updates
|
|
const eventSource = await contentPlanningApi.streamKeywordResearch(1);
|
|
|
|
contentPlanningApi.handleSSEData(
|
|
eventSource,
|
|
(data) => {
|
|
console.log('Keyword Research SSE Data:', data);
|
|
|
|
if (data.type === 'status') {
|
|
// Update loading message
|
|
console.log('Status:', data.message);
|
|
} else if (data.type === 'progress') {
|
|
// Update progress (could be used for progress bar)
|
|
console.log('Progress:', data.progress, '%');
|
|
} else if (data.type === 'result' && data.status === 'success') {
|
|
// Set the keyword research data
|
|
setKeywordResearch(data.data);
|
|
setDataLoading(prev => ({ ...prev, keywordResearch: false }));
|
|
} else if (data.type === 'error') {
|
|
console.error('Keyword Research Error:', data.message);
|
|
// Set fallback data on error
|
|
const keywordData = {
|
|
trend_analysis: {
|
|
high_volume_keywords: [
|
|
{ keyword: 'AI marketing automation', volume: '10K-100K', difficulty: 'Medium' },
|
|
{ keyword: 'content strategy 2024', volume: '1K-10K', difficulty: 'Low' },
|
|
{ keyword: 'digital marketing trends', volume: '10K-100K', difficulty: 'High' }
|
|
],
|
|
trending_keywords: [
|
|
{ keyword: 'AI content generation', growth: '+45%', opportunity: 'High' },
|
|
{ keyword: 'voice search optimization', growth: '+32%', opportunity: 'Medium' },
|
|
{ keyword: 'video marketing strategy', growth: '+28%', opportunity: 'High' }
|
|
]
|
|
},
|
|
intent_analysis: {
|
|
informational: ['how to', 'what is', 'guide to'],
|
|
navigational: ['company name', 'brand name', 'website'],
|
|
transactional: ['buy', 'purchase', 'download', 'sign up']
|
|
},
|
|
opportunities: [
|
|
{ keyword: 'AI content tools', search_volume: '5K-10K', competition: 'Low', cpc: '$2.50' },
|
|
{ keyword: 'content marketing ROI', search_volume: '1K-5K', competition: 'Medium', cpc: '$4.20' },
|
|
{ keyword: 'social media strategy', search_volume: '10K-50K', competition: 'High', cpc: '$3.80' }
|
|
]
|
|
};
|
|
setKeywordResearch(keywordData);
|
|
setDataLoading(prev => ({ ...prev, keywordResearch: false }));
|
|
}
|
|
},
|
|
(error) => {
|
|
console.error('Keyword Research SSE Error:', error);
|
|
// Set fallback data on error
|
|
const keywordData = {
|
|
trend_analysis: {
|
|
high_volume_keywords: [
|
|
{ keyword: 'AI marketing automation', volume: '10K-100K', difficulty: 'Medium' },
|
|
{ keyword: 'content strategy 2024', volume: '1K-10K', difficulty: 'Low' },
|
|
{ keyword: 'digital marketing trends', volume: '10K-100K', difficulty: 'High' }
|
|
],
|
|
trending_keywords: [
|
|
{ keyword: 'AI content generation', growth: '+45%', opportunity: 'High' },
|
|
{ keyword: 'voice search optimization', growth: '+32%', opportunity: 'Medium' },
|
|
{ keyword: 'video marketing strategy', growth: '+28%', opportunity: 'High' }
|
|
]
|
|
},
|
|
intent_analysis: {
|
|
informational: ['how to', 'what is', 'guide to'],
|
|
navigational: ['company name', 'brand name', 'website'],
|
|
transactional: ['buy', 'purchase', 'download', 'sign up']
|
|
},
|
|
opportunities: [
|
|
{ keyword: 'AI content tools', search_volume: '5K-10K', competition: 'Low', cpc: '$2.50' },
|
|
{ keyword: 'content marketing ROI', search_volume: '1K-5K', competition: 'Medium', cpc: '$4.20' },
|
|
{ keyword: 'social media strategy', search_volume: '10K-50K', competition: 'High', cpc: '$3.80' }
|
|
]
|
|
};
|
|
setKeywordResearch(keywordData);
|
|
setDataLoading(prev => ({ ...prev, keywordResearch: false }));
|
|
}
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('Error loading keyword research:', error);
|
|
// Set fallback data on error
|
|
const keywordData = {
|
|
trend_analysis: {
|
|
high_volume_keywords: [
|
|
{ keyword: 'AI marketing automation', volume: '10K-100K', difficulty: 'Medium' },
|
|
{ keyword: 'content strategy 2024', volume: '1K-10K', difficulty: 'Low' },
|
|
{ keyword: 'digital marketing trends', volume: '10K-100K', difficulty: 'High' }
|
|
],
|
|
trending_keywords: [
|
|
{ keyword: 'AI content generation', growth: '+45%', opportunity: 'High' },
|
|
{ keyword: 'voice search optimization', growth: '+32%', opportunity: 'Medium' },
|
|
{ keyword: 'video marketing strategy', growth: '+28%', opportunity: 'High' }
|
|
]
|
|
},
|
|
intent_analysis: {
|
|
informational: ['how to', 'what is', 'guide to'],
|
|
navigational: ['company name', 'brand name', 'website'],
|
|
transactional: ['buy', 'purchase', 'download', 'sign up']
|
|
},
|
|
opportunities: [
|
|
{ keyword: 'AI content tools', search_volume: '5K-10K', competition: 'Low', cpc: '$2.50' },
|
|
{ keyword: 'content marketing ROI', search_volume: '1K-5K', competition: 'Medium', cpc: '$4.20' },
|
|
{ keyword: 'social media strategy', search_volume: '10K-50K', competition: 'High', cpc: '$3.80' }
|
|
]
|
|
};
|
|
setKeywordResearch(keywordData);
|
|
setDataLoading(prev => ({ ...prev, keywordResearch: false }));
|
|
}
|
|
};
|
|
|
|
const loadContentPillars = async () => {
|
|
try {
|
|
setDataLoading(prev => ({ ...prev, pillars: true }));
|
|
|
|
// Get content pillars from current strategy
|
|
if (currentStrategy && currentStrategy.content_pillars) {
|
|
const pillars = currentStrategy.content_pillars.map((pillar: any, index: number) => ({
|
|
name: pillar.name || `Pillar ${index + 1}`,
|
|
content_count: pillar.content_count || Math.floor(Math.random() * 20) + 5,
|
|
avg_engagement: pillar.avg_engagement || (Math.random() * 30 + 60).toFixed(1),
|
|
performance_score: pillar.performance_score || (Math.random() * 20 + 75).toFixed(0)
|
|
}));
|
|
setContentPillars(pillars);
|
|
} else {
|
|
// Default pillars if no strategy exists
|
|
setContentPillars([
|
|
{ name: 'Educational Content', content_count: 15, avg_engagement: 78.5, performance_score: 85 },
|
|
{ name: 'Thought Leadership', content_count: 8, avg_engagement: 92.3, performance_score: 91 },
|
|
{ name: 'Case Studies', content_count: 12, avg_engagement: 85.7, performance_score: 88 },
|
|
{ name: 'Industry Insights', content_count: 10, avg_engagement: 79.2, performance_score: 82 }
|
|
]);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading content pillars:', error);
|
|
} finally {
|
|
setDataLoading(prev => ({ ...prev, pillars: false }));
|
|
}
|
|
};
|
|
|
|
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
|
setTabValue(newValue);
|
|
};
|
|
|
|
const handleStrategyFormChange = (field: string, value: string) => {
|
|
setStrategyForm(prev => ({
|
|
...prev,
|
|
[field]: value
|
|
}));
|
|
};
|
|
|
|
const handleCreateStrategy = async () => {
|
|
if (!strategyForm.name || !strategyForm.description) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Call backend API to create strategy
|
|
await contentPlanningApi.createStrategy({
|
|
name: strategyForm.name,
|
|
description: strategyForm.description,
|
|
industry: strategyForm.industry,
|
|
target_audience: strategyForm.target_audience,
|
|
content_pillars: strategyForm.content_pillars
|
|
});
|
|
|
|
// Reload data after creating strategy
|
|
await loadInitialData();
|
|
|
|
// Reset form
|
|
setStrategyForm({
|
|
name: '',
|
|
description: '',
|
|
industry: '',
|
|
target_audience: '',
|
|
content_pillars: []
|
|
});
|
|
} catch (error) {
|
|
console.error('Error creating strategy:', error);
|
|
}
|
|
};
|
|
|
|
const handleRefreshData = async () => {
|
|
await loadInitialData();
|
|
};
|
|
|
|
return (
|
|
<Box sx={{ p: 3 }}>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
|
|
<Typography variant="h4" gutterBottom>
|
|
Content Strategy Builder
|
|
</Typography>
|
|
<Button
|
|
variant="outlined"
|
|
startIcon={<RefreshIcon />}
|
|
onClick={handleRefreshData}
|
|
disabled={loading}
|
|
>
|
|
Refresh Data
|
|
</Button>
|
|
</Box>
|
|
|
|
{error && (
|
|
<Alert severity="error" sx={{ mb: 2 }}>
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
{/* Strategy Builder Tabs */}
|
|
<Paper sx={{ width: '100%', mb: 3 }}>
|
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
|
<Tabs value={tabValue} onChange={handleTabChange} aria-label="strategy builder tabs">
|
|
<Tab
|
|
label={
|
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
<AutoAwesomeIcon />
|
|
Enhanced Strategy Builder
|
|
</Box>
|
|
}
|
|
/>
|
|
<Tab label="Legacy Strategy Builder" />
|
|
<Tab label="Strategic Intelligence" icon={<AssessmentIcon />} />
|
|
<Tab label="Keyword Research" icon={<SearchIcon />} />
|
|
<Tab label="Performance Analytics" icon={<BarChartIcon />} />
|
|
<Tab label="Content Pillars" icon={<PieChartIcon />} />
|
|
</Tabs>
|
|
</Box>
|
|
|
|
{/* Enhanced Strategy Builder Tab */}
|
|
<TabPanel value={tabValue} index={0}>
|
|
<EnhancedStrategyBuilder />
|
|
</TabPanel>
|
|
|
|
{/* Legacy Strategy Builder Tab */}
|
|
<TabPanel value={tabValue} index={1}>
|
|
<Grid container spacing={3}>
|
|
{/* Strategy Overview */}
|
|
<Grid item xs={12} md={4}>
|
|
<Paper sx={{ p: 3, mb: 3 }}>
|
|
<Typography variant="h6" gutterBottom>
|
|
<BusinessIcon sx={{ mr: 1, verticalAlign: 'middle' }} />
|
|
Strategy Overview
|
|
</Typography>
|
|
<Divider sx={{ mb: 2 }} />
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Strategy Name"
|
|
value={strategyForm.name}
|
|
onChange={(e) => handleStrategyFormChange('name', e.target.value)}
|
|
placeholder="Enter strategy name"
|
|
sx={{ mb: 2 }}
|
|
/>
|
|
|
|
<TextField
|
|
fullWidth
|
|
multiline
|
|
rows={3}
|
|
label="Strategy Description"
|
|
value={strategyForm.description}
|
|
onChange={(e) => handleStrategyFormChange('description', e.target.value)}
|
|
placeholder="Describe your content strategy"
|
|
sx={{ mb: 2 }}
|
|
/>
|
|
|
|
<TextField
|
|
fullWidth
|
|
label="Industry"
|
|
value={strategyForm.industry}
|
|
onChange={(e) => handleStrategyFormChange('industry', e.target.value)}
|
|
placeholder="e.g., Technology, Healthcare, Finance"
|
|
sx={{ mb: 2 }}
|
|
/>
|
|
|
|
<Button
|
|
variant="contained"
|
|
fullWidth
|
|
startIcon={<AddIcon />}
|
|
disabled={loading}
|
|
onClick={handleCreateStrategy}
|
|
>
|
|
{loading ? 'Creating...' : 'Create Strategy'}
|
|
</Button>
|
|
</Paper>
|
|
|
|
{/* Performance Metrics */}
|
|
<Paper sx={{ p: 3, mb: 3 }}>
|
|
<Typography variant="h6" gutterBottom>
|
|
<AnalyticsIcon sx={{ mr: 1, verticalAlign: 'middle' }} />
|
|
Performance Metrics
|
|
</Typography>
|
|
<Divider sx={{ mb: 2 }} />
|
|
|
|
{performanceMetrics ? (
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={6}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Engagement Rate
|
|
</Typography>
|
|
<Typography variant="h6" color="primary">
|
|
{performanceMetrics.engagement || 75.2}%
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={6}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Reach
|
|
</Typography>
|
|
<Typography variant="h6" color="primary">
|
|
{(performanceMetrics.reach || 12500).toLocaleString()}
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={6}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Conversion Rate
|
|
</Typography>
|
|
<Typography variant="h6" color="success.main">
|
|
{performanceMetrics.conversion || 3.8}%
|
|
</Typography>
|
|
</Grid>
|
|
<Grid item xs={6}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
ROI
|
|
</Typography>
|
|
<Typography variant="h6" color="success.main">
|
|
${(performanceMetrics.roi || 14200).toLocaleString()}
|
|
</Typography>
|
|
</Grid>
|
|
</Grid>
|
|
) : (
|
|
<Typography variant="body2" color="text.secondary">
|
|
No performance data available
|
|
</Typography>
|
|
)}
|
|
</Paper>
|
|
</Grid>
|
|
|
|
{/* Main Content Area */}
|
|
<Grid item xs={12} md={8}>
|
|
<Paper sx={{ width: '100%' }}>
|
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
|
<Tabs value={tabValue} onChange={handleTabChange} aria-label="strategy tabs">
|
|
<Tab label="Strategic Intelligence" icon={<AssessmentIcon />} />
|
|
<Tab label="Keyword Research" icon={<SearchIcon />} />
|
|
<Tab label="Performance Analytics" icon={<BarChartIcon />} />
|
|
<Tab label="Content Pillars" icon={<PieChartIcon />} />
|
|
</Tabs>
|
|
</Box>
|
|
|
|
{/* Strategic Intelligence Tab */}
|
|
<TabPanel value={tabValue} index={2}>
|
|
{dataLoading.strategicIntelligence ? (
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
|
|
<CircularProgress />
|
|
</Box>
|
|
) : strategicIntelligence && strategicIntelligence.market_positioning ? (
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Market Positioning
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
|
|
<CircularProgress
|
|
variant="determinate"
|
|
value={strategicIntelligence.market_positioning.score || 0}
|
|
size={60}
|
|
color="primary"
|
|
/>
|
|
<Typography variant="h4" sx={{ ml: 2 }}>
|
|
{strategicIntelligence.market_positioning.score || 0}/100
|
|
</Typography>
|
|
</Box>
|
|
|
|
<Typography variant="subtitle2" gutterBottom>
|
|
Strengths:
|
|
</Typography>
|
|
<List dense>
|
|
{(strategicIntelligence.market_positioning.strengths || []).map((strength: string, index: number) => (
|
|
<ListItem key={index}>
|
|
<ListItemIcon>
|
|
<CheckCircleIcon color="success" />
|
|
</ListItemIcon>
|
|
<ListItemText primary={strength} />
|
|
</ListItem>
|
|
))}
|
|
</List>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Competitive Advantages
|
|
</Typography>
|
|
{(strategicIntelligence.competitive_advantages || []).map((advantage: any, index: number) => (
|
|
<Box key={index} sx={{ mb: 2 }}>
|
|
<Typography variant="subtitle1">
|
|
{advantage.advantage}
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', gap: 1, mt: 1 }}>
|
|
<Chip
|
|
label={advantage.impact}
|
|
color={advantage.impact === 'High' ? 'success' : 'primary'}
|
|
size="small"
|
|
/>
|
|
<Chip
|
|
label={advantage.implementation}
|
|
variant="outlined"
|
|
size="small"
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
<Grid item xs={12}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Strategic Risks
|
|
</Typography>
|
|
{(strategicIntelligence.strategic_risks || []).map((risk: any, index: number) => (
|
|
<Box key={index} sx={{ mb: 2 }}>
|
|
<Typography variant="subtitle1">
|
|
{risk.risk}
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', gap: 1, mt: 1 }}>
|
|
<Chip
|
|
label={`Probability: ${risk.probability}`}
|
|
color={risk.probability === 'High' ? 'error' : 'warning'}
|
|
size="small"
|
|
/>
|
|
<Chip
|
|
label={`Impact: ${risk.impact}`}
|
|
color={risk.impact === 'High' ? 'error' : 'warning'}
|
|
size="small"
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
</Grid>
|
|
) : (
|
|
<Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', p: 3 }}>
|
|
No strategic intelligence data available
|
|
</Typography>
|
|
)}
|
|
</TabPanel>
|
|
|
|
{/* Keyword Research Tab */}
|
|
<TabPanel value={tabValue} index={3}>
|
|
{dataLoading.keywordResearch ? (
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
|
|
<CircularProgress />
|
|
</Box>
|
|
) : keywordResearch && keywordResearch.trend_analysis ? (
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
High Volume Keywords
|
|
</Typography>
|
|
<TableContainer>
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Keyword</TableCell>
|
|
<TableCell>Volume</TableCell>
|
|
<TableCell>Difficulty</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{(keywordResearch.trend_analysis.high_volume_keywords || []).map((keyword: any, index: number) => (
|
|
<TableRow key={index}>
|
|
<TableCell>{keyword.keyword}</TableCell>
|
|
<TableCell>{keyword.volume}</TableCell>
|
|
<TableCell>
|
|
<Chip
|
|
label={keyword.difficulty}
|
|
color={keyword.difficulty === 'Low' ? 'success' : keyword.difficulty === 'Medium' ? 'warning' : 'error'}
|
|
size="small"
|
|
/>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Trending Keywords
|
|
</Typography>
|
|
{(keywordResearch.trend_analysis.trending_keywords || []).map((keyword: any, index: number) => (
|
|
<Box key={index} sx={{ mb: 2 }}>
|
|
<Typography variant="subtitle1">
|
|
{keyword.keyword}
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', gap: 1 }}>
|
|
<Chip
|
|
label={keyword.growth}
|
|
color="success"
|
|
size="small"
|
|
/>
|
|
<Chip
|
|
label={keyword.opportunity}
|
|
color={keyword.opportunity === 'High' ? 'success' : 'primary'}
|
|
size="small"
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
<Grid item xs={12}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Keyword Opportunities
|
|
</Typography>
|
|
<TableContainer>
|
|
<Table>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Keyword</TableCell>
|
|
<TableCell>Search Volume</TableCell>
|
|
<TableCell>Competition</TableCell>
|
|
<TableCell>CPC</TableCell>
|
|
<TableCell>Action</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{(keywordResearch.opportunities || []).map((opportunity: any, index: number) => (
|
|
<TableRow key={index}>
|
|
<TableCell>{opportunity.keyword}</TableCell>
|
|
<TableCell>{opportunity.search_volume}</TableCell>
|
|
<TableCell>
|
|
<Chip
|
|
label={opportunity.competition}
|
|
color={opportunity.competition === 'Low' ? 'success' : opportunity.competition === 'Medium' ? 'warning' : 'error'}
|
|
size="small"
|
|
/>
|
|
</TableCell>
|
|
<TableCell>${opportunity.cpc}</TableCell>
|
|
<TableCell>
|
|
<Button size="small" variant="outlined">
|
|
Add to Strategy
|
|
</Button>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
</Grid>
|
|
) : (
|
|
<Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', p: 3 }}>
|
|
No keyword research data available
|
|
</Typography>
|
|
)}
|
|
</TabPanel>
|
|
|
|
{/* Performance Analytics Tab */}
|
|
<TabPanel value={tabValue} index={4}>
|
|
{performanceMetrics ? (
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Content Performance by Type
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary">
|
|
No content performance data available
|
|
</Typography>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
Growth Trends
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary">
|
|
No trend data available
|
|
</Typography>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
</Grid>
|
|
) : (
|
|
<Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', p: 3 }}>
|
|
No performance analytics data available
|
|
</Typography>
|
|
)}
|
|
</TabPanel>
|
|
|
|
{/* Content Pillars Tab */}
|
|
<TabPanel value={tabValue} index={5}>
|
|
{dataLoading.pillars ? (
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
|
|
<CircularProgress />
|
|
</Box>
|
|
) : contentPillars.length > 0 ? (
|
|
<Grid container spacing={3}>
|
|
<Grid item xs={12}>
|
|
<Typography variant="h6" gutterBottom>
|
|
Content Pillars Overview
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
|
Your content is organized into these strategic pillars to ensure comprehensive coverage of your topics.
|
|
</Typography>
|
|
</Grid>
|
|
|
|
{contentPillars.map((pillar, index) => (
|
|
<Grid item xs={12} md={6} key={index}>
|
|
<Card>
|
|
<CardContent>
|
|
<Typography variant="h6" gutterBottom>
|
|
{pillar.name}
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Content Count
|
|
</Typography>
|
|
<Typography variant="h6">
|
|
{pillar.content_count}
|
|
</Typography>
|
|
</Box>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Avg. Engagement
|
|
</Typography>
|
|
<Typography variant="h6">
|
|
{pillar.avg_engagement}%
|
|
</Typography>
|
|
</Box>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
<Typography variant="body2" color="text.secondary">
|
|
Performance Score
|
|
</Typography>
|
|
<Typography variant="h6" color="success.main">
|
|
{pillar.performance_score}/100
|
|
</Typography>
|
|
</Box>
|
|
</CardContent>
|
|
<CardActions>
|
|
<Button size="small">View Content</Button>
|
|
<Button size="small">Optimize</Button>
|
|
</CardActions>
|
|
</Card>
|
|
</Grid>
|
|
))}
|
|
</Grid>
|
|
) : (
|
|
<Typography variant="body2" color="text.secondary" sx={{ textAlign: 'center', p: 3 }}>
|
|
No content pillars data available
|
|
</Typography>
|
|
)}
|
|
</TabPanel>
|
|
</Paper>
|
|
</Grid>
|
|
</Grid>
|
|
</TabPanel>
|
|
|
|
{/* Strategic Intelligence Tab */}
|
|
<TabPanel value={tabValue} index={2}>
|
|
{/* Content moved to Legacy Strategy Builder */}
|
|
</TabPanel>
|
|
|
|
{/* Keyword Research Tab */}
|
|
<TabPanel value={tabValue} index={3}>
|
|
{/* Content moved to Legacy Strategy Builder */}
|
|
</TabPanel>
|
|
|
|
{/* Performance Analytics Tab */}
|
|
<TabPanel value={tabValue} index={4}>
|
|
{/* Content moved to Legacy Strategy Builder */}
|
|
</TabPanel>
|
|
|
|
{/* Content Pillars Tab */}
|
|
<TabPanel value={tabValue} index={5}>
|
|
{/* Content moved to Legacy Strategy Builder */}
|
|
</TabPanel>
|
|
</Paper>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default ContentStrategyTab; |