119 lines
3.6 KiB
React
119 lines
3.6 KiB
React
|
|
import React from 'react'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Inline-Angebot: aus Suchstring neue Übung per KI anlegen (Fokusbereich + optional Titel/Skizze).
|
||
|
|
*/
|
||
|
|
export default function ExerciseAiQuickCreateOffer({
|
||
|
|
searchLabel,
|
||
|
|
title,
|
||
|
|
onTitleChange,
|
||
|
|
sketch,
|
||
|
|
onSketchChange,
|
||
|
|
focusAreaId,
|
||
|
|
onFocusAreaChange,
|
||
|
|
focusAreas = [],
|
||
|
|
catalogsReady = true,
|
||
|
|
busy = false,
|
||
|
|
error = '',
|
||
|
|
onRunAi,
|
||
|
|
showSketchField = false,
|
||
|
|
hint,
|
||
|
|
}) {
|
||
|
|
const canRun =
|
||
|
|
!busy &&
|
||
|
|
(title || '').trim().length >= 3 &&
|
||
|
|
(sketch || '').trim().length > 0 &&
|
||
|
|
focusAreaId
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className="card"
|
||
|
|
style={{
|
||
|
|
padding: '14px 16px',
|
||
|
|
marginBottom: '12px',
|
||
|
|
borderColor: 'var(--accent-dark, rgba(29,158,117,0.35))',
|
||
|
|
background: 'var(--surface2)',
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<strong style={{ display: 'block', marginBottom: '6px', fontSize: '0.95rem' }}>
|
||
|
|
Keine passende Übung gefunden
|
||
|
|
</strong>
|
||
|
|
<p style={{ margin: '0 0 12px', fontSize: '13px', color: 'var(--text2)', lineHeight: 1.45 }}>
|
||
|
|
{hint ||
|
||
|
|
(searchLabel
|
||
|
|
? `Für „${searchLabel}“ lässt sich eine neue Übung mit KI vorschlagen — Texte danach bearbeiten und speichern.`
|
||
|
|
: 'Neue Übung mit KI vorschlagen — Texte danach bearbeiten und speichern.')}
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<div style={{ display: 'grid', gap: '10px' }}>
|
||
|
|
<div>
|
||
|
|
<label className="form-label" htmlFor="ex-ai-quick-title">
|
||
|
|
Titel *
|
||
|
|
</label>
|
||
|
|
<input
|
||
|
|
id="ex-ai-quick-title"
|
||
|
|
type="text"
|
||
|
|
className="form-input"
|
||
|
|
value={title}
|
||
|
|
onChange={(e) => onTitleChange(e.target.value)}
|
||
|
|
autoComplete="off"
|
||
|
|
maxLength={300}
|
||
|
|
placeholder="Titel der neuen Übung"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div>
|
||
|
|
<label className="form-label" htmlFor="ex-ai-quick-focus">
|
||
|
|
Fokusbereich *
|
||
|
|
</label>
|
||
|
|
<select
|
||
|
|
id="ex-ai-quick-focus"
|
||
|
|
className="form-input"
|
||
|
|
value={focusAreaId}
|
||
|
|
onChange={(e) => onFocusAreaChange(e.target.value)}
|
||
|
|
disabled={!catalogsReady}
|
||
|
|
>
|
||
|
|
<option value="">— wählen —</option>
|
||
|
|
{(focusAreas || []).map((fa) => (
|
||
|
|
<option key={fa.id} value={String(fa.id)}>
|
||
|
|
{`${fa.icon ? `${fa.icon} ` : ''}${fa.name || `#${fa.id}`}`.trim()}
|
||
|
|
</option>
|
||
|
|
))}
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{showSketchField ? (
|
||
|
|
<div>
|
||
|
|
<label className="form-label" htmlFor="ex-ai-quick-sketch">
|
||
|
|
Skizze / Idee *
|
||
|
|
</label>
|
||
|
|
<textarea
|
||
|
|
id="ex-ai-quick-sketch"
|
||
|
|
className="form-input"
|
||
|
|
rows={3}
|
||
|
|
value={sketch}
|
||
|
|
onChange={(e) => onSketchChange(e.target.value)}
|
||
|
|
placeholder="Kurze Beschreibung für die KI …"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
<p style={{ margin: 0, fontSize: '12px', color: 'var(--text3)' }}>
|
||
|
|
Ausgangstext: {(sketch || '').trim().slice(0, 160)}
|
||
|
|
{(sketch || '').trim().length > 160 ? '…' : ''}
|
||
|
|
</p>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{error ? (
|
||
|
|
<p style={{ margin: 0, fontSize: '13px', color: 'var(--danger)' }}>{error}</p>
|
||
|
|
) : null}
|
||
|
|
|
||
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||
|
|
<button type="button" className="btn btn-primary" disabled={!canRun} onClick={() => onRunAi()}>
|
||
|
|
{busy ? 'KI erzeugt Vorschlag…' : 'Mit KI anlegen'}
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|