website (17 pages + 3 components): - multiplayer/wizard, middleware/wizard+test-wizard, communication - builds/wizard, staff-search, voice, sbom/wizard - foerderantrag, mail/tasks, tools/communication, sbom - compliance/evidence, uni-crawler, brandbook (already done) - CollectionsTab, IngestionTab, RiskHeatmap backend-lehrer (5 files): - letters_api (641 → 2), certificates_api (636 → 2) - alerts_agent/db/models (636 → 3) - llm_gateway/communication_service (614 → 2) - game/database already done in prior batch klausur-service (2 files): - hybrid_vocab_extractor (664 → 2) - klausur-service/frontend: api.ts (620 → 3), EHUploadWizard (591 → 2) voice-service (3 files): - bqas/rag_judge (618 → 3), runner (529 → 2) - enhanced_task_orchestrator (519 → 2) studio-v2 (6 files): - korrektur/[klausurId] (578 → 4), fairness (569 → 2) - AlertsWizard (552 → 2), OnboardingWizard (513 → 2) - korrektur/api.ts (506 → 3), geo-lernwelt (501 → 2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
127 lines
4.3 KiB
TypeScript
127 lines
4.3 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { API_BASE } from './types'
|
|
|
|
interface CreateTaskModalProps {
|
|
onClose: () => void
|
|
onSuccess: () => void
|
|
}
|
|
|
|
export function CreateTaskModal({
|
|
onClose,
|
|
onSuccess
|
|
}: CreateTaskModalProps) {
|
|
const [formData, setFormData] = useState({
|
|
title: '',
|
|
description: '',
|
|
priority: 'medium',
|
|
deadline: '',
|
|
})
|
|
const [submitting, setSubmitting] = useState(false)
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
setSubmitting(true)
|
|
|
|
try {
|
|
const res = await fetch(`${API_BASE}/api/v1/mail/tasks`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
title: formData.title,
|
|
description: formData.description,
|
|
priority: formData.priority,
|
|
deadline: formData.deadline || null,
|
|
}),
|
|
})
|
|
|
|
if (res.ok) {
|
|
onSuccess()
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to create task:', err)
|
|
} finally {
|
|
setSubmitting(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
|
<div className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4">
|
|
<div className="p-6 border-b border-slate-200">
|
|
<h2 className="text-lg font-semibold text-slate-900">Neue Aufgabe erstellen</h2>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="p-6 space-y-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Titel</label>
|
|
<input
|
|
type="text"
|
|
required
|
|
value={formData.title}
|
|
onChange={(e) => setFormData({ ...formData, title: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
|
|
placeholder="Was muss erledigt werden?"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Beschreibung</label>
|
|
<textarea
|
|
value={formData.description}
|
|
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
|
|
rows={3}
|
|
placeholder="Weitere Details..."
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Prioritaet</label>
|
|
<select
|
|
value={formData.priority}
|
|
onChange={(e) => setFormData({ ...formData, priority: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
|
|
>
|
|
<option value="urgent">Dringend</option>
|
|
<option value="high">Hoch</option>
|
|
<option value="medium">Mittel</option>
|
|
<option value="low">Niedrig</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-slate-700 mb-1">Frist</label>
|
|
<input
|
|
type="date"
|
|
value={formData.deadline}
|
|
onChange={(e) => setFormData({ ...formData, deadline: e.target.value })}
|
|
className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-3 pt-4 border-t border-slate-200">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
className="px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 rounded-lg"
|
|
>
|
|
Abbrechen
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
disabled={submitting}
|
|
className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 disabled:opacity-50"
|
|
>
|
|
{submitting ? 'Erstellen...' : 'Aufgabe erstellen'}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|