feat: move input forms into section headers for Skills, Languages and Experience

Input fields now appear inline next to the section title, matching the
layout pattern used by Projects, Certifications and Attachments sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Thomas Reitz 2026-03-09 10:47:31 +01:00
parent c7992040a3
commit a275cf83e1
4 changed files with 113 additions and 85 deletions

View file

@ -54,6 +54,52 @@
font-size: 1rem;
font-weight: 600;
margin: 0;
white-space: nowrap;
}
/* === Header Form (inline neben Titel) === */
.headerForm {
display: flex;
gap: 0.375rem;
align-items: center;
}
.headerForm input,
.headerForm select {
padding: 0.375rem 0.5rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
font-size: 0.8125rem;
}
.headerForm input {
max-width: 160px;
}
.headerForm input:focus,
.headerForm select:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 2px var(--color-primary-light);
}
@media (max-width: 640px) {
.sectionHeader {
flex-direction: column;
align-items: flex-start;
gap: 0.75rem;
}
.headerForm {
flex-wrap: wrap;
width: 100%;
}
.headerForm input {
max-width: none;
flex: 1;
min-width: 120px;
}
}
/* === Chips/Tags === */

View file

@ -55,6 +55,35 @@ export function ExperienceSection({ experiences, onUpdate }: ExperienceSectionPr
<div className={styles.section}>
<div className={styles.sectionHeader}>
<h3 className={styles.sectionTitle}>Erfahrung</h3>
<form onSubmit={handleAdd} className={styles.headerForm}>
<input
type="text"
value={area}
onChange={(e) => setArea(e.target.value)}
placeholder="z.B. IT Infrastruktur"
maxLength={200}
required
/>
<input
type="number"
value={years}
onChange={(e) => setYears(e.target.value)}
placeholder="Jahre"
min={0}
max={60}
style={{ width: '70px' }}
required
/>
<select value={level} onChange={(e) => setLevel(e.target.value)}>
<option value="">Level</option>
<option value="Experte">Experte</option>
<option value="Fortgeschritten">Fortgeschritten</option>
<option value="Grundkenntnisse">Grundkenntnisse</option>
</select>
<button type="submit" className={styles.btnPrimary} disabled={loading || !area.trim() || !years}>
Hinzufügen
</button>
</form>
</div>
{error && <div className={styles.error}>{error}</div>}
@ -85,45 +114,6 @@ export function ExperienceSection({ experiences, onUpdate }: ExperienceSectionPr
) : (
<p className={styles.emptyState}>Noch keine Erfahrung hinzugefügt</p>
)}
<form onSubmit={handleAdd} className={styles.addForm}>
<div className={styles.fieldInline}>
<label>Bereich</label>
<input
type="text"
value={area}
onChange={(e) => setArea(e.target.value)}
placeholder="z.B. IT Infrastruktur"
maxLength={200}
required
/>
</div>
<div className={styles.fieldInline}>
<label>Jahre</label>
<input
type="number"
value={years}
onChange={(e) => setYears(e.target.value)}
placeholder="0"
min={0}
max={60}
style={{ width: '80px' }}
required
/>
</div>
<div className={styles.fieldInline}>
<label>Level</label>
<select value={level} onChange={(e) => setLevel(e.target.value)}>
<option value=""> Optional </option>
<option value="Experte">Experte</option>
<option value="Fortgeschritten">Fortgeschritten</option>
<option value="Grundkenntnisse">Grundkenntnisse</option>
</select>
</div>
<button type="submit" className={styles.btnPrimary} disabled={loading || !area.trim() || !years}>
Hinzufügen
</button>
</form>
</div>
);
}

View file

@ -54,6 +54,25 @@ export function LanguagesSection({ languages, onUpdate }: LanguagesSectionProps)
<div className={styles.section}>
<div className={styles.sectionHeader}>
<h3 className={styles.sectionTitle}>Sprachen</h3>
<form onSubmit={handleAdd} className={styles.headerForm}>
<input
type="text"
value={language}
onChange={(e) => setLanguage(e.target.value)}
placeholder="z.B. Deutsch"
maxLength={100}
required
/>
<select value={level} onChange={(e) => setLevel(e.target.value)} required>
<option value="">Niveau</option>
{LANGUAGE_LEVELS.map((l) => (
<option key={l} value={l}>{l}</option>
))}
</select>
<button type="submit" className={styles.btnPrimary} disabled={loading || !language.trim() || !level}>
Hinzufügen
</button>
</form>
</div>
{error && <div className={styles.error}>{error}</div>}
@ -83,32 +102,6 @@ export function LanguagesSection({ languages, onUpdate }: LanguagesSectionProps)
) : (
<p className={styles.emptyState}>Noch keine Sprachen hinzugefügt</p>
)}
<form onSubmit={handleAdd} className={styles.addForm}>
<div className={styles.fieldInline}>
<label>Sprache</label>
<input
type="text"
value={language}
onChange={(e) => setLanguage(e.target.value)}
placeholder="z.B. Deutsch"
maxLength={100}
required
/>
</div>
<div className={styles.fieldInline}>
<label>Niveau</label>
<select value={level} onChange={(e) => setLevel(e.target.value)} required>
<option value="">Bitte wählen</option>
{LANGUAGE_LEVELS.map((l) => (
<option key={l} value={l}>{l}</option>
))}
</select>
</div>
<button type="submit" className={styles.btnPrimary} disabled={loading || !language.trim() || !level}>
Hinzufügen
</button>
</form>
</div>
);
}

View file

@ -59,6 +59,25 @@ export function SkillsSection({ skills, onUpdate }: SkillsSectionProps) {
<div className={styles.section}>
<div className={styles.sectionHeader}>
<h3 className={styles.sectionTitle}>Skills</h3>
<div className={styles.chipInput}>
<input
type="text"
value={newSkill}
onChange={(e) => setNewSkill(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Neuer Skill..."
maxLength={100}
disabled={loading}
/>
<button
type="button"
className={styles.btnPrimary}
onClick={handleAdd}
disabled={loading || !newSkill.trim()}
>
Hinzufügen
</button>
</div>
</div>
{error && <div className={styles.error}>{error}</div>}
@ -83,26 +102,6 @@ export function SkillsSection({ skills, onUpdate }: SkillsSectionProps) {
) : (
<p className={styles.emptyState}>Noch keine Skills hinzugefügt</p>
)}
<div className={styles.chipInput}>
<input
type="text"
value={newSkill}
onChange={(e) => setNewSkill(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Neuer Skill..."
maxLength={100}
disabled={loading}
/>
<button
type="button"
className={styles.btnPrimary}
onClick={handleAdd}
disabled={loading || !newSkill.trim()}
>
Hinzufügen
</button>
</div>
</div>
);
}