mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-24 21:16:40 +02:00
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:
parent
c7992040a3
commit
a275cf83e1
4 changed files with 113 additions and 85 deletions
|
|
@ -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 === */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue