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> </button>
)} )}
{/* Profile Builder */} {/* Edit form (only for new type creation, at top) */}
{editingProfileId && ( {editingId === 'new' && formData && (
<div style={{ marginBottom: 16 }}>
<ProfileBuilder
trainingType={types.find(t => t.id === editingProfileId)}
parameters={parameters}
onSave={handleSaveProfile}
onCancel={cancelEditProfile}
/>
</div>
)}
{/* Edit form */}
{editingId && formData && (
<div className="card" style={{ padding: 16, marginBottom: 16 }}> <div className="card" style={{ padding: 16, marginBottom: 16 }}>
<div style={{ fontWeight: 600, marginBottom: 12 }}> <div style={{ fontWeight: 600, marginBottom: 12 }}>
{editingId === 'new' ? ' Neuer Trainingstyp' : '✏️ Trainingstyp bearbeiten'} {editingId === 'new' ? ' Neuer Trainingstyp' : '✏️ Trainingstyp bearbeiten'}
@ -360,79 +348,182 @@ export default function AdminTrainingTypesPage() {
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}> <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
{catTypes.sort((a, b) => a.sort_order - b.sort_order).map(type => ( {catTypes.sort((a, b) => a.sort_order - b.sort_order).map(type => (
<div <div key={type.id}>
key={type.id} {/* Type Row */}
style={{ <div
display: 'flex', style={{
alignItems: 'center', display: 'flex',
gap: 8, alignItems: 'center',
padding: 8, gap: 8,
background: 'var(--surface)', padding: 8,
borderRadius: 6 background: 'var(--surface)',
}} borderRadius: 6
> }}
<div style={{ fontSize: 18 }}>{type.icon}</div> >
<div style={{ flex: 1 }}> <div style={{ fontSize: 18 }}>{type.icon}</div>
<div style={{ fontSize: 13, fontWeight: 500 }}> <div style={{ flex: 1 }}>
{type.name_de} <span style={{ color: 'var(--text3)' }}>/ {type.name_en}</span> <div style={{ fontSize: 13, fontWeight: 500 }}>
{type.profile && ( {type.name_de} <span style={{ color: 'var(--text3)' }}>/ {type.name_en}</span>
<span style={{ {type.profile && (
marginLeft: 8, <span style={{
padding: '2px 6px', marginLeft: 8,
background: 'var(--accent)', padding: '2px 6px',
color: 'white', background: 'var(--accent)',
borderRadius: 4, color: 'white',
fontSize: 10 borderRadius: 4,
}}> fontSize: 10
Profil }}>
</span> Profil
</span>
)}
</div>
{type.subcategory && (
<div style={{ fontSize: 11, color: 'var(--text3)' }}>
Subkategorie: {type.subcategory}
</div>
)} )}
</div> </div>
{type.subcategory && ( <button
<div style={{ fontSize: 11, color: 'var(--text3)' }}> onClick={() => startEditProfile(type.id)}
Subkategorie: {type.subcategory} style={{
</div> 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> </div>
<button
onClick={() => startEditProfile(type.id)} {/* Inline Profile Builder */}
style={{ {editingProfileId === type.id && (
background: 'none', <div style={{ marginTop: 8 }}>
border: 'none', <ProfileBuilder
cursor: 'pointer', trainingType={type}
padding: 6, parameters={parameters}
color: 'var(--accent)' onSave={handleSaveProfile}
}} onCancel={cancelEditProfile}
title="Profil konfigurieren" />
> </div>
<Settings size={16} /> )}
</button>
<button {/* Inline Type Editor */}
onClick={() => startEdit(type)} {editingId === type.id && formData && (
style={{ <div style={{ marginTop: 8, padding: 16, background: 'var(--surface2)', borderRadius: 8 }}>
background: 'none', <div style={{ fontWeight: 600, marginBottom: 12 }}> Trainingstyp bearbeiten</div>
border: 'none', <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
cursor: 'pointer', <div>
padding: 6, <div className="form-label">Kategorie *</div>
color: 'var(--accent)' <select
}} className="form-input"
title="Bearbeiten" value={formData.category}
> onChange={e => setFormData({ ...formData, category: e.target.value })}
<Pencil size={16} /> style={{ width: '100%' }}
</button> >
<button {Object.keys(categories).map(cat => (
onClick={() => handleDelete(type.id, type.name_de)} <option key={cat} value={cat}>
style={{ {categories[cat].icon} {categories[cat].name_de}
background: 'none', </option>
border: 'none', ))}
cursor: 'pointer', </select>
padding: 6, </div>
color: '#D85A30'
}} <div>
title="Löschen" <div className="form-label">Subkategorie</div>
> <input
<Trash2 size={16} /> className="form-input"
</button> 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>
))} ))}
</div> </div>