Files
ALwrity/frontend/src/components/OnboardingWizard/FinalStep/components/SetupSummary.tsx

357 lines
16 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import {
Box,
Paper,
Zoom,
Grid,
Typography,
Card,
CardContent,
Chip,
Tooltip,
IconButton
} from '@mui/material';
import {
CheckCircle,
Security,
TrendingUp,
Settings,
Web,
Psychology,
LockOpen,
Visibility,
VisibilityOff
} from '@mui/icons-material';
import { OnboardingData, Capability } from '../types';
interface SetupSummaryProps {
onboardingData: OnboardingData;
capabilities: Capability[];
expandedSection: string | null;
setExpandedSection: (section: string | null) => void;
}
export const SetupSummary: React.FC<SetupSummaryProps> = ({
onboardingData,
capabilities,
expandedSection,
setExpandedSection
}) => {
const [showApiKeys, setShowApiKeys] = useState(false);
const unlockedCapabilities = capabilities.filter(cap => cap.unlocked);
return (
<Zoom in={true} timeout={800}>
<Paper elevation={0} sx={{
p: 4,
mb: 4,
background: 'linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%)',
border: '1px solid rgba(16, 185, 129, 0.2)',
borderRadius: 3
}}>
{/* Header with Stats Chips */}
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 4, flexWrap: 'wrap', gap: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<CheckCircle sx={{ color: 'success.main', fontSize: 32 }} />
<Typography variant="h4" color="success.main" sx={{ fontWeight: 600 }}>
Setup Summary
</Typography>
</Box>
{/* Stats Chips */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, flexWrap: 'wrap' }}>
<Chip
label={`${Object.keys(onboardingData.apiKeys).length} AI Providers`}
color="primary"
variant="filled"
size="small"
icon={<Security />}
/>
<Chip
label={`${unlockedCapabilities.length}/${capabilities.length} Capabilities`}
color="success"
variant="filled"
size="small"
icon={<LockOpen />}
/>
{/* Only show missing chip if there are actually missing items */}
{(() => {
const missingCount = capabilities.length - unlockedCapabilities.length;
return missingCount > 0 ? (
<Chip
label={`${missingCount} Missing`}
color="warning"
variant="filled"
size="small"
/>
) : (
<Chip
label="All Complete"
color="success"
variant="filled"
size="small"
icon={<CheckCircle sx={{ fontSize: 16 }} />}
/>
);
})()}
</Box>
</Box>
{/* Main Content Grid - Compact Single Card */}
<Grid container spacing={3}>
{/* Configuration Details Card */}
<Grid item xs={12}>
<Card elevation={0} sx={{ background: 'rgba(255, 255, 255, 0.9)', borderRadius: 2 }}>
<CardContent sx={{ p: 3 }}>
{/* Configuration Details Header - Updated for readability */}
<Typography variant="h6" sx={{
fontWeight: 600,
mb: 3,
display: 'flex',
alignItems: 'center',
gap: 1,
color: '#000000 !important'
}}>
<Settings sx={{ color: 'primary.main' }} />
Configuration Details
</Typography>
<Grid container spacing={2}>
{/* API Keys */}
<Grid item xs={6} sm={3}>
<Box
sx={{
p: 2,
border: '1px solid rgba(0,0,0,0.1)',
borderRadius: 1,
background: 'rgba(255,255,255,0.5)',
cursor: 'pointer',
'&:hover': { background: 'rgba(255,255,255,0.7)' }
}}
onClick={() => setExpandedSection(expandedSection === 'api-keys' ? null : 'api-keys')}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
<Security sx={{ color: 'primary.main', fontSize: 18 }} />
<Typography variant="subtitle2" sx={{ fontWeight: 600, color: '#000000' }}>
API Keys
</Typography>
</Box>
<Typography variant="body2" sx={{ color: '#000000' }}>
{Object.keys(onboardingData.apiKeys).length} configured
</Typography>
</Box>
</Grid>
{/* Website Analysis */}
<Grid item xs={6} sm={3}>
<Box
sx={{
p: 2,
border: '1px solid rgba(0,0,0,0.1)',
borderRadius: 1,
background: 'rgba(255,255,255,0.5)',
cursor: 'pointer',
'&:hover': { background: 'rgba(255,255,255,0.7)' }
}}
onClick={() => setExpandedSection(expandedSection === 'website' ? null : 'website')}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
<Web sx={{ color: 'primary.main', fontSize: 18 }} />
<Typography variant="subtitle2" sx={{ fontWeight: 600, color: '#000000' }}>
Website Analysis
</Typography>
</Box>
<Typography variant="body2" sx={{ color: '#000000' }}>
{onboardingData.websiteUrl ? 'Configured' : 'Not set'}
</Typography>
</Box>
</Grid>
{/* Research Configuration */}
<Grid item xs={6} sm={3}>
<Box
sx={{
p: 2,
border: '1px solid rgba(0,0,0,0.1)',
borderRadius: 1,
background: 'rgba(255,255,255,0.5)',
cursor: 'pointer',
'&:hover': { background: 'rgba(255,255,255,0.7)' }
}}
onClick={() => setExpandedSection(expandedSection === 'research' ? null : 'research')}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
<TrendingUp sx={{ color: 'primary.main', fontSize: 18 }} />
<Typography variant="subtitle2" sx={{ fontWeight: 600, color: '#000000' }}>
Research Config
</Typography>
</Box>
<Typography variant="body2" sx={{ color: '#000000' }}>
{onboardingData.researchPreferences ? 'Configured' : 'Not set'}
</Typography>
</Box>
</Grid>
{/* Personalization */}
<Grid item xs={6} sm={3}>
<Box
sx={{
p: 2,
border: '1px solid rgba(0,0,0,0.1)',
borderRadius: 1,
background: 'rgba(255,255,255,0.5)',
cursor: 'pointer',
'&:hover': { background: 'rgba(255,255,255,0.7)' }
}}
onClick={() => setExpandedSection(expandedSection === 'personalization' ? null : 'personalization')}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
<Psychology sx={{ color: 'primary.main', fontSize: 18 }} />
<Typography variant="subtitle2" sx={{ fontWeight: 600, color: '#000000' }}>
Personalization
</Typography>
</Box>
<Typography variant="body2" sx={{ color: '#000000' }}>
{onboardingData.personalizationSettings ? 'Configured' : 'Not set'}
</Typography>
</Box>
</Grid>
</Grid>
{/* Expandable Details */}
{(expandedSection === 'api-keys' || expandedSection === 'website' || expandedSection === 'research' || expandedSection === 'personalization') && (
<Box sx={{ mt: 3 }}>
<Paper elevation={0} sx={{
background: 'rgba(255, 255, 255, 0.9)',
borderRadius: 2,
p: 3
}}>
{/* API Keys Details */}
{expandedSection === 'api-keys' && (
<Box>
<Typography variant="h6" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1, color: '#000000' }}>
<Security sx={{ color: 'primary.main' }} />
API Keys ({Object.keys(onboardingData.apiKeys).length} configured)
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
{Object.entries(onboardingData.apiKeys).map(([provider, key]) => (
<Box key={provider} sx={{
p: 2,
border: '1px solid rgba(0,0,0,0.1)',
borderRadius: 1,
background: 'rgba(255,255,255,0.5)'
}}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
<Typography variant="subtitle2" sx={{ fontWeight: 600, textTransform: 'capitalize' }}>
{provider}
</Typography>
<Tooltip title={showApiKeys ? 'Hide key' : 'Show key'}>
<IconButton
size="small"
onClick={() => setShowApiKeys(!showApiKeys)}
>
{showApiKeys ? <VisibilityOff /> : <Visibility />}
</IconButton>
</Tooltip>
</Box>
<Typography variant="body2" sx={{ fontFamily: 'monospace' }}>
{showApiKeys ? key : '••••••••••••••••••••••••••••••••'}
</Typography>
</Box>
))}
</Box>
</Box>
)}
{/* Website Analysis Details */}
{expandedSection === 'website' && (
<Box>
<Typography variant="h6" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1, color: '#000000' }}>
<Web sx={{ color: 'primary.main' }} />
Website Analysis
</Typography>
{onboardingData.websiteUrl ? (
<Box>
<Typography variant="body2" sx={{ mb: 2 }}>
<strong>URL:</strong> {onboardingData.websiteUrl}
</Typography>
{onboardingData.styleAnalysis && (
<Typography variant="body2" color="success.main">
Style analysis completed
</Typography>
)}
</Box>
) : (
<Typography variant="body2" color="warning.main">
No website URL configured
</Typography>
)}
</Box>
)}
{/* Research Configuration Details */}
{expandedSection === 'research' && (
<Box>
<Typography variant="h6" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1, color: '#000000' }}>
<TrendingUp sx={{ color: 'primary.main' }} />
Research Configuration
</Typography>
{onboardingData.researchPreferences ? (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2">
<strong>Depth:</strong> {onboardingData.researchPreferences.research_depth}
</Typography>
<Typography variant="body2">
<strong>Content Types:</strong> {onboardingData.researchPreferences.content_types?.join(', ')}
</Typography>
<Typography variant="body2">
<strong>Auto Research:</strong> {onboardingData.researchPreferences.auto_research ? 'Enabled' : 'Disabled'}
</Typography>
</Box>
) : (
<Typography variant="body2" color="warning.main">
Research preferences not configured
</Typography>
)}
</Box>
)}
{/* Personalization Details */}
{expandedSection === 'personalization' && (
<Box>
<Typography variant="h6" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1, color: '#000000' }}>
<Psychology sx={{ color: 'primary.main' }} />
Personalization
</Typography>
{onboardingData.personalizationSettings ? (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2">
<strong>Style:</strong> {onboardingData.personalizationSettings.writing_style}
</Typography>
<Typography variant="body2">
<strong>Tone:</strong> {onboardingData.personalizationSettings.tone}
</Typography>
<Typography variant="body2">
<strong>Brand Voice:</strong> {onboardingData.personalizationSettings.brand_voice}
</Typography>
</Box>
) : (
<Typography variant="body2" color="warning.main">
Personalization not configured
</Typography>
)}
</Box>
)}
</Paper>
</Box>
)}
</CardContent>
</Card>
</Grid>
</Grid>
</Paper>
</Zoom>
);
};
export default SetupSummary;