Files
ALwrity/frontend/src/components/OnboardingWizard/common/WizardHeader.tsx

263 lines
8.4 KiB
TypeScript

import React from 'react';
import {
Box,
Typography,
LinearProgress,
Stepper,
Step,
StepLabel,
IconButton,
Tooltip,
Fade,
CircularProgress
} from '@mui/material';
import {
HelpOutline,
Close
} from '@mui/icons-material';
import UserBadge from '../../shared/UserBadge';
import UsageDashboard from '../../shared/UsageDashboard';
interface WizardHeaderProps {
activeStep: number;
progress: number;
stepHeaderContent: {
title: string;
description: string;
};
showProgressMessage: boolean;
progressMessage: string;
showHelp: boolean;
isMobile: boolean;
steps: Array<{
label: string;
description: string;
icon: string;
}>;
onStepClick: (stepIndex: number) => void;
onHelpToggle: () => void;
}
export const WizardHeader: React.FC<WizardHeaderProps> = ({
activeStep,
progress,
stepHeaderContent,
showProgressMessage,
progressMessage,
showHelp,
isMobile,
steps,
onStepClick,
onHelpToggle
}) => {
return (
<Box
sx={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white',
p: { xs: 2, md: 3 },
position: 'relative',
overflow: 'hidden',
'&::before': {
content: '""',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: 'radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%)',
pointerEvents: 'none',
}
}}
>
{/* Progress Message */}
{showProgressMessage && (
<Fade in={showProgressMessage}>
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
background: 'rgba(16, 185, 129, 0.9)',
color: 'white',
p: 2,
textAlign: 'center',
zIndex: 10,
backdropFilter: 'blur(10px)',
borderBottom: '1px solid rgba(255, 255, 255, 0.2)'
}}
>
<Typography variant="body1" sx={{ fontWeight: 600 }}>
{progressMessage}
</Typography>
</Box>
</Fade>
)}
{/* Top Row - Title and Actions */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1.5, position: 'relative', zIndex: 1 }}>
<Box sx={{ flex: 1, display: 'flex', alignItems: 'center', gap: 1.5 }}>
<UserBadge colorMode="dark" />
{/* Usage Dashboard - Show API usage statistics during onboarding */}
<UsageDashboard compact={true} />
</Box>
<Box sx={{ flex: 2, textAlign: 'center' }}>
<Typography variant="h4" sx={{ fontWeight: 700, letterSpacing: '-0.025em' }}>
{stepHeaderContent.title}
</Typography>
</Box>
<Box sx={{ display: 'flex', gap: 1.5, flex: 1, justifyContent: 'flex-end', alignItems: 'center' }}>
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', mr: 0.5 }}>
<Tooltip title={`Setup progress: ${Math.round(progress)}%`} arrow>
<Box sx={{ position: 'relative', width: 36, height: 36 }}>
<CircularProgress
variant="determinate"
value={progress}
size={36}
thickness={3.6}
sx={{
color: 'rgba(248, 250, 252, 0.95)',
'& .MuiCircularProgress-circle': {
strokeLinecap: 'round'
}
}}
/>
<Box
sx={{
position: 'absolute',
inset: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', lineHeight: 1 }}>
<Typography variant="caption" sx={{ fontSize: 9, opacity: 0.85 }}>
Setup
</Typography>
<Typography variant="caption" sx={{ fontWeight: 700 }}>
{Math.round(progress)}%
</Typography>
</Box>
</Box>
</Box>
</Tooltip>
</Box>
<Tooltip title="Get Help" arrow>
<IconButton
onClick={onHelpToggle}
sx={{
color: 'white',
bgcolor: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
'&:hover': {
bgcolor: 'rgba(255, 255, 255, 0.2)',
}
}}
>
<HelpOutline />
</IconButton>
</Tooltip>
<Tooltip title="Skip for now" arrow>
<IconButton
sx={{
color: 'white',
bgcolor: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
'&:hover': {
bgcolor: 'rgba(255, 255, 255, 0.2)',
}
}}
>
<Close />
</IconButton>
</Tooltip>
</Box>
</Box>
{/* Stepper in Header */}
<Box sx={{ position: 'relative', zIndex: 1, mt: 0.25 }}>
<Stepper
activeStep={activeStep}
alternativeLabel={!isMobile}
sx={{
'& .MuiStepLabel-root': {
cursor: 'pointer',
},
'& .MuiStepLabel-label': {
fontSize: '0.8rem',
fontWeight: 600,
color: 'white',
},
'& .MuiStepLabel-labelContainer': {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
mt: 0.25
},
'& .MuiStepLabel-label.Mui-completed': {
color: 'rgba(255, 255, 255, 0.9)',
},
'& .MuiStepLabel-label.Mui-active': {
color: 'white',
},
'& .MuiStepLabel-label.Mui-disabled': {
color: 'rgba(255, 255, 255, 0.6)',
},
}}
>
{steps.map((step, index) => (
<Step key={step.label}>
<Tooltip title={step.description} arrow>
<StepLabel
onClick={() => onStepClick(index)}
sx={{
cursor: index <= activeStep ? 'pointer' : 'default',
'& .MuiStepLabel-iconContainer': {
background: index <= activeStep
? 'rgba(255, 255, 255, 0.2)'
: 'rgba(255, 255, 255, 0.08)',
borderRadius: '50%',
width: 28,
height: 28,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: index <= activeStep ? 'white' : 'rgba(255, 255, 255, 0.6)',
transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
boxShadow: index <= activeStep
? '0 3px 10px rgba(15, 23, 42, 0.45)'
: 'none',
border: index < activeStep
? '1px solid rgba(248, 250, 252, 0.9)'
: '1px solid rgba(148, 163, 184, 0.4)',
'&:hover': {
transform: index <= activeStep ? 'translateY(-1px) scale(1.03)' : 'none',
boxShadow: index <= activeStep
? '0 5px 14px rgba(15, 23, 42, 0.55)'
: 'none',
}
},
'& .MuiStepLabel-label': {
fontSize: '0.8rem',
fontWeight: 600,
textAlign: 'center',
textDecoration: index < activeStep ? 'underline' : 'none',
opacity: index <= activeStep ? 0.98 : 0.7
}
}}
>
<Typography variant="body2" sx={{ fontWeight: 600, textAlign: 'center' }}>
{step.label}
</Typography>
</StepLabel>
</Tooltip>
</Step>
))}
</Stepper>
</Box>
</Box>
);
};