fixes admin panel
This commit is contained in:
parent
d4b2cb1dd6
commit
d45dab587f
2 changed files with 26 additions and 56 deletions
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* AdminInvitationWizardPage
|
||||
*
|
||||
* 5-step wizard for batch user invitations:
|
||||
|
|
@ -13,7 +13,6 @@ import React, { useState, useEffect } from 'react';
|
|||
import { useInvitations, type InvitationCreate } from '../../hooks/useInvitations';
|
||||
import { useUserMandates, type Mandate, type Role } from '../../hooks/useUserMandates';
|
||||
import { useFeatureAccess, type FeatureInstance, type FeatureInstanceRole } from '../../hooks/useFeatureAccess';
|
||||
import { useToast } from '../../contexts/ToastContext';
|
||||
import styles from './Admin.module.css';
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -79,7 +78,6 @@ export const AdminInvitationWizardPage: React.FC = () => {
|
|||
const { createInvitation } = useInvitations();
|
||||
const { fetchMandates, fetchRoles } = useUserMandates();
|
||||
const { fetchInstances, fetchInstanceRoles } = useFeatureAccess();
|
||||
const { showError: showToastError } = useToast();
|
||||
|
||||
const [step, setStep] = useState(1);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* AdminMandateWizardPage (v4.0 - poweron port)
|
||||
*
|
||||
* 4-step wizard for mandate management:
|
||||
|
|
@ -35,7 +35,7 @@ interface RoleOption {
|
|||
}
|
||||
|
||||
export const AdminMandateWizardPage: React.FC = () => {
|
||||
const { showSuccess, showError } = useToast();
|
||||
const { showSuccess } = useToast();
|
||||
|
||||
const {
|
||||
fetchMandateUsers,
|
||||
|
|
@ -66,7 +66,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
const [mandates, setMandates] = useState<Mandate[]>([]);
|
||||
const [selectedMandate, setSelectedMandate] = useState<Record<string, any> | null>(null);
|
||||
const [isCreatingMandate, setIsCreatingMandate] = useState(false);
|
||||
const [mandateForm, setMandateForm] = useState({ name: '', maxInstances: 1, quotaNamesPerYear: 100 });
|
||||
const [mandateForm, setMandateForm] = useState({ name: '' });
|
||||
|
||||
// Step 2: Mandate Users
|
||||
const [mandateUsers, setMandateUsers] = useState<MandateUser[]>([]);
|
||||
|
|
@ -205,8 +205,6 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
try {
|
||||
const response = await api.post('/api/mandates/', {
|
||||
name: mandateForm.name,
|
||||
maxInstances: mandateForm.maxInstances,
|
||||
quotaNamesPerYear: mandateForm.quotaNamesPerYear,
|
||||
enabled: true,
|
||||
});
|
||||
setSelectedMandate(response.data);
|
||||
|
|
@ -232,10 +230,10 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
if (result.success) {
|
||||
setIsAddingMandateUser(false);
|
||||
setAddMandateUserForm({ userId: '', roleIds: [] });
|
||||
showSuccess('Hinzugefügt', 'Benutzer zum Mandanten hinzugefügt');
|
||||
showSuccess('Hinzugefügt', 'Benutzer zum Mandanten hinzugefügt');
|
||||
await loadMandateUsers();
|
||||
} else {
|
||||
setError(result.error || 'Fehler beim Hinzufügen');
|
||||
setError(result.error || 'Fehler beim Hinzufügen');
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
|
|
@ -280,10 +278,10 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
if (!selectedMandate) return;
|
||||
const result = await deleteInstance(selectedMandate.id, instanceId);
|
||||
if (result.success) {
|
||||
showSuccess('Gelöscht', 'Instance gelöscht');
|
||||
showSuccess('Gelöscht', 'Instance gelöscht');
|
||||
await loadInstances();
|
||||
} else {
|
||||
setError(result.error || 'Fehler beim Löschen');
|
||||
setError(result.error || 'Fehler beim Löschen');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -299,10 +297,10 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
if (result.success) {
|
||||
setIsAddingInstanceUser(false);
|
||||
setAddInstanceUserForm({ userId: '', roleIds: [] });
|
||||
showSuccess('Hinzugefügt', 'Benutzer zur Feature-Instanz hinzugefügt');
|
||||
showSuccess('Hinzugefügt', 'Benutzer zur Feature-Instanz hinzugefügt');
|
||||
await loadInstanceUsers();
|
||||
} else {
|
||||
setError(result.error || 'Fehler beim Hinzufügen');
|
||||
setError(result.error || 'Fehler beim Hinzufügen');
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
|
|
@ -409,7 +407,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
value={formValue.userId}
|
||||
onChange={e => setFormValue(p => ({ ...p, userId: e.target.value }))}
|
||||
>
|
||||
<option value="">-- Benutzer wählen --</option>
|
||||
<option value="">-- Benutzer wählen --</option>
|
||||
{availableUsers.map(u => {
|
||||
const uid = u.userId || u.id || '';
|
||||
const name = getUserDisplayName(u as any);
|
||||
|
|
@ -447,7 +445,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
)}
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
<button className={styles.primaryButton} onClick={onSubmit} disabled={isLoading || !formValue.userId}>
|
||||
{isLoading ? 'Hinzufügen...' : 'Hinzufügen'}
|
||||
{isLoading ? 'Hinzufügen...' : 'Hinzufügen'}
|
||||
</button>
|
||||
<button className={styles.secondaryButton} onClick={onCancel}>
|
||||
Abbrechen
|
||||
|
|
@ -514,7 +512,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
<div className={styles.pageHeader}>
|
||||
<div>
|
||||
<h1 className={styles.pageTitle}>Mandanten-Verwaltung</h1>
|
||||
<p className={styles.pageSubtitle}>Schritt-für-Schritt Wizard zur Mandanten-Konfiguration</p>
|
||||
<p className={styles.pageSubtitle}>Schritt-für-Schritt Wizard zur Mandanten-Konfiguration</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -534,7 +532,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
{/* â•â•â• STEP 1: MANDATE â•â•â• */}
|
||||
{step === 1 && (
|
||||
<div style={cardStyle}>
|
||||
<h3 style={{ fontSize: '15px', fontWeight: 600, marginBottom: '16px', marginTop: 0 }}>Mandant auswählen oder erstellen</h3>
|
||||
<h3 style={{ fontSize: '15px', fontWeight: 600, marginBottom: '16px', marginTop: 0 }}>Mandant auswählen oder erstellen</h3>
|
||||
|
||||
{!isCreatingMandate ? (
|
||||
<>
|
||||
|
|
@ -555,9 +553,6 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
>
|
||||
<div>
|
||||
<div style={{ fontWeight: 600, fontSize: '14px' }}>{getMandateName(m)}</div>
|
||||
<div style={{ fontSize: '12px', color: 'var(--text-secondary)' }}>
|
||||
Max. {(m as any).maxInstances || '?'} Instances | Quota: {(m as any).quotaNamesPerYear || '?'} Namen/Jahr
|
||||
</div>
|
||||
</div>
|
||||
{selectedMandate?.id === m.id && <span style={{ color: 'var(--primary-color)', fontWeight: 700, fontSize: '16px' }}>{'\u2713'}</span>}
|
||||
</button>
|
||||
|
|
@ -578,29 +573,6 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
placeholder="z.B. Swiss Trust AG"
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
|
||||
<div className={styles.formGroup}>
|
||||
<label className={styles.formLabel}>Max. Instances</label>
|
||||
<input
|
||||
className={styles.formInput}
|
||||
type="number"
|
||||
min={1}
|
||||
value={mandateForm.maxInstances}
|
||||
onChange={e => setMandateForm(p => ({ ...p, maxInstances: parseInt(e.target.value) || 1 }))}
|
||||
/>
|
||||
<span style={{ fontSize: '11px', color: 'var(--text-secondary)' }}>1 = Einzelkunde, >1 = Service Provider</span>
|
||||
</div>
|
||||
<div className={styles.formGroup}>
|
||||
<label className={styles.formLabel}>Kontingent (Namen/Jahr)</label>
|
||||
<input
|
||||
className={styles.formInput}
|
||||
type="number"
|
||||
min={0}
|
||||
value={mandateForm.quotaNamesPerYear}
|
||||
onChange={e => setMandateForm(p => ({ ...p, quotaNamesPerYear: parseInt(e.target.value) || 0 }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
<button className={styles.primaryButton} onClick={handleCreateMandate} disabled={isLoading}>
|
||||
{isLoading ? 'Erstellen...' : 'Mandant erstellen'}
|
||||
|
|
@ -631,11 +603,11 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
onClick={() => setIsAddingMandateUser(true)}
|
||||
disabled={availableUsersForMandate.length === 0}
|
||||
>
|
||||
+ Benutzer hinzufügen
|
||||
+ Benutzer hinzufügen
|
||||
</button>
|
||||
</div>
|
||||
<p style={{ fontSize: '12px', color: 'var(--text-secondary)', marginBottom: '16px' }}>
|
||||
Alle Systembenutzer können dem Mandanten zugewiesen werden.
|
||||
Alle Systembenutzer können dem Mandanten zugewiesen werden.
|
||||
</p>
|
||||
|
||||
{isAddingMandateUser && renderAddUserForm(
|
||||
|
|
@ -652,7 +624,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div style={{ marginTop: '24px', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(1)}>← Zurück</button>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(1)}>← Zurück</button>
|
||||
<button className={styles.primaryButton} onClick={() => setStep(3)}>
|
||||
Weiter →
|
||||
</button>
|
||||
|
|
@ -665,10 +637,10 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
<div style={cardStyle}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
|
||||
<h3 style={{ fontSize: '15px', fontWeight: 600, margin: 0 }}>
|
||||
Feature-Instances für «{getMandateName(selectedMandate)}»
|
||||
Feature-Instances für «{getMandateName(selectedMandate)}»
|
||||
</h3>
|
||||
<span style={{ fontSize: '12px', color: 'var(--text-secondary)' }}>
|
||||
{instances.length} / {(selectedMandate as any).maxInstances || '?'} Instances
|
||||
{instances.length} Instances
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
@ -716,7 +688,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
}}
|
||||
onClick={() => handleDeleteInstance(inst.id)}
|
||||
>
|
||||
Löschen
|
||||
Löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -737,7 +709,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
value={selectedFeatureCode}
|
||||
onChange={e => setSelectedFeatureCode(e.target.value)}
|
||||
>
|
||||
<option value="">-- Feature wählen --</option>
|
||||
<option value="">-- Feature wählen --</option>
|
||||
{features.map(f => (
|
||||
<option key={f.code} value={f.code}>{getFeatureLabel(f.code)}</option>
|
||||
))}
|
||||
|
|
@ -770,7 +742,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
)}
|
||||
|
||||
<div style={{ marginTop: '24px', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(2)}>← Zurück</button>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(2)}>← Zurück</button>
|
||||
<button
|
||||
className={styles.primaryButton}
|
||||
onClick={() => { if (instances.length > 0) { setSelectedInstance(instances[0]); setStep(4); } }}
|
||||
|
|
@ -787,7 +759,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
<div style={cardStyle}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
|
||||
<h3 style={{ fontSize: '15px', fontWeight: 600, margin: 0 }}>
|
||||
Feature-Benutzer für «{selectedInstance.label}»
|
||||
Feature-Benutzer für «{selectedInstance.label}»
|
||||
</h3>
|
||||
<button
|
||||
className={styles.primaryButton}
|
||||
|
|
@ -795,11 +767,11 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
onClick={() => setIsAddingInstanceUser(true)}
|
||||
disabled={availableUsersForInstance.length === 0 || instanceRoles.length === 0}
|
||||
>
|
||||
+ Benutzer hinzufügen
|
||||
+ Benutzer hinzufügen
|
||||
</button>
|
||||
</div>
|
||||
<p style={{ fontSize: '12px', color: 'var(--text-secondary)', marginBottom: '16px' }}>
|
||||
Mandant: {getMandateName(selectedMandate)} | Mitglieder des Mandanten können der Feature-Instanz zugewiesen werden.
|
||||
Mandant: {getMandateName(selectedMandate)} | Mitglieder des Mandanten können der Feature-Instanz zugewiesen werden.
|
||||
</p>
|
||||
|
||||
{isAddingInstanceUser && renderAddUserForm(
|
||||
|
|
@ -819,7 +791,7 @@ export const AdminMandateWizardPage: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div style={{ marginTop: '24px', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(3)}>← Zurück</button>
|
||||
<button className={styles.secondaryButton} onClick={() => setStep(3)}>← Zurück</button>
|
||||
<button className={styles.primaryButton} onClick={() => {
|
||||
showSuccess('Fertig', 'Konfiguration abgeschlossen!');
|
||||
setSelectedInstance(null);
|
||||
|
|
|
|||
Loading…
Reference in a new issue