da50f3b5ea
- Design tokens (ds.ts, theme.ts, scoreTheme.ts): new warm palette (#152642 navy, #f9f8f6 warm white, #e8e7e4 borders, #b8975a gold accent), flat score tier badges replacing CSS gradients, Inter + DM Serif Display typography - Card components: white-background cards, DM Serif score numbers, max-2 badge chips with +N overflow tooltip, editorial score badge positioning - Layout shell: gold left-accent nav active state, 64px top bar, outlined workspace chip, DM Serif page titles - Shared atoms: GenericBadge (outlined/solid variants), ResultFilterBar (simplified chip styles), DecisionContextPanel (dot metrics, no left accent) - Global replacement (118 files): #1e3a5f→#152642, #e2e8f0→#e8e7e4, #f4f6f9→#f9f8f6 — all handled via Node.js for proper UTF-8 safety Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
104 lines
4.5 KiB
TypeScript
104 lines
4.5 KiB
TypeScript
import { Box, Button, CircularProgress, LinearProgress, Typography } from '@mui/material'
|
|
import { Download, Send } from 'lucide-react'
|
|
import type { OfferReportDraft } from '../../domain/offerReport'
|
|
import type { Property } from '../../domain/property'
|
|
|
|
interface OfferWizardPdfStepProps {
|
|
generating: boolean
|
|
progress: number
|
|
ready: boolean
|
|
draft: OfferReportDraft | null
|
|
property: Property | undefined
|
|
onDownload: () => void
|
|
onAttach: () => void
|
|
}
|
|
|
|
export function OfferWizardPdfStep({ generating, progress, ready, draft, property, onDownload, onAttach }: OfferWizardPdfStepProps) {
|
|
return (
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', gap: 3 }}>
|
|
{generating ? (
|
|
<>
|
|
<CircularProgress size={48} sx={{ color: '#152642' }} />
|
|
<Typography variant="body1" sx={{ fontWeight: 600, color: '#152642' }}>
|
|
PDF wird generiert…
|
|
</Typography>
|
|
<Box sx={{ width: '100%', maxWidth: 400 }}>
|
|
<LinearProgress variant="determinate" value={progress} sx={{ height: 6, borderRadius: 3 }} />
|
|
<Typography variant="caption" sx={{ color: '#64748b', display: 'block', textAlign: 'center', mt: 1 }}>
|
|
{Math.round(progress)}%
|
|
</Typography>
|
|
</Box>
|
|
</>
|
|
) : ready ? (
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2, width: '100%' }}>
|
|
<Box
|
|
sx={{
|
|
width: '100%',
|
|
maxWidth: 520,
|
|
height: 380,
|
|
bgcolor: '#f8fafc',
|
|
border: '1px solid #e2e8f0',
|
|
borderRadius: 1.5,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
overflow: 'hidden',
|
|
}}
|
|
>
|
|
<Box sx={{ bgcolor: '#152642', px: 2, py: 1, display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
<Box sx={{ width: 10, height: 10, borderRadius: '50%', bgcolor: '#ef4444' }} />
|
|
<Box sx={{ width: 10, height: 10, borderRadius: '50%', bgcolor: '#f59e0b' }} />
|
|
<Box sx={{ width: 10, height: 10, borderRadius: '50%', bgcolor: '#10b981' }} />
|
|
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.7)', ml: 1, fontSize: '0.7rem' }}>
|
|
Angebot_{property?.title ?? 'Objekt'}.pdf
|
|
</Typography>
|
|
</Box>
|
|
<Box sx={{ flex: 1, p: 3 }}>
|
|
<Typography variant="body2" sx={{ fontWeight: 700, color: '#152642', mb: 1 }}>
|
|
Angebotsschreiben
|
|
</Typography>
|
|
{draft?.editableFields.slice(0, 3).map(f => (
|
|
<Box key={f.id} sx={{ mb: 1 }}>
|
|
<Typography variant="caption" sx={{ color: '#94a3b8', fontSize: '0.65rem', display: 'block' }}>{f.label}</Typography>
|
|
<Typography variant="caption" sx={{ color: '#374151', fontSize: '0.75rem', display: 'block' }}>
|
|
{f.value.slice(0, 80)}{f.value.length > 80 ? '…' : ''}
|
|
</Typography>
|
|
</Box>
|
|
))}
|
|
{(draft?.viewingAppointments.length ?? 0) > 0 && (
|
|
<Box sx={{ mt: 1.5, p: 1, bgcolor: '#f1f5f9', borderRadius: 1 }}>
|
|
<Typography variant="caption" sx={{ fontWeight: 600, fontSize: '0.72rem', display: 'block', mb: 0.5 }}>
|
|
Besichtigungstermine
|
|
</Typography>
|
|
{draft!.viewingAppointments.map(a => (
|
|
<Typography key={a.id} variant="caption" sx={{ fontSize: '0.7rem', display: 'block', color: '#475569' }}>
|
|
{new Date(a.date).toLocaleDateString('de-CH')} · {a.timeSlot}
|
|
</Typography>
|
|
))}
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
<Box sx={{ display: 'flex', gap: 1.5 }}>
|
|
<Button
|
|
variant="contained"
|
|
startIcon={<Download size={16} />}
|
|
onClick={onDownload}
|
|
sx={{ textTransform: 'none', bgcolor: '#152642', '&:hover': { bgcolor: '#16304d' } }}
|
|
>
|
|
Herunterladen
|
|
</Button>
|
|
<Button
|
|
variant="outlined"
|
|
startIcon={<Send size={16} />}
|
|
onClick={onAttach}
|
|
sx={{ textTransform: 'none' }}
|
|
>
|
|
An Nachricht anhängen
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
) : null}
|
|
</Box>
|
|
)
|
|
}
|