Files
ALwrity/frontend/src/components/OnboardingWizard/PersonaStep/PersonaPreviewSection.tsx

389 lines
13 KiB
TypeScript

import React from 'react';
import {
Box,
Button,
Typography,
Alert,
Chip,
Divider,
Accordion,
AccordionSummary,
AccordionDetails,
Fade
} from '@mui/material';
import {
ExpandMore as ExpandMoreIcon,
Refresh as RefreshIcon,
Psychology as PsychologyIcon,
AutoAwesome as AutoAwesomeIcon,
Assessment as AssessmentIcon,
LinkedIn as LinkedInIcon,
Facebook as FacebookIcon,
Twitter as TwitterIcon,
Article as ArticleIcon,
Instagram as InstagramIcon
} from '@mui/icons-material';
import { CorePersonaDisplay } from './sections/CorePersonaDisplay';
import { PlatformPersonaDisplay } from './sections/PlatformPersonaDisplay';
import { QualityMetricsDisplay } from './QualityMetricsDisplay';
interface PersonaPreviewSectionProps {
showPreview: boolean;
corePersona: any;
platformPersonas: Record<string, any>;
qualityMetrics: any;
selectedPlatforms: string[];
expandedAccordion: string | false;
setExpandedAccordion: (accordion: string | false) => void;
setCorePersona: (persona: any) => void;
setPlatformPersonas: (personas: Record<string, any>) => void;
handleRegenerate: () => void;
}
const availablePlatforms = [
{ id: 'linkedin', name: 'LinkedIn', icon: <LinkedInIcon />, color: '#0077B5' },
{ id: 'facebook', name: 'Facebook', icon: <FacebookIcon />, color: '#1877F2' },
{ id: 'twitter', name: 'Twitter', icon: <TwitterIcon />, color: '#1DA1F2' },
{ id: 'blog', name: 'Blog', icon: <ArticleIcon />, color: '#FF6B35' },
{ id: 'instagram', name: 'Instagram', icon: <InstagramIcon />, color: '#E4405F' }
];
export const PersonaPreviewSection: React.FC<PersonaPreviewSectionProps> = ({
showPreview,
corePersona,
platformPersonas,
qualityMetrics,
selectedPlatforms,
expandedAccordion,
setExpandedAccordion,
setCorePersona,
setPlatformPersonas,
handleRegenerate
}) => {
if (!showPreview || !corePersona) {
return null;
}
return (
<Fade in={true}>
<Box>
<Box sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
mb: 4,
p: 3,
background: 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)',
border: '1px solid #e2e8f0',
borderRadius: 3,
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.05)'
}}>
<Box>
<Typography variant="h5" sx={{ fontWeight: 700, color: '#1e293b', mb: 0.5 }}>
Your AI Writing Brand Voice
</Typography>
<Typography variant="body2" sx={{ color: '#64748b' }}>
Comprehensive analysis of your unique brand identity and communication style
</Typography>
</Box>
<Button
variant="outlined"
startIcon={<RefreshIcon />}
onClick={handleRegenerate}
size="small"
sx={{
borderColor: '#e2e8f0',
color: '#475569',
'&:hover': {
borderColor: '#3b82f6',
backgroundColor: '#f8fafc'
}
}}
>
Regenerate
</Button>
</Box>
<Alert
severity="info"
icon={<AutoAwesomeIcon />}
sx={{
mb: 4,
borderRadius: 3,
backgroundColor: '#f0f9ff',
border: '1px solid #bae6fd',
'& .MuiAlert-message': { color: '#0369a1' }
}}
>
<Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 0.5 }}>
Adaptive Learning Active
</Typography>
<Typography variant="body2">
This Brand Voice was initialized from your website's home page. As you generate more content, ALwrity will automatically refine and update your brand identity to match your evolving style.
</Typography>
</Alert>
{/* Core Persona */}
<Accordion
expanded={expandedAccordion === 'core'}
onChange={() => setExpandedAccordion(expandedAccordion === 'core' ? false : 'core')}
sx={{
mb: 3,
background: 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)',
border: '1px solid #e2e8f0',
borderRadius: 3,
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.05)',
'&:before': {
display: 'none'
},
'&.Mui-expanded': {
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)'
}
}}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon sx={{ color: '#64748b' }} />}
sx={{
px: 4,
py: 3,
'&:hover': {
backgroundColor: '#f8fafc'
}
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, width: '100%' }}>
<Box
sx={{
p: 2,
borderRadius: 2,
background: 'linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<PsychologyIcon sx={{ fontSize: 24 }} />
</Box>
<Box sx={{ flex: 1 }}>
<Typography variant="h6" sx={{ fontWeight: 600, color: '#1e293b', mb: 0.5 }}>
Brand Writing Style
</Typography>
<Typography variant="body2" sx={{ color: '#64748b' }}>
Your unique brand voice and communication characteristics
</Typography>
</Box>
{qualityMetrics && (
<Chip
label={`${qualityMetrics.overall_score}% Quality`}
sx={{
background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
color: 'white',
fontWeight: 600,
'& .MuiChip-label': {
px: 2
}
}}
size="small"
/>
)}
</Box>
</AccordionSummary>
<AccordionDetails sx={{ px: 4, pb: 4 }}>
<CorePersonaDisplay
persona={corePersona}
onChange={(updatedPersona) => {
setCorePersona(updatedPersona);
// TODO: Add debounced auto-save
}}
/>
</AccordionDetails>
</Accordion>
{/* Platform Adaptations */}
<Accordion
expanded={expandedAccordion === 'platforms'}
onChange={() => setExpandedAccordion(expandedAccordion === 'platforms' ? false : 'platforms')}
sx={{
mb: 3,
background: 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)',
border: '1px solid #e2e8f0',
borderRadius: 3,
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.05)',
'&:before': {
display: 'none'
},
'&.Mui-expanded': {
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)'
}
}}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon sx={{ color: '#64748b' }} />}
sx={{
px: 4,
py: 3,
'&:hover': {
backgroundColor: '#f8fafc'
}
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, width: '100%' }}>
<Box
sx={{
p: 2,
borderRadius: 2,
background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<AutoAwesomeIcon sx={{ fontSize: 24 }} />
</Box>
<Box sx={{ flex: 1 }}>
<Typography variant="h6" sx={{ fontWeight: 600, color: '#1e293b', mb: 0.5 }}>
Platform Adaptations
</Typography>
<Typography variant="body2" sx={{ color: '#64748b' }}>
Optimized for different content platforms
</Typography>
</Box>
<Chip
label={`${selectedPlatforms.length} Platforms`}
sx={{
background: 'linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)',
color: 'white',
fontWeight: 600,
'& .MuiChip-label': {
px: 2
}
}}
size="small"
/>
</Box>
</AccordionSummary>
<AccordionDetails sx={{ px: 4, pb: 4 }}>
<Box>
{selectedPlatforms.map((platformId, index) => {
const platformInfo = availablePlatforms.find(p => p.id === platformId);
return (
<Box key={platformId} sx={{ mb: index < selectedPlatforms.length - 1 ? 4 : 0 }}>
<Divider sx={{ mb: 3 }}>
<Chip
icon={platformInfo?.icon}
label={platformInfo?.name || platformId}
sx={{
background: 'linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)',
color: 'white',
fontWeight: 600
}}
/>
</Divider>
<PlatformPersonaDisplay
platformPersona={platformPersonas[platformId] || {}}
platformName={platformId}
onChange={(updatedPersona) => {
setPlatformPersonas({
...platformPersonas,
[platformId]: updatedPersona
});
// TODO: Add debounced auto-save
}}
/>
</Box>
);
})}
{selectedPlatforms.length === 0 && (
<Alert severity="info" sx={{
background: 'linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%)',
border: '1px solid #0ea5e9',
color: '#0c4a6e'
}}>
No platforms selected. Please select at least one platform to see optimized personas.
</Alert>
)}
</Box>
</AccordionDetails>
</Accordion>
{/* Quality Metrics */}
{qualityMetrics && (
<Accordion
expanded={expandedAccordion === 'quality'}
onChange={() => setExpandedAccordion(expandedAccordion === 'quality' ? false : 'quality')}
sx={{
mb: 4,
background: 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)',
border: '1px solid #e2e8f0',
borderRadius: 3,
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.05)',
'&:before': {
display: 'none'
},
'&.Mui-expanded': {
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)'
}
}}
>
<AccordionSummary
expandIcon={<ExpandMoreIcon sx={{ color: '#64748b' }} />}
sx={{
px: 4,
py: 3,
'&:hover': {
backgroundColor: '#f8fafc'
}
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, width: '100%' }}>
<Box
sx={{
p: 2,
borderRadius: 2,
background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<AssessmentIcon sx={{ fontSize: 24 }} />
</Box>
<Box sx={{ flex: 1 }}>
<Typography variant="h6" sx={{ fontWeight: 600, color: '#1e293b', mb: 0.5 }}>
Quality Assessment
</Typography>
<Typography variant="body2" sx={{ color: '#64748b' }}>
Performance metrics and recommendations
</Typography>
</Box>
<Chip
label={`${qualityMetrics.overall_score}% Quality`}
sx={{
background: qualityMetrics.overall_score >= 85
? 'linear-gradient(135deg, #10b981 0%, #059669 100%)'
: qualityMetrics.overall_score >= 70
? 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)'
: 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)',
color: 'white',
fontWeight: 600,
'& .MuiChip-label': {
px: 2
}
}}
size="small"
/>
</Box>
</AccordionSummary>
<AccordionDetails sx={{ px: 4, pb: 4 }}>
<QualityMetricsDisplay metrics={qualityMetrics} />
</AccordionDetails>
</Accordion>
)}
</Box>
</Fade>
);
};