fix: restore inline editing for training type profiles
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 12s

- ProfileBuilder now renders inline below training type row
- Type editor form also inline (not at top of page)
- Both forms appear at item position with marginTop: 8
- User feedback: 'Die Position bleibt die ganze Zeit gleich!'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lars 2026-03-23 13:23:00 +01:00
parent 6fa15f7f57
commit 41c7084159

View File

@ -189,20 +189,8 @@ export default function AdminTrainingTypesPage() {
</button>
)}
{/* Profile Builder */}
{editingProfileId && (
<div style={{ marginBottom: 16 }}>
<ProfileBuilder
trainingType={types.find(t => t.id === editingProfileId)}
parameters={parameters}
onSave={handleSaveProfile}
onCancel={cancelEditProfile}
/>
</div>
)}
{/* Edit form */}
{editingId && formData && (
{/* Edit form (only for new type creation, at top) */}
{editingId === 'new' && formData && (
<div className="card" style={{ padding: 16, marginBottom: 16 }}>
<div style={{ fontWeight: 600, marginBottom: 12 }}>
{editingId === 'new' ? ' Neuer Trainingstyp' : '✏️ Trainingstyp bearbeiten'}
@ -360,79 +348,182 @@ export default function AdminTrainingTypesPage() {
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{catTypes.sort((a, b) => a.sort_order - b.sort_order).map(type => (
<div
key={type.id}
style={{
display: 'flex',
alignItems: 'center',
gap: 8,
padding: 8,
background: 'var(--surface)',
borderRadius: 6
}}
>
<div style={{ fontSize: 18 }}>{type.icon}</div>
<div style={{ flex: 1 }}>
<div style={{ fontSize: 13, fontWeight: 500 }}>
{type.name_de} <span style={{ color: 'var(--text3)' }}>/ {type.name_en}</span>
{type.profile && (
<span style={{
marginLeft: 8,
padding: '2px 6px',
background: 'var(--accent)',
color: 'white',
borderRadius: 4,
fontSize: 10
}}>
Profil
</span>
<div key={type.id}>
{/* Type Row */}
<div
style={{
display: 'flex',
alignItems: 'center',
gap: 8,
padding: 8,
background: 'var(--surface)',
borderRadius: 6
}}
>
<div style={{ fontSize: 18 }}>{type.icon}</div>
<div style={{ flex: 1 }}>
<div style={{ fontSize: 13, fontWeight: 500 }}>
{type.name_de} <span style={{ color: 'var(--text3)' }}>/ {type.name_en}</span>
{type.profile && (
<span style={{
marginLeft: 8,
padding: '2px 6px',
background: 'var(--accent)',
color: 'white',
borderRadius: 4,
fontSize: 10
}}>
Profil
</span>
)}
</div>
{type.subcategory && (
<div style={{ fontSize: 11, color: 'var(--text3)' }}>
Subkategorie: {type.subcategory}
</div>
)}
</div>
{type.subcategory && (
<div style={{ fontSize: 11, color: 'var(--text3)' }}>
Subkategorie: {type.subcategory}
</div>
)}
<button
onClick={() => startEditProfile(type.id)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: 'var(--accent)'
}}
title="Profil konfigurieren"
>
<Settings size={16} />
</button>
<button
onClick={() => startEdit(type)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: 'var(--accent)'
}}
title="Bearbeiten"
>
<Pencil size={16} />
</button>
<button
onClick={() => handleDelete(type.id, type.name_de)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: '#D85A30'
}}
title="Löschen"
>
<Trash2 size={16} />
</button>
</div>
<button
onClick={() => startEditProfile(type.id)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: 'var(--accent)'
}}
title="Profil konfigurieren"
>
<Settings size={16} />
</button>
<button
onClick={() => startEdit(type)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: 'var(--accent)'
}}
title="Bearbeiten"
>
<Pencil size={16} />
</button>
<button
onClick={() => handleDelete(type.id, type.name_de)}
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
padding: 6,
color: '#D85A30'
}}
title="Löschen"
>
<Trash2 size={16} />
</button>
{/* Inline Profile Builder */}
{editingProfileId === type.id && (
<div style={{ marginTop: 8 }}>
<ProfileBuilder
trainingType={type}
parameters={parameters}
onSave={handleSaveProfile}
onCancel={cancelEditProfile}
/>
</div>
)}
{/* Inline Type Editor */}
{editingId === type.id && formData && (
<div style={{ marginTop: 8, padding: 16, background: 'var(--surface2)', borderRadius: 8 }}>
<div style={{ fontWeight: 600, marginBottom: 12 }}> Trainingstyp bearbeiten</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div>
<div className="form-label">Kategorie *</div>
<select
className="form-input"
value={formData.category}
onChange={e => setFormData({ ...formData, category: e.target.value })}
style={{ width: '100%' }}
>
{Object.keys(categories).map(cat => (
<option key={cat} value={cat}>
{categories[cat].icon} {categories[cat].name_de}
</option>
))}
</select>
</div>
<div>
<div className="form-label">Subkategorie</div>
<input
className="form-input"
value={formData.subcategory}
onChange={e => setFormData({ ...formData, subcategory: e.target.value })}
placeholder="z.B. running, hypertrophy, meditation"
style={{ width: '100%' }}
/>
</div>
<div>
<div className="form-label">Name (Deutsch) *</div>
<input
className="form-input"
value={formData.name_de}
onChange={e => setFormData({ ...formData, name_de: e.target.value })}
placeholder="z.B. Laufen"
style={{ width: '100%' }}
/>
</div>
<div>
<div className="form-label">Name (English) *</div>
<input
className="form-input"
value={formData.name_en}
onChange={e => setFormData({ ...formData, name_en: e.target.value })}
placeholder="e.g. Running"
style={{ width: '100%' }}
/>
</div>
<div>
<div className="form-label">Icon (Emoji)</div>
<input
className="form-input"
value={formData.icon}
onChange={e => setFormData({ ...formData, icon: e.target.value })}
placeholder="🏃"
maxLength={10}
style={{ width: '100%' }}
/>
</div>
<div>
<div className="form-label">Sortierung</div>
<input
type="number"
className="form-input"
value={formData.sort_order}
onChange={e => setFormData({ ...formData, sort_order: parseInt(e.target.value) })}
style={{ width: '100%' }}
/>
</div>
<div style={{ display: 'flex', gap: 8 }}>
<button onClick={handleSave} disabled={saving} className="btn btn-primary" style={{ flex: 1 }}>
{saving ? <><div className="spinner" style={{ width: 14, height: 14 }} /> Speichere...</> : <><Save size={16} /> Speichern</>}
</button>
<button onClick={cancelEdit} disabled={saving} className="btn btn-secondary" style={{ flex: 1 }}>
<X size={16} /> Abbrechen
</button>
</div>
</div>
</div>
)}
</div>
))}
</div>