122 lines
4.8 KiB
TypeScript
122 lines
4.8 KiB
TypeScript
import React, { useState } from 'react';
|
|
import api from '../api';
|
|
|
|
interface OnboardingWizardProps {
|
|
onComplete: () => void;
|
|
onDismiss: () => void;
|
|
}
|
|
|
|
const OnboardingWizard: React.FC<OnboardingWizardProps> = ({ onComplete, onDismiss }) => {
|
|
const [planKey, setPlanKey] = useState<'TRIAL_7D' | 'STANDARD_MONTHLY'>('TRIAL_7D');
|
|
const [mandateName, setMandateName] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const _handleSubmit = async () => {
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
const res = await api.post('/api/local/onboarding', {
|
|
planKey,
|
|
companyName: mandateName.trim() || undefined,
|
|
});
|
|
if (res.data?.alreadyProvisioned) {
|
|
setError('Du hast bereits einen Mandanten mit Admin-Zugang.');
|
|
return;
|
|
}
|
|
window.dispatchEvent(new CustomEvent('features-changed'));
|
|
onComplete();
|
|
} catch (err: any) {
|
|
setError(err?.response?.data?.detail || 'Fehler bei der Einrichtung');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div style={{
|
|
position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
|
|
background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
zIndex: 9999,
|
|
}}>
|
|
<div style={{
|
|
background: 'var(--bg-primary, #fff)', borderRadius: '12px', padding: '32px',
|
|
maxWidth: '480px', width: '90%', boxShadow: '0 8px 32px rgba(0,0,0,0.2)',
|
|
}}>
|
|
<h2 style={{ margin: '0 0 8px', fontSize: '1.5rem' }}>Mandant erstellen</h2>
|
|
<p style={{ color: 'var(--text-secondary, #666)', margin: '0 0 24px' }}>
|
|
Erstelle deinen eigenen Arbeitsbereich mit Abo-Auswahl.
|
|
</p>
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginBottom: '20px' }}>
|
|
<label style={{
|
|
display: 'flex', alignItems: 'center', gap: '12px', padding: '16px',
|
|
border: planKey === 'TRIAL_7D' ? '2px solid var(--accent, #4f46e5)' : '2px solid var(--border, #e5e7eb)',
|
|
borderRadius: '8px', cursor: 'pointer',
|
|
}}>
|
|
<input type="radio" name="plan" checked={planKey === 'TRIAL_7D'}
|
|
onChange={() => setPlanKey('TRIAL_7D')} />
|
|
<div>
|
|
<strong>Kostenlos testen</strong>
|
|
<div style={{ fontSize: '0.85rem', color: 'var(--text-secondary, #666)' }}>
|
|
7 Tage gratis, danach flexibel upgraden
|
|
</div>
|
|
</div>
|
|
</label>
|
|
|
|
<label style={{
|
|
display: 'flex', alignItems: 'center', gap: '12px', padding: '16px',
|
|
border: planKey === 'STANDARD_MONTHLY' ? '2px solid var(--accent, #4f46e5)' : '2px solid var(--border, #e5e7eb)',
|
|
borderRadius: '8px', cursor: 'pointer',
|
|
}}>
|
|
<input type="radio" name="plan" checked={planKey === 'STANDARD_MONTHLY'}
|
|
onChange={() => setPlanKey('STANDARD_MONTHLY')} />
|
|
<div>
|
|
<strong>Standard (Monatlich)</strong>
|
|
<div style={{ fontSize: '0.85rem', color: 'var(--text-secondary, #666)' }}>
|
|
Team-Workspace mit vollem Funktionsumfang
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
|
|
<div style={{ marginBottom: '20px' }}>
|
|
<label style={{ display: 'block', marginBottom: '6px', fontWeight: 500 }}>
|
|
Name des Mandanten <span style={{ fontWeight: 400, color: 'var(--text-secondary, #666)' }}>(optional)</span>
|
|
</label>
|
|
<input
|
|
type="text" value={mandateName}
|
|
onChange={(e) => setMandateName(e.target.value)}
|
|
placeholder="z. B. Firmenname oder Projektname"
|
|
style={{
|
|
width: '100%', padding: '10px 12px', borderRadius: '6px',
|
|
border: '1px solid var(--border, #d1d5db)', fontSize: '1rem',
|
|
boxSizing: 'border-box',
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
{error && <p style={{ color: '#ef4444', margin: '0 0 16px' }}>{error}</p>}
|
|
|
|
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end' }}>
|
|
<button onClick={onDismiss} style={{
|
|
padding: '10px 20px', borderRadius: '6px', border: '1px solid var(--border, #d1d5db)',
|
|
background: 'transparent', cursor: 'pointer',
|
|
}}>
|
|
Abbrechen
|
|
</button>
|
|
<button onClick={_handleSubmit} disabled={loading}
|
|
style={{
|
|
padding: '10px 20px', borderRadius: '6px', border: 'none',
|
|
background: 'var(--accent, #4f46e5)', color: '#fff', cursor: 'pointer',
|
|
opacity: loading ? 0.6 : 1,
|
|
}}>
|
|
{loading ? 'Wird eingerichtet...' : 'Mandant erstellen'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default OnboardingWizard;
|