🎯 Problemet: Kunder synes det er svært at lave smart pakker ✅ Løsningen: Komplet redesign med guidet oprettelse 🚀 Nye Funktioner: 1. SMART PACKAGE WIZARD (SmartPackageWizard.js) - Trin-for-trin guide gennem 4 nemme steps - Trin 1: Grundinfo med templates og tooltips - Trin 2: Materialer med visuelt overblik - Trin 3: Opgaver med auto-beregning - Trin 4: Gennemgang før gemning - Indbygget validation på hvert trin - Auto-save i edit mode - Responsive design (mobil + desktop) 2. QUICK START DIALOG (QuickStartDialog.js) - Vælg mellem 3 oprettelsesmetoder: * Guidet Wizard (anbefalet for begyndere) * Start med Skabelon (hurtigst) * Avanceret (fuld kontrol) - Visuelle cards med ikoner og forklaring - Template selector med preview 3. HJÆLPE-PANEL (SmartPackagesHelpPanel.js) - Sticky sidebar med kontekstuel hjælp - "Kom i gang" guide i 4 trin - Tips & Tricks sektion - "Undgå disse fejl" warnings - Tommelfingerregler (timepris, buffer, spild) - Kan åbnes/lukkes efter behov - Drawer på mobil 4. INTEGRATION AF CARPENTER UX KOMPONENTER - FormField: Real-time validation på alle inputs - Tooltips: Hjælpetekst ved svære felter - AutosaveIndicator: Viser gem-status - LoadingSpinner: Bedre loading states 💡 UX Forbedringer: ✓ Klare instruktioner ved hvert trin ✓ Visual feedback (ikoner, farver, progress) ✓ Foreslåede værdier (standard timepris: 580 kr) ✓ Template system til hurtig start ✓ Automatisk beregning af totaler ✓ Fejlmeddelelser med forklaringer ✓ Responsivt design (mobil/tablet/desktop) ✓ Hjælp altid tilgængelig ✓ Kan ikke gå videre uden at udfylde påkrævet ✓ Gennemse alt før gemning 📊 Validering: - Pakkenavn: min 3 tegn - Beskrivelse: min 10 tegn - Timepris: 100-2000 kr. - Mindst 1 materiale - Mindst 1 opgave - Estimeret tid > 0 🎨 Visuelle Elementer: - Stepper viser fremskridt - Alert boxes med vigtige tips - Ikoner for hver sektion - Chips for templates - Cards for materialer/opgaver - Farvekodet totaler (grøn for success) 📱 Responsive Features: - Hjælpepanel: Sidebar på desktop, drawer på mobil - Grid layouts tilpasser sig skærmstørrelse - Touch-venlige buttons - Optimeret scrolling 🔧 Tekniske Detaljer: - Bruger useState hooks for lokal state - useEffect for data loading - Axios for API kald - Material-UI komponenter - React Beautiful DnD ready - Validering før navigation - Auto-save med 2s debounce Dette gør det 10x nemmere at lave smart pakker! 🎉
228 lines
8.8 KiB
JavaScript
228 lines
8.8 KiB
JavaScript
import React, { useState } from 'react';
|
|
import {
|
|
Dialog, DialogTitle, DialogContent, DialogActions,
|
|
Button, Grid, Card, CardContent, Typography, Box,
|
|
Alert, Chip, RadioGroup, FormControlLabel, Radio
|
|
} from '@mui/material';
|
|
import {
|
|
Rocket, AutoAwesome, Build, Close
|
|
} from '@mui/icons-material';
|
|
|
|
/**
|
|
* Quick Start Dialog - hjælper brugeren med at vælge hvordan de vil starte
|
|
*/
|
|
const QuickStartDialog = ({ open, onClose, onSelectMode, templates }) => {
|
|
const [selectedMode, setSelectedMode] = useState('wizard');
|
|
const [selectedTemplate, setSelectedTemplate] = useState(null);
|
|
|
|
const handleStart = () => {
|
|
if (selectedMode === 'template' && selectedTemplate) {
|
|
onSelectMode('template', selectedTemplate);
|
|
} else {
|
|
onSelectMode(selectedMode);
|
|
}
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
|
<DialogTitle>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
<Typography variant="h6">
|
|
🚀 Kom i gang med Smart Pakker
|
|
</Typography>
|
|
<Button onClick={onClose} size="small">
|
|
<Close />
|
|
</Button>
|
|
</Box>
|
|
</DialogTitle>
|
|
|
|
<DialogContent>
|
|
<Alert severity="info" sx={{ mb: 3 }}>
|
|
<Typography variant="body2">
|
|
Vælg hvordan du vil oprette din smart pakke. Vi anbefaler at starte med wizarden hvis det er første gang.
|
|
</Typography>
|
|
</Alert>
|
|
|
|
<RadioGroup value={selectedMode} onChange={(e) => setSelectedMode(e.target.value)}>
|
|
<Grid container spacing={2}>
|
|
{/* Wizard Mode */}
|
|
<Grid item xs={12} md={4}>
|
|
<Card
|
|
variant="outlined"
|
|
sx={{
|
|
cursor: 'pointer',
|
|
border: selectedMode === 'wizard' ? 2 : 1,
|
|
borderColor: selectedMode === 'wizard' ? 'primary.main' : 'divider',
|
|
'&:hover': { borderColor: 'primary.main' }
|
|
}}
|
|
onClick={() => setSelectedMode('wizard')}
|
|
>
|
|
<CardContent>
|
|
<FormControlLabel
|
|
value="wizard"
|
|
control={<Radio />}
|
|
label=""
|
|
sx={{ m: 0, display: 'none' }}
|
|
/>
|
|
<Box sx={{ textAlign: 'center' }}>
|
|
<Rocket sx={{ fontSize: 48, color: 'primary.main', mb: 2 }} />
|
|
<Typography variant="h6" gutterBottom>
|
|
Guidet Wizard
|
|
</Typography>
|
|
<Chip label="Anbefalet" color="success" size="small" sx={{ mb: 1 }} />
|
|
<Typography variant="body2" color="textSecondary">
|
|
Nem trin-for-trin guide der hjælper dig igennem hele processen
|
|
</Typography>
|
|
<Typography variant="caption" display="block" sx={{ mt: 2, color: 'primary.main' }}>
|
|
✓ Perfekt til begyndere
|
|
<br />
|
|
✓ Ingen vigtige felter glemmes
|
|
<br />
|
|
✓ Hjælpetekst undervejs
|
|
</Typography>
|
|
</Box>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
{/* Template Mode */}
|
|
<Grid item xs={12} md={4}>
|
|
<Card
|
|
variant="outlined"
|
|
sx={{
|
|
cursor: 'pointer',
|
|
border: selectedMode === 'template' ? 2 : 1,
|
|
borderColor: selectedMode === 'template' ? 'primary.main' : 'divider',
|
|
'&:hover': { borderColor: 'primary.main' }
|
|
}}
|
|
onClick={() => setSelectedMode('template')}
|
|
>
|
|
<CardContent>
|
|
<FormControlLabel
|
|
value="template"
|
|
control={<Radio />}
|
|
label=""
|
|
sx={{ m: 0, display: 'none' }}
|
|
/>
|
|
<Box sx={{ textAlign: 'center' }}>
|
|
<AutoAwesome sx={{ fontSize: 48, color: 'secondary.main', mb: 2 }} />
|
|
<Typography variant="h6" gutterBottom>
|
|
Start med Skabelon
|
|
</Typography>
|
|
<Chip label="Hurtigst" color="info" size="small" sx={{ mb: 1 }} />
|
|
<Typography variant="body2" color="textSecondary">
|
|
Brug en færdiglavet skabelon og tilpas den til dine behov
|
|
</Typography>
|
|
<Typography variant="caption" display="block" sx={{ mt: 2, color: 'secondary.main' }}>
|
|
✓ Spar tid
|
|
<br />
|
|
✓ Best practices inkluderet
|
|
<br />
|
|
✓ Klar til brug
|
|
</Typography>
|
|
</Box>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
|
|
{/* Advanced Mode */}
|
|
<Grid item xs={12} md={4}>
|
|
<Card
|
|
variant="outlined"
|
|
sx={{
|
|
cursor: 'pointer',
|
|
border: selectedMode === 'advanced' ? 2 : 1,
|
|
borderColor: selectedMode === 'advanced' ? 'primary.main' : 'divider',
|
|
'&:hover': { borderColor: 'primary.main' }
|
|
}}
|
|
onClick={() => setSelectedMode('advanced')}
|
|
>
|
|
<CardContent>
|
|
<FormControlLabel
|
|
value="advanced"
|
|
control={<Radio />}
|
|
label=""
|
|
sx={{ m: 0, display: 'none' }}
|
|
/>
|
|
<Box sx={{ textAlign: 'center' }}>
|
|
<Build sx={{ fontSize: 48, color: 'warning.main', mb: 2 }} />
|
|
<Typography variant="h6" gutterBottom>
|
|
Avanceret
|
|
</Typography>
|
|
<Chip label="Erfarne" color="warning" size="small" sx={{ mb: 1 }} />
|
|
<Typography variant="body2" color="textSecondary">
|
|
Fuld kontrol med alle felter og indstillinger
|
|
</Typography>
|
|
<Typography variant="caption" display="block" sx={{ mt: 2, color: 'warning.main' }}>
|
|
✓ Alle funktioner
|
|
<br />
|
|
✓ Fuld tilpasning
|
|
<br />
|
|
✓ Kræver erfaring
|
|
</Typography>
|
|
</Box>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
</Grid>
|
|
</RadioGroup>
|
|
|
|
{/* Template Selection */}
|
|
{selectedMode === 'template' && templates && templates.length > 0 && (
|
|
<Box sx={{ mt: 3 }}>
|
|
<Typography variant="subtitle2" gutterBottom>
|
|
Vælg en skabelon:
|
|
</Typography>
|
|
<Grid container spacing={2}>
|
|
{templates.map(template => (
|
|
<Grid item xs={12} sm={6} key={template.id}>
|
|
<Card
|
|
variant="outlined"
|
|
sx={{
|
|
cursor: 'pointer',
|
|
border: selectedTemplate?.id === template.id ? 2 : 1,
|
|
borderColor: selectedTemplate?.id === template.id ? 'primary.main' : 'divider',
|
|
'&:hover': { borderColor: 'primary.main' }
|
|
}}
|
|
onClick={() => setSelectedTemplate(template)}
|
|
>
|
|
<CardContent>
|
|
<Typography variant="subtitle1" gutterBottom>
|
|
{template.name}
|
|
</Typography>
|
|
<Typography variant="body2" color="textSecondary" gutterBottom>
|
|
{template.description}
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', gap: 1, mt: 1 }}>
|
|
<Chip label={template.category} size="small" />
|
|
<Chip label={`${template.materials?.length || 0} materialer`} size="small" variant="outlined" />
|
|
<Chip label={`${template.tasks?.length || 0} opgaver`} size="small" variant="outlined" />
|
|
</Box>
|
|
</CardContent>
|
|
</Card>
|
|
</Grid>
|
|
))}
|
|
</Grid>
|
|
</Box>
|
|
)}
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
<Button onClick={onClose}>
|
|
Annuller
|
|
</Button>
|
|
<Button
|
|
variant="contained"
|
|
onClick={handleStart}
|
|
disabled={selectedMode === 'template' && !selectedTemplate}
|
|
>
|
|
Kom i gang
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
export default QuickStartDialog;
|