Files
werte-next/components/WerteForm.tsx
rxf 5fbfc067af Spinner an den Eingabe entfernt
mifgration.ts duchr proxy.ts ersetzt
2026-03-04 08:23:39 +01:00

275 lines
10 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useState, useEffect } from 'react';
import { CreateWerteEntry, WerteEntry } from '@/types/werte';
interface WerteFormProps {
onSuccess: () => void;
selectedEntry?: WerteEntry | null;
}
export default function WerteForm({ onSuccess, selectedEntry }: WerteFormProps) {
const [formData, setFormData] = useState<CreateWerteEntry>({
Datum: '',
Zeit: '',
Zucker: '',
Essen: 'nüchtern',
Gewicht: '',
DruckS: '',
DruckD: '',
Puls: '',
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [weekday, setWeekday] = useState('');
const [editId, setEditId] = useState<number | null>(null);
useEffect(() => {
if (selectedEntry) {
// Load selected entry for editing
const dateStr = selectedEntry.Datum.toString().split('T')[0];
const timeStr = selectedEntry.Zeit.toString().substring(0, 5);
setFormData({
Datum: dateStr,
Zeit: timeStr,
Zucker: selectedEntry.Zucker || '',
Essen: selectedEntry.Essen || '',
Gewicht: selectedEntry.Gewicht || '',
DruckS: selectedEntry.DruckS || '',
DruckD: selectedEntry.DruckD || '',
Puls: selectedEntry.Puls || '',
});
setEditId(selectedEntry.ID || null);
// Parse date to avoid timezone issues
const [year, month, day] = dateStr.split('T')[0].split('-');
const date = new Date(Number(year), Number(month) - 1, Number(day));
updateWeekday(date);
} else {
// Initialize with current date and time for new entry
const now = new Date();
const dateStr = now.toISOString().split('T')[0];
const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
setFormData(prev => ({
...prev,
Datum: dateStr,
Zeit: timeStr,
}));
setEditId(null);
updateWeekday(now);
}
}, [selectedEntry]);
const updateWeekday = (date: Date) => {
const weekdays = ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'];
setWeekday(weekdays[date.getDay()]);
};
const handleDateChange = (dateStr: string) => {
setFormData(prev => ({ ...prev, Datum: dateStr }));
// Parse date to avoid timezone issues
const [year, month, day] = dateStr.split('-');
const date = new Date(Number(year), Number(month) - 1, Number(day));
updateWeekday(date);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
try {
const url = editId ? `/api/werte/${editId}` : '/api/werte';
const method = editId ? 'PUT' : 'POST';
const response = await fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
});
if (response.ok) {
// Reset form but keep date and time
const now = new Date();
const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
setFormData(prev => ({
...prev,
Zeit: timeStr,
Zucker: '',
Essen: 'nüchtern',
Gewicht: '',
DruckS: '',
DruckD: '',
Puls: '',
}));
setEditId(null);
onSuccess();
} else {
alert('Fehler beim Speichern!');
}
} catch (error) {
console.error('Error:', error);
alert('Fehler beim Speichern!');
} finally {
setIsSubmitting(false);
}
};
const handleReset = () => {
const now = new Date();
const dateStr = now.toISOString().split('T')[0];
const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
setFormData({
Datum: dateStr,
Zeit: timeStr,
Zucker: '',
Essen: 'nüchtern',
Gewicht: '',
DruckS: '',
DruckD: '',
Puls: '',
});
setEditId(null);
updateWeekday(now);
};
return (
<div className="bg-[#CCCCFF] border border-black p-6 rounded-lg mb-6">
{editId && (
<div className="mb-4 p-3 bg-blue-100 border border-blue-400 rounded text-sm text-blue-800">
<strong>Bearbeitungsmodus:</strong> Sie bearbeiten einen bestehenden Eintrag. Klicken Sie auf &quot;Aktualisieren&quot;, um die Änderungen zu speichern, oder &quot;Abbrechen&quot;, um zur Neuerfassung zurückzukehren.
</div>
)}
<form onSubmit={handleSubmit}>
<table className="w-full text-center">
<thead>
<tr className="border-b-2 border-gray-400">
<th className="p-2">Datum</th>
<th className="p-2">Zeit</th>
<th className="p-2">Zucker</th>
<th className="p-2">Essen</th>
<th className="p-2">Gewicht</th>
<th className="p-2">Druck sys</th>
<th className="p-2">Druck dia</th>
<th className="p-2">Puls</th>
</tr>
<tr className="border-b-2 border-gray-400">
<th className="p-2 font-normal text-sm">{weekday}</th>
<th className="p-2"></th>
<th className="p-2 font-normal text-sm">mg/dl</th>
<th className="p-2"></th>
<th className="p-2 font-normal text-sm">kg</th>
<th className="p-2 font-normal text-sm">mmHg</th>
<th className="p-2 font-normal text-sm">mmHg</th>
<th className="p-2 font-normal text-sm">bpm</th>
</tr>
</thead>
<tbody>
<tr>
<td className="p-2">
<input
type="date"
className="w-full px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none"
value={formData.Datum}
onChange={(e) => handleDateChange(e.target.value)}
required
/>
</td>
<td className="p-2">
<input
type="time"
className="w-full px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none"
value={formData.Zeit}
onChange={(e) => setFormData(prev => ({ ...prev, Zeit: e.target.value }))}
required
/>
</td>
<td className="p-2">
<input
type="number"
className="w-20 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={formData.Zucker}
onChange={(e) => setFormData(prev => ({ ...prev, Zucker: e.target.value }))}
maxLength={4}
/>
</td>
<td className="p-2">
<textarea
className="w-full px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none resize-none align-middle"
style={{ height: '28px' }}
value={formData.Essen}
onChange={(e) => setFormData(prev => ({ ...prev, Essen: e.target.value }))}
rows={1}
/>
</td>
<td className="p-2">
<input
type="number"
step="0.1"
className="w-20 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={formData.Gewicht}
onChange={(e) => setFormData(prev => ({ ...prev, Gewicht: e.target.value }))}
maxLength={4}
/>
</td>
<td className="p-2">
<input
type="number"
className="w-20 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={formData.DruckS}
onChange={(e) => setFormData(prev => ({ ...prev, DruckS: e.target.value }))}
maxLength={4}
/>
</td>
<td className="p-2">
<input
type="number"
className="w-20 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={formData.DruckD}
onChange={(e) => setFormData(prev => ({ ...prev, DruckD: e.target.value }))}
maxLength={4}
/>
</td>
<td className="p-2">
<input
type="number"
className="w-20 px-2 py-1 text-sm rounded border-2 border-gray-400 bg-white focus:border-blue-500 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={formData.Puls}
onChange={(e) => setFormData(prev => ({ ...prev, Puls: e.target.value }))}
maxLength={4}
/>
</td>
</tr>
</tbody>
</table>
<div className="flex justify-center gap-4 mt-6">
<button
type="submit"
disabled={isSubmitting}
className="bg-[#85B7D7] hover:bg-[#6a9fc5] text-black font-medium py-2 px-8 rounded-lg transition-colors disabled:opacity-50"
>
{isSubmitting ? (editId ? 'Aktualisieren...' : 'Speichern...') : (editId ? 'Aktualisieren' : 'Speichern')}
</button>
<button
type="button"
onClick={handleReset}
className="bg-[#85B7D7] hover:bg-[#6a9fc5] text-black font-medium py-2 px-8 rounded-lg transition-colors"
>
{editId ? 'Abbrechen' : 'Löschen'}
</button>
</div>
</form>
</div>
);
}